src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java

Print this page

        

@@ -2211,14 +2211,14 @@
      *
      * @param valueType type of the value to set
      * @param name      name of property
      * @param flags     call site flags
      * @param isMethod  should it prefer retrieving methods
-     *
+     * @param isIndex   is this an index operation?
      * @return the method emitter
      */
-    MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {
+    MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod, final boolean isIndex) {
         if (name.length() > LARGE_STRING_THRESHOLD) { // use getIndex for extremely long names
             return load(name).dynamicGetIndex(valueType, flags, isMethod);
         }
 
         debug("dynamic_get", name, valueType, getProgramPoint(flags));

@@ -2227,12 +2227,12 @@
         if (type.isObject() || type.isBoolean()) {
             type = Type.OBJECT; //promote e.g strings to object generic setter
         }
 
         popType(Type.SCOPE);
-        method.visitInvokeDynamicInsn((isMethod ? "dyn:getMethod|getProp|getElem:" : "dyn:getProp|getElem|getMethod:") +
-                NameCodec.encode(name), Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
+        method.visitInvokeDynamicInsn(dynGetOperation(isMethod, isIndex) + ':' + NameCodec.encode(name),
+                Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
 
         pushType(type);
         convert(valueType); //most probably a nop
 
         return this;

@@ -2241,12 +2241,13 @@
     /**
      * Generate dynamic setter. Pop receiver and property from stack.
      *
      * @param name  name of property
      * @param flags call site flags
+     * @param isIndex is this an index operation?
      */
-    void dynamicSet(final String name, final int flags) {
+    void dynamicSet(final String name, final int flags, final boolean isIndex) {
         if (name.length() > LARGE_STRING_THRESHOLD) { // use setIndex for extremely long names
             load(name).swap().dynamicSetIndex(flags);
             return;
         }
 

@@ -2259,11 +2260,12 @@
             convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
         }
         popType(type);
         popType(Type.SCOPE);
 
-        method.visitInvokeDynamicInsn("dyn:setProp|setElem:" + NameCodec.encode(name), methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
+        method.visitInvokeDynamicInsn(dynSetOperation(isIndex) + ':' + NameCodec.encode(name),
+                methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
     }
 
      /**
      * Dynamic getter for indexed structures. Pop index and receiver from stack,
      * generate appropriate signatures based on types

@@ -2292,11 +2294,11 @@
 
         popType(Type.OBJECT);
 
         final String signature = Type.getMethodDescriptor(resultType, Type.OBJECT /*e.g STRING->OBJECT*/, index);
 
-        method.visitInvokeDynamicInsn(isMethod ? "dyn:getMethod|getElem|getProp" : "dyn:getElem|getProp|getMethod", signature, LINKERBOOTSTRAP, flags);
+        method.visitInvokeDynamicInsn(dynGetOperation(isMethod, true), signature, LINKERBOOTSTRAP, flags);
         pushType(resultType);
 
         if (result.isBoolean()) {
             convert(Type.BOOLEAN);
         }

@@ -2506,10 +2508,22 @@
             }
             next = next.getNext();
         }
     }
 
+    private static String dynGetOperation(final boolean isMethod, final boolean isIndex) {
+        if (isMethod) {
+            return isIndex ? "dyn:getMethod|getElem|getProp" : "dyn:getMethod|getProp|getElem";
+        } else {
+            return isIndex ? "dyn:getElem|getProp|getMethod" : "dyn:getProp|getElem|getMethod";
+        }
+    }
+
+    private static String dynSetOperation(final boolean isIndex) {
+        return isIndex ? "dyn:setElem|setProp" : "dyn:setProp|setElem";
+    }
+
     private Type emitLocalVariableConversion(final LocalVariableConversion conversion, final boolean onlySymbolLiveValue) {
         final Type from = conversion.getFrom();
         final Type to = conversion.getTo();
         final Symbol symbol = conversion.getSymbol();
         assert symbol.isBytecodeLocal();