| Index: src/builtins/builtins-regexp.cc
|
| diff --git a/src/builtins/builtins-regexp.cc b/src/builtins/builtins-regexp.cc
|
| index 10dff90dcd0d5cde4f6cd26d635447a81ad7154f..5f8d18be433e7ce0957c62c05eb3b5e7fcc4723f 100644
|
| --- a/src/builtins/builtins-regexp.cc
|
| +++ b/src/builtins/builtins-regexp.cc
|
| @@ -481,18 +481,16 @@
|
|
|
| // ES#sec-regexp.prototype.exec
|
| // RegExp.prototype.exec ( string )
|
| -void Builtins::Generate_RegExpPrototypeExec(
|
| - compiler::CodeAssemblerState* state) {
|
| +void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) {
|
| typedef compiler::Node Node;
|
| - CodeStubAssembler a(state);
|
| -
|
| - Node* const maybe_receiver = a.Parameter(0);
|
| - Node* const maybe_string = a.Parameter(1);
|
| - Node* const context = a.Parameter(4);
|
| +
|
| + Node* const maybe_receiver = a->Parameter(0);
|
| + Node* const maybe_string = a->Parameter(1);
|
| + Node* const context = a->Parameter(4);
|
|
|
| Node* const result =
|
| - RegExpPrototypeExecInternal(&a, context, maybe_receiver, maybe_string);
|
| - a.Return(result);
|
| + RegExpPrototypeExecInternal(a, context, maybe_receiver, maybe_string);
|
| + a->Return(result);
|
| }
|
|
|
| namespace {
|
| @@ -587,59 +585,58 @@
|
|
|
| } // namespace
|
|
|
| -void Builtins::Generate_RegExpPrototypeFlagsGetter(
|
| - compiler::CodeAssemblerState* state) {
|
| +void Builtins::Generate_RegExpPrototypeFlagsGetter(CodeStubAssembler* a) {
|
| typedef CodeStubAssembler::Variable Variable;
|
| typedef CodeStubAssembler::Label Label;
|
| typedef compiler::Node Node;
|
| - CodeStubAssembler a(state);
|
| -
|
| - Node* const receiver = a.Parameter(0);
|
| - Node* const context = a.Parameter(3);
|
| -
|
| - Isolate* isolate = a.isolate();
|
| - Node* const int_zero = a.IntPtrConstant(0);
|
| - Node* const int_one = a.IntPtrConstant(1);
|
| -
|
| - Node* const map = ThrowIfNotJSReceiver(&a, isolate, context, receiver,
|
| +
|
| + Node* const receiver = a->Parameter(0);
|
| + Node* const context = a->Parameter(3);
|
| +
|
| + Isolate* isolate = a->isolate();
|
| + Node* const int_zero = a->IntPtrConstant(0);
|
| + Node* const int_one = a->IntPtrConstant(1);
|
| +
|
| + Node* const map = ThrowIfNotJSReceiver(a, isolate, context, receiver,
|
| MessageTemplate::kRegExpNonObject,
|
| "RegExp.prototype.flags");
|
|
|
| - Variable var_length(&a, MachineType::PointerRepresentation());
|
| - Variable var_flags(&a, MachineType::PointerRepresentation());
|
| + Variable var_length(a, MachineType::PointerRepresentation());
|
| + Variable var_flags(a, MachineType::PointerRepresentation());
|
|
|
| // First, count the number of characters we will need and check which flags
|
| // are set.
|
|
|
| var_length.Bind(int_zero);
|
|
|
| - Label if_isunmodifiedjsregexp(&a),
|
| - if_isnotunmodifiedjsregexp(&a, Label::kDeferred);
|
| - a.Branch(IsInitialRegExpMap(&a, context, map), &if_isunmodifiedjsregexp,
|
| - &if_isnotunmodifiedjsregexp);
|
| -
|
| - Label construct_string(&a);
|
| - a.Bind(&if_isunmodifiedjsregexp);
|
| + Label if_isunmodifiedjsregexp(a),
|
| + if_isnotunmodifiedjsregexp(a, Label::kDeferred);
|
| + a->Branch(IsInitialRegExpMap(a, context, map), &if_isunmodifiedjsregexp,
|
| + &if_isnotunmodifiedjsregexp);
|
| +
|
| + Label construct_string(a);
|
| + a->Bind(&if_isunmodifiedjsregexp);
|
| {
|
| // Refer to JSRegExp's flag property on the fast-path.
|
| - Node* const flags_smi = a.LoadObjectField(receiver, JSRegExp::kFlagsOffset);
|
| - Node* const flags_intptr = a.SmiUntag(flags_smi);
|
| + Node* const flags_smi =
|
| + a->LoadObjectField(receiver, JSRegExp::kFlagsOffset);
|
| + Node* const flags_intptr = a->SmiUntag(flags_smi);
|
| var_flags.Bind(flags_intptr);
|
|
|
| - Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
|
| - label_unicode(&a), label_sticky(&a);
|
| -
|
| -#define CASE_FOR_FLAG(FLAG, LABEL, NEXT_LABEL) \
|
| - do { \
|
| - a.Bind(&LABEL); \
|
| - Node* const mask = a.IntPtrConstant(FLAG); \
|
| - a.GotoIf(a.WordEqual(a.WordAnd(flags_intptr, mask), int_zero), \
|
| - &NEXT_LABEL); \
|
| - var_length.Bind(a.IntPtrAdd(var_length.value(), int_one)); \
|
| - a.Goto(&NEXT_LABEL); \
|
| + Label label_global(a), label_ignorecase(a), label_multiline(a),
|
| + label_unicode(a), label_sticky(a);
|
| +
|
| +#define CASE_FOR_FLAG(FLAG, LABEL, NEXT_LABEL) \
|
| + do { \
|
| + a->Bind(&LABEL); \
|
| + Node* const mask = a->IntPtrConstant(FLAG); \
|
| + a->GotoIf(a->WordEqual(a->WordAnd(flags_intptr, mask), int_zero), \
|
| + &NEXT_LABEL); \
|
| + var_length.Bind(a->IntPtrAdd(var_length.value(), int_one)); \
|
| + a->Goto(&NEXT_LABEL); \
|
| } while (false)
|
|
|
| - a.Goto(&label_global);
|
| + a->Goto(&label_global);
|
| CASE_FOR_FLAG(JSRegExp::kGlobal, label_global, label_ignorecase);
|
| CASE_FOR_FLAG(JSRegExp::kIgnoreCase, label_ignorecase, label_multiline);
|
| CASE_FOR_FLAG(JSRegExp::kMultiline, label_multiline, label_unicode);
|
| @@ -648,31 +645,31 @@
|
| #undef CASE_FOR_FLAG
|
| }
|
|
|
| - a.Bind(&if_isnotunmodifiedjsregexp);
|
| + a->Bind(&if_isnotunmodifiedjsregexp);
|
| {
|
| // Fall back to GetProperty stub on the slow-path.
|
| var_flags.Bind(int_zero);
|
|
|
| - Callable getproperty_callable = CodeFactory::GetProperty(a.isolate());
|
| - Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
|
| - label_unicode(&a), label_sticky(&a);
|
| -
|
| -#define CASE_FOR_FLAG(NAME, FLAG, LABEL, NEXT_LABEL) \
|
| - do { \
|
| - a.Bind(&LABEL); \
|
| - Node* const name = \
|
| - a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked(NAME)); \
|
| - Node* const flag = \
|
| - a.CallStub(getproperty_callable, context, receiver, name); \
|
| - Label if_isflagset(&a); \
|
| - a.BranchIfToBooleanIsTrue(flag, &if_isflagset, &NEXT_LABEL); \
|
| - a.Bind(&if_isflagset); \
|
| - var_length.Bind(a.IntPtrAdd(var_length.value(), int_one)); \
|
| - var_flags.Bind(a.WordOr(var_flags.value(), a.IntPtrConstant(FLAG))); \
|
| - a.Goto(&NEXT_LABEL); \
|
| + Callable getproperty_callable = CodeFactory::GetProperty(a->isolate());
|
| + Label label_global(a), label_ignorecase(a), label_multiline(a),
|
| + label_unicode(a), label_sticky(a);
|
| +
|
| +#define CASE_FOR_FLAG(NAME, FLAG, LABEL, NEXT_LABEL) \
|
| + do { \
|
| + a->Bind(&LABEL); \
|
| + Node* const name = \
|
| + a->HeapConstant(isolate->factory()->NewStringFromAsciiChecked(NAME)); \
|
| + Node* const flag = \
|
| + a->CallStub(getproperty_callable, context, receiver, name); \
|
| + Label if_isflagset(a); \
|
| + a->BranchIfToBooleanIsTrue(flag, &if_isflagset, &NEXT_LABEL); \
|
| + a->Bind(&if_isflagset); \
|
| + var_length.Bind(a->IntPtrAdd(var_length.value(), int_one)); \
|
| + var_flags.Bind(a->WordOr(var_flags.value(), a->IntPtrConstant(FLAG))); \
|
| + a->Goto(&NEXT_LABEL); \
|
| } while (false)
|
|
|
| - a.Goto(&label_global);
|
| + a->Goto(&label_global);
|
| CASE_FOR_FLAG("global", JSRegExp::kGlobal, label_global, label_ignorecase);
|
| CASE_FOR_FLAG("ignoreCase", JSRegExp::kIgnoreCase, label_ignorecase,
|
| label_multiline);
|
| @@ -686,33 +683,33 @@
|
| // Allocate a string of the required length and fill it with the corresponding
|
| // char for each set flag.
|
|
|
| - a.Bind(&construct_string);
|
| + a->Bind(&construct_string);
|
| {
|
| Node* const result =
|
| - a.AllocateSeqOneByteString(context, var_length.value());
|
| + a->AllocateSeqOneByteString(context, var_length.value());
|
| Node* const flags_intptr = var_flags.value();
|
|
|
| - Variable var_offset(&a, MachineType::PointerRepresentation());
|
| + Variable var_offset(a, MachineType::PointerRepresentation());
|
| var_offset.Bind(
|
| - a.IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag));
|
| -
|
| - Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
|
| - label_unicode(&a), label_sticky(&a), out(&a);
|
| -
|
| -#define CASE_FOR_FLAG(FLAG, CHAR, LABEL, NEXT_LABEL) \
|
| - do { \
|
| - a.Bind(&LABEL); \
|
| - Node* const mask = a.IntPtrConstant(FLAG); \
|
| - a.GotoIf(a.WordEqual(a.WordAnd(flags_intptr, mask), int_zero), \
|
| - &NEXT_LABEL); \
|
| - Node* const value = a.IntPtrConstant(CHAR); \
|
| - a.StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \
|
| - var_offset.value(), value); \
|
| - var_offset.Bind(a.IntPtrAdd(var_offset.value(), int_one)); \
|
| - a.Goto(&NEXT_LABEL); \
|
| + a->IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag));
|
| +
|
| + Label label_global(a), label_ignorecase(a), label_multiline(a),
|
| + label_unicode(a), label_sticky(a), out(a);
|
| +
|
| +#define CASE_FOR_FLAG(FLAG, CHAR, LABEL, NEXT_LABEL) \
|
| + do { \
|
| + a->Bind(&LABEL); \
|
| + Node* const mask = a->IntPtrConstant(FLAG); \
|
| + a->GotoIf(a->WordEqual(a->WordAnd(flags_intptr, mask), int_zero), \
|
| + &NEXT_LABEL); \
|
| + Node* const value = a->IntPtrConstant(CHAR); \
|
| + a->StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \
|
| + var_offset.value(), value); \
|
| + var_offset.Bind(a->IntPtrAdd(var_offset.value(), int_one)); \
|
| + a->Goto(&NEXT_LABEL); \
|
| } while (false)
|
|
|
| - a.Goto(&label_global);
|
| + a->Goto(&label_global);
|
| CASE_FOR_FLAG(JSRegExp::kGlobal, 'g', label_global, label_ignorecase);
|
| CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i', label_ignorecase,
|
| label_multiline);
|
| @@ -721,8 +718,8 @@
|
| CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out);
|
| #undef CASE_FOR_FLAG
|
|
|
| - a.Bind(&out);
|
| - a.Return(result);
|
| + a->Bind(&out);
|
| + a->Return(result);
|
| }
|
| }
|
|
|
| @@ -872,46 +869,36 @@
|
| } // namespace
|
|
|
| // ES6 21.2.5.4.
|
| -void Builtins::Generate_RegExpPrototypeGlobalGetter(
|
| - compiler::CodeAssemblerState* state) {
|
| - CodeStubAssembler a(state);
|
| - Generate_FlagGetter(&a, JSRegExp::kGlobal,
|
| +void Builtins::Generate_RegExpPrototypeGlobalGetter(CodeStubAssembler* a) {
|
| + Generate_FlagGetter(a, JSRegExp::kGlobal,
|
| v8::Isolate::kRegExpPrototypeOldFlagGetter,
|
| "RegExp.prototype.global");
|
| }
|
|
|
| // ES6 21.2.5.5.
|
| -void Builtins::Generate_RegExpPrototypeIgnoreCaseGetter(
|
| - compiler::CodeAssemblerState* state) {
|
| - CodeStubAssembler a(state);
|
| - Generate_FlagGetter(&a, JSRegExp::kIgnoreCase,
|
| +void Builtins::Generate_RegExpPrototypeIgnoreCaseGetter(CodeStubAssembler* a) {
|
| + Generate_FlagGetter(a, JSRegExp::kIgnoreCase,
|
| v8::Isolate::kRegExpPrototypeOldFlagGetter,
|
| "RegExp.prototype.ignoreCase");
|
| }
|
|
|
| // ES6 21.2.5.7.
|
| -void Builtins::Generate_RegExpPrototypeMultilineGetter(
|
| - compiler::CodeAssemblerState* state) {
|
| - CodeStubAssembler a(state);
|
| - Generate_FlagGetter(&a, JSRegExp::kMultiline,
|
| +void Builtins::Generate_RegExpPrototypeMultilineGetter(CodeStubAssembler* a) {
|
| + Generate_FlagGetter(a, JSRegExp::kMultiline,
|
| v8::Isolate::kRegExpPrototypeOldFlagGetter,
|
| "RegExp.prototype.multiline");
|
| }
|
|
|
| // ES6 21.2.5.12.
|
| -void Builtins::Generate_RegExpPrototypeStickyGetter(
|
| - compiler::CodeAssemblerState* state) {
|
| - CodeStubAssembler a(state);
|
| - Generate_FlagGetter(&a, JSRegExp::kSticky,
|
| +void Builtins::Generate_RegExpPrototypeStickyGetter(CodeStubAssembler* a) {
|
| + Generate_FlagGetter(a, JSRegExp::kSticky,
|
| v8::Isolate::kRegExpPrototypeStickyGetter,
|
| "RegExp.prototype.sticky");
|
| }
|
|
|
| // ES6 21.2.5.15.
|
| -void Builtins::Generate_RegExpPrototypeUnicodeGetter(
|
| - compiler::CodeAssemblerState* state) {
|
| - CodeStubAssembler a(state);
|
| - Generate_FlagGetter(&a, JSRegExp::kUnicode,
|
| +void Builtins::Generate_RegExpPrototypeUnicodeGetter(CodeStubAssembler* a) {
|
| + Generate_FlagGetter(a, JSRegExp::kUnicode,
|
| v8::Isolate::kRegExpPrototypeUnicodeGetter,
|
| "RegExp.prototype.unicode");
|
| }
|
| @@ -1074,33 +1061,31 @@
|
|
|
| // ES#sec-regexp.prototype.test
|
| // RegExp.prototype.test ( S )
|
| -void Builtins::Generate_RegExpPrototypeTest(
|
| - compiler::CodeAssemblerState* state) {
|
| +void Builtins::Generate_RegExpPrototypeTest(CodeStubAssembler* a) {
|
| typedef compiler::Node Node;
|
| - CodeStubAssembler a(state);
|
| -
|
| - Isolate* const isolate = a.isolate();
|
| -
|
| - Node* const maybe_receiver = a.Parameter(0);
|
| - Node* const maybe_string = a.Parameter(1);
|
| - Node* const context = a.Parameter(4);
|
| +
|
| + Isolate* const isolate = a->isolate();
|
| +
|
| + Node* const maybe_receiver = a->Parameter(0);
|
| + Node* const maybe_string = a->Parameter(1);
|
| + Node* const context = a->Parameter(4);
|
|
|
| // Ensure {maybe_receiver} is a JSReceiver.
|
| - ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
|
| + ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver,
|
| MessageTemplate::kIncompatibleMethodReceiver,
|
| "RegExp.prototype.test");
|
| Node* const receiver = maybe_receiver;
|
|
|
| // Convert {maybe_string} to a String.
|
| - Node* const string = a.ToString(context, maybe_string);
|
| + Node* const string = a->ToString(context, maybe_string);
|
|
|
| // Call exec.
|
| - Node* const match_indices = RegExpExec(&a, context, receiver, string);
|
| + Node* const match_indices = RegExpExec(a, context, receiver, string);
|
|
|
| // Return true iff exec matched successfully.
|
| - Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()),
|
| - a.FalseConstant(), a.TrueConstant());
|
| - a.Return(result);
|
| + Node* const result = a->Select(a->WordEqual(match_indices, a->NullConstant()),
|
| + a->FalseConstant(), a->TrueConstant());
|
| + a->Return(result);
|
| }
|
|
|
| // ES#sec-regexp.prototype-@@match
|
| @@ -1268,36 +1253,34 @@
|
|
|
| // ES#sec-regexp.prototype-@@search
|
| // RegExp.prototype [ @@search ] ( string )
|
| -void Builtins::Generate_RegExpPrototypeSearch(
|
| - compiler::CodeAssemblerState* state) {
|
| +void Builtins::Generate_RegExpPrototypeSearch(CodeStubAssembler* a) {
|
| typedef CodeStubAssembler::Label Label;
|
| typedef compiler::Node Node;
|
| - CodeStubAssembler a(state);
|
| -
|
| - Isolate* const isolate = a.isolate();
|
| -
|
| - Node* const maybe_receiver = a.Parameter(0);
|
| - Node* const maybe_string = a.Parameter(1);
|
| - Node* const context = a.Parameter(4);
|
| +
|
| + Isolate* const isolate = a->isolate();
|
| +
|
| + Node* const maybe_receiver = a->Parameter(0);
|
| + Node* const maybe_string = a->Parameter(1);
|
| + Node* const context = a->Parameter(4);
|
|
|
| // Ensure {maybe_receiver} is a JSReceiver.
|
| Node* const map =
|
| - ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
|
| + ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver,
|
| MessageTemplate::kIncompatibleMethodReceiver,
|
| "RegExp.prototype.@@search");
|
| Node* const receiver = maybe_receiver;
|
|
|
| // Convert {maybe_string} to a String.
|
| - Node* const string = a.ToString(context, maybe_string);
|
| -
|
| - Label fast_path(&a), slow_path(&a);
|
| - BranchIfFastPath(&a, context, map, &fast_path, &slow_path);
|
| -
|
| - a.Bind(&fast_path);
|
| - Generate_RegExpPrototypeSearchBody(&a, receiver, string, context, true);
|
| -
|
| - a.Bind(&slow_path);
|
| - Generate_RegExpPrototypeSearchBody(&a, receiver, string, context, false);
|
| + Node* const string = a->ToString(context, maybe_string);
|
| +
|
| + Label fast_path(a), slow_path(a);
|
| + BranchIfFastPath(a, context, map, &fast_path, &slow_path);
|
| +
|
| + a->Bind(&fast_path);
|
| + Generate_RegExpPrototypeSearchBody(a, receiver, string, context, true);
|
| +
|
| + a->Bind(&slow_path);
|
| + Generate_RegExpPrototypeSearchBody(a, receiver, string, context, false);
|
| }
|
|
|
| namespace {
|
| @@ -1991,134 +1974,130 @@
|
|
|
| // ES#sec-regexp.prototype-@@replace
|
| // RegExp.prototype [ @@replace ] ( string, replaceValue )
|
| -void Builtins::Generate_RegExpPrototypeReplace(
|
| - compiler::CodeAssemblerState* state) {
|
| +void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) {
|
| typedef CodeStubAssembler::Label Label;
|
| typedef compiler::Node Node;
|
| - CodeStubAssembler a(state);
|
| -
|
| - Isolate* const isolate = a.isolate();
|
| -
|
| - Node* const maybe_receiver = a.Parameter(0);
|
| - Node* const maybe_string = a.Parameter(1);
|
| - Node* const replace_value = a.Parameter(2);
|
| - Node* const context = a.Parameter(5);
|
| -
|
| - Node* const int_zero = a.IntPtrConstant(0);
|
| +
|
| + Isolate* const isolate = a->isolate();
|
| +
|
| + Node* const maybe_receiver = a->Parameter(0);
|
| + Node* const maybe_string = a->Parameter(1);
|
| + Node* const replace_value = a->Parameter(2);
|
| + Node* const context = a->Parameter(5);
|
| +
|
| + Node* const int_zero = a->IntPtrConstant(0);
|
|
|
| // Ensure {maybe_receiver} is a JSReceiver.
|
| Node* const map =
|
| - ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
|
| + ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver,
|
| MessageTemplate::kIncompatibleMethodReceiver,
|
| "RegExp.prototype.@@replace");
|
| Node* const receiver = maybe_receiver;
|
|
|
| // Convert {maybe_string} to a String.
|
| Callable tostring_callable = CodeFactory::ToString(isolate);
|
| - Node* const string = a.CallStub(tostring_callable, context, maybe_string);
|
| + Node* const string = a->CallStub(tostring_callable, context, maybe_string);
|
|
|
| // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
|
| - Label checkreplacecallable(&a), runtime(&a, Label::kDeferred), fastpath(&a);
|
| - BranchIfFastPath(&a, context, map, &checkreplacecallable, &runtime);
|
| -
|
| - a.Bind(&checkreplacecallable);
|
| + Label checkreplacecallable(a), runtime(a, Label::kDeferred), fastpath(a);
|
| + BranchIfFastPath(a, context, map, &checkreplacecallable, &runtime);
|
| +
|
| + a->Bind(&checkreplacecallable);
|
| Node* const regexp = receiver;
|
|
|
| // 2. Is {replace_value} callable?
|
| - Label checkreplacestring(&a), if_iscallable(&a);
|
| - a.GotoIf(a.TaggedIsSmi(replace_value), &checkreplacestring);
|
| -
|
| - Node* const replace_value_map = a.LoadMap(replace_value);
|
| - a.Branch(a.IsCallableMap(replace_value_map), &if_iscallable,
|
| - &checkreplacestring);
|
| + Label checkreplacestring(a), if_iscallable(a);
|
| + a->GotoIf(a->TaggedIsSmi(replace_value), &checkreplacestring);
|
| +
|
| + Node* const replace_value_map = a->LoadMap(replace_value);
|
| + a->Branch(a->IsCallableMap(replace_value_map), &if_iscallable,
|
| + &checkreplacestring);
|
|
|
| // 3. Does ToString({replace_value}) contain '$'?
|
| - a.Bind(&checkreplacestring);
|
| + a->Bind(&checkreplacestring);
|
| {
|
| Node* const replace_string =
|
| - a.CallStub(tostring_callable, context, replace_value);
|
| -
|
| - Node* const dollar_char = a.IntPtrConstant('$');
|
| - Node* const smi_minusone = a.SmiConstant(Smi::FromInt(-1));
|
| - a.GotoUnless(a.SmiEqual(a.StringIndexOfChar(context, replace_string,
|
| - dollar_char, int_zero),
|
| - smi_minusone),
|
| - &runtime);
|
| -
|
| - a.Return(ReplaceSimpleStringFastPath(&a, context, regexp, string,
|
| - replace_string));
|
| + a->CallStub(tostring_callable, context, replace_value);
|
| +
|
| + Node* const dollar_char = a->IntPtrConstant('$');
|
| + Node* const smi_minusone = a->SmiConstant(Smi::FromInt(-1));
|
| + a->GotoUnless(a->SmiEqual(a->StringIndexOfChar(context, replace_string,
|
| + dollar_char, int_zero),
|
| + smi_minusone),
|
| + &runtime);
|
| +
|
| + a->Return(ReplaceSimpleStringFastPath(a, context, regexp, string,
|
| + replace_string));
|
| }
|
|
|
| // {regexp} is unmodified and {replace_value} is callable.
|
| - a.Bind(&if_iscallable);
|
| + a->Bind(&if_iscallable);
|
| {
|
| Node* const replace_callable = replace_value;
|
|
|
| // Check if the {regexp} is global.
|
| - Label if_isglobal(&a), if_isnotglobal(&a);
|
| - Node* const is_global = FastFlagGetter(&a, regexp, JSRegExp::kGlobal);
|
| - a.Branch(is_global, &if_isglobal, &if_isnotglobal);
|
| -
|
| - a.Bind(&if_isglobal);
|
| + Label if_isglobal(a), if_isnotglobal(a);
|
| + Node* const is_global = FastFlagGetter(a, regexp, JSRegExp::kGlobal);
|
| + a->Branch(is_global, &if_isglobal, &if_isnotglobal);
|
| +
|
| + a->Bind(&if_isglobal);
|
| {
|
| Node* const result = ReplaceGlobalCallableFastPath(
|
| - &a, context, regexp, string, replace_callable);
|
| - a.Return(result);
|
| - }
|
| -
|
| - a.Bind(&if_isnotglobal);
|
| + a, context, regexp, string, replace_callable);
|
| + a->Return(result);
|
| + }
|
| +
|
| + a->Bind(&if_isnotglobal);
|
| {
|
| Node* const result =
|
| - a.CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction,
|
| - context, string, regexp, replace_callable);
|
| - a.Return(result);
|
| - }
|
| - }
|
| -
|
| - a.Bind(&runtime);
|
| - {
|
| - Node* const result = a.CallRuntime(Runtime::kRegExpReplace, context,
|
| - receiver, string, replace_value);
|
| - a.Return(result);
|
| + a->CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction,
|
| + context, string, regexp, replace_callable);
|
| + a->Return(result);
|
| + }
|
| + }
|
| +
|
| + a->Bind(&runtime);
|
| + {
|
| + Node* const result = a->CallRuntime(Runtime::kRegExpReplace, context,
|
| + receiver, string, replace_value);
|
| + a->Return(result);
|
| }
|
| }
|
|
|
| // Simple string matching functionality for internal use which does not modify
|
| // the last match info.
|
| -void Builtins::Generate_RegExpInternalMatch(
|
| - compiler::CodeAssemblerState* state) {
|
| +void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) {
|
| typedef CodeStubAssembler::Label Label;
|
| typedef compiler::Node Node;
|
| - CodeStubAssembler a(state);
|
| -
|
| - Isolate* const isolate = a.isolate();
|
| -
|
| - Node* const regexp = a.Parameter(1);
|
| - Node* const string = a.Parameter(2);
|
| - Node* const context = a.Parameter(5);
|
| -
|
| - Node* const null = a.NullConstant();
|
| - Node* const smi_zero = a.SmiConstant(Smi::FromInt(0));
|
| -
|
| - Node* const native_context = a.LoadNativeContext(context);
|
| - Node* const internal_match_info = a.LoadContextElement(
|
| +
|
| + Isolate* const isolate = a->isolate();
|
| +
|
| + Node* const regexp = a->Parameter(1);
|
| + Node* const string = a->Parameter(2);
|
| + Node* const context = a->Parameter(5);
|
| +
|
| + Node* const null = a->NullConstant();
|
| + Node* const smi_zero = a->SmiConstant(Smi::FromInt(0));
|
| +
|
| + Node* const native_context = a->LoadNativeContext(context);
|
| + Node* const internal_match_info = a->LoadContextElement(
|
| native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX);
|
|
|
| Callable exec_callable = CodeFactory::RegExpExec(isolate);
|
| - Node* const match_indices = a.CallStub(exec_callable, context, regexp, string,
|
| - smi_zero, internal_match_info);
|
| -
|
| - Label if_matched(&a), if_didnotmatch(&a);
|
| - a.Branch(a.WordEqual(match_indices, null), &if_didnotmatch, &if_matched);
|
| -
|
| - a.Bind(&if_didnotmatch);
|
| - a.Return(null);
|
| -
|
| - a.Bind(&if_matched);
|
| - {
|
| - Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context,
|
| + Node* const match_indices = a->CallStub(
|
| + exec_callable, context, regexp, string, smi_zero, internal_match_info);
|
| +
|
| + Label if_matched(a), if_didnotmatch(a);
|
| + a->Branch(a->WordEqual(match_indices, null), &if_didnotmatch, &if_matched);
|
| +
|
| + a->Bind(&if_didnotmatch);
|
| + a->Return(null);
|
| +
|
| + a->Bind(&if_matched);
|
| + {
|
| + Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
|
| match_indices, string);
|
| - a.Return(result);
|
| + a->Return(result);
|
| }
|
| }
|
|
|
|
|