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 {
explicit RegExpBuiltinsAssembler(CodeAssemblerState* state)
: CodeStubAssembler(state) {}
void BranchIfFastRegExp(Node* context, Node* map, Label* if_isunmodified,
Label* if_ismodified);
void BranchIfFastRegExp(Node* const context, Node* const map,
Label* const if_isunmodified,
Label* const if_ismodified);
protected:
Node* FastLoadLastIndex(Node* regexp);
......@@ -48,6 +49,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
MessageTemplate::Template msg_template,
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);
void BranchIfFastRegExpResult(Node* context, Node* map,
Label* if_isunmodified, Label* if_ismodified);
......
......@@ -1115,7 +1115,7 @@ void StringBuiltinsAssembler::MaybeCallFunctionAtSymbol(
}
// Take the fast path for RegExps.
if (regexp_call != nullptr) {
{
Label stub_call(this), slow_lookup(this);
RegExpBuiltinsAssembler regexp_asm(state());
......@@ -1160,10 +1160,18 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
RequireObjectCoercible(context, receiver, "String.prototype.replace");
// Redirect to replacer method if {search[@@replace]} is not undefined.
// TODO(jgruber): Call RegExp.p.replace stub for fast path.
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) {
Callable call_callable = CodeFactory::Call(isolate());
return CallJS(call_callable, context, fn, search, receiver, replace);
......@@ -1317,10 +1325,18 @@ TF_BUILTIN(StringPrototypeSplit, StringBuiltinsAssembler) {
RequireObjectCoercible(context, receiver, "String.prototype.split");
// Redirect to splitter method if {separator[@@split]} is not undefined.
// TODO(jgruber): Call RegExp.p.split stub for fast path.
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) {
Callable call_callable = CodeFactory::Call(isolate());
return CallJS(call_callable, context, fn, separator, receiver, limit);
......
......@@ -707,16 +707,20 @@ class Isolate;
TFJ(RegExpPrototypeIgnoreCaseGetter, 0) \
TFJ(RegExpPrototypeMatch, 1) \
TFJ(RegExpPrototypeMultilineGetter, 0) \
TFJ(RegExpPrototypeReplace, 2) \
TFJ(RegExpPrototypeSearch, 1) \
TFJ(RegExpPrototypeSourceGetter, 0) \
TFJ(RegExpPrototypeSplit, 2) \
TFJ(RegExpPrototypeStickyGetter, 0) \
TFJ(RegExpPrototypeTest, 1) \
CPP(RegExpPrototypeToString) \
TFJ(RegExpPrototypeUnicodeGetter, 0) \
CPP(RegExpRightContextGetter) \
\
TFS(RegExpReplace, BUILTIN, kNoExtraICState, RegExpReplace) \
TFJ(RegExpPrototypeReplace, 2) \
\
TFS(RegExpSplit, BUILTIN, kNoExtraICState, RegExpSplit) \
TFJ(RegExpPrototypeSplit, 2) \
\
/* SharedArrayBuffer */ \
CPP(SharedArrayBufferPrototypeGetByteLength) \
TFJ(AtomicsLoad, 2) \
......
......@@ -251,6 +251,8 @@ TFS_BUILTIN(ForInFilter)
TFS_BUILTIN(GetSuperConstructor)
TFS_BUILTIN(KeyedLoadIC_Megamorphic)
TFS_BUILTIN(PromiseHandleReject)
TFS_BUILTIN(RegExpReplace)
TFS_BUILTIN(RegExpSplit)
TFS_BUILTIN(StringCharAt)
TFS_BUILTIN(StringCharCodeAt)
TFS_BUILTIN(StringEqual)
......
......@@ -132,6 +132,9 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable SubString(Isolate* isolate);
static Callable StringIndexOf(Isolate* isolate);
static Callable RegExpReplace(Isolate* isolate);
static Callable RegExpSplit(Isolate* isolate);
static Callable ClassOf(Isolate* isolate);
static Callable Typeof(Isolate* isolate);
static Callable GetSuperConstructor(Isolate* isolate);
......
......@@ -52,6 +52,8 @@ class PlatformInterfaceDescriptor;
V(ConstructStub) \
V(ConstructTrampoline) \
V(RegExpExec) \
V(RegExpReplace) \
V(RegExpSplit) \
V(CopyFastSmiOrObjectElements) \
V(TransitionElementsKind) \
V(AllocateHeapNumber) \
......@@ -619,6 +621,20 @@ class RegExpExecDescriptor : public 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 {
public:
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