summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/builtins-regexp-gen.cc
diff options
context:
space:
mode:
authorRefael Ackermann <refack@gmail.com>2019-05-28 08:46:21 -0400
committerRefael Ackermann <refack@gmail.com>2019-06-01 09:55:12 -0400
commited74896b1fae1c163b3906163f3bf46326618ddb (patch)
tree7fb05c5a19808e0c5cd95837528e9005999cf540 /deps/v8/src/builtins/builtins-regexp-gen.cc
parent2a850cd0664a4eee51f44d0bb8c2f7a3fe444154 (diff)
downloadandroid-node-v8-ed74896b1fae1c163b3906163f3bf46326618ddb.tar.gz
android-node-v8-ed74896b1fae1c163b3906163f3bf46326618ddb.tar.bz2
android-node-v8-ed74896b1fae1c163b3906163f3bf46326618ddb.zip
deps: update V8 to 7.5.288.22
PR-URL: https://github.com/nodejs/node/pull/27375 Reviewed-By: Michaƫl Zasso <targos@protonmail.com> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'deps/v8/src/builtins/builtins-regexp-gen.cc')
-rw-r--r--deps/v8/src/builtins/builtins-regexp-gen.cc231
1 files changed, 16 insertions, 215 deletions
diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc
index 00b1f1b921..1a0e014e3e 100644
--- a/deps/v8/src/builtins/builtins-regexp-gen.cc
+++ b/deps/v8/src/builtins/builtins-regexp-gen.cc
@@ -538,10 +538,12 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
IntPtrAdd(BitcastTaggedToWord(code),
IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)));
- TNode<Int32T> result = UncheckedCast<Int32T>(CallCFunction9(
- retval_type, arg0_type, arg1_type, arg2_type, arg3_type, arg4_type,
- arg5_type, arg6_type, arg7_type, arg8_type, code_entry, arg0, arg1,
- arg2, arg3, arg4, arg5, arg6, arg7, arg8));
+ TNode<Int32T> result = UncheckedCast<Int32T>(CallCFunction(
+ code_entry, retval_type, std::make_pair(arg0_type, arg0),
+ std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2),
+ std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4),
+ std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6),
+ std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8)));
// Check the result.
// We expect exactly one result since we force the called regexp to behave
@@ -779,6 +781,14 @@ RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
return CAST(var_result.value());
}
+TNode<RegExpMatchInfo>
+RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResultFast(
+ TNode<Context> context, TNode<JSReceiver> maybe_regexp,
+ TNode<String> string, Label* if_didnotmatch) {
+ return RegExpPrototypeExecBodyWithoutResult(context, maybe_regexp, string,
+ if_didnotmatch, true);
+}
+
// ES#sec-regexp.prototype.exec
// RegExp.prototype.exec ( string )
TNode<HeapObject> RegExpBuiltinsAssembler::RegExpPrototypeExecBody(
@@ -1821,6 +1831,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
if (is_fastpath) CSA_ASSERT(this, TaggedIsPositiveSmi(index));
// Default to last_index + 1.
+ // TODO(pwong): Consider using TrySmiAdd for the fast path to reduce generated
+ // code.
Node* const index_plus_one = NumberInc(index);
VARIABLE(var_result, MachineRepresentation::kTagged, index_plus_one);
@@ -2880,217 +2892,6 @@ Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath(
return var_result.value();
}
-Node* RegExpBuiltinsAssembler::ReplaceSimpleStringFastPath(
- Node* context, Node* regexp, TNode<String> string,
- TNode<String> replace_string) {
- // The fast path is reached only if {receiver} is an unmodified
- // JSRegExp instance, {replace_value} is non-callable, and
- // ToString({replace_value}) does not contain '$', i.e. we're doing a simple
- // string replacement.
-
- CSA_ASSERT(this, IsFastRegExp(context, regexp));
-
- const bool kIsFastPath = true;
-
- TVARIABLE(String, var_result, EmptyStringConstant());
- VARIABLE(var_last_match_end, MachineRepresentation::kTagged, SmiZero());
- VARIABLE(var_is_unicode, MachineRepresentation::kWord32, Int32Constant(0));
- Variable* vars[] = {&var_result, &var_last_match_end};
- Label out(this), loop(this, 2, vars), loop_end(this),
- if_nofurthermatches(this);
-
- // Is {regexp} global?
- Node* const is_global = FastFlagGetter(CAST(regexp), JSRegExp::kGlobal);
- GotoIfNot(is_global, &loop);
-
- var_is_unicode.Bind(FastFlagGetter(CAST(regexp), JSRegExp::kUnicode));
- FastStoreLastIndex(regexp, SmiZero());
- Goto(&loop);
-
- BIND(&loop);
- {
- TNode<RegExpMatchInfo> var_match_indices =
- RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp),
- string, &if_nofurthermatches,
- kIsFastPath);
-
- // Successful match.
- {
- TNode<Smi> const match_start = CAST(UnsafeLoadFixedArrayElement(
- var_match_indices, RegExpMatchInfo::kFirstCaptureIndex));
- TNode<Smi> const match_end = CAST(UnsafeLoadFixedArrayElement(
- var_match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1));
-
- TNode<Smi> const replace_length = LoadStringLengthAsSmi(replace_string);
-
- // TODO(jgruber): We could skip many of the checks that using SubString
- // here entails.
- TNode<String> first_part =
- CAST(CallBuiltin(Builtins::kSubString, context, string,
- var_last_match_end.value(), match_start));
- var_result = CAST(CallBuiltin(Builtins::kStringAdd_CheckNone, context,
- var_result.value(), first_part));
-
- GotoIf(SmiEqual(replace_length, SmiZero()), &loop_end);
-
- var_result = CAST(CallBuiltin(Builtins::kStringAdd_CheckNone, context,
- var_result.value(), replace_string));
- Goto(&loop_end);
-
- BIND(&loop_end);
- {
- var_last_match_end.Bind(match_end);
- // Non-global case ends here after the first replacement.
- GotoIfNot(is_global, &if_nofurthermatches);
-
- GotoIf(SmiNotEqual(match_end, match_start), &loop);
- // If match is the empty string, we have to increment lastIndex.
- Node* const this_index = FastLoadLastIndex(CAST(regexp));
- Node* const next_index = AdvanceStringIndex(
- string, this_index, var_is_unicode.value(), kIsFastPath);
- FastStoreLastIndex(regexp, next_index);
- Goto(&loop);
- }
- }
- }
-
- BIND(&if_nofurthermatches);
- {
- TNode<Smi> const string_length = LoadStringLengthAsSmi(string);
- TNode<String> last_part =
- CAST(CallBuiltin(Builtins::kSubString, context, string,
- var_last_match_end.value(), string_length));
- var_result = CAST(CallBuiltin(Builtins::kStringAdd_CheckNone, context,
- var_result.value(), last_part));
- Goto(&out);
- }
-
- BIND(&out);
- return var_result.value();
-}
-
-// Helper that skips a few initial checks.
-TF_BUILTIN(RegExpReplace, RegExpBuiltinsAssembler) {
- TNode<JSRegExp> regexp = CAST(Parameter(Descriptor::kRegExp));
- TNode<String> string = CAST(Parameter(Descriptor::kString));
- TNode<Object> replace_value = CAST(Parameter(Descriptor::kReplaceValue));
- TNode<Context> context = CAST(Parameter(Descriptor::kContext));
-
- CSA_ASSERT(this, IsFastRegExp(context, regexp));
-
- Label checkreplacestring(this), if_iscallable(this),
- runtime(this, Label::kDeferred);
-
- // 2. Is {replace_value} callable?
- GotoIf(TaggedIsSmi(replace_value), &checkreplacestring);
- Branch(IsCallableMap(LoadMap(CAST(replace_value))), &if_iscallable,
- &checkreplacestring);
-
- // 3. Does ToString({replace_value}) contain '$'?
- BIND(&checkreplacestring);
- {
- TNode<String> const replace_string =
- ToString_Inline(context, replace_value);
-
- // ToString(replaceValue) could potentially change the shape of the RegExp
- // object. Recheck that we are still on the fast path and bail to runtime
- // otherwise.
- {
- Label next(this);
- BranchIfFastRegExp(context, regexp, &next, &runtime);
- BIND(&next);
- }
-
- TNode<String> const dollar_string = HeapConstant(
- isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
- TNode<Smi> const dollar_ix =
- CAST(CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
- dollar_string, SmiZero()));
- GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
-
- Return(
- ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
- }
-
- // {regexp} is unmodified and {replace_value} is callable.
- BIND(&if_iscallable);
- {
- Node* const replace_fn = replace_value;
-
- // Check if the {regexp} is global.
- Label if_isglobal(this), if_isnotglobal(this);
-
- Node* const is_global = FastFlagGetter(regexp, JSRegExp::kGlobal);
- Branch(is_global, &if_isglobal, &if_isnotglobal);
-
- BIND(&if_isglobal);
- Return(ReplaceGlobalCallableFastPath(context, regexp, string, replace_fn));
-
- BIND(&if_isnotglobal);
- Return(CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction,
- context, string, regexp, replace_fn));
- }
-
- BIND(&runtime);
- Return(CallRuntime(Runtime::kRegExpReplace, context, regexp, string,
- replace_value));
-}
-
-// ES#sec-regexp.prototype-@@replace
-// RegExp.prototype [ @@replace ] ( string, replaceValue )
-TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) {
- const int kStringArg = 0;
- const int kReplaceValueArg = 1;
-
- TNode<IntPtrT> argc =
- ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
- CodeStubArguments args(this, argc);
-
- TNode<Object> maybe_receiver = args.GetReceiver();
- TNode<Object> maybe_string = args.GetOptionalArgumentValue(kStringArg);
- TNode<Object> replace_value = args.GetOptionalArgumentValue(kReplaceValueArg);
- TNode<Context> context = CAST(Parameter(Descriptor::kContext));
-
- // RegExpPrototypeReplace is a bit of a beast - a summary of dispatch logic:
- //
- // if (!IsFastRegExp(receiver)) CallRuntime(RegExpReplace)
- // if (IsCallable(replace)) {
- // if (IsGlobal(receiver)) {
- // // Called 'fast-path' but contains several runtime calls.
- // ReplaceGlobalCallableFastPath()
- // } else {
- // CallRuntime(StringReplaceNonGlobalRegExpWithFunction)
- // }
- // } else {
- // if (replace.contains("$")) {
- // CallRuntime(RegExpReplace)
- // } else {
- // ReplaceSimpleStringFastPath()
- // }
- // }
-
- // Ensure {maybe_receiver} is a JSReceiver.
- ThrowIfNotJSReceiver(context, maybe_receiver,
- MessageTemplate::kIncompatibleMethodReceiver,
- "RegExp.prototype.@@replace");
- Node* const receiver = maybe_receiver;
-
- // Convert {maybe_string} to a String.
- TNode<String> const string = ToString_Inline(context, maybe_string);
-
- // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
- Label stub(this), runtime(this, Label::kDeferred);
- BranchIfFastRegExp(context, receiver, &stub, &runtime);
-
- BIND(&stub);
- args.PopAndReturn(CallBuiltin(Builtins::kRegExpReplace, context, receiver,
- string, replace_value));
-
- BIND(&runtime);
- args.PopAndReturn(CallRuntime(Runtime::kRegExpReplace, context, receiver,
- string, replace_value));
-}
-
class RegExpStringIteratorAssembler : public RegExpBuiltinsAssembler {
public:
explicit RegExpStringIteratorAssembler(compiler::CodeAssemblerState* state)