Bug 1279366 - Handle @@hasInstance correctly for proxies. r=mrrrgn
authorTom Schuster <evilpies@gmail.com>
Fri, 10 Jun 2016 22:41:08 +0200
changeset 377710 130240034c3777a1fb4359b18a803cf76b498787
parent 377709 2e076bb03ff4458d2c6201bf17580573def0a8fc
child 377711 6d3a4e0d206ac0ef1d26cf7d4f033634a9a873a8
push id20857
push userbmo:james@hoppipolla.co.uk
push dateSun, 12 Jun 2016 16:59:39 +0000
reviewersmrrrgn
bugs1279366
milestone50.0a1
Bug 1279366 - Handle @@hasInstance correctly for proxies. r=mrrrgn
js/src/proxy/Proxy.cpp
js/src/proxy/ScriptedProxyHandler.cpp
js/src/tests/ecma_6/Proxy/hasInstance.js
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -672,21 +672,17 @@ js::proxy_ObjectMoved(JSObject* obj, con
 {
     MOZ_ASSERT(obj->is<ProxyObject>());
     obj->as<ProxyObject>().handler()->objectMoved(obj, old);
 }
 
 bool
 js::proxy_HasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp)
 {
-    bool b;
-    if (!Proxy::hasInstance(cx, proxy, v, &b))
-        return false;
-    *bp = !!b;
-    return true;
+    return Proxy::hasInstance(cx, proxy, v, bp);
 }
 
 bool
 js::proxy_Call(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedObject proxy(cx, &args.callee());
     MOZ_ASSERT(proxy->is<ProxyObject>());
--- a/js/src/proxy/ScriptedProxyHandler.cpp
+++ b/js/src/proxy/ScriptedProxyHandler.cpp
@@ -3,21 +3,21 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "proxy/ScriptedProxyHandler.h"
 
 #include "jsapi.h"
 
+#include "vm/Interpreter.h" // For InstanceOfOperator
+
 #include "jsobjinlines.h"
 #include "vm/NativeObject-inl.h"
 
-#include "vm/NativeObject-inl.h"
-
 using namespace js;
 
 using JS::IsArrayAnswer;
 using mozilla::ArrayLength;
 
 // ES8 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93
 // 9.1.6.2 IsCompatiblePropertyDescriptor.  BUT that method just calls
 // 9.1.6.3 ValidateAndApplyPropertyDescriptor with two additional constant
@@ -1230,23 +1230,17 @@ ScriptedProxyHandler::nativeCall(JSConte
     ReportIncompatible(cx, args);
     return false;
 }
 
 bool
 ScriptedProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
                                   bool* bp) const
 {
-    RootedObject target(cx, proxy->as<ProxyObject>().target());
-    if (!target) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
-        return false;
-    }
-
-    return HasInstance(cx, target, v, bp);
+    return InstanceOfOperator(cx, proxy, v, bp);
 }
 
 bool
 ScriptedProxyHandler::getBuiltinClass(JSContext* cx, HandleObject proxy,
                                       ESClassValue* classValue) const
 {
     *classValue = ESClass_Other;
     return true;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Proxy/hasInstance.js
@@ -0,0 +1,13 @@
+var get = [];
+var fun = function() {}
+var p = new Proxy(fun, {
+    get(target, key) {
+        get.push(key);
+        return target[key];
+    }
+});
+
+assertEq(new fun instanceof p, true);
+assertDeepEq(get, [Symbol.hasInstance, "prototype"]);
+
+reportCompare(true, true);