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

changeset 1250
9ee1fc3f6136
parent 1247
a7dc7be2d635
child 1251
85a6a7545dbe
equal deleted inserted replaced
1249:02702b17f1d8 1250:9ee1fc3f6136
25 25
26 package jdk.nashorn.internal.runtime.linker; 26 package jdk.nashorn.internal.runtime.linker;
27 27
28 import java.lang.invoke.MethodHandle; 28 import java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodHandles; 29 import java.lang.invoke.MethodHandles;
30 import java.lang.invoke.MethodType;
31 import java.util.HashMap;
32 import java.util.Map; 30 import java.util.Map;
33 import javax.script.Bindings; 31 import javax.script.Bindings;
34 import jdk.internal.dynalink.CallSiteDescriptor; 32 import jdk.internal.dynalink.CallSiteDescriptor;
35 import jdk.internal.dynalink.linker.GuardedInvocation; 33 import jdk.internal.dynalink.linker.GuardedInvocation;
36 import jdk.internal.dynalink.linker.GuardedTypeConversion;
37 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
38 import jdk.internal.dynalink.linker.LinkRequest; 34 import jdk.internal.dynalink.linker.LinkRequest;
39 import jdk.internal.dynalink.linker.LinkerServices; 35 import jdk.internal.dynalink.linker.LinkerServices;
40 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 36 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
41 import jdk.internal.dynalink.support.CallSiteDescriptorFactory; 37 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
42 import jdk.nashorn.api.scripting.JSObject; 38 import jdk.nashorn.api.scripting.JSObject;
47 43
48 /** 44 /**
49 * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well 45 * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
50 * as ScriptObjects from other Nashorn contexts. 46 * as ScriptObjects from other Nashorn contexts.
51 */ 47 */
52 final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory { 48 final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
53 private final NashornBeansLinker nashornBeansLinker; 49 private final NashornBeansLinker nashornBeansLinker;
54 50
55 JSObjectLinker(final NashornBeansLinker nashornBeansLinker) { 51 JSObjectLinker(final NashornBeansLinker nashornBeansLinker) {
56 this.nashornBeansLinker = nashornBeansLinker; 52 this.nashornBeansLinker = nashornBeansLinker;
57 } 53 }
92 throw new AssertionError(); // Should never reach here. 88 throw new AssertionError(); // Should never reach here.
93 } 89 }
94 90
95 return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc); 91 return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc);
96 } 92 }
97
98 @Override
99 public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
100 final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType);
101 if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) {
102 return null;
103 }
104
105 final MethodHandle converter = CONVERTERS.get(targetType);
106 if(converter == null) {
107 return null;
108 }
109
110 return new GuardedTypeConversion(new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)), true);
111 }
112
113 93
114 private GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request, final LinkerServices linkerServices) throws Exception { 94 private GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request, final LinkerServices linkerServices) throws Exception {
115 final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); 95 final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
116 final int c = desc.getNameTokenCount(); 96 final int c = desc.getNameTokenCount();
117 97
206 } else if (key instanceof String || key instanceof ConsString) { 186 } else if (key instanceof String || key instanceof ConsString) {
207 ((JSObject)jsobj).setMember(key.toString(), value); 187 ((JSObject)jsobj).setMember(key.toString(), value);
208 } 188 }
209 } 189 }
210 190
211 @SuppressWarnings("unused")
212 private static int toInt32(final JSObject obj) {
213 return JSType.toInt32(toNumber(obj));
214 }
215
216 @SuppressWarnings("unused")
217 private static long toLong(final JSObject obj) {
218 return JSType.toLong(toNumber(obj));
219 }
220
221 private static double toNumber(final JSObject obj) {
222 return obj == null ? 0 : obj.toNumber();
223 }
224
225 @SuppressWarnings("unused")
226 private static boolean toBoolean(final JSObject obj) {
227 return obj != null;
228 }
229
230 private static int getIndex(final Number n) { 191 private static int getIndex(final Number n) {
231 final double value = n.doubleValue(); 192 final double value = n.doubleValue();
232 return JSType.isRepresentableAsInt(value) ? (int)value : -1; 193 return JSType.isRepresentableAsInt(value) ? (int)value : -1;
233 } 194 }
234 195
259 private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class); 220 private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class);
260 private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class); 221 private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class);
261 private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class); 222 private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class);
262 private static final MethodHandle JSOBJECT_NEW = findJSObjectMH_V("newObject", Object.class, Object[].class); 223 private static final MethodHandle JSOBJECT_NEW = findJSObjectMH_V("newObject", Object.class, Object[].class);
263 224
264 private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>();
265 static {
266 CONVERTERS.put(boolean.class, findOwnMH_S("toBoolean", boolean.class, JSObject.class));
267 CONVERTERS.put(int.class, findOwnMH_S("toInt32", int.class, JSObject.class));
268 CONVERTERS.put(long.class, findOwnMH_S("toLong", long.class, JSObject.class));
269 CONVERTERS.put(double.class, findOwnMH_S("toNumber", double.class, JSObject.class));
270 }
271
272 private static MethodHandle findJSObjectMH_V(final String name, final Class<?> rtype, final Class<?>... types) { 225 private static MethodHandle findJSObjectMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
273 return MH.findVirtual(MethodHandles.lookup(), JSObject.class, name, MH.type(rtype, types)); 226 return MH.findVirtual(MethodHandles.lookup(), JSObject.class, name, MH.type(rtype, types));
274 } 227 }
275 228
276 private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) { 229 private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {

mercurial