# HG changeset patch # User attila # Date 1382457157 -7200 # Node ID 6f19eb443a47d49e6a293dcf52bc534c934f86f4 # Parent 0ecbc0188b647bff4b4d2578a5312a767fa46413 8027037: Make ScriptObjectMirror conversions work for any JSObject Reviewed-by: jlaskey, lagergren, sundar diff -r 0ecbc0188b64 -r 6f19eb443a47 src/jdk/nashorn/api/scripting/JSObject.java --- a/src/jdk/nashorn/api/scripting/JSObject.java Tue Oct 22 16:43:27 2013 +0200 +++ b/src/jdk/nashorn/api/scripting/JSObject.java Tue Oct 22 17:52:37 2013 +0200 @@ -234,4 +234,13 @@ public boolean isArray() { return false; } + + /** + * Returns this object's numeric value. + * + * @return this object's numeric value. + */ + public double toNumber() { + return Double.NaN; + } } diff -r 0ecbc0188b64 -r 6f19eb443a47 src/jdk/nashorn/api/scripting/ScriptObjectMirror.java --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Tue Oct 22 16:43:27 2013 +0200 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Tue Oct 22 17:52:37 2013 +0200 @@ -707,39 +707,7 @@ } } - /** - * JavaScript compliant Object to int32 conversion - * See ECMA 9.5 ToInt32 - * - * @return this object's int32 representation - */ - public int toInt32() { - return inGlobal(new Callable() { - @Override public Integer call() { - return JSType.toInt32(sobj); - } - }); - } - - /** - * JavaScript compliant Object to int64 conversion - * - * @return this object's int64 representation - */ - public long toInt64() { - return inGlobal(new Callable() { - @Override public Long call() { - return JSType.toInt64(sobj); - } - }); - } - - /** - * JavaScript compliant conversion of Object to number - * See ECMA 9.3 ToNumber - * - * @return this object's number representation - */ + @Override public double toNumber() { return inGlobal(new Callable() { @Override public Double call() { diff -r 0ecbc0188b64 -r 6f19eb443a47 src/jdk/nashorn/internal/runtime/JSType.java --- a/src/jdk/nashorn/internal/runtime/JSType.java Tue Oct 22 16:43:27 2013 +0200 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Tue Oct 22 17:52:37 2013 +0200 @@ -631,17 +631,6 @@ } /** - * JavaScript compliant Object to int32 conversion - * See ECMA 9.5 ToInt32 - * - * @param obj an object - * @return an int32 - */ - public static int toInt32(final ScriptObject obj) { - return toInt32(toNumber(obj)); - } - - /** * JavaScript compliant long to int32 conversion * * @param num a long @@ -672,16 +661,6 @@ } /** - * JavaScript compliant Object to int64 conversion - * - * @param obj an object - * @return an int64 - */ - public static long toInt64(final ScriptObject obj) { - return toInt64(toNumber(obj)); - } - - /** * JavaScript compliant number to int64 conversion * * @param num a number diff -r 0ecbc0188b64 -r 6f19eb443a47 src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java --- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Tue Oct 22 16:43:27 2013 +0200 +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Tue Oct 22 17:52:37 2013 +0200 @@ -38,7 +38,6 @@ import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.nashorn.api.scripting.JSObject; -import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.lookup.MethodHandleFunctionality; import jdk.nashorn.internal.runtime.JSType; @@ -81,16 +80,17 @@ @Override public GuardedInvocation convertToType(final Class sourceType, final Class targetType) throws Exception { - if(!sourceType.isAssignableFrom(ScriptObjectMirror.class)) { + final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType); + if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) { return null; } - final MethodHandle converter = MIRROR_CONVERTERS.get(targetType); + final MethodHandle converter = CONVERTERS.get(targetType); if(converter == null) { return null; } - return new GuardedInvocation(converter, sourceType == ScriptObjectMirror.class ? null : IS_MIRROR_GUARD).asType(MethodType.methodType(targetType, sourceType)); + return new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)); } @@ -157,11 +157,6 @@ } @SuppressWarnings("unused") - private static boolean isScriptObjectMirror(final Object self) { - return self instanceof ScriptObjectMirror; - } - - @SuppressWarnings("unused") private static Object get(final Object jsobj, final Object key) { if (key instanceof Integer) { return ((JSObject)jsobj).getSlot((Integer)key); @@ -187,6 +182,25 @@ } } + @SuppressWarnings("unused") + private static int toInt32(final JSObject obj) { + return JSType.toInt32(toNumber(obj)); + } + + @SuppressWarnings("unused") + private static long toInt64(final JSObject obj) { + return JSType.toInt64(toNumber(obj)); + } + + private static double toNumber(final JSObject obj) { + return obj == null ? 0 : obj.toNumber(); + } + + @SuppressWarnings("unused") + private static boolean toBoolean(final JSObject obj) { + return obj != null; + } + private static int getIndex(final Number n) { final double value = n.doubleValue(); return JSType.isRepresentableAsInt(value) ? (int)value : -1; @@ -196,7 +210,6 @@ // method handles of the current class private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); - private static final MethodHandle IS_MIRROR_GUARD = findOwnMH("isScriptObjectMirror", boolean.class, Object.class); private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH("get", Object.class, Object.class, Object.class); private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); @@ -207,12 +220,12 @@ private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class); private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class); - private static final Map, MethodHandle> MIRROR_CONVERTERS = new HashMap<>(); + private static final Map, MethodHandle> CONVERTERS = new HashMap<>(); static { - MIRROR_CONVERTERS.put(boolean.class, MH.dropArguments(MH.constant(boolean.class, Boolean.TRUE), 0, Object.class)); - MIRROR_CONVERTERS.put(int.class, findMirrorMH("toInt32", int.class)); - MIRROR_CONVERTERS.put(long.class, findMirrorMH("toInt64", long.class)); - MIRROR_CONVERTERS.put(double.class, findMirrorMH("toNumber", double.class)); + CONVERTERS.put(boolean.class, findOwnMH("toBoolean", boolean.class, JSObject.class)); + CONVERTERS.put(int.class, findOwnMH("toInt32", int.class, JSObject.class)); + CONVERTERS.put(long.class, findOwnMH("toInt64", long.class, JSObject.class)); + CONVERTERS.put(double.class, findOwnMH("toNumber", double.class, JSObject.class)); } private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { @@ -223,10 +236,6 @@ return findMH(name, JSObject.class, rtype, types); } - private static MethodHandle findMirrorMH(final String name, final Class rtype, final Class... types) { - return findMH(name, ScriptObjectMirror.class, rtype, types); - } - private static MethodHandle findMH(final String name, final Class target, final Class rtype, final Class... types) { final MethodType mt = MH.type(rtype, types); try {