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

Unified Diff: src/builtins/builtins-object-gen.cc

Issue 2934893002: [builtins] Properly optimize Object.prototype.isPrototypeOf. (Closed)
Patch Set: Make debug-evaluate happy. Created 3 years, 6 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
Index: src/builtins/builtins-object-gen.cc
diff --git a/src/builtins/builtins-object-gen.cc b/src/builtins/builtins-object-gen.cc
index 09930c21b804fff1c204d37441e72433018f1623..1f7a4ad225ed3e368e68bc795e7d2f52e5aca7af 100644
--- a/src/builtins/builtins-object-gen.cc
+++ b/src/builtins/builtins-object-gen.cc
@@ -192,6 +192,53 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) {
}
}
+// ES #sec-object.prototype.isprototypeof
+TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) {
+ Node* receiver = Parameter(Descriptor::kReceiver);
+ Node* value = Parameter(Descriptor::kValue);
+ Node* context = Parameter(Descriptor::kContext);
+ Label if_receiverisnullorundefined(this, Label::kDeferred),
+ if_valueisnotreceiver(this, Label::kDeferred);
+
+ // We only check whether {value} is a Smi here, so that the
+ // prototype chain walk below can safely access the {value}s
+ // map. We don't rule out Primitive {value}s, since all of
+ // them have null as their prototype, so the chain walk below
+ // immediately aborts and returns false anyways.
+ GotoIf(TaggedIsSmi(value), &if_valueisnotreceiver);
+
+ // Check if {receiver} is either null or undefined and in that case,
+ // invoke the ToObject builtin, which raises the appropriate error.
+ // Otherwise we don't need to invoke ToObject, since {receiver} is
+ // either already a JSReceiver, in which case ToObject is a no-op,
+ // or it's a Primitive and ToObject would allocate a fresh JSValue
+ // wrapper, which wouldn't be identical to any existing JSReceiver
+ // found in the prototype chain of {value}, hence it will return
+ // false no matter if we search for the Primitive {receiver} or
+ // a newly allocated JSValue wrapper for {receiver}.
+ GotoIf(WordEqual(receiver, NullConstant()), &if_receiverisnullorundefined);
jgruber 2017/06/13 07:49:51 Nit: IsNull, IsUndefined (predicates are autogener
Benedikt Meurer 2017/06/13 18:22:44 Done.
+ GotoIf(WordEqual(receiver, UndefinedConstant()),
+ &if_receiverisnullorundefined);
+
+ // Loop through the prototype chain looking for the {receiver}.
+ Return(HasInPrototypeChain(context, value, receiver));
+
+ BIND(&if_receiverisnullorundefined);
+ {
+ // If {value} is a primitive HeapObject, we need to return
+ // false instead of throwing an exception per order of the
+ // steps in the specification, so check that first here.
+ GotoIfNot(IsJSReceiver(value), &if_valueisnotreceiver);
+
+ // Simulate the ToObject invocation on {receiver}.
+ CallBuiltin(Builtins::kToObject, context, receiver);
+ Unreachable();
+ }
+
+ BIND(&if_valueisnotreceiver);
+ Return(BooleanConstant(false));
+}
+
// ES6 #sec-object.prototype.tostring
TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) {
Label return_undefined(this, Label::kDeferred),

Powered by Google App Engine
This is Rietveld 408576698