src/jdk/nashorn/internal/runtime/linker/NashornLinker.java

Print this page

        

*** 30,48 **** --- 30,53 ---- import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Modifier; import java.util.Deque; import java.util.List; + import java.util.Map; + import javax.script.Bindings; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.ConversionComparator; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; import jdk.internal.dynalink.support.Guards; + import jdk.nashorn.api.scripting.JSObject; + import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.objects.NativeArray; + import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.Undefined;
*** 113,125 **** final MethodHandle mh = JavaArgumentConverters.getConverter(targetType); if (mh != null) { return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE); } ! GuardedInvocation inv = getArrayConverter(sourceType, targetType); ! if(inv != null) { ! return inv; } return getSamTypeConverter(sourceType, targetType); } --- 118,135 ---- final MethodHandle mh = JavaArgumentConverters.getConverter(targetType); if (mh != null) { return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE); } ! final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType); ! if(arrayConverter != null) { ! return arrayConverter; ! } ! ! final GuardedInvocation mapConverter = getMirrorConverter(sourceType, targetType); ! if(mapConverter != null) { ! return mapConverter; } return getSamTypeConverter(sourceType, targetType); }
*** 179,188 **** --- 189,210 ---- assert type.isArray(); final MethodHandle converter = MH.insertArguments(JSType.TO_JAVA_ARRAY.methodHandle(), 1, type.getComponentType()); return MH.asType(converter, converter.type().changeReturnType(type)); } + private static GuardedInvocation getMirrorConverter(Class<?> sourceType, Class<?> targetType) { + // Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but + // it's probably better to explicitly spell out the supported target types + if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) { + if(ScriptObject.class.isAssignableFrom(sourceType)) { + return new GuardedInvocation(CREATE_MIRROR, null); + } + return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT); + } + return null; + } + private static boolean isAutoConvertibleFromFunction(final Class<?> clazz) { return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) && JavaAdapterFactory.isAutoConvertibleFromFunction(clazz); }
*** 233,253 **** private static boolean isList(Class<?> clazz) { return clazz == List.class || clazz == Deque.class; } private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class)); private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class)); ! private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", ! Boolean.TYPE, Object.class); @SuppressWarnings("unused") private static boolean isNashornTypeOrUndefined(final Object obj) { return obj instanceof ScriptObject || obj instanceof Undefined; } private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types)); } } --- 255,281 ---- private static boolean isList(Class<?> clazz) { return clazz == List.class || clazz == Deque.class; } + private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class)); private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class)); private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class)); ! private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class); ! private static final MethodHandle CREATE_MIRROR = findOwnMH("createMirror", Object.class, Object.class); @SuppressWarnings("unused") private static boolean isNashornTypeOrUndefined(final Object obj) { return obj instanceof ScriptObject || obj instanceof Undefined; } + @SuppressWarnings("unused") + private static Object createMirror(final Object obj) { + return ScriptObjectMirror.wrap(obj, Context.getGlobal()); + } + private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types)); } }