Commit 2cb40dc7 authored by machenbach's avatar machenbach Committed by Commit bot

Reland of [proxies] Make Object.prototype.isPrototypeOf work with proxies....

Reland of [proxies] Make Object.prototype.isPrototypeOf work with proxies. (patchset #1 id:1 of https://codereview.chromium.org/1494283002/ )

Reason for revert:
Did not help...

Original issue's description:
> Revert of [proxies] Make Object.prototype.isPrototypeOf work with proxies. (patchset #2 id:20001 of https://codereview.chromium.org/1492863002/ )
>
> Reason for revert:
> [Sheriff] Speculative revert for:
> https://uberchromegw.corp.google.com/i/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/3225
>
> Can just be relanded if it doesn't get green.
>
> Original issue's description:
> > [proxies] Make Object.prototype.isPrototypeOf step into proxies.
> >
> > R=rossberg, verwaest@chromium.org
> > BUG=v8:1543
> > LOG=n
> >
> > Committed: https://crrev.com/4ca1180d2e7c409312ae0761cb12843989466573
> > Cr-Commit-Position: refs/heads/master@{#32569}
>
> TBR=rossberg@chromium.org,verwaest@chromium.org,neis@chromium.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=v8:1543
>
> Committed: https://crrev.com/48fba9439f291edd5929e19951262dc7e8a09609
> Cr-Commit-Position: refs/heads/master@{#32588}

TBR=rossberg@chromium.org,verwaest@chromium.org,neis@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:1543

Review URL: https://codereview.chromium.org/1491743010

Cr-Commit-Position: refs/heads/master@{#32598}
parent 8aae841c
......@@ -1193,16 +1193,10 @@ MaybeHandle<Object> Object::GetPrototype(Isolate* isolate,
!isolate->MayAccess(context, Handle<JSObject>::cast(receiver))) {
return isolate->factory()->null_value();
}
if (receiver->IsJSProxy()) {
return JSProxy::GetPrototype(Handle<JSProxy>::cast(receiver));
}
PrototypeIterator iter(isolate, receiver,
PrototypeIterator::START_AT_RECEIVER);
do {
iter.AdvanceIgnoringProxies();
if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
return PrototypeIterator::GetCurrent(iter);
}
if (!iter.AdvanceFollowingProxies()) return MaybeHandle<Object>();
} while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
return PrototypeIterator::GetCurrent(iter);
}
......
......@@ -1313,12 +1313,13 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
}
bool Object::HasInPrototypeChain(Isolate* isolate, Object* target) {
PrototypeIterator iter(isolate, this, PrototypeIterator::START_AT_RECEIVER);
Maybe<bool> Object::HasInPrototypeChain(Isolate* isolate, Handle<Object> object,
Handle<Object> proto) {
PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER);
while (true) {
iter.AdvanceIgnoringProxies();
if (iter.IsAtEnd()) return false;
if (iter.IsAtEnd(target)) return true;
if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
if (iter.IsAtEnd()) return Just(false);
if (iter.IsAtEnd(proto)) return Just(true);
}
}
......
......@@ -1313,7 +1313,9 @@ class Object {
static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
Handle<Object> receiver);
bool HasInPrototypeChain(Isolate* isolate, Object* object);
MUST_USE_RESULT static Maybe<bool> HasInPrototypeChain(Isolate* isolate,
Handle<Object> object,
Handle<Object> proto);
// Returns the permanent hash code associated with this object. May return
// undefined if not yet created.
......
......@@ -106,6 +106,20 @@ class PrototypeIterator {
}
}
// Returns false iff a call to JSProxy::GetPrototype throws.
// TODO(neis): This should probably replace Advance().
bool AdvanceFollowingProxies() {
DCHECK(!(handle_.is_null() && object_->IsJSProxy()));
if (!handle_.is_null() && handle_->IsJSProxy()) {
did_jump_to_prototype_chain_ = true;
MaybeHandle<Object> proto =
JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_));
return proto.ToHandle(&handle_);
}
AdvanceIgnoringProxies();
return true;
}
bool IsAtEnd(WhereToEnd where_to_end = END_AT_NULL) const {
if (handle_.is_null()) {
return object_->IsNull() ||
......
......@@ -1350,6 +1350,17 @@ RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
}
static bool HasInPrototypeChainIgnoringProxies(Isolate* isolate, Object* object,
Object* proto) {
PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER);
while (true) {
iter.AdvanceIgnoringProxies();
if (iter.IsAtEnd()) return false;
if (iter.IsAtEnd(proto)) return true;
}
}
// Scan the heap for objects with direct references to an object
// args[0]: the object to find references to
// args[1]: constructor function for instances to exclude (Mirror)
......@@ -1379,7 +1390,7 @@ RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
// Check filter if supplied. This is normally used to avoid
// references from mirror objects.
if (!filter->IsUndefined() &&
obj->HasInPrototypeChain(isolate, *filter)) {
HasInPrototypeChainIgnoringProxies(isolate, obj, *filter)) {
continue;
}
if (obj->IsJSGlobalObject()) {
......
......@@ -1551,18 +1551,20 @@ RUNTIME_FUNCTION(Runtime_InstanceOf) {
NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype));
}
// Return whether or not {prototype} is in the prototype chain of {object}.
return isolate->heap()->ToBoolean(
object->HasInPrototypeChain(isolate, *prototype));
Maybe<bool> result = Object::HasInPrototypeChain(isolate, object, prototype);
MAYBE_RETURN(result, isolate->heap()->exception());
return isolate->heap()->ToBoolean(result.FromJust());
}
RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
SealHandleScope scope(isolate);
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_CHECKED(Object, object, 0);
CONVERT_ARG_CHECKED(Object, prototype, 1);
return isolate->heap()->ToBoolean(
object->HasInPrototypeChain(isolate, prototype));
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Maybe<bool> result = Object::HasInPrototypeChain(isolate, object, prototype);
MAYBE_RETURN(result, isolate->heap()->exception());
return isolate->heap()->ToBoolean(result.FromJust());
}
......
......@@ -36,3 +36,58 @@ var handler_proxy = new Proxy({
}, {});
var proxy3 = new Proxy(target, handler_proxy);
assertSame(Object.getPrototypeOf(proxy3), proxy3_prototype);
// Some tests with Object.prototype.isPrototypeOf
(function () {
var object = {};
var handler = {};
var proto = new Proxy({}, handler);
object.__proto__ = proto;
assertTrue(proto.isPrototypeOf(object));
assertTrue(Object.prototype.isPrototypeOf.call(proto, object));
handler.getPrototypeOf = function () { return Object.prototype };
assertTrue(proto.isPrototypeOf(object));
assertTrue(Object.prototype.isPrototypeOf.call(proto, object));
assertTrue(Object.prototype.isPrototypeOf(object));
assertFalse(Object.prototype.isPrototypeOf.call(Array.prototype, object));
assertFalse(Array.prototype.isPrototypeOf(object));
handler.getPrototypeOf = function () { return object };
assertTrue(Object.prototype.isPrototypeOf.call(proto, object));
assertTrue(proto.isPrototypeOf(object));
assertTrue(Object.prototype.isPrototypeOf.call(object, object));
assertTrue(object.isPrototypeOf(object));
handler.getPrototypeOf = function () { throw "foo" };
assertTrue(proto.isPrototypeOf(object));
assertTrue(Object.prototype.isPrototypeOf.call(proto, object));
assertThrows(()=> Object.prototype.isPrototypeOf(object));
assertThrows(()=> Object.prototype.isPrototypeOf.call(Array.prototype, object));
assertThrows(()=> Array.prototype.isPrototypeOf(object));
})();
(function () {
var handler = {};
var object = new Proxy({}, handler);
var proto = {};
assertFalse(Object.prototype.isPrototypeOf.call(object, object));
assertFalse(Object.prototype.isPrototypeOf.call(proto, object));
assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, object));
handler.getPrototypeOf = function () { return proto };
assertTrue(Object.prototype.isPrototypeOf.call(proto, object));
assertFalse(Object.prototype.isPrototypeOf.call({}, object));
assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, object));
handler.getPrototypeOf = function () { return object };
assertTrue(Object.prototype.isPrototypeOf.call(object, object));
handler.getPrototypeOf = function () { throw "foo" };
assertThrows(()=> Object.prototype.isPrototypeOf.call(object, object));
assertThrows(()=> Object.prototype.isPrototypeOf(object));
})();
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