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

Print this page




1574      * @param table         label table
1575      */
1576     void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label... table) {
1577         debug("tableswitch", peekType());
1578         adjustStackForSwitch(defaultLabel, table);
1579         method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table));
1580         doesNotContinueSequentially();
1581     }
1582 
1583     private void adjustStackForSwitch(final Label defaultLabel, final Label... table) {
1584         popType(Type.INT);
1585         joinTo(defaultLabel);
1586         for(final Label label: table) {
1587             joinTo(label);
1588         }
1589     }
1590 
1591     /**
1592      * Abstraction for performing a conditional jump of any type
1593      *
1594      * @see MethodEmitter.Condition
1595      *
1596      * @param cond      the condition to test
1597      * @param trueLabel the destination label is condition is true
1598      */
1599     void conditionalJump(final Condition cond, final Label trueLabel) {
1600         conditionalJump(cond, cond != Condition.GT && cond != Condition.GE, trueLabel);
1601     }
1602 
1603     /**
1604      * Abstraction for performing a conditional jump of any type,
1605      * including a dcmpg/dcmpl semantic for doubles.
1606      *
1607      * @param cond      the condition to test
1608      * @param isCmpG    is this a dcmpg for numbers, false if it's a dcmpl
1609      * @param trueLabel the destination label if condition is true
1610      */
1611     void conditionalJump(final Condition cond, final boolean isCmpG, final Label trueLabel) {
1612         if (peekType().isCategory2()) {
1613             debug("[ld]cmp isCmpG=", isCmpG);
1614             pushType(get2n().cmp(method, isCmpG));


2200         debug("dynamic_runtime_call", name, "args=", request.getArity(), "returnType=", returnType);
2201         final String signature = getDynamicSignature(returnType, request.getArity());
2202         debug("   signature", signature);
2203         method.visitInvokeDynamicInsn(name, signature, RUNTIMEBOOTSTRAP);
2204         pushType(returnType);
2205 
2206         return this;
2207     }
2208 
2209     /**
2210      * Generate dynamic getter. Pop scope from stack. Push result
2211      *
2212      * @param valueType type of the value to set
2213      * @param name      name of property
2214      * @param flags     call site flags
2215      * @param isMethod  should it prefer retrieving methods
2216      *
2217      * @return the method emitter
2218      */
2219     MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {




2220         debug("dynamic_get", name, valueType, getProgramPoint(flags));
2221 
2222         Type type = valueType;
2223         if (type.isObject() || type.isBoolean()) {
2224             type = Type.OBJECT; //promote e.g strings to object generic setter
2225         }
2226 
2227         popType(Type.SCOPE);
2228         method.visitInvokeDynamicInsn((isMethod ? "dyn:getMethod|getProp|getElem:" : "dyn:getProp|getElem|getMethod:") +
2229                 NameCodec.encode(name), Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
2230 
2231         pushType(type);
2232         convert(valueType); //most probably a nop
2233 
2234         return this;
2235     }
2236 
2237     /**
2238      * Generate dynamic setter. Pop receiver and property from stack.
2239      *
2240      * @param name  name of property
2241      * @param flags call site flags
2242      */
2243      void dynamicSet(final String name, final int flags) {





2244          assert !isOptimistic(flags);
2245          debug("dynamic_set", name, peekType());
2246 
2247         Type type = peekType();
2248         if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
2249             type = Type.OBJECT;
2250             convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
2251         }
2252         popType(type);
2253         popType(Type.SCOPE);
2254 
2255         method.visitInvokeDynamicInsn("dyn:setProp|setElem:" + NameCodec.encode(name), methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
2256     }
2257 
2258      /**
2259      * Dynamic getter for indexed structures. Pop index and receiver from stack,
2260      * generate appropriate signatures based on types
2261      *
2262      * @param result result type for getter
2263      * @param flags call site flags for getter




1574      * @param table         label table
1575      */
1576     void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label... table) {
1577         debug("tableswitch", peekType());
1578         adjustStackForSwitch(defaultLabel, table);
1579         method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table));
1580         doesNotContinueSequentially();
1581     }
1582 
1583     private void adjustStackForSwitch(final Label defaultLabel, final Label... table) {
1584         popType(Type.INT);
1585         joinTo(defaultLabel);
1586         for(final Label label: table) {
1587             joinTo(label);
1588         }
1589     }
1590 
1591     /**
1592      * Abstraction for performing a conditional jump of any type
1593      *
1594      * @see Condition
1595      *
1596      * @param cond      the condition to test
1597      * @param trueLabel the destination label is condition is true
1598      */
1599     void conditionalJump(final Condition cond, final Label trueLabel) {
1600         conditionalJump(cond, cond != Condition.GT && cond != Condition.GE, trueLabel);
1601     }
1602 
1603     /**
1604      * Abstraction for performing a conditional jump of any type,
1605      * including a dcmpg/dcmpl semantic for doubles.
1606      *
1607      * @param cond      the condition to test
1608      * @param isCmpG    is this a dcmpg for numbers, false if it's a dcmpl
1609      * @param trueLabel the destination label if condition is true
1610      */
1611     void conditionalJump(final Condition cond, final boolean isCmpG, final Label trueLabel) {
1612         if (peekType().isCategory2()) {
1613             debug("[ld]cmp isCmpG=", isCmpG);
1614             pushType(get2n().cmp(method, isCmpG));


2200         debug("dynamic_runtime_call", name, "args=", request.getArity(), "returnType=", returnType);
2201         final String signature = getDynamicSignature(returnType, request.getArity());
2202         debug("   signature", signature);
2203         method.visitInvokeDynamicInsn(name, signature, RUNTIMEBOOTSTRAP);
2204         pushType(returnType);
2205 
2206         return this;
2207     }
2208 
2209     /**
2210      * Generate dynamic getter. Pop scope from stack. Push result
2211      *
2212      * @param valueType type of the value to set
2213      * @param name      name of property
2214      * @param flags     call site flags
2215      * @param isMethod  should it prefer retrieving methods
2216      *
2217      * @return the method emitter
2218      */
2219     MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {
2220         if (name.length() > LARGE_STRING_THRESHOLD) { // use getIndex for extremely long names
2221             return load(name).dynamicGetIndex(valueType, flags, isMethod);
2222         }
2223 
2224         debug("dynamic_get", name, valueType, getProgramPoint(flags));
2225 
2226         Type type = valueType;
2227         if (type.isObject() || type.isBoolean()) {
2228             type = Type.OBJECT; //promote e.g strings to object generic setter
2229         }
2230 
2231         popType(Type.SCOPE);
2232         method.visitInvokeDynamicInsn((isMethod ? "dyn:getMethod|getProp|getElem:" : "dyn:getProp|getElem|getMethod:") +
2233                 NameCodec.encode(name), Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
2234 
2235         pushType(type);
2236         convert(valueType); //most probably a nop
2237 
2238         return this;
2239     }
2240 
2241     /**
2242      * Generate dynamic setter. Pop receiver and property from stack.
2243      *
2244      * @param name  name of property
2245      * @param flags call site flags
2246      */
2247     void dynamicSet(final String name, final int flags) {
2248         if (name.length() > LARGE_STRING_THRESHOLD) { // use setIndex for extremely long names
2249             load(name).swap().dynamicSetIndex(flags);
2250             return;
2251         }
2252 
2253         assert !isOptimistic(flags);
2254         debug("dynamic_set", name, peekType());
2255 
2256         Type type = peekType();
2257         if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
2258             type = Type.OBJECT;
2259             convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
2260         }
2261         popType(type);
2262         popType(Type.SCOPE);
2263 
2264         method.visitInvokeDynamicInsn("dyn:setProp|setElem:" + NameCodec.encode(name), methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
2265     }
2266 
2267      /**
2268      * Dynamic getter for indexed structures. Pop index and receiver from stack,
2269      * generate appropriate signatures based on types
2270      *
2271      * @param result result type for getter
2272      * @param flags call site flags for getter