summaryrefslogtreecommitdiff
path: root/js/src
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-02-07 10:39:40 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-02-07 10:39:40 +0100
commit88db0108b14d58cf5d82ed7346f48f010feaaf0d (patch)
tree1d78ae8cd21d7d17293f66c166ca44718501d4aa /js/src
parent8db772d2ca44ff44f32d434e7f62acba289b4155 (diff)
downloaduxp-88db0108b14d58cf5d82ed7346f48f010feaaf0d.tar.gz
Align `instanceof` with the final ES6 spec.
Diffstat (limited to 'js/src')
-rw-r--r--js/src/jsapi.h7
-rw-r--r--js/src/jsfun.cpp10
-rw-r--r--js/src/jswrapper.h2
-rw-r--r--js/src/proxy/OpaqueCrossCompartmentWrapper.cpp8
-rw-r--r--js/src/proxy/ScriptedProxyHandler.cpp4
-rw-r--r--js/src/vm/Interpreter.cpp14
-rw-r--r--js/src/vm/Interpreter.h3
7 files changed, 30 insertions, 18 deletions
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 799396a0af..005d2278e4 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2154,6 +2154,13 @@ namespace JS {
extern JS_PUBLIC_API(bool)
OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp);
+// Implementation of
+// https://www.ecma-international.org/ecma-262/6.0/#sec-instanceofoperator
+// This is almost identical to JS_HasInstance, except the latter may call a
+// custom hasInstance class op instead of InstanceofOperator.
+extern JS_PUBLIC_API(bool)
+InstanceofOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp);
+
} // namespace JS
extern JS_PUBLIC_API(void*)
diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp
index bcb0da80b2..863871df93 100644
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -690,7 +690,7 @@ js::fun_symbolHasInstance(JSContext* cx, unsigned argc, Value* vp)
}
/*
- * ES6 (4-25-16) 7.3.19 OrdinaryHasInstance
+ * ES6 7.3.19 OrdinaryHasInstance
*/
bool
JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp)
@@ -707,7 +707,7 @@ JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool*
if (obj->is<JSFunction>() && obj->isBoundFunction()) {
/* Steps 2a-b. */
obj = obj->as<JSFunction>().getBoundFunctionTarget();
- return InstanceOfOperator(cx, obj, v, bp);
+ return InstanceofOperator(cx, obj, v, bp);
}
/* Step 3. */
@@ -716,12 +716,12 @@ JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool*
return true;
}
- /* Step 4. */
+ /* Step 4-5. */
RootedValue pval(cx);
if (!GetProperty(cx, obj, obj, cx->names().prototype, &pval))
return false;
- /* Step 5. */
+ /* Step 6. */
if (pval.isPrimitive()) {
/*
* Throw a runtime error if instanceof is called on a function that
@@ -732,7 +732,7 @@ JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool*
return false;
}
- /* Step 6. */
+ /* Step 7. */
RootedObject pobj(cx, &pval.toObject());
bool isDelegate;
if (!IsDelegate(cx, pobj, v, &isDelegate))
diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h
index 3c73979f88..84ebe27324 100644
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -270,6 +270,8 @@ class JS_FRIEND_API(OpaqueCrossCompartmentWrapper) : public CrossCompartmentWrap
virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override;
virtual bool isArray(JSContext* cx, HandleObject obj,
JS::IsArrayAnswer* answer) const override;
+ virtual bool hasInstance(JSContext* cx, HandleObject wrapper,
+ MutableHandleValue v, bool* bp) const override;
virtual const char* className(JSContext* cx, HandleObject wrapper) const override;
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override;
diff --git a/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp b/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
index ff3f4145cc..02bf237ff2 100644
--- a/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
+++ b/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
@@ -175,6 +175,14 @@ OpaqueCrossCompartmentWrapper::isArray(JSContext* cx, HandleObject obj,
return true;
}
+bool OpaqueCrossCompartmentWrapper::hasInstance(JSContext* cx,
+ HandleObject wrapper,
+ MutableHandleValue v,
+ bool* bp) const {
+ *bp = false;
+ return true;
+}
+
const char*
OpaqueCrossCompartmentWrapper::className(JSContext* cx,
HandleObject proxy) const
diff --git a/js/src/proxy/ScriptedProxyHandler.cpp b/js/src/proxy/ScriptedProxyHandler.cpp
index 7765473371..0e25f470c0 100644
--- a/js/src/proxy/ScriptedProxyHandler.cpp
+++ b/js/src/proxy/ScriptedProxyHandler.cpp
@@ -8,8 +8,6 @@
#include "jsapi.h"
-#include "vm/Interpreter.h" // For InstanceOfOperator
-
#include "jsobjinlines.h"
#include "vm/NativeObject-inl.h"
@@ -1230,7 +1228,7 @@ bool
ScriptedProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
bool* bp) const
{
- return InstanceOfOperator(cx, proxy, v, bp);
+ return InstanceofOperator(cx, proxy, v, bp);
}
bool
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index b747e4d7a0..e6d6630c4b 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -718,14 +718,14 @@ js::Execute(JSContext* cx, HandleScript script, JSObject& envChainArg, Value* rv
}
/*
- * ES6 (4-25-16) 12.10.4 InstanceofOperator
+ * ES6 12.9.4 InstanceofOperator
*/
extern bool
-js::InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
+JS::InstanceofOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
{
/* Step 1. is handled by caller. */
- /* Step 2. */
+ /* Step 2-3. */
RootedValue hasInstance(cx);
RootedId id(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().hasInstance));
if (!GetProperty(cx, obj, obj, id, &hasInstance))
@@ -735,7 +735,7 @@ js::InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
if (!IsCallable(hasInstance))
return ReportIsNotFunction(cx, hasInstance);
- /* Step 3. */
+ /* Step 4. */
RootedValue rval(cx);
if (!Call(cx, hasInstance, obj, v, &rval))
return false;
@@ -743,13 +743,13 @@ js::InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
return true;
}
- /* Step 4. */
+ /* Step 5. */
if (!obj->isCallable()) {
RootedValue val(cx, ObjectValue(*obj));
return ReportIsNotFunction(cx, val);
}
- /* Step 5. */
+ /* Step 6. */
return OrdinaryHasInstance(cx, obj, v, bp);
}
@@ -760,7 +760,7 @@ js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
RootedValue local(cx, v);
if (JSHasInstanceOp hasInstance = clasp->getHasInstance())
return hasInstance(cx, obj, &local, bp);
- return js::InstanceOfOperator(cx, obj, local, bp);
+ return JS::InstanceofOperator(cx, obj, local, bp);
}
static inline bool
diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h
index 330dbef5f5..9fefd75ccd 100644
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -323,9 +323,6 @@ extern JSType
TypeOfValue(const Value& v);
extern bool
-InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp);
-
-extern bool
HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp);
// Unwind environment chain and iterator to match the scope corresponding to