20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime.linker; 27 28 import static jdk.nashorn.internal.lookup.Lookup.MH; 29 30 import java.lang.invoke.MethodHandle; 31 import java.lang.invoke.MethodHandles; 32 import jdk.internal.dynalink.linker.ConversionComparator; 33 import jdk.internal.dynalink.linker.GuardedInvocation; 34 import jdk.internal.dynalink.linker.GuardedTypeConversion; 35 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; 36 import jdk.internal.dynalink.linker.LinkRequest; 37 import jdk.internal.dynalink.linker.LinkerServices; 38 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 39 import jdk.internal.dynalink.support.TypeUtilities; 40 import jdk.nashorn.internal.runtime.ConsString; 41 import jdk.nashorn.internal.runtime.Context; 42 import jdk.nashorn.internal.runtime.GlobalObject; 43 44 /** 45 * Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other 46 * engines. It is used for treatment of strings, boolean, and numbers as JavaScript primitives. Also provides ECMAScript 47 * primitive type conversions for these types when linking to Java methods. 48 */ 49 final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator { 50 @Override 51 public boolean canLinkType(final Class<?> type) { 52 return canLinkTypeStatic(type); 53 } 54 55 private static boolean canLinkTypeStatic(final Class<?> type) { 56 return type == String.class || type == Boolean.class || type == ConsString.class || Number.class.isAssignableFrom(type); 57 } 58 59 @Override 60 public GuardedInvocation getGuardedInvocation(final LinkRequest origRequest, final LinkerServices linkerServices) 61 throws Exception { 62 final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context 63 64 final Object self = request.getReceiver(); 65 final GlobalObject global = (GlobalObject) Context.getGlobal(); 66 final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor(); 67 68 return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc); 69 } 70 71 /** 72 * This implementation of type converter factory will pretty much allow implicit conversions of anything to anything 73 * else that's allowed among JavaScript primitive types (string to number, boolean to string, etc.) 74 * @param sourceType the type to convert from 75 * @param targetType the type to convert to 76 * @return a conditional converter from source to target type 77 */ 78 @Override 79 public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) { 80 final MethodHandle mh = JavaArgumentConverters.getConverter(targetType); 81 if (mh == null) { 82 return null; 83 } 84 85 return new GuardedTypeConversion(new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : GUARD_PRIMITIVE).asType(mh.type().changeParameterType(0, sourceType)), true); | 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime.linker; 27 28 import static jdk.nashorn.internal.lookup.Lookup.MH; 29 30 import java.lang.invoke.MethodHandle; 31 import java.lang.invoke.MethodHandles; 32 import jdk.internal.dynalink.linker.ConversionComparator; 33 import jdk.internal.dynalink.linker.GuardedInvocation; 34 import jdk.internal.dynalink.linker.GuardedTypeConversion; 35 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; 36 import jdk.internal.dynalink.linker.LinkRequest; 37 import jdk.internal.dynalink.linker.LinkerServices; 38 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 39 import jdk.internal.dynalink.support.TypeUtilities; 40 import jdk.nashorn.internal.objects.Global; 41 import jdk.nashorn.internal.runtime.ConsString; 42 import jdk.nashorn.internal.runtime.Context; 43 44 /** 45 * Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other 46 * engines. It is used for treatment of strings, boolean, and numbers as JavaScript primitives. Also provides ECMAScript 47 * primitive type conversions for these types when linking to Java methods. 48 */ 49 final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator { 50 @Override 51 public boolean canLinkType(final Class<?> type) { 52 return canLinkTypeStatic(type); 53 } 54 55 private static boolean canLinkTypeStatic(final Class<?> type) { 56 return type == String.class || type == Boolean.class || type == ConsString.class || Number.class.isAssignableFrom(type); 57 } 58 59 @Override 60 public GuardedInvocation getGuardedInvocation(final LinkRequest origRequest, final LinkerServices linkerServices) 61 throws Exception { 62 final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context 63 64 final Object self = request.getReceiver(); 65 final Global global = Context.getGlobal(); 66 final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor(); 67 68 return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc); 69 } 70 71 /** 72 * This implementation of type converter factory will pretty much allow implicit conversions of anything to anything 73 * else that's allowed among JavaScript primitive types (string to number, boolean to string, etc.) 74 * @param sourceType the type to convert from 75 * @param targetType the type to convert to 76 * @return a conditional converter from source to target type 77 */ 78 @Override 79 public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) { 80 final MethodHandle mh = JavaArgumentConverters.getConverter(targetType); 81 if (mh == null) { 82 return null; 83 } 84 85 return new GuardedTypeConversion(new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : GUARD_PRIMITIVE).asType(mh.type().changeParameterType(0, sourceType)), true); |