Esempio n. 1
0
  public void visitLocalVariableTable(LocalVariableTable table) {
    table.accept(visitor);

    LocalVariable[] vars = table.getLocalVariableTable();
    for (int i = 0; i < vars.length; i++) vars[i].accept(this);
  }
Esempio n. 2
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);
  }
  /**
   * Called from {@link ClassFileReader#readClass(TypeReference,DataInputStream)} to create an
   * instance of a RVMMethod by reading the relevant data from the argument bytecode stream.
   *
   * @param declaringClass the TypeReference of the class being loaded
   * @param constantPool the constantPool of the RVMClass object that's being constructed
   * @param memRef the canonical memberReference for this member.
   * @param modifiers modifiers associated with this member.
   * @param input the DataInputStream to read the method's attributes from
   */
  static RVMMethod readMethod(
      TypeReference declaringClass,
      int[] constantPool,
      MemberReference memRef,
      short modifiers,
      DataInputStream input)
      throws IOException {
    short tmp_localWords = 0;
    short tmp_operandWords = 0;
    byte[] tmp_bytecodes = null;
    ExceptionHandlerMap tmp_exceptionHandlerMap = null;
    TypeReference[] tmp_exceptionTypes = null;
    int[] tmp_lineNumberMap = null;
    LocalVariableTable tmp_localVariableTable = null;
    Atom tmp_signature = null;
    RVMAnnotation[] annotations = null;
    RVMAnnotation[][] parameterAnnotations = null;
    Object tmp_annotationDefault = null;

    // Read the attributes
    for (int i = 0, n = input.readUnsignedShort(); i < n; i++) {
      Atom attName = ClassFileReader.getUtf(constantPool, input.readUnsignedShort());
      int attLength = input.readInt();

      // Only bother to interpret non-boring Method attributes
      if (attName == RVMClassLoader.codeAttributeName) {
        tmp_operandWords = input.readShort();
        tmp_localWords = input.readShort();
        tmp_bytecodes = new byte[input.readInt()];
        input.readFully(tmp_bytecodes);
        tmp_exceptionHandlerMap = ExceptionHandlerMap.readExceptionHandlerMap(input, constantPool);

        // Read the attributes portion of the code attribute
        for (int j = 0, n2 = input.readUnsignedShort(); j < n2; j++) {
          attName = ClassFileReader.getUtf(constantPool, input.readUnsignedShort());
          attLength = input.readInt();

          if (attName == RVMClassLoader.lineNumberTableAttributeName) {
            int cnt = input.readUnsignedShort();
            if (cnt != 0) {
              tmp_lineNumberMap = new int[cnt];
              for (int k = 0; k < cnt; k++) {
                int startPC = input.readUnsignedShort();
                int lineNumber = input.readUnsignedShort();
                tmp_lineNumberMap[k] = (lineNumber << BITS_IN_SHORT) | startPC;
              }
            }
          } else if (attName == RVMClassLoader.localVariableTableAttributeName) {
            tmp_localVariableTable = LocalVariableTable.readLocalVariableTable(input, constantPool);
          } else {
            // All other entries in the attribute portion of the code attribute are boring.
            int skippedAmount = input.skipBytes(attLength);
            if (skippedAmount != attLength) {
              throw new IOException("Unexpected short skip");
            }
          }
        }
      } else if (attName == RVMClassLoader.exceptionsAttributeName) {
        int cnt = input.readUnsignedShort();
        if (cnt != 0) {
          tmp_exceptionTypes = new TypeReference[cnt];
          for (int j = 0, m = tmp_exceptionTypes.length; j < m; ++j) {
            tmp_exceptionTypes[j] =
                ClassFileReader.getTypeRef(constantPool, input.readUnsignedShort());
          }
        }
      } else if (attName == RVMClassLoader.syntheticAttributeName) {
        modifiers |= ACC_SYNTHETIC;
      } else if (attName == RVMClassLoader.signatureAttributeName) {
        tmp_signature = ClassFileReader.getUtf(constantPool, input.readUnsignedShort());
      } else if (attName == RVMClassLoader.runtimeVisibleAnnotationsAttributeName) {
        annotations =
            AnnotatedElement.readAnnotations(constantPool, input, declaringClass.getClassLoader());
      } else if (attName == RVMClassLoader.runtimeVisibleParameterAnnotationsAttributeName) {
        int numParameters = input.readByte() & 0xFF;
        parameterAnnotations = new RVMAnnotation[numParameters][];
        for (int a = 0; a < numParameters; ++a) {
          parameterAnnotations[a] =
              AnnotatedElement.readAnnotations(
                  constantPool, input, declaringClass.getClassLoader());
        }
      } else if (attName == RVMClassLoader.annotationDefaultAttributeName) {
        try {
          tmp_annotationDefault =
              RVMAnnotation.readValue(
                  memRef.asMethodReference().getReturnType(),
                  constantPool,
                  input,
                  declaringClass.getClassLoader());
        } catch (ClassNotFoundException e) {
          throw new Error(e);
        }
      } else {
        // all other method attributes are boring
        int skippedAmount = input.skipBytes(attLength);
        if (skippedAmount != attLength) {
          throw new IOException("Unexpected short skip");
        }
      }
    }
    RVMMethod method;
    if ((modifiers & ACC_NATIVE) != 0) {
      method =
          new NativeMethod(
              declaringClass,
              memRef,
              modifiers,
              tmp_exceptionTypes,
              tmp_signature,
              annotations,
              parameterAnnotations,
              tmp_annotationDefault);
    } else if ((modifiers & ACC_ABSTRACT) != 0) {
      method =
          new AbstractMethod(
              declaringClass,
              memRef,
              modifiers,
              tmp_exceptionTypes,
              tmp_signature,
              annotations,
              parameterAnnotations,
              tmp_annotationDefault);

    } else {
      method =
          new NormalMethod(
              declaringClass,
              memRef,
              modifiers,
              tmp_exceptionTypes,
              tmp_localWords,
              tmp_operandWords,
              tmp_bytecodes,
              tmp_exceptionHandlerMap,
              tmp_lineNumberMap,
              tmp_localVariableTable,
              constantPool,
              tmp_signature,
              annotations,
              parameterAnnotations,
              tmp_annotationDefault);
    }
    return method;
  }
Esempio n. 4
0
 /**
  * Return the local variable object this instruction operates on, or null if none.
  *
  * @see LocalVariableTable#getLocalVariable(int)
  */
 public LocalVariable getLocalVariable() {
   LocalVariableTable table = getCode().getLocalVariableTable(false);
   if (table == null) return null;
   return table.getLocalVariable(getLocal());
 }