8027037: Make ScriptObjectMirror conversions work for any JSObject

Reviewed-by: jlaskey, lagergren, sundar
This commit is contained in:
Attila Szegedi 2013-10-22 17:52:37 +02:00
parent 806a003cb6
commit d24b73ab43
4 changed files with 38 additions and 73 deletions

View File

@ -234,4 +234,13 @@ public abstract class JSObject {
public boolean isArray() {
return false;
}
/**
* Returns this object's numeric value.
*
* @return this object's numeric value.
*/
public double toNumber() {
return Double.NaN;
}
}

View File

@ -707,39 +707,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
}
}
/**
* JavaScript compliant Object to int32 conversion
* See ECMA 9.5 ToInt32
*
* @return this object's int32 representation
*/
public int toInt32() {
return inGlobal(new Callable<Integer>() {
@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<Long>() {
@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<Double>() {
@Override public Double call() {

View File

@ -630,17 +630,6 @@ public enum JSType {
return toInt32(toNumber(obj));
}
/**
* 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
*
@ -671,16 +660,6 @@ public enum JSType {
return toInt64(toNumber(obj));
}
/**
* 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
*

View File

@ -38,7 +38,6 @@ import jdk.internal.dynalink.linker.LinkerServices;
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 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
@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));
}
@ -156,11 +156,6 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
return self instanceof JSObject;
}
@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) {
@ -187,6 +182,25 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
}
}
@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 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
// 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 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
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<Class<?>, MethodHandle> MIRROR_CONVERTERS = new HashMap<>();
private static final Map<Class<?>, 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 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
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 {