diff --git a/rhino/src/main/java/org/mozilla/javascript/BaseFunction.java b/rhino/src/main/java/org/mozilla/javascript/BaseFunction.java
index 13794f945b..4adf30d467 100644
--- a/rhino/src/main/java/org/mozilla/javascript/BaseFunction.java
+++ b/rhino/src/main/java/org/mozilla/javascript/BaseFunction.java
@@ -31,7 +31,8 @@ static void init(Context cx, Scriptable scope, boolean sealed) {
if (cx.getLanguageVersion() >= Context.VERSION_ES6) {
obj.setStandardPropertyAttributes(READONLY | DONTENUM);
}
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ IdFunctionObject constructor = obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ ScriptRuntimeES6.addSymbolHasInstance(cx, scope, constructor);
}
/**
@@ -80,7 +81,7 @@ protected boolean hasDefaultParameters() {
/**
* Gets the value returned by calling the typeof operator on this object.
*
- * @see org.mozilla.javascript.ScriptableObject#getTypeOf()
+ * @see ScriptableObject#getTypeOf()
* @return "function" or "undefined" if {@link #avoidObjectDetection()} returns true
*
*/
@@ -156,6 +157,8 @@ protected int findInstanceIdInfo(String s) {
@Override
protected String getInstanceIdName(int id) {
switch (id) {
+ case SymbolId_hasInstance:
+ return "SymbolId_hasInstance";
case Id_length:
return "length";
case Id_arity:
@@ -265,6 +268,11 @@ protected void fillConstructorProperties(IdFunctionObject ctor) {
@Override
protected void initPrototypeId(int id) {
+ if (id == SymbolId_hasInstance) {
+ initPrototypeValue(id, SymbolKey.HAS_INSTANCE, makeHasInstance(), 0x0F);
+ return;
+ }
+
String s;
int arity;
switch (id) {
@@ -313,6 +321,53 @@ static boolean isApplyOrCall(IdFunctionObject f) {
return false;
}
+ private Object makeHasInstance() {
+ Context cx = Context.getCurrentContext();
+ ScriptableObject obj = null;
+
+ if (cx != null) {
+ Scriptable scope = this.getParentScope();
+ obj =
+ new LambdaFunction(
+ scope,
+ 0,
+ new Callable() {
+ @Override
+ public Object call(
+ Context cx,
+ Scriptable scope,
+ Scriptable thisObj,
+ Object[] args) {
+ if (thisObj != null
+ && args.length == 1
+ && args[0] instanceof Scriptable) {
+ Scriptable obj = (Scriptable) args[0];
+ Object protoProp = null;
+ if (thisObj instanceof BoundFunction)
+ protoProp =
+ ((NativeFunction)
+ ((BoundFunction) thisObj)
+ .getTargetFunction())
+ .getPrototypeProperty();
+ else
+ protoProp =
+ ScriptableObject.getProperty(
+ thisObj, "prototype");
+ if (protoProp instanceof IdScriptableObject) {
+ return ScriptRuntime.jsDelegatesTo(
+ obj, (Scriptable) protoProp);
+ }
+ throw ScriptRuntime.typeErrorById(
+ "msg.instanceof.bad.prototype", getFunctionName());
+ } else {
+ return false; // NOT_FOUND, null etc.
+ }
+ }
+ });
+ }
+ return obj;
+ }
+
@Override
public Object execIdCall(
IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
@@ -509,6 +564,26 @@ protected boolean hasPrototypeProperty() {
return prototypeProperty != null || this instanceof NativeFunction;
}
+ @Override
+ ScriptableObject buildDataDescriptorHelper(
+ int instanceIdInfo, Scriptable scope, Object value, int attr) {
+ if (instanceIdInfo == SymbolId_hasInstance) {
+ return buildDataDescriptor(scope, value, attr, SymbolKey.HAS_INSTANCE.toString(), 1);
+ } else {
+ return super.buildDataDescriptorHelper(instanceIdInfo, scope, value, attr);
+ }
+ }
+
+ @Override
+ ScriptableObject buildDataDescriptorHelper(
+ Symbol key, Scriptable scope, Object value, int attr) {
+ if (key == SymbolKey.HAS_INSTANCE) {
+ return buildDataDescriptor(scope, value, attr, key.toString(), 1);
+ } else {
+ return super.buildDataDescriptorHelper(key, scope, value, attr);
+ }
+ }
+
public Object getPrototypeProperty() {
Object result = prototypeProperty;
if (result == null) {
@@ -627,6 +702,12 @@ private Object jsConstructor(Context cx, Scriptable scope, Object[] args) {
return cx.compileFunction(global, source, evaluator, reporter, sourceURI, 1, null);
}
+ @Override
+ protected int findPrototypeId(Symbol k) {
+ if (SymbolKey.HAS_INSTANCE.equals(k)) return SymbolId_hasInstance;
+ else return 0;
+ }
+
@Override
protected int findPrototypeId(String s) {
int id;
@@ -662,7 +743,8 @@ protected int findPrototypeId(String s) {
Id_apply = 4,
Id_call = 5,
Id_bind = 6,
- MAX_PROTOTYPE_ID = Id_bind;
+ SymbolId_hasInstance = 7,
+ MAX_PROTOTYPE_ID = SymbolId_hasInstance;
private Object prototypeProperty;
private Object argumentsObj = NOT_FOUND;
diff --git a/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java b/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java
index b21484dda3..51b3a0bfc4 100644
--- a/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java
+++ b/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java
@@ -201,7 +201,13 @@ final void delete(int id) {
Context cx = Context.getContext();
if (cx.isStrictMode()) {
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
- String name = (String) valueArray[nameSlot];
+
+ String name = null;
+ if (valueArray[nameSlot] instanceof String)
+ name = (String) valueArray[nameSlot];
+ else if (valueArray[nameSlot] instanceof SymbolKey) {
+ name = valueArray[nameSlot].toString();
+ }
throw ScriptRuntime.typeErrorById(
"msg.delete.property.with.configurable.false", name);
}
@@ -936,6 +942,21 @@ protected ScriptableObject getOwnPropertyDescriptor(Context cx, Object id) {
return desc;
}
+ /**
+ * Overridden in the base class for different descriptors
+ *
+ * @return ScriptableObject
+ */
+ ScriptableObject buildDataDescriptorHelper(
+ Symbol key, Scriptable scope, Object value, int attr) {
+ return buildDataDescriptor(scope, value, attr);
+ }
+
+ ScriptableObject buildDataDescriptorHelper(
+ int instanceIdInfo, Scriptable scope, Object value, int attr) {
+ return buildDataDescriptor(scope, value, attr);
+ }
+
private ScriptableObject getBuiltInDescriptor(String name) {
Object value = null;
int attr = EMPTY;
@@ -950,14 +971,14 @@ private ScriptableObject getBuiltInDescriptor(String name) {
int id = (info & 0xFFFF);
value = getInstanceIdValue(id);
attr = (info >>> 16);
- return buildDataDescriptor(scope, value, attr);
+ return buildDataDescriptorHelper(info, scope, value, attr);
}
if (prototypeValues != null) {
int id = prototypeValues.findId(name);
if (id != 0) {
value = prototypeValues.get(id);
attr = prototypeValues.getAttributes(id);
- return buildDataDescriptor(scope, value, attr);
+ return buildDataDescriptorHelper(info, scope, value, attr);
}
}
return null;
@@ -977,7 +998,7 @@ private ScriptableObject getBuiltInDescriptor(Symbol key) {
if (id != 0) {
value = prototypeValues.get(id);
attr = prototypeValues.getAttributes(id);
- return buildDataDescriptor(scope, value, attr);
+ return buildDataDescriptorHelper(key, scope, value, attr);
}
}
return null;
diff --git a/rhino/src/main/java/org/mozilla/javascript/Node.java b/rhino/src/main/java/org/mozilla/javascript/Node.java
index 928426fef5..1d28f1b21e 100644
--- a/rhino/src/main/java/org/mozilla/javascript/Node.java
+++ b/rhino/src/main/java/org/mozilla/javascript/Node.java
@@ -1178,7 +1178,7 @@ private void toString(Map printIds, StringBuilder sb) {
Object[] a = (Object[]) x.objectValue;
sb.append("[");
for (int i = 0; i < a.length; i++) {
- sb.append(a[i].toString());
+ if (a[i] != null) sb.append(a[i].toString());
if (i + 1 < a.length) sb.append(", ");
}
sb.append("]");
diff --git a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntimeES6.java b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntimeES6.java
index 204e2422b0..ec3136c7e8 100644
--- a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntimeES6.java
+++ b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntimeES6.java
@@ -46,4 +46,15 @@ public static void addSymbolUnscopables(
ScriptableObject.putProperty(unScopablesDescriptor, "writable", false);
constructor.defineOwnProperty(cx, SymbolKey.UNSCOPABLES, unScopablesDescriptor, false);
}
+
+ /** Registers the symbol [Symbol.hasInstance]
on the given constructor function. */
+ public static void addSymbolHasInstance(
+ Context cx, Scriptable scope, IdScriptableObject constructor) {
+ ScriptableObject hasInstanceDescriptor = (ScriptableObject) cx.newObject(scope);
+ ScriptableObject.putProperty(hasInstanceDescriptor, "value", ScriptableObject.EMPTY);
+ ScriptableObject.putProperty(hasInstanceDescriptor, "enumerable", false);
+ ScriptableObject.putProperty(hasInstanceDescriptor, "configurable", false);
+ ScriptableObject.putProperty(hasInstanceDescriptor, "writable", false);
+ constructor.defineOwnProperty(cx, SymbolKey.HAS_INSTANCE, hasInstanceDescriptor, false);
+ }
}
diff --git a/rhino/src/main/java/org/mozilla/javascript/ScriptableObject.java b/rhino/src/main/java/org/mozilla/javascript/ScriptableObject.java
index 8fc9cd5eca..48998047af 100644
--- a/rhino/src/main/java/org/mozilla/javascript/ScriptableObject.java
+++ b/rhino/src/main/java/org/mozilla/javascript/ScriptableObject.java
@@ -135,14 +135,28 @@ public abstract class ScriptableObject
protected static ScriptableObject buildDataDescriptor(
Scriptable scope, Object value, int attributes) {
+ return buildDataDescriptor(scope, value, attributes, null, -1);
+ }
+
+ protected static ScriptableObject buildDataDescriptor(
+ Scriptable scope, Object value, int attributes, String name, int length) {
ScriptableObject desc = new NativeObject();
ScriptRuntime.setBuiltinProtoAndParent(desc, scope, TopLevel.Builtins.Object);
desc.defineProperty("value", value, EMPTY);
- desc.setCommonDescriptorProperties(attributes, true);
+ desc.setCommonDescriptorProperties(attributes, true, name, length);
return desc;
}
- protected void setCommonDescriptorProperties(int attributes, boolean defineWritable) {
+ protected void setCommonDescriptorProperties(
+ int attributes, boolean defineWritable, String name, int length) {
+ if (name != null) {
+ defineProperty("name", "[Symbol.hasInstance]", attributes);
+ }
+
+ if (length != -1) {
+ defineProperty("length", length, attributes);
+ }
+
if (defineWritable) {
defineProperty("writable", (attributes & READONLY) == 0, EMPTY);
}
@@ -150,6 +164,10 @@ protected void setCommonDescriptorProperties(int attributes, boolean defineWrita
defineProperty("configurable", (attributes & PERMANENT) == 0, EMPTY);
}
+ protected void setCommonDescriptorProperties(int attributes, boolean defineWritable) {
+ setCommonDescriptorProperties(attributes, defineWritable, null, -1);
+ }
+
static void checkValidAttributes(int attributes) {
final int mask = READONLY | DONTENUM | PERMANENT | UNINITIALIZED_CONST;
if ((attributes & ~mask) != 0) {
@@ -831,6 +849,12 @@ public boolean hasInstance(Scriptable instance) {
// chasing. This will be overridden in NativeFunction and non-JS
// objects.
+ Context cx = Context.getCurrentContext();
+ Object hasInstance = ScriptRuntime.getObjectElem(this, SymbolKey.HAS_INSTANCE, cx);
+ if (hasInstance instanceof Callable) {
+ return (boolean)
+ ((Callable) hasInstance).call(cx, getParentScope(), this, new Object[] {this});
+ }
return ScriptRuntime.jsDelegatesTo(instance, this);
}
diff --git a/rhino/src/test/java/org/mozilla/javascript/FunctionPrototypeSymbolHasInstanceTest.java b/rhino/src/test/java/org/mozilla/javascript/FunctionPrototypeSymbolHasInstanceTest.java
new file mode 100644
index 0000000000..56e1644a4f
--- /dev/null
+++ b/rhino/src/test/java/org/mozilla/javascript/FunctionPrototypeSymbolHasInstanceTest.java
@@ -0,0 +1,263 @@
+package org.mozilla.javascript;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mozilla.javascript.tests.Utils;
+
+public class FunctionPrototypeSymbolHasInstanceTest {
+ @Test
+ public void testSymbolHasInstanceIsPresent() {
+ String script =
+ ""
+ + "var f = {\n"
+ + " [Symbol.hasInstance](value) { "
+ + " }"
+ + "};\n"
+ + "var g = {};\n"
+ + "`${f.hasOwnProperty(Symbol.hasInstance)}:${g.hasOwnProperty(Symbol.hasInstance)}`";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ String result =
+ (String)
+ cx.evaluateString(
+ scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("true:false", result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSymbolHasInstanceCanBeCalledLikeAnotherMethod() {
+ String script =
+ ""
+ + "var f = {\n"
+ + " [Symbol.hasInstance](value) { "
+ + " return 42;"
+ + " }"
+ + "};\n"
+ + "f[Symbol.hasInstance]() == 42";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals(true, result);
+ return null;
+ });
+ }
+
+ // See: https://tc39.es/ecma262/#sec-function.prototype-%symbol.hasinstance%
+ @Test
+ public void testFunctionPrototypeSymbolHasInstanceHasAttributes() {
+ String script =
+ "var a = Object.getOwnPropertyDescriptor(Function.prototype, Symbol.hasInstance);\n"
+ + "a.writable + ':' + a.configurable + ':' + a.enumerable";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("false:false:false", result);
+ return null;
+ });
+ }
+
+ // See: https://tc39.es/ecma262/#sec-function.prototype-%symbol.hasinstance%
+ @Test
+ public void testFunctionPrototypeSymbolHasInstanceHasAttributesStrictMode() {
+ String script =
+ "'use strict';\n"
+ + "var t = typeof Function.prototype[Symbol.hasInstance];\n"
+ + "var a = Object.getOwnPropertyDescriptor(Function.prototype, Symbol.hasInstance);\n"
+ + "var typeErrorThrown = false;\n"
+ + "try { \n"
+ + " delete Function.prototype[Symbol.hasInstance] \n"
+ + "} catch (e) { \n"
+ + " typeErrorThrown = true \n"
+ + "}\n"
+ + "Object.prototype.hasOwnProperty.call(Function.prototype, Symbol.hasInstance) + ':' + typeErrorThrown + ':' + t + ':' + a.writable + ':' + a.configurable + ':' + a.enumerable; \n";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("true:true:function:false:false:false", result);
+ return null;
+ });
+ }
+
+ @Test
+ @Ignore("name-length-params-prototype-set-incorrectly")
+ public void testFunctionPrototypeSymbolHasInstanceHasProperties() {
+ String script =
+ "var a = Object.getOwnPropertyDescriptor(Function.prototype[Symbol.hasInstance], 'length');\n"
+ + "a.value + ':' + a.writable + ':' + a.configurable + ':' + a.enumerable";
+
+ String script2 =
+ "var a = Object.getOwnPropertyDescriptor(Function.prototype[Symbol.hasInstance], 'name');\n"
+ + "a.value + ':' + a.writable + ':' + a.configurable + ':' + a.enumerable";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Object result2 =
+ cx.evaluateString(scope, script2, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("1:false:true:false", result);
+ Assert.assertEquals("Symbol(Symbol.hasInstance):false:true:false", result2);
+ return null;
+ });
+ }
+
+ @Test
+ public void testFunctionPrototypeSymbolHasInstance() {
+ String script =
+ "(Function.prototype[Symbol.hasInstance] instanceof Function) + ':' + "
+ + "Function.prototype[Symbol.hasInstance].call(Function, Object)\n";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("true:true", result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testFunctionPrototypeSymbolHasInstanceOnObjectReturnsTrue() {
+ String script =
+ "var f = function() {};\n"
+ + "var o = new f();\n"
+ + "var o2 = Object.create(o);\n"
+ + "(f[Symbol.hasInstance](o)) + ':' + "
+ + "(f[Symbol.hasInstance](o2));\n";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("true:true", result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testFunctionPrototypeSymbolHasInstanceOnBoundTargetReturnsTrue() {
+ String script =
+ "var BC = function() {};\n"
+ + "var bc = new BC();\n"
+ + "var bound = BC.bind();\n"
+ + "bound[Symbol.hasInstance](bc);\n";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals(true, result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testFunctionInstanceNullVoidEtc() {
+ String script =
+ "var f = function() {};\n"
+ + "var x;\n"
+ + "a = (undefined instanceof f) + ':' +\n"
+ + "(x instanceof f) + ':' +\n"
+ + "(null instanceof f) + ':' +\n"
+ + "(void 0 instanceof f)\n"
+ + "a";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("false:false:false:false", result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testFunctionPrototypeSymbolHasInstanceReturnsFalseOnUndefinedOrProtoypeNotFound() {
+ String script =
+ "Function.prototype[Symbol.hasInstance].call() + ':' +"
+ + "Function.prototype[Symbol.hasInstance].call({});";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals("false:false", result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSymbolHasInstanceIsInvokedInInstanceOf() {
+ String script =
+ ""
+ + "var globalSet = 0;"
+ + "var f = {\n"
+ + " [Symbol.hasInstance](value) { "
+ + " globalSet = 1;"
+ + " return true;"
+ + " }"
+ + "}\n"
+ + "var g = {}\n"
+ + "Object.setPrototypeOf(g, f);\n"
+ + "g instanceof f;"
+ + "globalSet == 1";
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ Object result =
+ cx.evaluateString(scope, script, "testSymbolHasInstance", 0, null);
+ Assert.assertEquals(true, result);
+ return null;
+ });
+ }
+
+ @Test
+ public void testThrowTypeErrorOnNonObjectIncludingSymbol() {
+ String script =
+ ""
+ + "var f = function() {}; \n"
+ + "f.prototype = Symbol(); \n"
+ + "f[Symbol.hasInstance]({})";
+
+ Utils.runWithAllOptimizationLevels(
+ (cx) -> {
+ cx.setLanguageVersion(Context.VERSION_ES6);
+ final Scriptable scope = cx.initStandardObjects();
+ var error =
+ Assert.assertThrows(
+ EcmaError.class,
+ () ->
+ cx.evaluateString(
+ scope,
+ script,
+ "testSymbolHasInstance",
+ 0,
+ null));
+ Assert.assertTrue(
+ error.toString()
+ .contains("'prototype' property of is not an object."));
+ return null;
+ });
+ }
+}
diff --git a/tests/testsrc/test262.properties b/tests/testsrc/test262.properties
index a5b400211e..acf95d07ad 100644
--- a/tests/testsrc/test262.properties
+++ b/tests/testsrc/test262.properties
@@ -708,7 +708,7 @@ built-ins/Error 6/41 (14.63%)
~built-ins/FinalizationRegistry
-built-ins/Function 186/508 (36.61%)
+built-ins/Function 179/508 (35.24%)
internals/Call 2/2 (100.0%)
internals/Construct 6/6 (100.0%)
length/S15.3.5.1_A1_T3.js strict
@@ -769,14 +769,7 @@ built-ins/Function 186/508 (36.61%)
prototype/call/S15.3.4.4_A6_T7.js non-interpreted
prototype/Symbol.hasInstance/length.js
prototype/Symbol.hasInstance/name.js
- prototype/Symbol.hasInstance/prop-desc.js
- prototype/Symbol.hasInstance/this-val-bound-target.js
- prototype/Symbol.hasInstance/this-val-not-callable.js
- prototype/Symbol.hasInstance/this-val-poisoned-prototype.js
prototype/Symbol.hasInstance/value-get-prototype-of-err.js {unsupported: [Proxy]}
- prototype/Symbol.hasInstance/value-negative.js
- prototype/Symbol.hasInstance/value-non-obj.js
- prototype/Symbol.hasInstance/value-positive.js
prototype/toString/async-arrow-function.js {unsupported: [async-functions]}
prototype/toString/async-function-declaration.js {unsupported: [async-functions]}
prototype/toString/async-function-expression.js {unsupported: [async-functions]}