summaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen/code-stub-assembler.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/codegen/code-stub-assembler.h')
-rw-r--r--deps/v8/src/codegen/code-stub-assembler.h199
1 files changed, 124 insertions, 75 deletions
diff --git a/deps/v8/src/codegen/code-stub-assembler.h b/deps/v8/src/codegen/code-stub-assembler.h
index 559deafa85..fa41984c6a 100644
--- a/deps/v8/src/codegen/code-stub-assembler.h
+++ b/deps/v8/src/codegen/code-stub-assembler.h
@@ -82,6 +82,9 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(NoElementsProtector, no_elements_protector, NoElementsProtector) \
V(MegaDOMProtector, mega_dom_protector, MegaDOMProtector) \
V(NumberStringCache, number_string_cache, NumberStringCache) \
+ V(NumberStringPrototypeNoReplaceProtector, \
+ number_string_prototype_no_replace_protector, \
+ NumberStringPrototypeNoReplaceProtector) \
V(PromiseAllResolveElementSharedFun, promise_all_resolve_element_shared_fun, \
PromiseAllResolveElementSharedFun) \
V(PromiseAllSettledRejectElementSharedFun, \
@@ -163,7 +166,6 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap) \
V(Function_string, function_string, FunctionString) \
V(function_to_string, function_to_string, FunctionToString) \
- V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap) \
V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol) \
V(Infinity_string, Infinity_string, InfinityString) \
V(is_concat_spreadable_symbol, is_concat_spreadable_symbol, \
@@ -184,6 +186,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap) \
V(null_to_string, null_to_string, NullToString) \
V(NullValue, null_value, Null) \
+ IF_WASM(V, WasmNull, wasm_null, WasmNull) \
V(number_string, number_string, NumberString) \
V(number_to_string, number_to_string, NumberToString) \
V(Object_string, Object_string, ObjectString) \
@@ -501,6 +504,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// TODO(v8:9708): Define BInt operations once all uses are ported.
PARAMETER_BINOP(IntPtrOrSmiEqual, WordEqual, SmiEqual)
PARAMETER_BINOP(IntPtrOrSmiNotEqual, WordNotEqual, SmiNotEqual)
+ PARAMETER_BINOP(IntPtrOrSmiLessThan, IntPtrLessThan, SmiLessThan)
PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual,
SmiLessThanOrEqual)
PARAMETER_BINOP(IntPtrOrSmiGreaterThan, IntPtrGreaterThan, SmiGreaterThan)
@@ -781,6 +785,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// BigInt operations.
void GotoIfLargeBigInt(TNode<BigInt> bigint, Label* true_label);
+ TNode<Word32T> NormalizeShift32OperandIfNecessary(TNode<Word32T> right32);
TNode<Number> BitwiseOp(TNode<Word32T> left32, TNode<Word32T> right32,
Operation bitwise_op);
TNode<Number> BitwiseSmiOp(TNode<Smi> left32, TNode<Smi> right32,
@@ -832,63 +837,28 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void FastCheck(TNode<BoolT> condition);
- TNode<BoolT> IsCodeTMap(TNode<Map> map) {
- return V8_EXTERNAL_CODE_SPACE_BOOL ? IsCodeDataContainerMap(map)
- : IsCodeMap(map);
- }
- TNode<BoolT> IsCodeT(TNode<HeapObject> object) {
- return IsCodeTMap(LoadMap(object));
- }
-
- // TODO(v8:11880): remove once Code::bytecode_or_interpreter_data field
- // is cached in or moved to CodeT.
- TNode<Code> FromCodeTNonBuiltin(TNode<CodeT> code) {
-#ifdef V8_EXTERNAL_CODE_SPACE
- // Compute the Code object pointer from the code entry point.
+ // TODO(v8:11880): remove once InstructionStream::bytecode_or_interpreter_data
+ // field is cached in or moved to Code.
+ TNode<InstructionStream> FromCodeNonBuiltin(TNode<Code> code) {
+ // Compute the InstructionStream object pointer from the code entry point.
TNode<RawPtrT> code_entry = Load<RawPtrT>(
- code, IntPtrConstant(CodeDataContainer::kCodeEntryPointOffset -
- kHeapObjectTag));
+ code, IntPtrConstant(Code::kCodeEntryPointOffset - kHeapObjectTag));
TNode<Object> o = BitcastWordToTagged(IntPtrSub(
- code_entry, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)));
+ code_entry,
+ IntPtrConstant(InstructionStream::kHeaderSize - kHeapObjectTag)));
return CAST(o);
-#else
- return code;
-#endif
}
- TNode<CodeDataContainer> CodeDataContainerFromCodeT(TNode<CodeT> code) {
-#ifdef V8_EXTERNAL_CODE_SPACE
- return code;
-#else
- return LoadObjectField<CodeDataContainer>(code,
- Code::kCodeDataContainerOffset);
-#endif
+ TNode<Code> ToCode(TNode<InstructionStream> code) {
+ return LoadObjectField<Code>(code, InstructionStream::kCodeOffset);
}
- TNode<CodeT> ToCodeT(TNode<Code> code) {
-#ifdef V8_EXTERNAL_CODE_SPACE
- return LoadObjectField<CodeDataContainer>(code,
- Code::kCodeDataContainerOffset);
-#else
- return code;
-#endif
- }
-
- TNode<CodeT> ToCodeT(TNode<Code> code,
- TNode<CodeDataContainer> code_data_container) {
-#ifdef V8_EXTERNAL_CODE_SPACE
- return code_data_container;
-#else
- return code;
-#endif
- }
-
- TNode<RawPtrT> GetCodeEntry(TNode<CodeT> code);
- TNode<BoolT> IsMarkedForDeoptimization(TNode<CodeT> codet);
+ TNode<RawPtrT> GetCodeEntry(TNode<Code> code);
+ TNode<BoolT> IsMarkedForDeoptimization(TNode<Code> code);
// The following Call wrappers call an object according to the semantics that
// one finds in the EcmaScript spec, operating on an Callable (e.g. a
- // JSFunction or proxy) rather than a Code object.
+ // JSFunction or proxy) rather than a InstructionStream object.
template <class... TArgs>
TNode<Object> Call(TNode<Context> context, TNode<Object> callable,
TNode<JSReceiver> receiver, TArgs... args) {
@@ -909,11 +879,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
}
TNode<Object> CallApiCallback(TNode<Object> context, TNode<RawPtrT> callback,
- TNode<IntPtrT> argc, TNode<Object> data,
+ TNode<Int32T> argc, TNode<Object> data,
TNode<Object> holder, TNode<Object> receiver);
TNode<Object> CallApiCallback(TNode<Object> context, TNode<RawPtrT> callback,
- TNode<IntPtrT> argc, TNode<Object> data,
+ TNode<Int32T> argc, TNode<Object> data,
TNode<Object> holder, TNode<Object> receiver,
TNode<Object> value);
@@ -1193,6 +1163,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
kExternalStringResourceDataTag);
}
+ TNode<RawPtr<Uint64T>> Log10OffsetTable() {
+ return ReinterpretCast<RawPtr<Uint64T>>(
+ ExternalConstant(ExternalReference::address_of_log10_offset_table()));
+ }
+
#if V8_ENABLE_WEBASSEMBLY
TNode<RawPtrT> LoadWasmInternalFunctionCallTargetPtr(
TNode<WasmInternalFunction> object) {
@@ -1241,6 +1216,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return LoadBufferData<IntPtrT>(buffer, offset);
}
TNode<Uint8T> LoadUint8Ptr(TNode<RawPtrT> ptr, TNode<IntPtrT> offset);
+ TNode<Uint64T> LoadUint64Ptr(TNode<RawPtrT> ptr, TNode<IntPtrT> index);
// Load a field from an object on the heap.
template <class T, typename std::enable_if<
@@ -1538,7 +1514,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsWeakReferenceToObject(TNode<MaybeObject> maybe_object,
TNode<Object> object);
- TNode<MaybeObject> MakeWeak(TNode<HeapObject> value);
+ TNode<HeapObjectReference> MakeWeak(TNode<HeapObject> value);
TNode<MaybeObject> ClearedValue();
void FixedArrayBoundsCheck(TNode<FixedArrayBase> array, TNode<Smi> index,
@@ -1864,13 +1840,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void StoreJSSharedStructPropertyArrayElement(TNode<PropertyArray> array,
TNode<IntPtrT> index,
TNode<Object> value) {
- // JSSharedStructs are allocated in the shared old space, which is currently
- // collected by stopping the world, so the incremental write barrier is not
- // needed. They can only store Smis and other HeapObjects in the shared old
- // space, so the generational write barrier is also not needed.
- // TODO(v8:12547): Add a safer, shared variant of SKIP_WRITE_BARRIER.
- StoreFixedArrayOrPropertyArrayElement(array, index, value,
- UNSAFE_SKIP_WRITE_BARRIER);
+ StoreFixedArrayOrPropertyArrayElement(array, index, value);
}
// EnsureArrayPushable verifies that receiver with this map is:
@@ -2468,17 +2438,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Object> value);
void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
Label* if_number, TVariable<Word32T>* var_word32,
- Label* if_bigint,
+ Label* if_bigint, Label* if_bigint64,
TVariable<BigInt>* var_maybe_bigint);
void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
TNode<Object> value, Label* if_number,
TVariable<Word32T>* var_word32,
- Label* if_bigint,
+ Label* if_bigint, Label* if_bigint64,
TVariable<BigInt>* var_maybe_bigint,
TVariable<Smi>* var_feedback);
void TaggedPointerToWord32OrBigIntWithFeedback(
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
- TVariable<Word32T>* var_word32, Label* if_bigint,
+ TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
TVariable<BigInt>* var_maybe_bigint, TVariable<Smi>* var_feedback);
TNode<Int32T> TruncateNumberToWord32(TNode<Number> value);
@@ -2508,11 +2478,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Int32T> ChangeBoolToInt32(TNode<BoolT> b);
- void TaggedToNumeric(TNode<Context> context, TNode<Object> value,
- TVariable<Numeric>* var_numeric);
- void TaggedToNumericWithFeedback(TNode<Context> context, TNode<Object> value,
- TVariable<Numeric>* var_numeric,
- TVariable<Smi>* var_feedback);
+ void TaggedToBigInt(TNode<Context> context, TNode<Object> value,
+ Label* if_not_bigint, Label* if_bigint,
+ Label* if_bigint64, TVariable<BigInt>* var_bigint,
+ TVariable<Smi>* var_feedback);
// Ensures that {var_shared_value} is shareable across Isolates, and throws if
// not.
@@ -2595,6 +2564,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> InstanceTypeEqual(TNode<Int32T> instance_type, int type);
TNode<BoolT> IsNoElementsProtectorCellInvalid();
TNode<BoolT> IsMegaDOMProtectorCellInvalid();
+ TNode<BoolT> IsAlwaysSharedSpaceJSObjectInstanceType(
+ TNode<Int32T> instance_type);
TNode<BoolT> IsArrayIteratorProtectorCellInvalid();
TNode<BoolT> IsBigIntInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsBigInt(TNode<HeapObject> object);
@@ -2627,6 +2598,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsIndirectStringInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsJSArrayBuffer(TNode<HeapObject> object);
TNode<BoolT> IsJSDataView(TNode<HeapObject> object);
+ TNode<BoolT> IsJSRabGsabDataView(TNode<HeapObject> object);
TNode<BoolT> IsJSArrayInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsJSArrayMap(TNode<Map> map);
TNode<BoolT> IsJSArray(TNode<HeapObject> object);
@@ -2658,6 +2630,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsJSReceiverInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsJSReceiverMap(TNode<Map> map);
TNode<BoolT> IsJSReceiver(TNode<HeapObject> object);
+ // The following two methods assume that we deal either with a primitive
+ // object or a JS receiver.
+ TNode<BoolT> JSAnyIsNotPrimitiveMap(TNode<Map> map);
+ TNode<BoolT> JSAnyIsNotPrimitive(TNode<HeapObject> object);
TNode<BoolT> IsJSRegExp(TNode<HeapObject> object);
TNode<BoolT> IsJSTypedArrayInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsJSTypedArrayMap(TNode<Map> map);
@@ -2730,6 +2706,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsTypedArraySpeciesProtectorCellInvalid();
TNode<BoolT> IsRegExpSpeciesProtectorCellInvalid();
TNode<BoolT> IsPromiseSpeciesProtectorCellInvalid();
+ TNode<BoolT> IsNumberStringPrototypeNoReplaceProtectorCellInvalid();
TNode<IntPtrT> LoadBasicMemoryChunkFlags(TNode<HeapObject> object);
@@ -2875,6 +2852,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// Try to convert an object to a BigInt. Throws on failure (e.g. for Numbers).
// https://tc39.github.io/proposal-bigint/#sec-to-bigint
TNode<BigInt> ToBigInt(TNode<Context> context, TNode<Object> input);
+ // Try to convert any object to a BigInt, including Numbers.
+ TNode<BigInt> ToBigIntConvertNumber(TNode<Context> context,
+ TNode<Object> input);
// Converts |input| to one of 2^32 integer values in the range 0 through
// 2^32-1, inclusive.
@@ -3234,6 +3214,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
next_enum_index_smi, SKIP_WRITE_BARRIER);
}
+ template <class Dictionary>
+ TNode<Smi> GetNameDictionaryFlags(TNode<Dictionary> dictionary);
+ template <class Dictionary>
+ void SetNameDictionaryFlags(TNode<Dictionary>, TNode<Smi> flags);
+
// Looks up an entry in a NameDictionaryBase successor. If the entry is found
// control goes to {if_found} and {var_name_index} contains an index of the
// key field of the entry found. If the key is not found control goes to
@@ -3313,6 +3298,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TVariable<Object>* var_raw_value, Label* if_not_found,
Label* if_bailout, GetOwnPropertyMode mode);
+ TNode<PropertyDescriptorObject> AllocatePropertyDescriptorObject(
+ TNode<Context> context);
+ void InitializePropertyDescriptorObject(
+ TNode<PropertyDescriptorObject> descriptor, TNode<Object> value,
+ TNode<Uint32T> details, Label* if_bailout);
+
TNode<Object> GetProperty(TNode<Context> context, TNode<Object> receiver,
Handle<Name> name) {
return GetProperty(context, receiver, HeapConstant(name));
@@ -3345,6 +3336,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Object> CreateAsyncFromSyncIterator(TNode<Context> context,
TNode<Object> sync_iterator);
+ TNode<JSObject> CreateAsyncFromSyncIterator(TNode<Context> context,
+ TNode<JSReceiver> sync_iterator,
+ TNode<Object> next);
template <class... TArgs>
TNode<Object> CallBuiltin(Builtin id, TNode<Object> context, TArgs... args) {
@@ -3593,23 +3587,50 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Int32T> LoadElementsKind(TNode<AllocationSite> allocation_site);
enum class IndexAdvanceMode { kPre, kPost };
+ enum class LoopUnrollingMode { kNo, kYes };
template <typename TIndex>
using FastLoopBody = std::function<void(TNode<TIndex> index)>;
template <typename TIndex>
TNode<TIndex> BuildFastLoop(
- const VariableList& var_list, TNode<TIndex> start_index,
- TNode<TIndex> end_index, const FastLoopBody<TIndex>& body, int increment,
+ const VariableList& vars, TVariable<TIndex>& var_index,
+ TNode<TIndex> start_index, TNode<TIndex> end_index,
+ const FastLoopBody<TIndex>& body, int increment,
+ LoopUnrollingMode unrolling_mode,
IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);
template <typename TIndex>
TNode<TIndex> BuildFastLoop(
+ TVariable<TIndex>& var_index, TNode<TIndex> start_index,
+ TNode<TIndex> end_index, const FastLoopBody<TIndex>& body, int increment,
+ LoopUnrollingMode unrolling_mode,
+ IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
+ return BuildFastLoop(VariableList(0, zone()), var_index, start_index,
+ end_index, body, increment, unrolling_mode,
+ advance_mode);
+ }
+
+ template <typename TIndex>
+ TNode<TIndex> BuildFastLoop(const VariableList& vars,
+ TNode<TIndex> start_index,
+ TNode<TIndex> end_index,
+ const FastLoopBody<TIndex>& body, int increment,
+ LoopUnrollingMode unrolling_mode,
+ IndexAdvanceMode advance_mode) {
+ TVARIABLE(TIndex, var_index);
+ return BuildFastLoop(vars, var_index, start_index, end_index, body,
+ increment, unrolling_mode, advance_mode);
+ }
+
+ template <typename TIndex>
+ TNode<TIndex> BuildFastLoop(
TNode<TIndex> start_index, TNode<TIndex> end_index,
const FastLoopBody<TIndex>& body, int increment,
+ LoopUnrollingMode unrolling_mode,
IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
return BuildFastLoop(VariableList(0, zone()), start_index, end_index, body,
- increment, advance_mode);
+ increment, unrolling_mode, advance_mode);
}
enum class ForEachDirection { kForward, kReverse };
@@ -3622,6 +3643,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<UnionT<UnionT<FixedArray, PropertyArray>, HeapObject>> array,
ElementsKind kind, TNode<TIndex> first_element_inclusive,
TNode<TIndex> last_element_exclusive, const FastArrayForEachBody& body,
+ LoopUnrollingMode loop_unrolling_mode,
ForEachDirection direction = ForEachDirection::kReverse);
template <typename TIndex>
@@ -3731,6 +3753,29 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Oddball> StrictEqual(TNode<Object> lhs, TNode<Object> rhs,
TVariable<Smi>* var_type_feedback = nullptr);
+ void GotoIfStringEqual(TNode<String> lhs, TNode<IntPtrT> lhs_length,
+ TNode<String> rhs, Label* if_true) {
+ Label if_false(this);
+ TNode<IntPtrT> rhs_length = LoadStringLengthAsWord(rhs);
+ BranchIfStringEqual(lhs, lhs_length, rhs, rhs_length, if_true, &if_false,
+ nullptr);
+
+ BIND(&if_false);
+ }
+
+ void BranchIfStringEqual(TNode<String> lhs, TNode<String> rhs, Label* if_true,
+ Label* if_false,
+ TVariable<Oddball>* result = nullptr) {
+ return BranchIfStringEqual(lhs, LoadStringLengthAsWord(lhs), rhs,
+ LoadStringLengthAsWord(rhs), if_true, if_false,
+ result);
+ }
+
+ void BranchIfStringEqual(TNode<String> lhs, TNode<IntPtrT> lhs_length,
+ TNode<String> rhs, TNode<IntPtrT> rhs_length,
+ Label* if_true, Label* if_false,
+ TVariable<Oddball>* result = nullptr);
+
// ECMA#sec-samevalue
// Similar to StrictEqual except that NaNs are treated as equal and minus zero
// differs from positive zero.
@@ -3851,7 +3896,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
ElementsKind kind = HOLEY_ELEMENTS);
// Load a builtin's code from the builtin array in the isolate.
- TNode<CodeT> LoadBuiltin(TNode<Smi> builtin_id);
+ TNode<Code> LoadBuiltin(TNode<Smi> builtin_id);
// Figure out the SFI's code object using its data field.
// If |data_type_out| is provided, the instance type of the function data will
@@ -3859,7 +3904,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// data_type_out will be set to 0.
// If |if_compile_lazy| is provided then the execution will go to the given
// label in case of an CompileLazy code object.
- TNode<CodeT> GetSharedFunctionInfoCode(
+ TNode<Code> GetSharedFunctionInfoCode(
TNode<SharedFunctionInfo> shared_info,
TVariable<Uint16T>* data_type_out = nullptr,
Label* if_compile_lazy = nullptr);
@@ -3970,6 +4015,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
uint8_t ConstexprIntegerLiteralToUint8(const IntegerLiteral& i) {
return i.To<uint8_t>();
}
+ int64_t ConstexprIntegerLiteralToInt64(const IntegerLiteral& i) {
+ return i.To<int64_t>();
+ }
uint64_t ConstexprIntegerLiteralToUint64(const IntegerLiteral& i) {
return i.To<uint64_t>();
}
@@ -4248,6 +4296,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
private:
friend class CodeStubArguments;
+ void BigInt64Comparison(Operation op, TNode<Object>& left,
+ TNode<Object>& right, Label* return_true,
+ Label* return_false);
+
void HandleBreakOnNode();
TNode<HeapObject> AllocateRawDoubleAligned(TNode<IntPtrT> size_in_bytes,
@@ -4311,10 +4363,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Context> context, TNode<HeapObject> input, Object::Conversion mode,
BigIntHandling bigint_handling = BigIntHandling::kThrow);
- void TaggedToNumeric(TNode<Context> context, TNode<Object> value,
- TVariable<Numeric>* var_numeric,
- TVariable<Smi>* var_feedback);
-
enum IsKnownTaggedPointer { kNo, kYes };
template <Object::Conversion conversion>
void TaggedToWord32OrBigIntImpl(TNode<Context> context, TNode<Object> value,
@@ -4322,6 +4370,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TVariable<Word32T>* var_word32,
IsKnownTaggedPointer is_known_tagged_pointer,
Label* if_bigint = nullptr,
+ Label* if_bigint64 = nullptr,
TVariable<BigInt>* var_maybe_bigint = nullptr,
TVariable<Smi>* var_feedback = nullptr);