Commit 082bf306 authored by jgruber's avatar jgruber Committed by Commit bot

[stubs] Add RegExpReplace and RegExpSplit stubs

This adds helper stubs for RegExp split and replace operations, called directly
by both RegExpPrototype{Replace,Split} and StringPrototype{Replace,Split}.

BUG=

Review-Url: https://codereview.chromium.org/2668703002
Cr-Commit-Position: refs/heads/master@{#42919}
parent 87e53cb8
This diff is collapsed.
...@@ -19,8 +19,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { ...@@ -19,8 +19,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
explicit RegExpBuiltinsAssembler(CodeAssemblerState* state) explicit RegExpBuiltinsAssembler(CodeAssemblerState* state)
: CodeStubAssembler(state) {} : CodeStubAssembler(state) {}
void BranchIfFastRegExp(Node* context, Node* map, Label* if_isunmodified, void BranchIfFastRegExp(Node* const context, Node* const map,
Label* if_ismodified); Label* const if_isunmodified,
Label* const if_ismodified);
protected: protected:
Node* FastLoadLastIndex(Node* regexp); Node* FastLoadLastIndex(Node* regexp);
...@@ -48,6 +49,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { ...@@ -48,6 +49,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
MessageTemplate::Template msg_template, MessageTemplate::Template msg_template,
char const* method_name); char const* method_name);
// Analogous to BranchIfFastRegExp, for use in asserts.
Node* IsFastRegExpMap(Node* const context, Node* const map);
Node* IsInitialRegExpMap(Node* context, Node* map); Node* IsInitialRegExpMap(Node* context, Node* map);
void BranchIfFastRegExpResult(Node* context, Node* map, void BranchIfFastRegExpResult(Node* context, Node* map,
Label* if_isunmodified, Label* if_ismodified); Label* if_isunmodified, Label* if_ismodified);
......
...@@ -1115,7 +1115,7 @@ void StringBuiltinsAssembler::MaybeCallFunctionAtSymbol( ...@@ -1115,7 +1115,7 @@ void StringBuiltinsAssembler::MaybeCallFunctionAtSymbol(
} }
// Take the fast path for RegExps. // Take the fast path for RegExps.
if (regexp_call != nullptr) { {
Label stub_call(this), slow_lookup(this); Label stub_call(this), slow_lookup(this);
RegExpBuiltinsAssembler regexp_asm(state()); RegExpBuiltinsAssembler regexp_asm(state());
...@@ -1160,10 +1160,18 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) { ...@@ -1160,10 +1160,18 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
RequireObjectCoercible(context, receiver, "String.prototype.replace"); RequireObjectCoercible(context, receiver, "String.prototype.replace");
// Redirect to replacer method if {search[@@replace]} is not undefined. // Redirect to replacer method if {search[@@replace]} is not undefined.
// TODO(jgruber): Call RegExp.p.replace stub for fast path.
MaybeCallFunctionAtSymbol( MaybeCallFunctionAtSymbol(
context, search, isolate()->factory()->replace_symbol(), nullptr, context, search, isolate()->factory()->replace_symbol(),
[=]() {
Callable tostring_callable = CodeFactory::ToString(isolate());
Node* const subject_string =
CallStub(tostring_callable, context, receiver);
Callable replace_callable = CodeFactory::RegExpReplace(isolate());
return CallStub(replace_callable, context, search, subject_string,
replace);
},
[=](Node* fn) { [=](Node* fn) {
Callable call_callable = CodeFactory::Call(isolate()); Callable call_callable = CodeFactory::Call(isolate());
return CallJS(call_callable, context, fn, search, receiver, replace); return CallJS(call_callable, context, fn, search, receiver, replace);
...@@ -1317,10 +1325,18 @@ TF_BUILTIN(StringPrototypeSplit, StringBuiltinsAssembler) { ...@@ -1317,10 +1325,18 @@ TF_BUILTIN(StringPrototypeSplit, StringBuiltinsAssembler) {
RequireObjectCoercible(context, receiver, "String.prototype.split"); RequireObjectCoercible(context, receiver, "String.prototype.split");
// Redirect to splitter method if {separator[@@split]} is not undefined. // Redirect to splitter method if {separator[@@split]} is not undefined.
// TODO(jgruber): Call RegExp.p.split stub for fast path.
MaybeCallFunctionAtSymbol( MaybeCallFunctionAtSymbol(
context, separator, isolate()->factory()->split_symbol(), nullptr, context, separator, isolate()->factory()->split_symbol(),
[=]() {
Callable tostring_callable = CodeFactory::ToString(isolate());
Node* const subject_string =
CallStub(tostring_callable, context, receiver);
Callable split_callable = CodeFactory::RegExpSplit(isolate());
return CallStub(split_callable, context, separator, subject_string,
limit);
},
[=](Node* fn) { [=](Node* fn) {
Callable call_callable = CodeFactory::Call(isolate()); Callable call_callable = CodeFactory::Call(isolate());
return CallJS(call_callable, context, fn, separator, receiver, limit); return CallJS(call_callable, context, fn, separator, receiver, limit);
......
...@@ -707,16 +707,20 @@ class Isolate; ...@@ -707,16 +707,20 @@ class Isolate;
TFJ(RegExpPrototypeIgnoreCaseGetter, 0) \ TFJ(RegExpPrototypeIgnoreCaseGetter, 0) \
TFJ(RegExpPrototypeMatch, 1) \ TFJ(RegExpPrototypeMatch, 1) \
TFJ(RegExpPrototypeMultilineGetter, 0) \ TFJ(RegExpPrototypeMultilineGetter, 0) \
TFJ(RegExpPrototypeReplace, 2) \
TFJ(RegExpPrototypeSearch, 1) \ TFJ(RegExpPrototypeSearch, 1) \
TFJ(RegExpPrototypeSourceGetter, 0) \ TFJ(RegExpPrototypeSourceGetter, 0) \
TFJ(RegExpPrototypeSplit, 2) \
TFJ(RegExpPrototypeStickyGetter, 0) \ TFJ(RegExpPrototypeStickyGetter, 0) \
TFJ(RegExpPrototypeTest, 1) \ TFJ(RegExpPrototypeTest, 1) \
CPP(RegExpPrototypeToString) \ CPP(RegExpPrototypeToString) \
TFJ(RegExpPrototypeUnicodeGetter, 0) \ TFJ(RegExpPrototypeUnicodeGetter, 0) \
CPP(RegExpRightContextGetter) \ CPP(RegExpRightContextGetter) \
\ \
TFS(RegExpReplace, BUILTIN, kNoExtraICState, RegExpReplace) \
TFJ(RegExpPrototypeReplace, 2) \
\
TFS(RegExpSplit, BUILTIN, kNoExtraICState, RegExpSplit) \
TFJ(RegExpPrototypeSplit, 2) \
\
/* SharedArrayBuffer */ \ /* SharedArrayBuffer */ \
CPP(SharedArrayBufferPrototypeGetByteLength) \ CPP(SharedArrayBufferPrototypeGetByteLength) \
TFJ(AtomicsLoad, 2) \ TFJ(AtomicsLoad, 2) \
......
...@@ -251,6 +251,8 @@ TFS_BUILTIN(ForInFilter) ...@@ -251,6 +251,8 @@ TFS_BUILTIN(ForInFilter)
TFS_BUILTIN(GetSuperConstructor) TFS_BUILTIN(GetSuperConstructor)
TFS_BUILTIN(KeyedLoadIC_Megamorphic) TFS_BUILTIN(KeyedLoadIC_Megamorphic)
TFS_BUILTIN(PromiseHandleReject) TFS_BUILTIN(PromiseHandleReject)
TFS_BUILTIN(RegExpReplace)
TFS_BUILTIN(RegExpSplit)
TFS_BUILTIN(StringCharAt) TFS_BUILTIN(StringCharAt)
TFS_BUILTIN(StringCharCodeAt) TFS_BUILTIN(StringCharCodeAt)
TFS_BUILTIN(StringEqual) TFS_BUILTIN(StringEqual)
......
...@@ -132,6 +132,9 @@ class V8_EXPORT_PRIVATE CodeFactory final { ...@@ -132,6 +132,9 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable SubString(Isolate* isolate); static Callable SubString(Isolate* isolate);
static Callable StringIndexOf(Isolate* isolate); static Callable StringIndexOf(Isolate* isolate);
static Callable RegExpReplace(Isolate* isolate);
static Callable RegExpSplit(Isolate* isolate);
static Callable ClassOf(Isolate* isolate); static Callable ClassOf(Isolate* isolate);
static Callable Typeof(Isolate* isolate); static Callable Typeof(Isolate* isolate);
static Callable GetSuperConstructor(Isolate* isolate); static Callable GetSuperConstructor(Isolate* isolate);
......
...@@ -52,6 +52,8 @@ class PlatformInterfaceDescriptor; ...@@ -52,6 +52,8 @@ class PlatformInterfaceDescriptor;
V(ConstructStub) \ V(ConstructStub) \
V(ConstructTrampoline) \ V(ConstructTrampoline) \
V(RegExpExec) \ V(RegExpExec) \
V(RegExpReplace) \
V(RegExpSplit) \
V(CopyFastSmiOrObjectElements) \ V(CopyFastSmiOrObjectElements) \
V(TransitionElementsKind) \ V(TransitionElementsKind) \
V(AllocateHeapNumber) \ V(AllocateHeapNumber) \
...@@ -619,6 +621,20 @@ class RegExpExecDescriptor : public CallInterfaceDescriptor { ...@@ -619,6 +621,20 @@ class RegExpExecDescriptor : public CallInterfaceDescriptor {
CallInterfaceDescriptor) CallInterfaceDescriptor)
}; };
class RegExpReplaceDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kString, kReplaceValue)
DECLARE_DEFAULT_DESCRIPTOR(RegExpReplaceDescriptor, CallInterfaceDescriptor,
kParameterCount)
};
class RegExpSplitDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kString, kLimit)
DECLARE_DEFAULT_DESCRIPTOR(RegExpSplitDescriptor, CallInterfaceDescriptor,
kParameterCount)
};
class CopyFastSmiOrObjectElementsDescriptor : public CallInterfaceDescriptor { class CopyFastSmiOrObjectElementsDescriptor : public CallInterfaceDescriptor {
public: public:
DEFINE_PARAMETERS(kObject) DEFINE_PARAMETERS(kObject)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment