diff --git a/src/org/mozilla/javascript/NativeArray.java b/src/org/mozilla/javascript/NativeArray.java index 69cb0d0090..752cf26ad5 100644 --- a/src/org/mozilla/javascript/NativeArray.java +++ b/src/org/mozilla/javascript/NativeArray.java @@ -2241,6 +2241,9 @@ private static boolean js_isArray(Object o) { if (!(o instanceof Scriptable)) { return false; } + if (o instanceof NativeProxy) { + return js_isArray(((NativeProxy)o).getTargetThrowIfRevoked()); + } return "Array".equals(((Scriptable) o).getClassName()); } diff --git a/src/org/mozilla/javascript/NativeProxy.java b/src/org/mozilla/javascript/NativeProxy.java index 980030262a..ad77702547 100644 --- a/src/org/mozilla/javascript/NativeProxy.java +++ b/src/org/mozilla/javascript/NativeProxy.java @@ -35,8 +35,8 @@ final class NativeProxy extends ScriptableObject implements Callable, Constructa private static final String TRAP_APPLY = "apply"; private static final String TRAP_CONSTRUCT = "construct"; - private ScriptableObject target; - private Scriptable handler; + private ScriptableObject targetObj; + private Scriptable handlerObj; private final String typeOf; private static final class Revoker implements Callable { @@ -49,8 +49,8 @@ public Revoker(NativeProxy proxy) { @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (revocableProxy != null) { - revocableProxy.handler = null; - revocableProxy.target = null; + revocableProxy.handlerObj = null; + revocableProxy.targetObj = null; revocableProxy = null; } return Undefined.instance; @@ -88,8 +88,8 @@ public Scriptable construct(Context cx, Scriptable scope, Object[] args) { } private NativeProxy(ScriptableObject target, Scriptable handler) { - this.target = target; - this.handler = handler; + this.targetObj = target; + this.handlerObj = handler; if (target == null || !(target instanceof Callable)) { typeOf = super.getTypeOf(); @@ -100,7 +100,7 @@ private NativeProxy(ScriptableObject target, Scriptable handler) { @Override public String getClassName() { - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); return target.getClassName(); } @@ -124,7 +124,7 @@ public Scriptable construct(Context cx, Scriptable scope, Object[] args) { * 10. If Type(newObj) is not Object, throw a TypeError exception. * 11. Return newObj. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_CONSTRUCT); if (trap != null) { @@ -161,7 +161,7 @@ public boolean has(String name, Scriptable start) { * iii. If extensibleTarget is false, throw a TypeError exception. * 10. Return booleanTrapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_HAS); if (trap != null) { @@ -211,7 +211,7 @@ public boolean has(int index, Scriptable start) { * iii. If extensibleTarget is false, throw a TypeError exception. * 10. Return booleanTrapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_HAS); if (trap != null) { @@ -241,7 +241,7 @@ public boolean has(int index, Scriptable start) { */ @Override public boolean has(Symbol key, Scriptable start) { - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_HAS); if (trap != null) { @@ -307,7 +307,7 @@ Object[] getIds(boolean getNonEnumerable, boolean getSymbols) { * 22. If uncheckedResultKeys is not empty, throw a TypeError exception. * 23. Return trapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_OWN_KEYS); if (trap != null) { @@ -407,7 +407,7 @@ public Object get(String name, Scriptable start) { * i. If trapResult is not undefined, throw a TypeError exception. * 11. Return trapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_GET); if (trap != null) { @@ -463,7 +463,7 @@ public Object get(int index, Scriptable start) { * i. If trapResult is not undefined, throw a TypeError exception. * 11. Return trapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_GET); if (trap != null) { @@ -519,7 +519,7 @@ public Object get(Symbol key, Scriptable start) { * i. If trapResult is not undefined, throw a TypeError exception. * 11. Return trapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_GET); if (trap != null) { @@ -579,7 +579,7 @@ public void put(String name, Scriptable start, Object value) { * i. If targetDesc.[[Set]] is undefined, throw a TypeError exception. * 12. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_SET); if (trap != null) { @@ -614,7 +614,7 @@ public void put(int index, Scriptable start, Object value) { * i. If targetDesc.[[Set]] is undefined, throw a TypeError exception. * 12. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_SET); if (trap != null) { @@ -649,7 +649,7 @@ public void put(Symbol key, Scriptable start, Object value) { * i. If targetDesc.[[Set]] is undefined, throw a TypeError exception. * 12. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_SET); if (trap != null) { @@ -688,7 +688,7 @@ public void delete(String name) { * 14. If extensibleTarget is false, throw a TypeError exception. * 15. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_DELETE_PROPERTY); if (trap != null) { @@ -738,7 +738,7 @@ public void delete(int index) { * 14. If extensibleTarget is false, throw a TypeError exception. * 15. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_DELETE_PROPERTY); if (trap != null) { @@ -788,7 +788,7 @@ public void delete(Symbol key) { * 14. If extensibleTarget is false, throw a TypeError exception. * 15. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_DELETE_PROPERTY); if (trap != null) { @@ -851,7 +851,7 @@ protected ScriptableObject getOwnPropertyDescriptor(Context cx, Object id) { * i. If targetDesc.[[Writable]] is true, throw a TypeError exception. * 18. Return resultDesc. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_GET_OWN_PROPERTY_DESCRIPTOR); if (trap != null) { @@ -939,7 +939,7 @@ public void defineOwnProperty(Context cx, Object id, ScriptableObject desc) { * i. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, throw a TypeError exception. * 17. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_DEFINE_PROPERTY); if (trap != null) { @@ -968,7 +968,7 @@ public boolean isExtensible() { * 9. If SameValue(booleanTrapResult, targetResult) is false, throw a TypeError exception. * 10. Return booleanTrapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_IS_EXTENSIBLE); if (trap == null) { @@ -1005,7 +1005,7 @@ public void preventExtensions() { * b. If extensibleTarget is true, throw a TypeError exception. * 9. Return booleanTrapResult. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_PREVENT_EXTENSIONS); if (trap == null) { @@ -1045,7 +1045,7 @@ public Scriptable getPrototype() { * 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception. * 13. Return handlerProto. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_GET_PROTOTYPE_OF); if (trap != null) { @@ -1101,7 +1101,7 @@ public void setPrototype(Scriptable prototype) { * 13. If SameValue(V, targetProto) is false, throw a TypeError exception. * 14. Return true. */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Callable trap = getTrap(TRAP_SET_PROTOTYPE_OF); if (trap != null) { @@ -1137,7 +1137,7 @@ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] ar * 7. Let argArray be ! CreateArrayFromList(argumentsList). * 8. Return ? Call(trap, handler, « target, thisArgument, argArray »). */ - assertNotRevoked(); + ScriptableObject target = getTargetThrowIfRevoked(); Scriptable argumentsList = cx.newArray(scope, args); @@ -1184,7 +1184,7 @@ private static Object revocable( } private Callable getTrap(String trapName) { - Object handlerProp = ScriptableObject.getProperty(handler, trapName); + Object handlerProp = ScriptableObject.getProperty(handlerObj, trapName); if (Scriptable.NOT_FOUND == handlerProp) { return null; } @@ -1199,12 +1199,13 @@ private Callable getTrap(String trapName) { } private Object callTrap(Callable trap, Object[] args) { - return trap.call(Context.getContext(), handler, handler, args); + return trap.call(Context.getContext(), handlerObj, handlerObj, args); } - private void assertNotRevoked() { - if (target == null) { + ScriptableObject getTargetThrowIfRevoked() { + if (targetObj == null) { throw ScriptRuntime.typeError("Illegal operation attempted on a revoked proxy"); } + return targetObj; } } diff --git a/src/org/mozilla/javascript/ScriptRuntime.java b/src/org/mozilla/javascript/ScriptRuntime.java index f432beebc0..2f3a72baa0 100644 --- a/src/org/mozilla/javascript/ScriptRuntime.java +++ b/src/org/mozilla/javascript/ScriptRuntime.java @@ -3645,6 +3645,10 @@ public static boolean shallowEq(Object x, Object y) { if (y instanceof Boolean) { return x.equals(y); } + } else if (x instanceof SymbolKey) { + return x.equals(y); + } else if (y instanceof SymbolKey) { + return y.equals(x); } else if (x instanceof Scriptable) { if (x instanceof Wrapper && y instanceof Wrapper) { return ((Wrapper) x).unwrap() == ((Wrapper) y).unwrap(); diff --git a/testsrc/org/mozilla/javascript/tests/es6/NativeProxyTest.java b/testsrc/org/mozilla/javascript/tests/es6/NativeProxyTest.java index 78e5e32ff9..edcc7d7e93 100644 --- a/testsrc/org/mozilla/javascript/tests/es6/NativeProxyTest.java +++ b/testsrc/org/mozilla/javascript/tests/es6/NativeProxyTest.java @@ -27,8 +27,8 @@ public void testToStringRevoke() { + "rev.revoke();\n" + "try {" + " Object.prototype.toString.call(%s);\n" - + "} catch(e) {" - + " '' + e;" + + "} catch(e) {\n" + + " '' + e;\n" + "}"; testString(