Example #1
0
  /**
   * Write the local variable table. The necessary constants have already been added to the constant
   * table by the collect() method. The flowFields method is used to determine which variables are
   * alive at each pc.
   */
  public void writeLocalVariableTable(
      Environment env, MemberDefinition field, DataOutputStream out, ConstantPool tab)
      throws IOException {
    MemberDefinition locals[] = new MemberDefinition[maxvar];
    int i = 0;

    // Initialize arguments
    if ((field != null) && (field.getArguments() != null)) {
      int reg = 0;
      Vector v = field.getArguments();
      for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
        MemberDefinition f = ((MemberDefinition) e.nextElement());
        locals[reg] = f;
        reg += f.getType().stackSize();
      }
    }

    flowFields(env, first, locals);
    LocalVariableTable lvtab = new LocalVariableTable();

    // Initialize arguments again
    for (i = 0; i < maxvar; i++) locals[i] = null;
    if ((field != null) && (field.getArguments() != null)) {
      int reg = 0;
      Vector v = field.getArguments();
      for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
        MemberDefinition f = ((MemberDefinition) e.nextElement());
        locals[reg] = f;
        lvtab.define(f, reg, 0, maxpc);
        reg += f.getType().stackSize();
      }
    }

    int pcs[] = new int[maxvar];

    for (Instruction inst = first; inst != null; inst = inst.next) {
      switch (inst.opc) {
        case opc_istore:
        case opc_istore_0:
        case opc_istore_1:
        case opc_istore_2:
        case opc_istore_3:
        case opc_fstore:
        case opc_fstore_0:
        case opc_fstore_1:
        case opc_fstore_2:
        case opc_fstore_3:
        case opc_astore:
        case opc_astore_0:
        case opc_astore_1:
        case opc_astore_2:
        case opc_astore_3:
        case opc_lstore:
        case opc_lstore_0:
        case opc_lstore_1:
        case opc_lstore_2:
        case opc_lstore_3:
        case opc_dstore:
        case opc_dstore_0:
        case opc_dstore_1:
        case opc_dstore_2:
        case opc_dstore_3:
          if (inst.value instanceof LocalVariable) {
            LocalVariable v = (LocalVariable) inst.value;
            int pc = (inst.next != null) ? inst.next.pc : inst.pc;
            if (locals[v.slot] != null) {
              lvtab.define(locals[v.slot], v.slot, pcs[v.slot], pc);
            }
            pcs[v.slot] = pc;
            locals[v.slot] = v.field;
          }
          break;

        case opc_label:
          {
            // flush  previous labels
            for (i = 0; i < maxvar; i++) {
              if (locals[i] != null) {
                lvtab.define(locals[i], i, pcs[i], inst.pc);
              }
            }
            // init new labels
            int pc = inst.pc;
            MemberDefinition[] labelLocals = ((Label) inst).locals;
            if (labelLocals == null) { // unreachable code??
              for (i = 0; i < maxvar; i++) locals[i] = null;
            } else {
              System.arraycopy(labelLocals, 0, locals, 0, maxvar);
            }
            for (i = 0; i < maxvar; i++) {
              pcs[i] = pc;
            }
            break;
          }
      }
    }

    // flush  remaining labels
    for (i = 0; i < maxvar; i++) {
      if (locals[i] != null) {
        lvtab.define(locals[i], i, pcs[i], maxpc);
      }
    }

    // write the local variable table
    lvtab.write(env, out, tab);
  }
Example #2
0
  /**
   * Figure out when registers contain a legal value. This is done using a simple data flow
   * algorithm. This information is later used to generate the local variable table.
   */
  void flowFields(Environment env, Label lbl, MemberDefinition locals[]) {
    if (lbl.locals != null) {
      // Been here before. Erase any conflicts.
      MemberDefinition f[] = lbl.locals;
      for (int i = 0; i < maxvar; i++) {
        if (f[i] != locals[i]) {
          f[i] = null;
        }
      }
      return;
    }

    // Remember the set of active registers at this point
    lbl.locals = new MemberDefinition[maxvar];
    System.arraycopy(locals, 0, lbl.locals, 0, maxvar);

    MemberDefinition newlocals[] = new MemberDefinition[maxvar];
    System.arraycopy(locals, 0, newlocals, 0, maxvar);
    locals = newlocals;

    for (Instruction inst = lbl.next; inst != null; inst = inst.next) {
      switch (inst.opc) {
        case opc_istore:
        case opc_istore_0:
        case opc_istore_1:
        case opc_istore_2:
        case opc_istore_3:
        case opc_fstore:
        case opc_fstore_0:
        case opc_fstore_1:
        case opc_fstore_2:
        case opc_fstore_3:
        case opc_astore:
        case opc_astore_0:
        case opc_astore_1:
        case opc_astore_2:
        case opc_astore_3:
        case opc_lstore:
        case opc_lstore_0:
        case opc_lstore_1:
        case opc_lstore_2:
        case opc_lstore_3:
        case opc_dstore:
        case opc_dstore_0:
        case opc_dstore_1:
        case opc_dstore_2:
        case opc_dstore_3:
          if (inst.value instanceof LocalVariable) {
            LocalVariable v = (LocalVariable) inst.value;
            locals[v.slot] = v.field;
          }
          break;

        case opc_label:
          flowFields(env, (Label) inst, locals);
          return;

        case opc_ifeq:
        case opc_ifne:
        case opc_ifgt:
        case opc_ifge:
        case opc_iflt:
        case opc_ifle:
        case opc_if_icmpeq:
        case opc_if_icmpne:
        case opc_if_icmpgt:
        case opc_if_icmpge:
        case opc_if_icmplt:
        case opc_if_icmple:
        case opc_if_acmpeq:
        case opc_if_acmpne:
        case opc_ifnull:
        case opc_ifnonnull:
        case opc_jsr:
          flowFields(env, (Label) inst.value, locals);
          break;

        case opc_goto:
          flowFields(env, (Label) inst.value, locals);
          return;

        case opc_return:
        case opc_ireturn:
        case opc_lreturn:
        case opc_freturn:
        case opc_dreturn:
        case opc_areturn:
        case opc_athrow:
        case opc_ret:
          return;

        case opc_tableswitch:
        case opc_lookupswitch:
          {
            SwitchData sw = (SwitchData) inst.value;
            flowFields(env, sw.defaultLabel, locals);
            for (Enumeration e = sw.tab.elements(); e.hasMoreElements(); ) {
              flowFields(env, (Label) e.nextElement(), locals);
            }
            return;
          }

        case opc_try:
          {
            Vector catches = ((TryData) inst.value).catches;
            for (Enumeration e = catches.elements(); e.hasMoreElements(); ) {
              CatchData cd = (CatchData) e.nextElement();
              flowFields(env, cd.getLabel(), locals);
            }
            break;
          }
      }
    }
  }