29 |
29 |
30 import java.lang.invoke.MethodHandle; |
30 import java.lang.invoke.MethodHandle; |
31 import java.lang.invoke.MethodHandles; |
31 import java.lang.invoke.MethodHandles; |
32 import java.lang.invoke.MethodType; |
32 import java.lang.invoke.MethodType; |
33 import java.util.Map; |
33 import java.util.Map; |
34 import javax.script.Bindings; |
34 import java.util.Objects; |
35 import jdk.dynalink.CallSiteDescriptor; |
35 import jdk.dynalink.CallSiteDescriptor; |
36 import jdk.dynalink.Operation; |
36 import jdk.dynalink.Operation; |
37 import jdk.dynalink.StandardOperation; |
37 import jdk.dynalink.StandardOperation; |
38 import jdk.dynalink.linker.GuardedInvocation; |
38 import jdk.dynalink.linker.GuardedInvocation; |
39 import jdk.dynalink.linker.LinkRequest; |
39 import jdk.dynalink.linker.LinkRequest; |
62 @Override |
62 @Override |
63 public boolean canLinkType(final Class<?> type) { |
63 public boolean canLinkType(final Class<?> type) { |
64 return canLinkTypeStatic(type); |
64 return canLinkTypeStatic(type); |
65 } |
65 } |
66 |
66 |
67 static boolean canLinkTypeStatic(final Class<?> type) { |
67 private static boolean canLinkTypeStatic(final Class<?> type) { |
68 // can link JSObject also handles Map, Bindings to make |
68 // can link JSObject also handles Map (this includes Bindings) to make |
69 // sure those are not JSObjects. |
69 // sure those are not JSObjects. |
70 return Map.class.isAssignableFrom(type) || |
70 return Map.class.isAssignableFrom(type) || |
71 Bindings.class.isAssignableFrom(type) || |
|
72 JSObject.class.isAssignableFrom(type); |
71 JSObject.class.isAssignableFrom(type); |
73 } |
72 } |
74 |
73 |
75 @Override |
74 @Override |
76 public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { |
75 public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { |
82 |
81 |
83 GuardedInvocation inv; |
82 GuardedInvocation inv; |
84 if (self instanceof JSObject) { |
83 if (self instanceof JSObject) { |
85 inv = lookup(desc, request, linkerServices); |
84 inv = lookup(desc, request, linkerServices); |
86 inv = inv.replaceMethods(linkerServices.filterInternalObjects(inv.getInvocation()), inv.getGuard()); |
85 inv = inv.replaceMethods(linkerServices.filterInternalObjects(inv.getInvocation()), inv.getGuard()); |
87 } else if (self instanceof Map || self instanceof Bindings) { |
86 } else if (self instanceof Map) { |
88 // guard to make sure the Map or Bindings does not turn into JSObject later! |
87 // guard to make sure the Map or Bindings does not turn into JSObject later! |
89 final GuardedInvocation beanInv = nashornBeansLinker.getGuardedInvocation(request, linkerServices); |
88 final GuardedInvocation beanInv = nashornBeansLinker.getGuardedInvocation(request, linkerServices); |
90 inv = new GuardedInvocation(beanInv.getInvocation(), |
89 inv = new GuardedInvocation(beanInv.getInvocation(), |
91 NashornGuards.combineGuards(beanInv.getGuard(), NashornGuards.getNotJSObjectGuard())); |
90 NashornGuards.combineGuards(beanInv.getGuard(), NashornGuards.getNotJSObjectGuard())); |
92 } else { |
91 } else { |
114 case SET: |
113 case SET: |
115 if (NashornCallSiteDescriptor.hasStandardNamespace(desc)) { |
114 if (NashornCallSiteDescriptor.hasStandardNamespace(desc)) { |
116 return name != null ? findSetMethod(name) : findSetIndexMethod(); |
115 return name != null ? findSetMethod(name) : findSetIndexMethod(); |
117 } |
116 } |
118 break; |
117 break; |
|
118 case REMOVE: |
|
119 if (NashornCallSiteDescriptor.hasStandardNamespace(desc)) { |
|
120 return new GuardedInvocation( |
|
121 name == null ? JSOBJECTLINKER_DEL : MH.insertArguments(JSOBJECTLINKER_DEL, 1, name), |
|
122 IS_JSOBJECT_GUARD); |
|
123 } |
|
124 break; |
119 case CALL: |
125 case CALL: |
120 return findCallMethod(desc); |
126 return findCallMethod(desc); |
121 case NEW: |
127 case NEW: |
122 return findNewMethod(desc); |
128 return findNewMethod(desc); |
123 default: |
129 default: |
202 ((JSObject)jsobj).setMember(JSType.toString(key), value); |
208 ((JSObject)jsobj).setMember(JSType.toString(key), value); |
203 } |
209 } |
204 } else if (isString(key)) { |
210 } else if (isString(key)) { |
205 ((JSObject)jsobj).setMember(key.toString(), value); |
211 ((JSObject)jsobj).setMember(key.toString(), value); |
206 } |
212 } |
|
213 } |
|
214 |
|
215 @SuppressWarnings("unused") |
|
216 private static boolean del(final Object jsobj, final Object key) { |
|
217 if (jsobj instanceof ScriptObjectMirror) { |
|
218 return ((ScriptObjectMirror)jsobj).delete(key); |
|
219 } |
|
220 ((JSObject) jsobj).removeMember(Objects.toString(key)); |
|
221 return true; |
207 } |
222 } |
208 |
223 |
209 private static int getIndex(final Number n) { |
224 private static int getIndex(final Number n) { |
210 final double value = n.doubleValue(); |
225 final double value = n.doubleValue(); |
211 return JSType.isRepresentableAsInt(value) ? (int)value : -1; |
226 return JSType.isRepresentableAsInt(value) ? (int)value : -1; |
243 |
258 |
244 // method handles of the current class |
259 // method handles of the current class |
245 private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH_S("isJSObject", boolean.class, Object.class); |
260 private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH_S("isJSObject", boolean.class, Object.class); |
246 private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH_S("get", Object.class, MethodHandle.class, Object.class, Object.class); |
261 private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH_S("get", Object.class, MethodHandle.class, Object.class, Object.class); |
247 private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH_S("put", Void.TYPE, Object.class, Object.class, Object.class); |
262 private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH_S("put", Void.TYPE, Object.class, Object.class, Object.class); |
|
263 private static final MethodHandle JSOBJECTLINKER_DEL = findOwnMH_S("del", boolean.class, Object.class, Object.class); |
248 |
264 |
249 // method handles of JSObject class |
265 // method handles of JSObject class |
250 private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH_V("getMember", Object.class, String.class); |
266 private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH_V("getMember", Object.class, String.class); |
251 private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class); |
267 private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class); |
252 private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class); |
268 private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class); |