src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java
changeset 48354 c96d4c720995
parent 48247 fa5a47cad0c9
child 49145 2854589fd853
equal deleted inserted replaced
48353:315c690bb90b 48354:c96d4c720995
  2201         pushType(Type.OBJECT_ARRAY);
  2201         pushType(Type.OBJECT_ARRAY);
  2202         return this;
  2202         return this;
  2203     }
  2203     }
  2204 
  2204 
  2205     /**
  2205     /**
  2206      * Generate dynamic getter. Pop scope from stack. Push result
  2206      * Generate dynamic getter. Pop object from stack. Push result.
  2207      *
  2207      *
  2208      * @param valueType type of the value to set
  2208      * @param valueType type of the value to set
  2209      * @param name      name of property
  2209      * @param name      name of property
  2210      * @param flags     call site flags
  2210      * @param flags     call site flags
  2211      * @param isMethod  should it prefer retrieving methods
  2211      * @param isMethod  should it prefer retrieving methods
  2222         Type type = valueType;
  2222         Type type = valueType;
  2223         if (type.isObject() || type.isBoolean()) {
  2223         if (type.isObject() || type.isBoolean()) {
  2224             type = Type.OBJECT; //promote e.g strings to object generic setter
  2224             type = Type.OBJECT; //promote e.g strings to object generic setter
  2225         }
  2225         }
  2226 
  2226 
  2227         popType(Type.SCOPE);
  2227         popType(Type.OBJECT);
  2228         method.visitInvokeDynamicInsn(NameCodec.encode(name),
  2228         method.visitInvokeDynamicInsn(NameCodec.encode(name),
  2229                 Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags | dynGetOperation(isMethod, isIndex));
  2229                 Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags | dynGetOperation(isMethod, isIndex));
  2230 
  2230 
  2231         pushType(type);
  2231         pushType(type);
  2232         convert(valueType); //most probably a nop
  2232         convert(valueType); //most probably a nop
  2254         if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
  2254         if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
  2255             type = Type.OBJECT;
  2255             type = Type.OBJECT;
  2256             convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
  2256             convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
  2257         }
  2257         }
  2258         popType(type);
  2258         popType(type);
  2259         popType(Type.SCOPE);
  2259         popType(Type.OBJECT);
  2260 
  2260 
  2261         method.visitInvokeDynamicInsn(NameCodec.encode(name),
  2261         method.visitInvokeDynamicInsn(NameCodec.encode(name),
  2262                 methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags | dynSetOperation(isIndex));
  2262                 methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags | dynSetOperation(isIndex));
  2263     }
  2263     }
  2264 
  2264 
  2265      /**
  2265     /**
       
  2266      * Generate dynamic remover. Pop object from stack. Push result.
       
  2267      *
       
  2268      * @param name      name of property
       
  2269      * @param flags     call site flags
       
  2270      * @return the method emitter
       
  2271      */
       
  2272     MethodEmitter dynamicRemove(final String name, final int flags, final boolean isIndex) {
       
  2273         if (name.length() > LARGE_STRING_THRESHOLD) { // use removeIndex for extremely long names
       
  2274             return load(name).dynamicRemoveIndex(flags);
       
  2275         }
       
  2276 
       
  2277         debug("dynamic_remove", name, Type.BOOLEAN, getProgramPoint(flags));
       
  2278 
       
  2279         popType(Type.OBJECT);
       
  2280         // Type is widened to OBJECT then coerced back to BOOLEAN
       
  2281         method.visitInvokeDynamicInsn(NameCodec.encode(name),
       
  2282                 Type.getMethodDescriptor(Type.OBJECT, Type.OBJECT), LINKERBOOTSTRAP, flags | dynRemoveOperation(isIndex));
       
  2283 
       
  2284         pushType(Type.OBJECT);
       
  2285         convert(Type.BOOLEAN); //most probably a nop
       
  2286 
       
  2287         return this;
       
  2288     }
       
  2289 
       
  2290     /**
  2266      * Dynamic getter for indexed structures. Pop index and receiver from stack,
  2291      * Dynamic getter for indexed structures. Pop index and receiver from stack,
  2267      * generate appropriate signatures based on types
  2292      * generate appropriate signatures based on types
  2268      *
  2293      *
  2269      * @param result result type for getter
  2294      * @param result result type for getter
  2270      * @param flags call site flags for getter
  2295      * @param flags call site flags for getter
  2337         assert receiver.isObject();
  2362         assert receiver.isObject();
  2338 
  2363 
  2339         method.visitInvokeDynamicInsn(EMPTY_NAME,
  2364         method.visitInvokeDynamicInsn(EMPTY_NAME,
  2340                 methodDescriptor(void.class, receiver.getTypeClass(), index.getTypeClass(), value.getTypeClass()),
  2365                 methodDescriptor(void.class, receiver.getTypeClass(), index.getTypeClass(), value.getTypeClass()),
  2341                 LINKERBOOTSTRAP, flags | NashornCallSiteDescriptor.SET_ELEMENT);
  2366                 LINKERBOOTSTRAP, flags | NashornCallSiteDescriptor.SET_ELEMENT);
       
  2367     }
       
  2368 
       
  2369     /**
       
  2370      * Dynamic remover for indexed structures. Pop index and receiver from stack,
       
  2371      * generate appropriate signatures based on types
       
  2372      *
       
  2373      * @param flags call site flags for getter
       
  2374      *
       
  2375      * @return the method emitter
       
  2376      */
       
  2377     MethodEmitter dynamicRemoveIndex(final int flags) {
       
  2378         debug("dynamic_remove_index", peekType(1), "[", peekType(), "]", getProgramPoint(flags));
       
  2379 
       
  2380         Type index = peekType();
       
  2381         if (index.isObject() || index.isBoolean()) {
       
  2382             index = Type.OBJECT; //e.g. string->object
       
  2383             convert(Type.OBJECT);
       
  2384         }
       
  2385         popType();
       
  2386 
       
  2387         popType(Type.OBJECT);
       
  2388 
       
  2389         final String signature = Type.getMethodDescriptor(Type.OBJECT, Type.OBJECT /*e.g STRING->OBJECT*/, index);
       
  2390 
       
  2391         method.visitInvokeDynamicInsn(EMPTY_NAME, signature, LINKERBOOTSTRAP, flags | dynRemoveOperation(true));
       
  2392         pushType(Type.OBJECT);
       
  2393         convert(Type.BOOLEAN);
       
  2394 
       
  2395         return this;
  2342     }
  2396     }
  2343 
  2397 
  2344     /**
  2398     /**
  2345      * Load a key value in the proper form.
  2399      * Load a key value in the proper form.
  2346      *
  2400      *
  2516         }
  2570         }
  2517     }
  2571     }
  2518 
  2572 
  2519     private static int dynSetOperation(final boolean isIndex) {
  2573     private static int dynSetOperation(final boolean isIndex) {
  2520         return isIndex ? NashornCallSiteDescriptor.SET_ELEMENT : NashornCallSiteDescriptor.SET_PROPERTY;
  2574         return isIndex ? NashornCallSiteDescriptor.SET_ELEMENT : NashornCallSiteDescriptor.SET_PROPERTY;
       
  2575     }
       
  2576 
       
  2577     private static int dynRemoveOperation(final boolean isIndex) {
       
  2578         return isIndex ? NashornCallSiteDescriptor.REMOVE_ELEMENT : NashornCallSiteDescriptor.REMOVE_PROPERTY;
  2521     }
  2579     }
  2522 
  2580 
  2523     private Type emitLocalVariableConversion(final LocalVariableConversion conversion, final boolean onlySymbolLiveValue) {
  2581     private Type emitLocalVariableConversion(final LocalVariableConversion conversion, final boolean onlySymbolLiveValue) {
  2524         final Type from = conversion.getFrom();
  2582         final Type from = conversion.getFrom();
  2525         final Type to = conversion.getTo();
  2583         final Type to = conversion.getTo();