Commit 29a970a2 authored by peterwmwong's avatar peterwmwong Committed by Commit Bot

[esnext] Update String.p.matchAll as per spec changes

As per (https://github.com/tc39/proposal-string-matchall/pull/41), String.p.matchAll's fallback was removed.
Additionally, removed a IsNullOrUndefined check that was already covered by MaybeCallFunctionAtSymbol.
Updates to Test262 has been submitted: https://github.com/tc39/test262/pull/1990

Bug: v8:6890
Change-Id: I246cbbcb4641ebded704c5f772809f182deaa30e
Reviewed-on: https://chromium-review.googlesource.com/c/1369091
Commit-Queue: Peter Wong <peter.wm.wong@gmail.com>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMathias Bynens <mathias@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58172}
parent 63d6b750
...@@ -1521,57 +1521,41 @@ TF_BUILTIN(StringPrototypeMatchAll, StringBuiltinsAssembler) { ...@@ -1521,57 +1521,41 @@ TF_BUILTIN(StringPrototypeMatchAll, StringBuiltinsAssembler) {
RequireObjectCoercible(context, receiver, method_name); RequireObjectCoercible(context, receiver, method_name);
// 2. If regexp is neither undefined nor null, then // 2. If regexp is neither undefined nor null, then
Label tostring_and_create_regexp_string_iterator(this, Label::kDeferred); // a. Let matcher be ? GetMethod(regexp, @@matchAll).
TVARIABLE(String, var_receiver_string); // b. If matcher is not undefined, then
GotoIf(IsNullOrUndefined(maybe_regexp), // i. Return ? Call(matcher, regexp, « O »).
&tostring_and_create_regexp_string_iterator); auto if_regexp_call = [&] {
{ // MaybeCallFunctionAtSymbol guarantees fast path is chosen only if
// a. Let matcher be ? GetMethod(regexp, @@matchAll). // maybe_regexp is a fast regexp and receiver is a string.
// b. If matcher is not undefined, then TNode<String> s = CAST(receiver);
// i. Return ? Call(matcher, regexp, « O »).
auto if_regexp_call = [&] {
// MaybeCallFunctionAtSymbol guarantees fast path is chosen only if
// maybe_regexp is a fast regexp and receiver is a string.
var_receiver_string = CAST(receiver);
CSA_ASSERT(this, IsString(var_receiver_string.value()));
RegExpMatchAllAssembler regexp_asm(state());
regexp_asm.Generate(context, native_context, maybe_regexp,
var_receiver_string.value());
};
auto if_generic_call = [=](Node* fn) {
Callable call_callable = CodeFactory::Call(isolate());
Return(CallJS(call_callable, context, fn, maybe_regexp, receiver));
};
MaybeCallFunctionAtSymbol(
context, maybe_regexp, receiver,
isolate()->factory()->match_all_symbol(),
DescriptorIndexAndName{JSRegExp::kSymbolMatchAllFunctionDescriptorIndex,
RootIndex::kmatch_all_symbol},
if_regexp_call, if_generic_call);
Goto(&tostring_and_create_regexp_string_iterator);
}
BIND(&tostring_and_create_regexp_string_iterator);
{
RegExpMatchAllAssembler regexp_asm(state()); RegExpMatchAllAssembler regexp_asm(state());
regexp_asm.Generate(context, native_context, maybe_regexp, s);
};
auto if_generic_call = [=](Node* fn) {
Callable call_callable = CodeFactory::Call(isolate());
Return(CallJS(call_callable, context, fn, maybe_regexp, receiver));
};
MaybeCallFunctionAtSymbol(
context, maybe_regexp, receiver, isolate()->factory()->match_all_symbol(),
DescriptorIndexAndName{JSRegExp::kSymbolMatchAllFunctionDescriptorIndex,
RootIndex::kmatch_all_symbol},
if_regexp_call, if_generic_call);
// 3. Let S be ? ToString(O). RegExpMatchAllAssembler regexp_asm(state());
var_receiver_string = ToString_Inline(context, receiver);
// 3. Let S be ? ToString(O).
// 4. Let matcher be ? RegExpCreate(R, "g"). TNode<String> s = ToString_Inline(context, receiver);
TNode<Object> regexp = regexp_asm.RegExpCreate(
context, native_context, maybe_regexp, StringConstant("g")); // 4. Let rx be ? RegExpCreate(R, "g").
TNode<Object> rx = regexp_asm.RegExpCreate(context, native_context,
// 5. Let global be true. maybe_regexp, StringConstant("g"));
// 6. Let fullUnicode be false.
// 7. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode). // 5. Return ? Invoke(rx, @@matchAll, « S »).
TNode<Int32T> global = Int32Constant(1); Callable callable = CodeFactory::Call(isolate());
TNode<Int32T> full_unicode = Int32Constant(0); TNode<Object> match_all_func =
TNode<Object> iterator = regexp_asm.CreateRegExpStringIterator( GetProperty(context, rx, isolate()->factory()->match_all_symbol());
native_context, regexp, var_receiver_string.value(), global, Return(CallJS(callable, context, match_all_func, rx, s));
full_unicode);
Return(iterator);
}
} }
class StringPadAssembler : public StringBuiltinsAssembler { class StringPadAssembler : public StringBuiltinsAssembler {
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-string-matchall
delete RegExp.prototype[Symbol.matchAll];
const str = 'a';
assertThrows(() => str.matchAll(/\w/g), TypeError);
...@@ -734,6 +734,10 @@ ...@@ -734,6 +734,10 @@
'harness/detachArrayBuffer': [SKIP], 'harness/detachArrayBuffer': [SKIP],
'harness/detachArrayBuffer-host-detachArrayBuffer': [SKIP], 'harness/detachArrayBuffer-host-detachArrayBuffer': [SKIP],
# Test needs to be updated to spec changes.
# https://github.com/tc39/test262/pull/1990
'built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll': [FAIL],
############################ SKIPPED TESTS ############################# ############################ SKIPPED TESTS #############################
# These tests take a looong time to run. # These tests take a looong time to run.
......
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