src/jdk/nashorn/internal/codegen/MethodEmitter.java

changeset 253
fb1d7ea3e1b6
parent 233
e8d7298f29a1
child 256
9073bcc4307b
     1.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Tue May 07 14:36:57 2013 +0200
     1.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Tue May 07 14:43:17 2013 +0200
     1.3 @@ -71,6 +71,7 @@
     1.4  import java.util.EnumSet;
     1.5  import java.util.Iterator;
     1.6  import java.util.List;
     1.7 +
     1.8  import jdk.internal.dynalink.support.NameCodec;
     1.9  import jdk.internal.org.objectweb.asm.Handle;
    1.10  import jdk.internal.org.objectweb.asm.MethodVisitor;
    1.11 @@ -189,7 +190,7 @@
    1.12      @Override
    1.13      public void begin() {
    1.14          classEmitter.beginMethod(this);
    1.15 -        stack = new ArrayDeque<>();
    1.16 +        newStack();
    1.17          method.visitCode();
    1.18      }
    1.19  
    1.20 @@ -205,6 +206,10 @@
    1.21          classEmitter.endMethod(this);
    1.22      }
    1.23  
    1.24 +    private void newStack() {
    1.25 +        stack = new ArrayDeque<>();
    1.26 +    }
    1.27 +
    1.28      @Override
    1.29      public String toString() {
    1.30          return "methodEmitter: " + (functionNode == null ? method : functionNode.getName()).toString() + ' ' + Debug.id(this);
    1.31 @@ -484,7 +489,7 @@
    1.32              name = THIS_DEBUGGER.symbolName();
    1.33          }
    1.34  
    1.35 -        method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start, end, symbol.getSlot());
    1.36 +        method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start.getLabel(), end.getLabel(), symbol.getSlot());
    1.37      }
    1.38  
    1.39      /**
    1.40 @@ -509,17 +514,6 @@
    1.41      }
    1.42  
    1.43      /**
    1.44 -     * Associate a variable with a given range
    1.45 -     *
    1.46 -     * @param name  name of the variable
    1.47 -     * @param start start
    1.48 -     * @param end   end
    1.49 -     */
    1.50 -    void markerVariable(final String name, final Label start, final Label end) {
    1.51 -        method.visitLocalVariable(name, Type.OBJECT.getDescriptor(), null, start, end, 0);
    1.52 -    }
    1.53 -
    1.54 -    /**
    1.55       * Pops two integer types from the stack, performs a bitwise and and pushes
    1.56       * the result
    1.57       *
    1.58 @@ -626,7 +620,7 @@
    1.59       * @param typeDescriptor type descriptor for exception
    1.60       */
    1.61      void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) {
    1.62 -        method.visitTryCatchBlock(entry, exit, recovery, typeDescriptor);
    1.63 +        method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), typeDescriptor);
    1.64      }
    1.65  
    1.66      /**
    1.67 @@ -638,7 +632,7 @@
    1.68       * @param clazz    exception class
    1.69       */
    1.70      void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) {
    1.71 -        method.visitTryCatchBlock(entry, exit, recovery, CompilerConstants.className(clazz));
    1.72 +        method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), CompilerConstants.className(clazz));
    1.73      }
    1.74  
    1.75      /**
    1.76 @@ -1228,6 +1222,14 @@
    1.77          return invoke(INVOKEINTERFACE, className, methodName, methodDescriptor, true);
    1.78      }
    1.79  
    1.80 +    static jdk.internal.org.objectweb.asm.Label[] getLabels(final Label... table) {
    1.81 +        final jdk.internal.org.objectweb.asm.Label[] internalLabels = new jdk.internal.org.objectweb.asm.Label[table.length];
    1.82 +        for (int i = 0; i < table.length; i++) {
    1.83 +            internalLabels[i] = table[i].getLabel();
    1.84 +        }
    1.85 +        return internalLabels;
    1.86 +    }
    1.87 +
    1.88      /**
    1.89       * Generate a lookup switch, popping the switch value from the stack
    1.90       *
    1.91 @@ -1235,10 +1237,10 @@
    1.92       * @param values       case values for the table
    1.93       * @param table        default label
    1.94       */
    1.95 -    void lookupswitch(final Label defaultLabel, final int[] values, final Label[] table) {
    1.96 +    void lookupswitch(final Label defaultLabel, final int[] values, final Label... table) {//Collection<Label> table) {
    1.97          debug("lookupswitch", peekType());
    1.98          popType(Type.INT);
    1.99 -        method.visitLookupSwitchInsn(defaultLabel, values, table);
   1.100 +        method.visitLookupSwitchInsn(defaultLabel.getLabel(), values, getLabels(table));
   1.101      }
   1.102  
   1.103      /**
   1.104 @@ -1248,10 +1250,10 @@
   1.105       * @param defaultLabel  default label
   1.106       * @param table         label table
   1.107       */
   1.108 -    void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label[] table) {
   1.109 +    void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label... table) {
   1.110          debug("tableswitch", peekType());
   1.111          popType(Type.INT);
   1.112 -        method.visitTableSwitchInsn(lo, hi, defaultLabel, table);
   1.113 +        method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table));
   1.114      }
   1.115  
   1.116      /**
   1.117 @@ -1358,7 +1360,7 @@
   1.118              popType();
   1.119          }
   1.120          mergeStackTo(label);
   1.121 -        method.visitJumpInsn(opcode, label);
   1.122 +        method.visitJumpInsn(opcode, label.getLabel());
   1.123      }
   1.124  
   1.125      /**
   1.126 @@ -1487,9 +1489,9 @@
   1.127       * @param label destination label
   1.128       */
   1.129      void _goto(final Label label) {
   1.130 -        debug("goto", label);
   1.131 +        //debug("goto", label);
   1.132          jump(GOTO, label, 0);
   1.133 -        stack = null;
   1.134 +        stack = null; //whoever reaches the point after us provides the stack, because we don't
   1.135      }
   1.136  
   1.137      /**
   1.138 @@ -1521,13 +1523,24 @@
   1.139      /**
   1.140       * A join in control flow - helper function that makes sure all entry stacks
   1.141       * discovered for the join point so far are equivalent
   1.142 -     * @param label
   1.143 +     *
   1.144 +     * MergeStack: we are about to enter a label. If its stack, label.getStack() is null
   1.145 +     * we have never been here before. Then we are expected to carry a stack with us.
   1.146 +     *
   1.147 +     * @param label label
   1.148       */
   1.149      private void mergeStackTo(final Label label) {
   1.150 +        //sometimes we can do a merge stack without having a stack - i.e. when jumping ahead to dead code
   1.151 +        //see NASHORN-73. So far we had been saved by the line number nodes. This should have been fixed
   1.152 +        //by Lower removing everything after an unconditionally executed terminating statement OR a break
   1.153 +        //or continue in a block. Previously code left over after breaks and continues was still there
   1.154 +        //and caused bytecode to be generated - which crashed on stack not being there, as the merge
   1.155 +        //was not in fact preceeded by a visit. Furthermore, this led to ASM putting out its NOP NOP NOP
   1.156 +        //ATHROW sequences instead of no code being generated at all. This should now be fixed.
   1.157 +        assert stack != null : label + " entered with no stack. deadcode that remains?";
   1.158 +
   1.159          final ArrayDeque<Type> labelStack = label.getStack();
   1.160 -        //debug(labelStack == null ? " >> Control flow - first visit ", label : " >> Control flow - JOIN with ", labelStack, " at ", label);
   1.161          if (labelStack == null) {
   1.162 -            assert stack != null;
   1.163              label.setStack(stack.clone());
   1.164              return;
   1.165          }
   1.166 @@ -1548,14 +1561,14 @@
   1.167          if (stack == null) {
   1.168              stack = label.getStack();
   1.169              if (stack == null) {
   1.170 -                stack = new ArrayDeque<>(); //we don't have a stack at this point.
   1.171 +                newStack();
   1.172              }
   1.173          }
   1.174          debug_label(label);
   1.175  
   1.176          mergeStackTo(label); //we have to merge our stack to whatever is in the label
   1.177  
   1.178 -        method.visitLabel(label);
   1.179 +        method.visitLabel(label.getLabel());
   1.180      }
   1.181  
   1.182      /**
   1.183 @@ -2018,8 +2031,13 @@
   1.184       * @param line  line number
   1.185       * @param label label
   1.186       */
   1.187 -    void lineNumber(final int line, final Label label) {
   1.188 -        method.visitLineNumber(line, label);
   1.189 +    void lineNumber(final int line) {
   1.190 +        if (env._debug_lines) {
   1.191 +            debug_label("[LINE]", line);
   1.192 +            final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label();
   1.193 +            method.visitLabel(l);
   1.194 +            method.visitLineNumber(line, l);
   1.195 +        }
   1.196      }
   1.197  
   1.198      /*
   1.199 @@ -2116,7 +2134,7 @@
   1.200                  pad--;
   1.201              }
   1.202  
   1.203 -            if (!stack.isEmpty()) {
   1.204 +            if (stack != null && !stack.isEmpty()) {
   1.205                  sb.append("{");
   1.206                  sb.append(stack.size());
   1.207                  sb.append(":");

mercurial