Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Unified Diff: src/builtins/builtins-regexp.cc

Issue 2441993002: [regexp] Move RegExp.prototype.test to TF (Closed)
Patch Set: Remove unused variables Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-regexp.cc
diff --git a/src/builtins/builtins-regexp.cc b/src/builtins/builtins-regexp.cc
index 2b103d2c60f2ce6e507d3de987878735b3aeaf1d..d993e82f2eae7ee0a2545f712ae43f22b0810db6 100644
--- a/src/builtins/builtins-regexp.cc
+++ b/src/builtins/builtins-regexp.cc
@@ -969,25 +969,106 @@ BUILTIN(RegExpRightContextGetter) {
return *isolate->factory()->NewSubString(last_subject, start_index, len);
}
+namespace {
+
+// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
+compiler::Node* RegExpExec(CodeStubAssembler* a, compiler::Node* context,
+ compiler::Node* recv, compiler::Node* string) {
+ typedef CodeStubAssembler::Variable Variable;
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+
+ Isolate* isolate = a->isolate();
+
+ Node* const null = a->NullConstant();
+
+ Variable var_result(a, MachineRepresentation::kTagged);
+ Label out(a), call_builtin_exec(a), slow_path(a, Label::kDeferred);
+
+ Node* const map = a->LoadMap(recv);
+ BranchIfFastPath(a, context, map, &call_builtin_exec, &slow_path);
+
+ a->Bind(&call_builtin_exec);
+ {
+ Node* const result = RegExpPrototypeExecInternal(a, context, recv, string);
+ var_result.Bind(result);
+ a->Goto(&out);
+ }
+
+ a->Bind(&slow_path);
+ {
+ // Take the slow path of fetching the exec property, calling it, and
+ // verifying its return value.
+
+ // Get the exec property.
+ Node* const name = a->HeapConstant(isolate->factory()->exec_string());
+ Callable getproperty_callable = CodeFactory::GetProperty(a->isolate());
+ Node* const exec = a->CallStub(getproperty_callable, context, recv, name);
+
+ // Is {exec} callable?
+ Label if_iscallable(a), if_isnotcallable(a);
+
+ a->GotoIf(a->TaggedIsSmi(exec), &if_isnotcallable);
+
+ Node* const exec_map = a->LoadMap(exec);
+ a->Branch(a->IsCallableMap(exec_map), &if_iscallable, &if_isnotcallable);
+
+ a->Bind(&if_iscallable);
+ {
+ Callable call_callable = CodeFactory::Call(isolate);
+ Node* const result =
+ a->CallJS(call_callable, context, exec, recv, string);
+
+ var_result.Bind(result);
+ a->GotoIf(a->WordEqual(result, null), &out);
+
+ ThrowIfNotJSReceiver(a, isolate, context, result,
+ MessageTemplate::kInvalidRegExpExecResult, "unused");
+
+ a->Goto(&out);
+ }
+
+ a->Bind(&if_isnotcallable);
+ {
+ a->ThrowIfNotInstanceType(context, recv, JS_REGEXP_TYPE,
+ "RegExp.prototype.exec");
+ a->Goto(&call_builtin_exec);
+ }
+ }
+
+ a->Bind(&out);
+ return var_result.value();
+}
+
+} // namespace
+
// ES#sec-regexp.prototype.test
// RegExp.prototype.test ( S )
-BUILTIN(RegExpPrototypeTest) {
- HandleScope scope(isolate);
- CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.test");
+void Builtins::Generate_RegExpPrototypeTest(CodeStubAssembler* a) {
+ typedef compiler::Node Node;
- Handle<Object> string_obj = args.atOrUndefined(isolate, 1);
+ Isolate* const isolate = a->isolate();
- Handle<String> string;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
- Object::ToString(isolate, string_obj));
+ Node* const maybe_receiver = a->Parameter(0);
+ Node* const maybe_string = a->Parameter(1);
+ Node* const context = a->Parameter(4);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- RegExpUtils::RegExpExec(isolate, recv, string,
- isolate->factory()->undefined_value()));
+ // Ensure {maybe_receiver} is a JSReceiver.
+ ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver,
+ MessageTemplate::kIncompatibleMethodReceiver,
+ "RegExp.prototype.test");
+ Node* const receiver = maybe_receiver;
- return isolate->heap()->ToBoolean(!result->IsNull(isolate));
+ // Convert {maybe_string} to a String.
+ Node* const string = a->ToString(context, maybe_string);
+
+ // Call exec.
+ Node* const match_indices = RegExpExec(a, context, receiver, string);
+
+ // Return true iff exec matched successfully.
+ Node* const result = a->Select(a->WordEqual(match_indices, a->NullConstant()),
+ a->FalseConstant(), a->TrueConstant());
+ a->Return(result);
}
// ES#sec-regexp.prototype-@@match
@@ -1820,7 +1901,7 @@ void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) {
Node* const int_zero = a->IntPtrConstant(0);
- // Ensure {receiver} is a JSReceiver.
+ // Ensure {maybe_receiver} is a JSReceiver.
Node* const map =
ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver,
MessageTemplate::kIncompatibleMethodReceiver,
« no previous file with comments | « src/builtins/builtins.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698