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

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

Issue 2934893002: [builtins] Properly optimize Object.prototype.isPrototypeOf. (Closed)
Patch Set: Address feedback. 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
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..f9ba906f2ea1b00bd84bf2af2705d3314a5af501 100644
--- a/src/builtins/builtins-object-gen.cc
+++ b/src/builtins/builtins-object-gen.cc
@@ -192,6 +192,52 @@ 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(IsNull(receiver), &if_receiverisnullorundefined);
+ GotoIf(IsUndefined(receiver), &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(FalseConstant());
+}
+
// ES6 #sec-object.prototype.tostring
TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) {
Label return_undefined(this, Label::kDeferred),
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698