From d82e1075dbc2cec2d6598ade10c1f43805f690fd Mon Sep 17 00:00:00 2001 From: Michaƫl Zasso Date: Tue, 12 Sep 2017 11:34:59 +0200 Subject: deps: update V8 to 6.1.534.36 PR-URL: https://github.com/nodejs/node/pull/14730 Reviewed-By: Ben Noordhuis Reviewed-By: Ali Ijaz Sheikh Reviewed-By: Colin Ihrig Reviewed-By: Matteo Collina --- deps/v8/src/builtins/builtins-regexp-gen.cc | 241 +++++++++++++++++++--------- 1 file changed, 167 insertions(+), 74 deletions(-) (limited to 'deps/v8/src/builtins/builtins-regexp-gen.cc') diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc index 04a35bd000..e32ff69c95 100644 --- a/deps/v8/src/builtins/builtins-regexp-gen.cc +++ b/deps/v8/src/builtins/builtins-regexp-gen.cc @@ -52,7 +52,7 @@ void RegExpBuiltinsAssembler::SlowStoreLastIndex(Node* context, Node* regexp, // Store through runtime. // TODO(ishell): Use SetPropertyStub here once available. Node* const name = HeapConstant(isolate()->factory()->lastIndex_string()); - Node* const language_mode = SmiConstant(Smi::FromInt(STRICT)); + Node* const language_mode = SmiConstant(STRICT); CallRuntime(Runtime::kSetProperty, context, regexp, name, value, language_mode); } @@ -257,7 +257,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ToDirectStringAssembler to_direct(state(), string); VARIABLE(var_result, MachineRepresentation::kTagged); - Label out(this), runtime(this, Label::kDeferred); + Label out(this), atom(this), runtime(this, Label::kDeferred); // External constants. Node* const isolate_address = @@ -269,11 +269,20 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, Node* const static_offsets_vector_address = ExternalConstant( ExternalReference::address_of_static_offsets_vector(isolate())); - // Ensure that a RegExp stack is allocated. + // At this point, last_index is definitely a canonicalized non-negative + // number, which implies that any non-Smi last_index is greater than + // the maximal string length. If lastIndex > string.length then the matcher + // must fail. + + Label if_failure(this); + Node* const smi_string_length = LoadStringLength(string); { - Node* const stack_size = - Load(MachineType::IntPtr(), regexp_stack_memory_size_address); - GotoIf(IntPtrEqual(stack_size, int_zero), &runtime); + CSA_ASSERT(this, IsNumberNormalized(last_index)); + CSA_ASSERT(this, IsNumberPositive(last_index)); + Node* const last_index_is_not_smi = TaggedIsNotSmi(last_index); + Node* const last_index_is_oob = + SmiGreaterThan(last_index, smi_string_length); + GotoIf(Word32Or(last_index_is_not_smi, last_index_is_oob), &if_failure); } Node* const data = LoadObjectField(regexp, JSRegExp::kDataOffset); @@ -282,10 +291,25 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, CSA_ASSERT(this, TaggedIsNotSmi(data)); CSA_ASSERT(this, HasInstanceType(data, FIXED_ARRAY_TYPE)); - // Check the type of the RegExp. Only continue if type is - // JSRegExp::IRREGEXP. - Node* const tag = LoadFixedArrayElement(data, JSRegExp::kTagIndex); - GotoIfNot(SmiEqual(tag, SmiConstant(JSRegExp::IRREGEXP)), &runtime); + // Dispatch on the type of the RegExp. + { + Label next(this), unreachable(this, Label::kDeferred); + Node* const tag = LoadAndUntagToWord32FixedArrayElement( + data, IntPtrConstant(JSRegExp::kTagIndex)); + + int32_t values[] = { + JSRegExp::IRREGEXP, JSRegExp::ATOM, JSRegExp::NOT_COMPILED, + }; + Label* labels[] = {&next, &atom, &runtime}; + + STATIC_ASSERT(arraysize(values) == arraysize(labels)); + Switch(tag, &unreachable, values, labels, arraysize(values)); + + BIND(&unreachable); + Unreachable(); + + BIND(&next); + } // Check (number_of_captures + 1) * 2 <= offsets vector size // Or number_of_captures <= offsets vector size / 2 - 1 @@ -300,23 +324,18 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, &runtime); } + // Ensure that a RegExp stack is allocated. This check is after branching off + // for ATOM regexps to avoid unnecessary trips to runtime. + { + Node* const stack_size = + Load(MachineType::IntPtr(), regexp_stack_memory_size_address); + GotoIf(IntPtrEqual(stack_size, int_zero), &runtime); + } + // Unpack the string if possible. to_direct.TryToDirect(&runtime); - Node* const smi_string_length = LoadStringLength(string); - - // At this point, last_index is definitely a canonicalized non-negative - // number, which implies that any non-Smi last_index is greater than - // the maximal string length. If lastIndex > string.length then the matcher - // must fail. - - Label if_failure(this); - CSA_ASSERT(this, IsNumberNormalized(last_index)); - CSA_ASSERT(this, IsNumberPositive(last_index)); - GotoIfNot(TaggedIsSmi(last_index), &if_failure); // Outside Smi range. - GotoIf(SmiGreaterThan(last_index, smi_string_length), &if_failure); - // Load the irregexp code object and offsets into the subject string. Both // depend on whether the string is one- or two-byte. @@ -358,10 +377,22 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, } // Check that the irregexp code has been generated for the actual string - // encoding. If it has, the field contains a code object otherwise it contains - // smi (code flushing support). + // encoding. If it has, the field contains a code object; and otherwise it + // contains the uninitialized sentinel as a smi. Node* const code = var_code.value(); +#ifdef DEBUG + { + Label next(this); + GotoIfNot(TaggedIsSmi(code), &next); + + CSA_ASSERT(this, + SmiEqual(code, SmiConstant(JSRegExp::kUninitializedValue))); + Goto(&next); + + BIND(&next); + } +#endif GotoIf(TaggedIsSmi(code), &runtime); CSA_ASSERT(this, HasInstanceType(code, CODE_TYPE)); @@ -481,7 +512,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, register_count, INT32_ELEMENTS, SMI_PARAMETERS, 0); Node* const to_offset = ElementOffsetFromIndex( - IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), FAST_ELEMENTS, + IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), PACKED_ELEMENTS, INTPTR_PARAMETERS, RegExpMatchInfo::kHeaderSize - kHeapObjectTag); VARIABLE(var_to_offset, MachineType::PointerRepresentation(), to_offset); @@ -513,8 +544,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, { // A stack overflow was detected in RegExp code. #ifdef DEBUG - Node* const pending_exception_address = ExternalConstant( - ExternalReference(Isolate::kPendingExceptionAddress, isolate())); + Node* const pending_exception_address = ExternalConstant(ExternalReference( + IsolateAddressId::kPendingExceptionAddress, isolate())); CSA_ASSERT(this, IsTheHole(Load(MachineType::AnyTagged(), pending_exception_address))); #endif // DEBUG @@ -530,6 +561,16 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, Goto(&out); } + BIND(&atom); + { + // TODO(jgruber): A call with 4 args stresses register allocation, this + // should probably just be inlined. + Node* const result = CallBuiltin(Builtins::kRegExpExecAtom, context, regexp, + string, last_index, match_info); + var_result.Bind(result); + Goto(&out); + } + BIND(&out); return var_result.value(); #endif // V8_INTERPRETED_REGEXP @@ -546,7 +587,7 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( Label* if_didnotmatch, const bool is_fastpath) { Node* const null = NullConstant(); Node* const int_zero = IntPtrConstant(0); - Node* const smi_zero = SmiConstant(Smi::kZero); + Node* const smi_zero = SmiConstant(0); if (is_fastpath) { CSA_ASSERT(this, IsFastRegExpNoPrototype(context, regexp)); @@ -714,16 +755,10 @@ Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver( // The {value} is not a compatible receiver for this method. BIND(&throw_exception); { - Node* const message_id = SmiConstant(Smi::FromInt(msg_template)); - Node* const method_name_str = HeapConstant( - isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED)); - Node* const value_str = CallBuiltin(Builtins::kToString, context, maybe_receiver); - - CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str, - value_str); - Unreachable(); + ThrowTypeError(context, msg_template, StringConstant(method_name), + value_str); } BIND(&out); @@ -851,6 +886,70 @@ TF_BUILTIN(RegExpPrototypeExecSlow, RegExpBuiltinsAssembler) { Return(RegExpPrototypeExecBody(context, regexp, string, false)); } +// Fast path stub for ATOM regexps. String matching is done by StringIndexOf, +// and {match_info} is updated on success. +// The slow path is implemented in RegExpImpl::AtomExec. +TF_BUILTIN(RegExpExecAtom, RegExpBuiltinsAssembler) { + Node* const regexp = Parameter(Descriptor::kRegExp); + Node* const subject_string = Parameter(Descriptor::kString); + Node* const last_index = Parameter(Descriptor::kLastIndex); + Node* const match_info = Parameter(Descriptor::kMatchInfo); + Node* const context = Parameter(Descriptor::kContext); + + CSA_ASSERT(this, IsJSRegExp(regexp)); + CSA_ASSERT(this, IsString(subject_string)); + CSA_ASSERT(this, TaggedIsPositiveSmi(last_index)); + CSA_ASSERT(this, IsFixedArray(match_info)); + + Node* const data = LoadObjectField(regexp, JSRegExp::kDataOffset); + CSA_ASSERT(this, IsFixedArray(data)); + CSA_ASSERT(this, SmiEqual(LoadFixedArrayElement(data, JSRegExp::kTagIndex), + SmiConstant(JSRegExp::ATOM))); + + // Callers ensure that last_index is in-bounds. + CSA_ASSERT(this, + SmiLessThanOrEqual(last_index, LoadStringLength(subject_string))); + + Node* const needle_string = + LoadFixedArrayElement(data, JSRegExp::kAtomPatternIndex); + CSA_ASSERT(this, IsString(needle_string)); + + Node* const match_from = + CallBuiltin(Builtins::kStringIndexOf, context, subject_string, + needle_string, last_index); + CSA_ASSERT(this, TaggedIsSmi(match_from)); + + Label if_failure(this), if_success(this); + Branch(SmiEqual(match_from, SmiConstant(-1)), &if_failure, &if_success); + + BIND(&if_success); + { + CSA_ASSERT(this, TaggedIsPositiveSmi(match_from)); + CSA_ASSERT(this, SmiLessThan(match_from, LoadStringLength(subject_string))); + + const int kNumRegisters = 2; + STATIC_ASSERT(RegExpMatchInfo::kInitialCaptureIndices >= kNumRegisters); + + Node* const match_to = SmiAdd(match_from, LoadStringLength(needle_string)); + + StoreFixedArrayElement(match_info, RegExpMatchInfo::kNumberOfCapturesIndex, + SmiConstant(kNumRegisters), SKIP_WRITE_BARRIER); + StoreFixedArrayElement(match_info, RegExpMatchInfo::kLastSubjectIndex, + subject_string); + StoreFixedArrayElement(match_info, RegExpMatchInfo::kLastInputIndex, + subject_string); + StoreFixedArrayElement(match_info, RegExpMatchInfo::kFirstCaptureIndex, + match_from, SKIP_WRITE_BARRIER); + StoreFixedArrayElement(match_info, RegExpMatchInfo::kFirstCaptureIndex + 1, + match_to, SKIP_WRITE_BARRIER); + + Return(match_info); + } + + BIND(&if_failure); + Return(NullConstant()); +} + // ES#sec-regexp.prototype.exec // RegExp.prototype.exec ( string ) TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { @@ -864,7 +963,7 @@ TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { Node* const receiver = maybe_receiver; // Convert {maybe_string} to a String. - Node* const string = ToString(context, maybe_string); + Node* const string = ToString_Inline(context, maybe_string); Label if_isfastpath(this), if_isslowpath(this); Branch(IsFastRegExpNoPrototype(context, receiver), &if_isfastpath, @@ -1050,13 +1149,13 @@ Node* RegExpBuiltinsAssembler::RegExpInitialize(Node* const context, // Normalize pattern. Node* const pattern = Select(IsUndefined(maybe_pattern), [=] { return EmptyStringConstant(); }, - [=] { return ToString(context, maybe_pattern); }, + [=] { return ToString_Inline(context, maybe_pattern); }, MachineRepresentation::kTagged); // Normalize flags. Node* const flags = Select(IsUndefined(maybe_flags), [=] { return EmptyStringConstant(); }, - [=] { return ToString(context, maybe_flags); }, + [=] { return ToString_Inline(context, maybe_flags); }, MachineRepresentation::kTagged); // Initialize. @@ -1308,8 +1407,7 @@ TF_BUILTIN(RegExpPrototypeSourceGetter, RegExpBuiltinsAssembler) { BIND(&if_isnotprototype); { - Node* const message_id = - SmiConstant(Smi::FromInt(MessageTemplate::kRegExpNonRegExp)); + Node* const message_id = SmiConstant(MessageTemplate::kRegExpNonRegExp); Node* const method_name_str = HeapConstant(isolate->factory()->NewStringFromAsciiChecked( "RegExp.prototype.source")); @@ -1322,9 +1420,9 @@ TF_BUILTIN(RegExpPrototypeSourceGetter, RegExpBuiltinsAssembler) { // Fast-path implementation for flag checks on an unmodified JSRegExp instance. Node* RegExpBuiltinsAssembler::FastFlagGetter(Node* const regexp, JSRegExp::Flag flag) { - Node* const smi_zero = SmiConstant(Smi::kZero); + Node* const smi_zero = SmiConstant(0); Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); - Node* const mask = SmiConstant(Smi::FromInt(flag)); + Node* const mask = SmiConstant(flag); Node* const is_flag_set = WordNotEqual(SmiAnd(flags, mask), smi_zero); return is_flag_set; @@ -1428,7 +1526,7 @@ void RegExpBuiltinsAssembler::FlagGetter(Node* context, Node* receiver, BIND(&if_isprototype); { if (counter != -1) { - Node* const counter_smi = SmiConstant(Smi::FromInt(counter)); + Node* const counter_smi = SmiConstant(counter); CallRuntime(Runtime::kIncrementUseCounter, context, counter_smi); } Return(UndefinedConstant()); @@ -1436,8 +1534,7 @@ void RegExpBuiltinsAssembler::FlagGetter(Node* context, Node* receiver, BIND(&if_isnotprototype); { - Node* const message_id = - SmiConstant(Smi::FromInt(MessageTemplate::kRegExpNonRegExp)); + Node* const message_id = SmiConstant(MessageTemplate::kRegExpNonRegExp); Node* const method_name_str = HeapConstant( isolate->factory()->NewStringFromAsciiChecked(method_name)); CallRuntime(Runtime::kThrowTypeError, context, message_id, @@ -1578,7 +1675,7 @@ TF_BUILTIN(RegExpPrototypeTest, RegExpBuiltinsAssembler) { Node* const receiver = maybe_receiver; // Convert {maybe_string} to a String. - Node* const string = ToString(context, maybe_string); + Node* const string = ToString_Inline(context, maybe_string); Label fast_path(this), slow_path(this); BranchIfFastRegExp(context, receiver, &fast_path, &slow_path); @@ -1720,7 +1817,7 @@ class GrowableFixedArray { Node* ToJSArray(Node* const context) { CodeStubAssembler* a = assembler_; - const ElementsKind kind = FAST_ELEMENTS; + const ElementsKind kind = PACKED_ELEMENTS; Node* const native_context = a->LoadNativeContext(context); Node* const array_map = a->LoadJSArrayElementsMap(kind, native_context); @@ -1757,7 +1854,7 @@ class GrowableFixedArray { void Initialize() { CodeStubAssembler* a = assembler_; - const ElementsKind kind = FAST_ELEMENTS; + const ElementsKind kind = PACKED_ELEMENTS; static const int kInitialArraySize = 8; Node* const capacity = a->IntPtrConstant(kInitialArraySize); @@ -1793,7 +1890,7 @@ class GrowableFixedArray { CSA_ASSERT(a, a->IntPtrGreaterThan(new_capacity, a->IntPtrConstant(0))); CSA_ASSERT(a, a->IntPtrGreaterThanOrEqual(new_capacity, element_count)); - const ElementsKind kind = FAST_ELEMENTS; + const ElementsKind kind = PACKED_ELEMENTS; const WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER; const CodeStubAssembler::ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; @@ -1827,7 +1924,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, Node* const null = NullConstant(); Node* const int_zero = IntPtrConstant(0); - Node* const smi_zero = SmiConstant(Smi::kZero); + Node* const smi_zero = SmiConstant(0); Node* const is_global = FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); @@ -1910,7 +2007,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, { // TODO(ishell): Use GetElement stub once it's available. Node* const match = GetProperty(context, result, smi_zero); - var_match.Bind(ToString(context, match)); + var_match.Bind(ToString_Inline(context, match)); Goto(&if_didmatch); } } @@ -1984,7 +2081,7 @@ TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) { Node* const receiver = maybe_receiver; // Convert {maybe_string} to a String. - Node* const string = ToString(context, maybe_string); + Node* const string = ToString_Inline(context, maybe_string); Label fast_path(this), slow_path(this); BranchIfFastRegExp(context, receiver, &fast_path, &slow_path); @@ -2005,7 +2102,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( Node* const previous_last_index = FastLoadLastIndex(regexp); // Ensure last index is 0. - FastStoreLastIndex(regexp, SmiConstant(Smi::kZero)); + FastStoreLastIndex(regexp, SmiConstant(0)); // Call exec. Label if_didnotmatch(this); @@ -2038,7 +2135,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow( Isolate* const isolate = this->isolate(); - Node* const smi_zero = SmiConstant(Smi::kZero); + Node* const smi_zero = SmiConstant(0); // Grab the initial value of last index. Node* const previous_last_index = SlowLoadLastIndex(context, regexp); @@ -2111,7 +2208,7 @@ TF_BUILTIN(RegExpPrototypeSearch, RegExpBuiltinsAssembler) { Node* const receiver = maybe_receiver; // Convert {maybe_string} to a String. - Node* const string = ToString(context, maybe_string); + Node* const string = ToString_Inline(context, maybe_string); Label fast_path(this), slow_path(this); BranchIfFastRegExp(context, receiver, &fast_path, &slow_path); @@ -2138,7 +2235,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(Node* const context, Node* const int_zero = IntPtrConstant(0); Node* const int_limit = SmiUntag(limit); - const ElementsKind kind = FAST_ELEMENTS; + const ElementsKind kind = PACKED_ELEMENTS; const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; Node* const allocation_site = nullptr; @@ -2444,10 +2541,8 @@ TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { CodeStubArguments args(this, argc); Node* const maybe_receiver = args.GetReceiver(); - Node* const maybe_string = - args.GetOptionalArgumentValue(kStringArg, UndefinedConstant()); - Node* const maybe_limit = - args.GetOptionalArgumentValue(kLimitArg, UndefinedConstant()); + Node* const maybe_string = args.GetOptionalArgumentValue(kStringArg); + Node* const maybe_limit = args.GetOptionalArgumentValue(kLimitArg); Node* const context = Parameter(BuiltinDescriptor::kContext); // Ensure {maybe_receiver} is a JSReceiver. @@ -2457,7 +2552,7 @@ TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { Node* const receiver = maybe_receiver; // Convert {maybe_string} to a String. - Node* const string = ToString(context, maybe_string); + Node* const string = ToString_Inline(context, maybe_string); Label stub(this), runtime(this, Label::kDeferred); BranchIfFastRegExp(context, receiver, &stub, &runtime); @@ -2486,7 +2581,7 @@ Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( Node* const undefined = UndefinedConstant(); Node* const int_zero = IntPtrConstant(0); Node* const int_one = IntPtrConstant(1); - Node* const smi_zero = SmiConstant(Smi::kZero); + Node* const smi_zero = SmiConstant(0); Node* const native_context = LoadNativeContext(context); @@ -2499,7 +2594,7 @@ Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( // Allocate {result_array}. Node* result_array; { - ElementsKind kind = FAST_ELEMENTS; + ElementsKind kind = PACKED_ELEMENTS; Node* const array_map = LoadJSArrayElementsMap(kind, native_context); Node* const capacity = IntPtrConstant(16); Node* const length = smi_zero; @@ -2536,7 +2631,7 @@ Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( Label if_hasexplicitcaptures(this), if_noexplicitcaptures(this), create_result(this); - Branch(SmiEqual(num_capture_registers, SmiConstant(Smi::FromInt(2))), + Branch(SmiEqual(num_capture_registers, SmiConstant(2)), &if_noexplicitcaptures, &if_hasexplicitcaptures); BIND(&if_noexplicitcaptures); @@ -2600,14 +2695,14 @@ Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( BIND(&if_isstring); { - CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(elem))); + CSA_ASSERT(this, IsString(elem)); Callable call_callable = CodeFactory::Call(isolate); Node* const replacement_obj = CallJS(call_callable, context, replace_callable, undefined, elem, var_match_start.value(), string); - Node* const replacement_str = ToString(context, replacement_obj); + Node* const replacement_str = ToString_Inline(context, replacement_obj); StoreFixedArrayElement(res_elems, i, replacement_str); Node* const elem_length = LoadStringLength(elem); @@ -2660,7 +2755,7 @@ Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( // we got back from the callback function. Node* const replacement_str = - ToString(context, replacement_obj); + ToString_Inline(context, replacement_obj); StoreFixedArrayElement(res_elems, index, replacement_str); Goto(&do_continue); @@ -2692,7 +2787,7 @@ Node* RegExpBuiltinsAssembler::ReplaceSimpleStringFastPath( // string replacement. Node* const int_zero = IntPtrConstant(0); - Node* const smi_zero = SmiConstant(Smi::kZero); + Node* const smi_zero = SmiConstant(0); CSA_ASSERT(this, IsFastRegExp(context, regexp)); CSA_ASSERT(this, IsString(replace_string)); @@ -2865,10 +2960,8 @@ TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) { CodeStubArguments args(this, argc); Node* const maybe_receiver = args.GetReceiver(); - Node* const maybe_string = - args.GetOptionalArgumentValue(kStringArg, UndefinedConstant()); - Node* const replace_value = - args.GetOptionalArgumentValue(kReplaceValueArg, UndefinedConstant()); + Node* const maybe_string = args.GetOptionalArgumentValue(kStringArg); + Node* const replace_value = args.GetOptionalArgumentValue(kReplaceValueArg); Node* const context = Parameter(BuiltinDescriptor::kContext); // RegExpPrototypeReplace is a bit of a beast - a summary of dispatch logic: -- cgit v1.2.3