diff options
author | Refael Ackermann <refack@gmail.com> | 2019-05-28 08:46:21 -0400 |
---|---|---|
committer | Refael Ackermann <refack@gmail.com> | 2019-06-01 09:55:12 -0400 |
commit | ed74896b1fae1c163b3906163f3bf46326618ddb (patch) | |
tree | 7fb05c5a19808e0c5cd95837528e9005999cf540 /deps/v8/src/builtins/builtins-regexp-gen.cc | |
parent | 2a850cd0664a4eee51f44d0bb8c2f7a3fe444154 (diff) | |
download | android-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.cc | 231 |
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) |