src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
changeset 48411 4ff5c5206427
parent 47216 71c04702a3d5
equal deleted inserted replaced
48410:8aab0cea56bf 48411:4ff5c5206427
    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);