Ejemplo n.º 1
0
  private void count(File f) throws FileNotFoundException, IOException {
    ProgramTokenizer tokenizer = new ProgramTokenizer(new FileReader(f));
    AgillaAssembler.getAssembler().expandMode(tokenizer);

    while (tokenizer.hasMoreInstructions()) {
      Instruction instr = tokenizer.nextInstruction();
      Integer count = (Integer) table.remove(instr);
      if (count == null) table.put(instr.opcode(), new Integer(1));
      else table.put(instr.opcode(), new Integer(count.intValue() + 1));
    }
  }
Ejemplo n.º 2
0
 private void markDeadInstructions() {
   Set<Instruction> instructionSet = Sets.newHashSet(instructions);
   for (Instruction instruction : mutableInstructionList) {
     if (!instructionSet.contains(instruction)) {
       ((InstructionImpl) instruction).setMarkedAsDead(true);
       for (Instruction nextInstruction : instruction.getNextInstructions()) {
         nextInstruction.getPreviousInstructions().remove(instruction);
       }
     }
   }
 }
Ejemplo n.º 3
0
  /** Start the method's visit. */
  public void start() {
    if (!mg.isAbstract() && !mg.isNative()) {
      for (InstructionHandle ih = mg.getInstructionList().getStart();
          ih != null;
          ih = ih.getNext()) {
        Instruction i = ih.getInstruction();

        if (!visitInstruction(i)) i.accept(this);
      }
      updateExceptionHandlers();
    }
  }
Ejemplo n.º 4
0
Archivo: Macro.java Proyecto: bramk/bnd
  protected String replace(String key, Link link) {
    if (link != null && link.contains(key)) return "${infinite:" + link.toString() + "}";

    if (key != null) {
      key = key.trim();
      if (key.length() > 0) {
        Processor source = domain;
        String value = null;

        if (key.indexOf(';') < 0) {
          Instruction ins = new Instruction(key);
          if (!ins.isLiteral()) {
            SortedList<String> sortedList = SortedList.fromIterator(domain.iterator());
            StringBuilder sb = new StringBuilder();
            String del = "";
            for (String k : sortedList) {
              if (ins.matches(k)) {
                String v = replace(k, new Link(source, link, key));
                if (v != null) {
                  sb.append(del);
                  del = ",";
                  sb.append(v);
                }
              }
            }
            return sb.toString();
          }
        }
        while (value == null && source != null) {
          value = source.getProperties().getProperty(key);
          source = source.getParent();
        }

        if (value != null) return process(value, new Link(source, link, key));

        value = doCommands(key, link);
        if (value != null) return process(value, new Link(source, link, key));

        if (key != null && key.trim().length() > 0) {
          value = System.getProperty(key);
          if (value != null) return value;
        }
        if (!flattening && !key.equals("@"))
          domain.warning("No translation found for macro: " + key);
      } else {
        domain.warning("Found empty macro key");
      }
    } else {
      domain.warning("Found null macro key");
    }
    return "${" + key + "}";
  }
Ejemplo n.º 5
0
  @NotNull
  protected DfaInstructionState[] acceptInstruction(
      @NotNull InstructionVisitor visitor, @NotNull DfaInstructionState instructionState) {
    Instruction instruction = instructionState.getInstruction();
    PsiElement closure = DfaUtil.getClosureInside(instruction);
    if (closure instanceof PsiClass) {
      registerNestedClosures(instructionState, (PsiClass) closure);
    } else if (closure instanceof PsiLambdaExpression) {
      registerNestedClosures(instructionState, (PsiLambdaExpression) closure);
    }

    return instruction.accept(this, instructionState.getMemoryState(), visitor);
  }
Ejemplo n.º 6
0
  public void writeSequence(Instruction _first, Instruction _last) throws CodeGenException {

    for (Instruction instruction = _first;
        instruction != _last;
        instruction = instruction.getNextExpr()) {
      if (instruction instanceof CompositeInstruction) {
        writeComposite((CompositeInstruction) instruction);
      } else if (!instruction.getByteCode().equals(ByteCode.NONE)) {
        newLine();
        writeInstruction(instruction);
        write(";");
      }
    }
  }
Ejemplo n.º 7
0
  CFG createCFG(String className) throws ClassNotFoundException {
    CFG cfg = new CFG();
    JavaClass jc = Repository.lookupClass(className);
    ClassGen cg = new ClassGen(jc);
    ConstantPoolGen cpg = cg.getConstantPool();
    for (Method m : cg.getMethods()) {
      MethodGen mg = new MethodGen(m, cg.getClassName(), cpg);
      InstructionList il = mg.getInstructionList();
      InstructionHandle[] handles = il.getInstructionHandles();
      int prev = 0;
      for (InstructionHandle ih : handles) {
        int position = ih.getPosition();
        cfg.addNode(position, m, jc);
        Instruction inst = ih.getInstruction();

        boolean br = inst.getName().contains("if") || inst.getName().contains("goto");
        boolean ret = inst.getName().contains("return");
        boolean stat = inst.getName().contains("invokestatic");
        int len = inst.getLength();

        if (stat) {
          int index = inst.toString(true).indexOf(" ");
          String name = inst.toString(true).substring(index + 1);
          int tar = Integer.valueOf(name);
          INVOKESTATIC inv = new INVOKESTATIC(tar);
          name = inv.getMethodName(cpg);

          Method m2 = null;
          Method[] tm = cg.getMethods();
          for (int i = 0; i < tm.length; i++) {
            if (tm[i].getName().equals(name)) {
              m2 = tm[i];
            }
          }
          cfg.addEdge(position, m, jc, 0, m2, jc);
          cfg.addEdge(-1, m2, jc, position + len, m, jc);
        }

        if (!ret && !stat) {
          cfg.addEdge(position, position + len, m, jc);
        }
        if (br) {
          cfg.addEdge(position, position + len, m, jc);
          IF_ICMPGE comp = new IF_ICMPGE(ih);
          String name = comp.getTarget().toString(false);
          int index = name.indexOf(">");
          name = name.substring(index + 2);
          int tar = Integer.valueOf(name);
          cfg.addEdge(position, tar, m, jc);
        }
        if (ret) {
          cfg.addEdge(position, -1, m, jc);
        }

        prev = position;
      }
      System.out.println(cfg.toString());
    }
    return cfg;
  }
Ejemplo n.º 8
0
  /** Visit a single instruction. */
  private boolean visitInstruction(Instruction i) {
    short opcode = i.getOpcode();

    return ((InstructionConstants.INSTRUCTIONS[opcode] != null)
        && !(i instanceof ConstantPushInstruction)
        && !(i instanceof ReturnInstruction));
  }
Ejemplo n.º 9
0
 /**
  * Set the last {@link Instruction} for which this local is in scope. The instruction must already
  * be a part of the method. WARNING: if this instruction is deleted, the results are undefined.
  */
 public void setEnd(Instruction end) {
   if (end.getCode() != getCode())
     throw new IllegalArgumentException(
         "Instruction pointers and " + "targets must be part of the same code block.");
   _end = end;
   _length = -1;
 }
Ejemplo n.º 10
0
  public int ExecuteInstruction(Object inObject) {

    if (inObject instanceof Program) {
      Program p = (Program) inObject;

      if (_useFrames) {
        _execStack.push("frame.pop");
      }

      p.PushAllReverse(_execStack);

      if (_useFrames) {
        _execStack.push("frame.push");
      }

      return 0;
    }

    if (inObject instanceof Integer) {
      _intStack.push((Integer) inObject);
      return 0;
    }

    if (inObject instanceof Number) {
      _floatStack.push(((Number) inObject).floatValue());
      return 0;
    }

    if (inObject instanceof Instruction) {
      ((Instruction) inObject).Execute(this);
      return 0;
    }

    if (inObject instanceof String) {
      Instruction i = _instructions.get(inObject);

      if (i != null) {
        i.Execute(this);
      } else {
        _nameStack.push(inObject);
      }

      return 0;
    }

    return -1;
  }
  private void assemble() {
    if (sourceFile == null) {
      printError("-i : No source file specified");
    }

    if (assembler == null) {
      printError("-f : No format specified");
    }

    print("...Assembling " + sourceFile.getName());

    assembler.assemble(sourceFile);

    print("..." + assembler.getErrors().length + " error(s) found");

    try {
      PrintWriter output = null;

      if (!assembler.hasErrors()) {
        if (!machineCode) {
          print("...saving .pco file");

          output = new PrintWriter(new FileWriter(baseFileName + ".pco"));

          for (Instruction instruction : assembler.getInstructions()) {
            output.print(instruction.getInstruction());
            output.println(" ;" + instruction.getSourceCode());
          }
        } else {
          print("Machine code file varified");
        }
      } else {
        print("...saving .err file");

        output = new PrintWriter(new FileWriter(baseFileName + ".err"));
        for (AssemblyError error : assembler.getErrors()) {
          output.println(error.toString());
        }
      }

      if (output != null) {
        output.close();
      }
    } catch (IOException e) {
      printError(e.getMessage());
    }
  }
Ejemplo n.º 12
0
  private void handleStepOutOfLoop(
      @NotNull final Instruction prevInstruction,
      @NotNull Instruction nextInstruction,
      @NotNull final int[] loopNumber,
      @NotNull MultiMap<BranchingInstruction, DfaMemoryState> processedStates,
      @NotNull MultiMap<BranchingInstruction, DfaMemoryState> incomingStates,
      @NotNull List<DfaInstructionState> inFlightStates,
      @NotNull DfaInstructionState[] afterStates,
      @NotNull StateQueue queue) {
    if (loopNumber[prevInstruction.getIndex()] == 0
        || inSameLoop(prevInstruction, nextInstruction, loopNumber)) {
      return;
    }
    // stepped out of loop. destroy all memory states from the loop, we don't need them anymore

    // but do not touch yet states being handled right now
    for (DfaInstructionState state : inFlightStates) {
      Instruction instruction = state.getInstruction();
      if (inSameLoop(prevInstruction, instruction, loopNumber)) {
        return;
      }
    }
    for (DfaInstructionState state : afterStates) {
      Instruction instruction = state.getInstruction();
      if (inSameLoop(prevInstruction, instruction, loopNumber)) {
        return;
      }
    }
    // and still in queue
    if (!queue.processAll(
        new Processor<DfaInstructionState>() {
          @Override
          public boolean process(DfaInstructionState state) {
            Instruction instruction = state.getInstruction();
            return !inSameLoop(prevInstruction, instruction, loopNumber);
          }
        })) return;

    // now remove obsolete memory states
    final Set<BranchingInstruction> mayRemoveStatesFor = new THashSet<BranchingInstruction>();
    for (Instruction instruction : myInstructions) {
      if (inSameLoop(prevInstruction, instruction, loopNumber)
          && instruction instanceof BranchingInstruction) {
        mayRemoveStatesFor.add((BranchingInstruction) instruction);
      }
    }

    for (Instruction instruction : mayRemoveStatesFor) {
      processedStates.remove((BranchingInstruction) instruction);
      incomingStates.remove((BranchingInstruction) instruction);
    }
  }
Ejemplo n.º 13
0
  /*package*/ void addInstruction(Instruction instruction) {
    mutableInstructionList.add(instruction);
    instruction.setOwner(this);

    if (instruction instanceof KtElementInstruction) {
      KtElementInstruction elementInstruction = (KtElementInstruction) instruction;
      representativeInstructions.put(elementInstruction.getElement(), instruction);
    }

    if (instruction instanceof MergeInstruction) {
      addMergedValues((MergeInstruction) instruction);
    }

    for (PseudoValue inputValue : instruction.getInputValues()) {
      addValueUsage(inputValue, instruction);
      for (PseudoValue mergedValue : getMergedValues(inputValue)) {
        addValueUsage(mergedValue, instruction);
      }
    }
    if (PseudocodeUtilsKt.calcSideEffectFree(instruction)) {
      sideEffectFree.add(instruction);
    }
  }
Ejemplo n.º 14
0
  /**
   * Transforms invoke instructions that match the specified list for this class to call the
   * specified static call instead.
   */
  private InstructionList xform_inst(MethodGen mg, Instruction inst) {

    switch (inst.getOpcode()) {
      case Constants.INVOKESTATIC:
        {
          InstructionList il = new InstructionList();
          INVOKESTATIC is = (INVOKESTATIC) inst;
          String cname = is.getClassName(pgen);
          String mname = is.getMethodName(pgen);
          Type[] args = is.getArgumentTypes(pgen);
          MethodDef orig = new MethodDef(cname + "." + mname, args);
          MethodInfo call = method_map.get(orig);
          if (call != null) {
            call.cnt++;
            String classname = call.method_class;
            String methodname = mname;
            debug_map.log(
                "%s.%s: Replacing method %s.%s (%s) with %s.%s%n",
                mg.getClassName(),
                mg.getName(),
                cname,
                mname,
                UtilMDE.join(args, ", "),
                classname,
                methodname);
            il.append(
                ifact.createInvoke(
                    classname, methodname, is.getReturnType(pgen), args, Constants.INVOKESTATIC));
          }
          return (il);
        }

      case Constants.INVOKEVIRTUAL:
        {
          InstructionList il = new InstructionList();
          INVOKEVIRTUAL iv = (INVOKEVIRTUAL) inst;
          String cname = iv.getClassName(pgen);
          String mname = iv.getMethodName(pgen);
          Type[] args = iv.getArgumentTypes(pgen);
          Type instance_type = iv.getReferenceType(pgen);
          Type[] new_args = BCELUtil.insert_type(instance_type, args);
          MethodDef orig = new MethodDef(cname + "." + mname, args);
          if (debug_class) System.out.printf("looking for %s in map %s%n", orig, method_map);
          MethodInfo call = method_map.get(orig);
          if (call != null) {
            call.cnt++;
            String classname = call.method_class;
            String methodname = mname;
            debug_map.log(
                "Replacing method %s.%s (%s) with %s.%s%n",
                cname, mname, ArraysMDE.toString(args), classname, methodname);
            il.append(
                ifact.createInvoke(
                    classname,
                    methodname,
                    iv.getReturnType(pgen),
                    new_args,
                    Constants.INVOKESTATIC));
          }
          return (il);
        }

      default:
        return (null);
    }
  }
Ejemplo n.º 15
0
  public static void main(String args[]) throws IOException {
    List<Instruction> insns = Instructions.getInstructions();
    Collections.sort(insns);

    List<Character> startLetters = new java.util.ArrayList<Character>();
    char last = 0;
    for (int i = 0; i < insns.size(); i++) {
      Instruction insn = (Instruction) insns.get(i);
      char leadChar = insn.getName().charAt(0);
      if (last != leadChar) {
        startLetters.add(leadChar);
        last = leadChar;
      }
    }

    File docdir = new File("SquawkBytecodeSpec");
    Build.mkdir(docdir);

    PrintWriter out = null;
    out = new PrintWriter(new FileWriter(new File(docdir, "Instructions.doc.html")));

    out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">");
    out.println("<html>");
    out.println("<head>");
    out.println("<title>Squawk Bytecode Instruction Set</title>");
    out.println("</head>");
    out.println("<body BGCOLOR=#eeeeff text=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>");
    out.println("<table width=100%><tr>");
    out.print(
        "<td>Prev | <a href=\"Instructions2.doc1.html\">Next</a> | <a href=\"Instructions2.index.html\">Index</a> </td>");
    out.println("<td align=right><i><i>Squawk Bytecode Instruction Set</i></i></td>");
    out.println("</tr></table>");
    out.println();
    out.println("<hr><br>");
    out.println();
    for (int i = 0; i < startLetters.size(); i++) {
      Character c = (Character) startLetters.get(i);
      out.println(
          "<a href=\"Instructions2.doc"
              + (i + 1)
              + ".html\">"
              + Character.toUpperCase(c.charValue())
              + "</a>");
    }
    out.println();
    out.println("<hr><br>");
    out.println();
    out.println("<h1>Squawk Bytecode Instruction Set</h1>");
    out.println("<hr><p>");
    out.println("A Squawk bytecode instruction consists of an opcode specifying the operation");
    out.println(
        "to be performed, followed by zero or more operands embodying values to be operated");
    out.println("upon. This chapter gives details about the format of each Squawk bytecode");
    out.println("instruction and the operation it performs.</p>");
    out.println("<hr>");

    out.println("<p>Prev | <a href=\"Instructions2.doc1.html\">Next</a></p>");
    out.println("</body></html>");

    out.close();

    PrintWriter indexPage =
        new PrintWriter(new FileWriter(new File(docdir, "Instructions2.index.html")));
    indexPage.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">");
    indexPage.println("<html>");
    indexPage.println("<head>");
    indexPage.println("<title>Squawk Bytecode Instruction Set</title>");
    indexPage.println("</head>");
    indexPage.println(
        "<body BGCOLOR=#eeeeff text=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>");
    indexPage.println("<table width=100%><tr>");
    indexPage.println("<td><a href=\"Instructions.doc.html\">Contents</a></td>");
    indexPage.println("<td align=right><i><i>Squawk Bytecode Instruction Set</i></i></td>");
    indexPage.println("</tr></table>");
    indexPage.println();
    indexPage.println("<hr><br>");
    indexPage.println();

    Iterator<Instruction> iter = insns.iterator();
    Instruction insn = (iter.hasNext()) ? iter.next() : null;
    for (int i = 0; i < startLetters.size(); i++) {
      String thisPage = "Instructions2.doc" + (i + 1) + ".html";
      String prevPage = "Instructions2.doc" + i + ".html";
      String nextPage = "Instructions2.doc" + (i + 2) + ".html";

      out = new PrintWriter(new FileWriter(new File(docdir, thisPage)));
      out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">");
      out.println("<html>");
      out.println("<head>");
      out.println("<title>Squawk Bytecode Instruction Descriptions</title>");
      out.println("</head>");
      out.println("<body BGCOLOR=#eeeeff text=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>");
      out.println("<table width=100%><tr>");
      out.print("<td>");
      out.print(" <a href=\"Instructions.doc.html\">Contents</a> | ");
      if (i > 0) out.print("<a href=\"" + prevPage + "\">Prev</a>");
      else out.print("<a href=\"Instructions.doc.html\">Prev</a>");
      out.print(" | ");
      if (i < startLetters.size() - 1) out.print("<a href=\"" + nextPage + "\">Next</a>");
      else out.print("Next");
      out.println(" | <a href=\"Instructions2.index.html\">Index</a> </td>");
      out.println("<td align=right><i><i>Squawk Bytecode Instruction Set</i></i></td>");
      out.println("</tr></table>");
      out.println();
      out.println("<hr><br>");
      out.println();
      for (int j = 0; j < startLetters.size(); j++) {
        Character c = (Character) startLetters.get(j);
        out.println(
            "<a href=\"Instructions2.doc"
                + (j + 1)
                + ".html\">"
                + Character.toUpperCase(c.charValue())
                + "</a>");
      }
      out.println();

      while (insn != null
          && Character.toUpperCase(insn.getName().charAt(0))
              == Character.toUpperCase(((Character) startLetters.get(i)).charValue())) {

        String name = insn.getName();
        indexPage.println("<a href=\"" + thisPage + "#" + name + "\">" + name + "</a><br>");

        out.println("<hr><a name=\"" + name + "\"><h2>" + name + "</h2>");

        out.println("<p><b>Operation</b></p>");
        out.println("<blockquote>");
        insn.printOperation(out);
        out.println("</blockquote>");

        out.println("<p><b>Format</b></p>");
        out.println("<blockquote>");
        insn.printFormat(out);
        out.println("</blockquote>");

        out.println("<p><b>Forms</b></p>");
        out.println("<blockquote>");
        insn.printForms(out);
        out.println("</blockquote>");

        out.println("<p><b>Operand Stack</b></p>");
        out.println("<blockquote>");
        insn.printOperandStack(out);
        out.println("</blockquote>");

        out.println("<p><b>Description</b></p>");
        out.println("<blockquote>");
        insn.printDescription(out);
        out.println("</blockquote>");

        if (insn.hasNotes()) {
          out.println("<p><b>Notes</b></p>");
          out.println("<blockquote>");
          insn.printNotes(out);
          out.println("</blockquote>");
        }

        insn = (iter.hasNext()) ? (Instruction) iter.next() : null;
      }

      out.println("<hr>");
      if (i > 0) out.print("<a href=\"Instructions2.doc" + i + ".html\">Prev</a>");
      else out.print("<a href=\"Instructions.doc.html\">Prev</a>");
      out.print(" | ");
      if (i < startLetters.size() - 1)
        out.print("<a href=\"Instructions2.doc" + (i + 2) + ".html\">Next</a>");
      else out.print("Next");
      out.println();
      out.println("</body></html>");

      out.flush();
      out.close();
    }

    indexPage.println("</body></html>");
    indexPage.close();

    for (int i = 0; i < 256; i++)
      if (!opcodes.contains(new Integer(i))) System.out.println("missing opcode: " + i);
  }
Ejemplo n.º 16
0
  public void writeInstruction(Instruction _instruction) throws CodeGenException {
    if (_instruction instanceof CompositeIfElseInstruction) {
      write("(");
      final Instruction lhs =
          writeConditional(((CompositeInstruction) _instruction).getBranchSet());
      write(")?");
      writeInstruction(lhs);
      write(":");
      writeInstruction(lhs.getNextExpr().getNextExpr());
    } else if (_instruction instanceof CompositeInstruction) {
      writeComposite((CompositeInstruction) _instruction);

    } else if (_instruction instanceof AssignToLocalVariable) {
      final AssignToLocalVariable assignToLocalVariable = (AssignToLocalVariable) _instruction;

      final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo();
      if (assignToLocalVariable.isDeclaration()) {
        final String descriptor = localVariableInfo.getVariableDescriptor();
        // Arrays always map to __global arrays
        if (descriptor.startsWith("[")) {
          write(" __global ");
        }
        write(convertType(descriptor, true));
      }
      if (localVariableInfo == null) {
        throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = ");
      } else {
        write(localVariableInfo.getVariableName() + " = ");
      }

      for (Instruction operand = _instruction.getFirstChild();
          operand != null;
          operand = operand.getNextExpr()) {
        writeInstruction(operand);
      }

    } else if (_instruction instanceof AssignToArrayElement) {
      final AssignToArrayElement arrayAssignmentInstruction = (AssignToArrayElement) _instruction;
      writeInstruction(arrayAssignmentInstruction.getArrayRef());
      write("[");
      writeInstruction(arrayAssignmentInstruction.getArrayIndex());
      write("]");
      write(" ");
      write(" = ");
      writeInstruction(arrayAssignmentInstruction.getValue());
    } else if (_instruction instanceof AccessArrayElement) {

      // we're getting an element from an array
      // if the array is a primitive then we just return the value
      // so the generated code looks like
      // arrayName[arrayIndex];
      // but if the array is an object, or multidimensional array, then we want to return
      // a pointer to our index our position in the array.  The code will look like
      // &(arrayName[arrayIndex * this->arrayNameLen_dimension]
      //
      final AccessArrayElement arrayLoadInstruction = (AccessArrayElement) _instruction;

      // object array, get address
      if (arrayLoadInstruction instanceof I_AALOAD) {
        write("(&");
      }
      writeInstruction(arrayLoadInstruction.getArrayRef());
      write("[");
      writeInstruction(arrayLoadInstruction.getArrayIndex());

      // object array, find the size of each object in the array
      // for 2D arrays, this size is the size of a row.
      if (arrayLoadInstruction instanceof I_AALOAD) {
        int dim = 0;
        Instruction load = arrayLoadInstruction.getArrayRef();
        while (load instanceof I_AALOAD) {
          load = load.getFirstChild();
          dim++;
        }

        String arrayName =
            ((AccessInstanceField) load)
                .getConstantPoolFieldEntry()
                .getNameAndTypeEntry()
                .getNameUTF8Entry()
                .getUTF8();
        write(" * this->" + arrayName + arrayDimMangleSuffix + dim);
      }

      write("]");

      // object array, close parentheses
      if (arrayLoadInstruction instanceof I_AALOAD) {
        write(")");
      }
    } else if (_instruction instanceof AccessField) {
      final AccessField accessField = (AccessField) _instruction;
      if (accessField instanceof AccessInstanceField) {
        Instruction accessInstanceField = ((AccessInstanceField) accessField).getInstance();
        if (accessInstanceField instanceof CloneInstruction) {
          accessInstanceField = ((CloneInstruction) accessInstanceField).getReal();
        }
        if (!(accessInstanceField instanceof I_ALOAD_0)) {
          writeInstruction(accessInstanceField);
          write(".");
        } else {
          writeThisRef();
        }
      }
      write(
          accessField
              .getConstantPoolFieldEntry()
              .getNameAndTypeEntry()
              .getNameUTF8Entry()
              .getUTF8());

    } else if (_instruction instanceof I_ARRAYLENGTH) {

      // getting the length of an array.
      // if this is a primitive array, then this is trivial
      // if we're getting an object array, then we need to find what dimension
      // we're looking at
      int dim = 0;
      Instruction load = _instruction.getFirstChild();
      while (load instanceof I_AALOAD) {
        load = load.getFirstChild();
        dim++;
      }
      final AccessInstanceField child = (AccessInstanceField) load;
      final String arrayName =
          child.getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry().getUTF8();
      write("this->" + arrayName + arrayLengthMangleSuffix + dim);
    } else if (_instruction instanceof AssignToField) {
      final AssignToField assignedField = (AssignToField) _instruction;

      if (assignedField instanceof AssignToInstanceField) {
        final Instruction accessInstanceField =
            ((AssignToInstanceField) assignedField).getInstance().getReal();

        if (!(accessInstanceField instanceof I_ALOAD_0)) {
          writeInstruction(accessInstanceField);
          write(".");
        } else {
          writeThisRef();
        }
      }
      write(
          assignedField
              .getConstantPoolFieldEntry()
              .getNameAndTypeEntry()
              .getNameUTF8Entry()
              .getUTF8());
      write("=");
      writeInstruction(assignedField.getValueToAssign());
    } else if (_instruction instanceof Constant<?>) {
      final Constant<?> constantInstruction = (Constant<?>) _instruction;
      final Object value = constantInstruction.getValue();

      if (value instanceof Float) {

        final Float f = (Float) value;
        if (f.isNaN()) {
          write("NAN");
        } else if (f.isInfinite()) {
          if (f < 0) {
            write("-");
          }
          write("INFINITY");
        } else {
          write(value.toString());
          write("f");
        }
      } else if (value instanceof Double) {

        final Double d = (Double) value;
        if (d.isNaN()) {
          write("NAN");
        } else if (d.isInfinite()) {
          if (d < 0) {
            write("-");
          }
          write("INFINITY");
        } else {
          write(value.toString());
        }
      } else {
        write(value.toString());
        if (value instanceof Long) {
          write("L");
        }
      }

    } else if (_instruction instanceof AccessLocalVariable) {
      final AccessLocalVariable localVariableLoadInstruction = (AccessLocalVariable) _instruction;
      final LocalVariableInfo localVariable = localVariableLoadInstruction.getLocalVariableInfo();
      write(localVariable.getVariableName());
    } else if (_instruction instanceof I_IINC) {
      final I_IINC location = (I_IINC) _instruction;
      final LocalVariableInfo localVariable = location.getLocalVariableInfo();
      final int adjust = location.getAdjust();

      write(localVariable.getVariableName());
      if (adjust == 1) {
        write("++");
      } else if (adjust == -1) {
        write("--");
      } else if (adjust > 1) {
        write("+=" + adjust);
      } else if (adjust < -1) {
        write("-=" + (-adjust));
      }
    } else if (_instruction instanceof BinaryOperator) {
      final BinaryOperator binaryInstruction = (BinaryOperator) _instruction;
      final Instruction parent = binaryInstruction.getParentExpr();
      boolean needsParenthesis = true;

      if (parent instanceof AssignToLocalVariable) {
        needsParenthesis = false;
      } else if (parent instanceof AssignToField) {
        needsParenthesis = false;
      } else if (parent instanceof AssignToArrayElement) {
        needsParenthesis = false;
      } else {
        /**
         * if (parent instanceof BinaryOperator) { BinaryOperator parentBinaryOperator =
         * (BinaryOperator) parent; if (parentBinaryOperator.getOperator().ordinal() >
         * binaryInstruction.getOperator().ordinal()) { needsParenthesis = false; } }
         */
      }

      if (needsParenthesis) {
        write("(");
      }

      writeInstruction(binaryInstruction.getLhs());

      write(" " + binaryInstruction.getOperator().getText() + " ");
      writeInstruction(binaryInstruction.getRhs());

      if (needsParenthesis) {
        write(")");
      }

    } else if (_instruction instanceof CastOperator) {
      final CastOperator castInstruction = (CastOperator) _instruction;
      //  write("(");
      write(convertCast(castInstruction.getOperator().getText()));

      writeInstruction(castInstruction.getUnary());
      //    write(")");
    } else if (_instruction instanceof UnaryOperator) {
      final UnaryOperator unaryInstruction = (UnaryOperator) _instruction;
      //   write("(");
      write(unaryInstruction.getOperator().getText());

      writeInstruction(unaryInstruction.getUnary());
      //   write(")");
    } else if (_instruction instanceof Return) {

      final Return ret = (Return) _instruction;
      write("return");
      if (ret.getStackConsumeCount() > 0) {
        write("(");
        writeInstruction(ret.getFirstChild());
        write(")");
      }

    } else if (_instruction instanceof MethodCall) {
      final MethodCall methodCall = (MethodCall) _instruction;

      final MethodEntry methodEntry = methodCall.getConstantPoolMethodEntry();

      writeMethod(methodCall, methodEntry);
    } else if (_instruction.getByteCode().equals(ByteCode.CLONE)) {
      final CloneInstruction cloneInstruction = (CloneInstruction) _instruction;
      writeInstruction(cloneInstruction.getReal());
    } else if (_instruction.getByteCode().equals(ByteCode.INCREMENT)) {
      final IncrementInstruction incrementInstruction = (IncrementInstruction) _instruction;

      if (incrementInstruction.isPre()) {
        if (incrementInstruction.isInc()) {
          write("++");
        } else {
          write("--");
        }
      }

      writeInstruction(incrementInstruction.getFieldOrVariableReference());
      if (!incrementInstruction.isPre()) {
        if (incrementInstruction.isInc()) {
          write("++");
        } else {
          write("--");
        }
      }
    } else if (_instruction.getByteCode().equals(ByteCode.MULTI_ASSIGN)) {
      final MultiAssignInstruction multiAssignInstruction = (MultiAssignInstruction) _instruction;
      AssignToLocalVariable from = (AssignToLocalVariable) multiAssignInstruction.getFrom();
      final AssignToLocalVariable last = (AssignToLocalVariable) multiAssignInstruction.getTo();
      final Instruction common = multiAssignInstruction.getCommon();
      final Stack<AssignToLocalVariable> stack = new Stack<AssignToLocalVariable>();

      while (from != last) {
        stack.push(from);
        from = (AssignToLocalVariable) ((Instruction) from).getNextExpr();
      }

      for (AssignToLocalVariable alv = stack.pop();
          alv != null;
          alv = stack.size() > 0 ? stack.pop() : null) {

        final LocalVariableInfo localVariableInfo = alv.getLocalVariableInfo();
        if (alv.isDeclaration()) {
          write(convertType(localVariableInfo.getVariableDescriptor(), true));
        }
        if (localVariableInfo == null) {
          throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = ");
        } else {
          write(localVariableInfo.getVariableName() + " = ");
        }
      }
      writeInstruction(common);
    } else if (_instruction.getByteCode().equals(ByteCode.INLINE_ASSIGN)) {
      final InlineAssignInstruction inlineAssignInstruction =
          (InlineAssignInstruction) _instruction;
      final AssignToLocalVariable assignToLocalVariable =
          inlineAssignInstruction.getAssignToLocalVariable();

      final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo();
      if (assignToLocalVariable.isDeclaration()) {
        // this is bad! we need a general way to hoist up a required declaration
        throw new CodeGenException(
            "/* we can't declare this "
                + convertType(localVariableInfo.getVariableDescriptor(), true)
                + " here */");
      }
      write(localVariableInfo.getVariableName());
      write("=");
      writeInstruction(inlineAssignInstruction.getRhs());
    } else if (_instruction.getByteCode().equals(ByteCode.FIELD_ARRAY_ELEMENT_ASSIGN)) {
      final FieldArrayElementAssign inlineAssignInstruction =
          (FieldArrayElementAssign) _instruction;
      final AssignToArrayElement arrayAssignmentInstruction =
          inlineAssignInstruction.getAssignToArrayElement();

      writeInstruction(arrayAssignmentInstruction.getArrayRef());
      write("[");
      writeInstruction(arrayAssignmentInstruction.getArrayIndex());
      write("]");
      write(" ");
      write(" = ");

      writeInstruction(inlineAssignInstruction.getRhs());
    } else if (_instruction.getByteCode().equals(ByteCode.FIELD_ARRAY_ELEMENT_INCREMENT)) {

      final FieldArrayElementIncrement fieldArrayElementIncrement =
          (FieldArrayElementIncrement) _instruction;
      final AssignToArrayElement arrayAssignmentInstruction =
          fieldArrayElementIncrement.getAssignToArrayElement();
      if (fieldArrayElementIncrement.isPre()) {
        if (fieldArrayElementIncrement.isInc()) {
          write("++");
        } else {
          write("--");
        }
      }
      writeInstruction(arrayAssignmentInstruction.getArrayRef());

      write("[");
      writeInstruction(arrayAssignmentInstruction.getArrayIndex());
      write("]");
      if (!fieldArrayElementIncrement.isPre()) {
        if (fieldArrayElementIncrement.isInc()) {
          write("++");
        } else {
          write("--");
        }
      }

    } else if (_instruction.getByteCode().equals(ByteCode.NONE)) {
      // we are done
    } else if (_instruction instanceof Branch) {
      throw new CodeGenException(
          String.format(
              "%s -> %04d",
              _instruction.getByteCode().toString().toLowerCase(),
              ((Branch) _instruction).getTarget().getThisPC()));
    } else if (_instruction instanceof I_POP) {
      // POP discarded void call return?
      writeInstruction(_instruction.getFirstChild());
    } else {
      throw new CodeGenException(
          String.format("%s", _instruction.getByteCode().toString().toLowerCase()));
    }
  }
Ejemplo n.º 17
0
  public void writeConditionalBranch16(ConditionalBranch16 _branch16, boolean _invert)
      throws CodeGenException {

    if (_branch16 instanceof If) {
      final If iff = (If) _branch16;

      writeInstruction(iff.getLhs());
      write(_branch16.getOperator().getText(_invert));
      writeInstruction(iff.getRhs());
    } else if (_branch16 instanceof I_IFNULL) {
      final I_IFNULL iff = (I_IFNULL) _branch16;
      writeInstruction(iff.getFirstChild());

      if (_invert) {
        write(" != NULL");
      } else {
        write(" == NULL");
      }

    } else if (_branch16 instanceof I_IFNONNULL) {
      final I_IFNONNULL iff = (I_IFNONNULL) _branch16;
      writeInstruction(iff.getFirstChild());

      if (_invert) {
        write(" == NULL");
      } else {
        write(" != NULL");
      }
    } else if (_branch16 instanceof IfUnary) {
      final IfUnary branch16 = (IfUnary) _branch16;
      final Instruction comparison = branch16.getUnary();
      final ByteCode comparisonByteCode = comparison.getByteCode();
      final String comparisonOperator = _branch16.getOperator().getText(_invert);

      switch (comparisonByteCode) {
        case FCMPG:
        case DCMPG:
        case FCMPL:
        case DCMPL:
          if (Config.verboseComparitor) {
            write("/* bytecode=" + comparisonByteCode.getName() + " invert=" + _invert + "*/");
          }
          writeInstruction(comparison.getFirstChild());
          write(comparisonOperator);
          writeInstruction(comparison.getLastChild());
          break;
        default:
          if (Config.verboseComparitor) {
            write(
                "/* default bytecode="
                    + comparisonByteCode.getName()
                    + " invert="
                    + _invert
                    + "*/");
          }
          writeInstruction(comparison);
          write(comparisonOperator);
          write("0");
      }
    }
  }
Ejemplo n.º 18
0
  public void writeComposite(CompositeInstruction instruction) throws CodeGenException {
    if (instruction instanceof CompositeArbitraryScopeInstruction) {
      newLine();

      writeBlock(instruction.getFirstChild(), null);
    } else if (instruction instanceof CompositeIfInstruction) {
      newLine();
      write("if (");
      final Instruction blockStart = writeConditional(instruction.getBranchSet());

      write(")");
      writeBlock(blockStart, null);
    } else if (instruction instanceof CompositeIfElseInstruction) {
      newLine();
      write("if (");
      final Instruction blockStart = writeConditional(instruction.getBranchSet());
      write(")");
      Instruction elseGoto = blockStart;
      while (!(elseGoto.isBranch() && elseGoto.asBranch().isUnconditional())) {
        elseGoto = elseGoto.getNextExpr();
      }
      writeBlock(blockStart, elseGoto);
      write(" else ");
      writeBlock(elseGoto.getNextExpr(), null);
    } else if (instruction instanceof CompositeForSunInstruction) {
      newLine();
      write("for (");
      Instruction topBranch = instruction.getFirstChild();
      if (topBranch instanceof AssignToLocalVariable) {
        writeInstruction(topBranch);
        topBranch = topBranch.getNextExpr();
      }
      write("; ");
      final BranchSet branchSet = instruction.getBranchSet();
      final Instruction blockStart = writeConditional(branchSet);

      final Instruction lastGoto = instruction.getLastChild();

      if (branchSet.getFallThrough() == lastGoto) {
        // empty body no delta!
        write(";){}");
      } else {
        final Instruction delta = lastGoto.getPrevExpr();
        write("; ");
        if (!(delta instanceof CompositeInstruction)) {
          writeInstruction(delta);
          write(")");
          writeBlock(blockStart, delta);
        } else {
          write("){");
          in();
          writeSequence(blockStart, delta);

          newLine();
          writeSequence(delta, delta.getNextExpr());
          out();
          newLine();
          write("}");
        }
      }

    } else if (instruction instanceof CompositeWhileInstruction) {
      newLine();
      write("while (");
      final BranchSet branchSet = instruction.getBranchSet();
      final Instruction blockStart = writeConditional(branchSet);
      write(")");
      final Instruction lastGoto = instruction.getLastChild();
      writeBlock(blockStart, lastGoto);

    } else if (instruction instanceof CompositeEmptyLoopInstruction) {
      newLine();
      write("for (");
      Instruction topBranch = instruction.getFirstChild();
      if (topBranch instanceof AssignToLocalVariable) {
        writeInstruction(topBranch);
        topBranch = topBranch.getNextExpr();
      }
      write("; ");
      writeConditional(instruction.getBranchSet());
      write(";){}");

    } else if (instruction instanceof CompositeForEclipseInstruction) {
      newLine();
      write("for (");
      Instruction topGoto = instruction.getFirstChild();
      if (topGoto instanceof AssignToLocalVariable) {
        writeInstruction(topGoto);
        topGoto = topGoto.getNextExpr();
      }
      write("; ");
      Instruction last = instruction.getLastChild();
      while (last.getPrevExpr().isBranch()) {
        last = last.getPrevExpr();
      }
      writeConditional(instruction.getBranchSet(), true);
      write("; ");
      final Instruction delta = last.getPrevExpr();
      if (!(delta instanceof CompositeInstruction)) {
        writeInstruction(delta);
        write(")");
        writeBlock(topGoto.getNextExpr(), delta);
      } else {
        write("){");
        in();
        writeSequence(topGoto.getNextExpr(), delta);

        newLine();
        writeSequence(delta, delta.getNextExpr());
        out();
        newLine();
        write("}");
      }

    } else if (instruction instanceof CompositeDoWhileInstruction) {
      newLine();
      write("do");
      Instruction blockStart = instruction.getFirstChild();
      Instruction blockEnd = instruction.getLastChild();
      writeBlock(blockStart, blockEnd);
      write("while(");
      writeConditional(((CompositeInstruction) instruction).getBranchSet(), true);
      write(");");
      newLine();
    }
  }
Ejemplo n.º 19
0
  /**
   * Adds all the constants found in the given class into the given ConstantSet, and returns it.
   *
   * @see #getConstants(String)
   */
  public static ConstantSet getConstants(String classname, ConstantSet result) {

    ClassParser cp;
    JavaClass jc;
    try {
      String classfileBase = classname.replace('.', '/');
      InputStream is = ClassPath.SYSTEM_CLASS_PATH.getInputStream(classfileBase, ".class");
      cp = new ClassParser(is, classname);
      jc = cp.parse();
    } catch (java.io.IOException e) {
      throw new Error("IOException while reading '" + classname + "': " + e.getMessage());
    }
    result.classname = jc.getClassName();

    // Get all of the constants from the pool
    ConstantPool constant_pool = jc.getConstantPool();
    for (Constant c : constant_pool.getConstantPool()) {
      // System.out.printf ("*Constant = %s%n", c);
      if (c == null
          || c instanceof ConstantClass
          || c instanceof ConstantFieldref
          || c instanceof ConstantInterfaceMethodref
          || c instanceof ConstantMethodref
          || c instanceof ConstantNameAndType
          || c instanceof ConstantUtf8) {
        continue;
      }
      if (c instanceof ConstantString) {
        result.strings.add((String) ((ConstantString) c).getConstantValue(constant_pool));
      } else if (c instanceof ConstantDouble) {
        result.doubles.add((Double) ((ConstantDouble) c).getConstantValue(constant_pool));
      } else if (c instanceof ConstantFloat) {
        result.floats.add((Float) ((ConstantFloat) c).getConstantValue(constant_pool));
      } else if (c instanceof ConstantInteger) {
        result.ints.add((Integer) ((ConstantInteger) c).getConstantValue(constant_pool));
      } else if (c instanceof ConstantLong) {
        result.longs.add((Long) ((ConstantLong) c).getConstantValue(constant_pool));
      } else {
        throw new RuntimeException("Unrecognized constant of type " + c.getClass() + ": " + c);
      }
    }

    ClassGen gen = new ClassGen(jc);
    ConstantPoolGen pool = gen.getConstantPool();

    // Process the code in each method looking for literals
    for (Method m : jc.getMethods()) {
      MethodGen mg = new MethodGen(m, jc.getClassName(), pool);
      InstructionList il = mg.getInstructionList();
      if (il == null) {
        // System.out.println("No instructions for " + mg);
      } else {
        for (Instruction inst : il.getInstructions()) {
          switch (inst.getOpcode()) {

              // Compare two objects, no literals
            case Constants.IF_ACMPEQ:
            case Constants.IF_ACMPNE:
              break;

              // These instructions compare the integer on the top of the stack
              // to zero.  There are no literals here (except 0)
            case Constants.IFEQ:
            case Constants.IFNE:
            case Constants.IFLT:
            case Constants.IFGE:
            case Constants.IFGT:
            case Constants.IFLE:
              {
                break;
              }

              // Instanceof pushes either 0 or 1 on the stack depending on whether
              // the object on top of stack is of the specified type.
              // If were interested in class literals, this would be interesting
            case Constants.INSTANCEOF:
              break;

              // Duplicates the item on the top of stack.  No literal.
            case Constants.DUP:
              {
                break;
              }

              // Duplicates the item on the top of the stack and inserts it 2
              // values down in the stack.  No literals
            case Constants.DUP_X1:
              {
                break;
              }

              // Duplicates either the top 2 category 1 values or a single
              // category 2 value and inserts it 2 or 3 values down on the
              // stack.
            case Constants.DUP2_X1:
              {
                break;
              }

              // Duplicate either one category 2 value or two category 1 values.
            case Constants.DUP2:
              {
                break;
              }

              // Dup the category 1 value on the top of the stack and insert it either
              // two or three values down on the stack.
            case Constants.DUP_X2:
              {
                break;
              }

            case Constants.DUP2_X2:
              {
                break;
              }

              // Pop instructions discard the top of the stack.
            case Constants.POP:
              {
                break;
              }

              // Pops either the top 2 category 1 values or a single category 2 value
              // from the top of the stack.
            case Constants.POP2:
              {
                break;
              }

              // Swaps the two category 1 types on the top of the stack.
            case Constants.SWAP:
              {
                break;
              }

              // Compares two integers on the stack
            case Constants.IF_ICMPEQ:
            case Constants.IF_ICMPGE:
            case Constants.IF_ICMPGT:
            case Constants.IF_ICMPLE:
            case Constants.IF_ICMPLT:
            case Constants.IF_ICMPNE:
              {
                break;
              }

              // Get the value of a field
            case Constants.GETFIELD:
              {
                break;
              }

              // stores the top of stack into a field
            case Constants.PUTFIELD:
              {
                break;
              }

              // Pushes the value of a static field on the stack
            case Constants.GETSTATIC:
              {
                break;
              }

              // Pops a value off of the stack into a static field
            case Constants.PUTSTATIC:
              {
                break;
              }

              // pushes a local onto the stack
            case Constants.DLOAD:
            case Constants.DLOAD_0:
            case Constants.DLOAD_1:
            case Constants.DLOAD_2:
            case Constants.DLOAD_3:
            case Constants.FLOAD:
            case Constants.FLOAD_0:
            case Constants.FLOAD_1:
            case Constants.FLOAD_2:
            case Constants.FLOAD_3:
            case Constants.ILOAD:
            case Constants.ILOAD_0:
            case Constants.ILOAD_1:
            case Constants.ILOAD_2:
            case Constants.ILOAD_3:
            case Constants.LLOAD:
            case Constants.LLOAD_0:
            case Constants.LLOAD_1:
            case Constants.LLOAD_2:
            case Constants.LLOAD_3:
              {
                break;
              }

              // Pops a value off of the stack into a local
            case Constants.DSTORE:
            case Constants.DSTORE_0:
            case Constants.DSTORE_1:
            case Constants.DSTORE_2:
            case Constants.DSTORE_3:
            case Constants.FSTORE:
            case Constants.FSTORE_0:
            case Constants.FSTORE_1:
            case Constants.FSTORE_2:
            case Constants.FSTORE_3:
            case Constants.ISTORE:
            case Constants.ISTORE_0:
            case Constants.ISTORE_1:
            case Constants.ISTORE_2:
            case Constants.ISTORE_3:
            case Constants.LSTORE:
            case Constants.LSTORE_0:
            case Constants.LSTORE_1:
            case Constants.LSTORE_2:
            case Constants.LSTORE_3:
              {
                break;
              }

              // Push a value from the runtime constant pool.  We'll get these
              // values when processing the constant pool itself
            case Constants.LDC:
            case Constants.LDC_W:
            case Constants.LDC2_W:
              {
                break;
              }

              // Push the length of an array on the stack
            case Constants.ARRAYLENGTH:
              {
                break;
              }

              // Push small constants (-1..5) on the stack.  These literals are
              // too common to bother mentioning
            case Constants.DCONST_0:
            case Constants.DCONST_1:
            case Constants.FCONST_0:
            case Constants.FCONST_1:
            case Constants.FCONST_2:
            case Constants.ICONST_0:
            case Constants.ICONST_1:
            case Constants.ICONST_2:
            case Constants.ICONST_3:
            case Constants.ICONST_4:
            case Constants.ICONST_5:
            case Constants.ICONST_M1:
            case Constants.LCONST_0:
            case Constants.LCONST_1:
              {
                break;
              }

            case Constants.BIPUSH:
            case Constants.SIPUSH:
              {
                ConstantPushInstruction cpi = (ConstantPushInstruction) inst;
                result.ints.add((Integer) cpi.getValue());
                break;
              }

              // Primitive Binary operators.
            case Constants.DADD:
            case Constants.DCMPG:
            case Constants.DCMPL:
            case Constants.DDIV:
            case Constants.DMUL:
            case Constants.DREM:
            case Constants.DSUB:
            case Constants.FADD:
            case Constants.FCMPG:
            case Constants.FCMPL:
            case Constants.FDIV:
            case Constants.FMUL:
            case Constants.FREM:
            case Constants.FSUB:
            case Constants.IADD:
            case Constants.IAND:
            case Constants.IDIV:
            case Constants.IMUL:
            case Constants.IOR:
            case Constants.IREM:
            case Constants.ISHL:
            case Constants.ISHR:
            case Constants.ISUB:
            case Constants.IUSHR:
            case Constants.IXOR:
            case Constants.LADD:
            case Constants.LAND:
            case Constants.LCMP:
            case Constants.LDIV:
            case Constants.LMUL:
            case Constants.LOR:
            case Constants.LREM:
            case Constants.LSHL:
            case Constants.LSHR:
            case Constants.LSUB:
            case Constants.LUSHR:
            case Constants.LXOR:
              break;

            case Constants.LOOKUPSWITCH:
            case Constants.TABLESWITCH:
              break;

            case Constants.ANEWARRAY:
            case Constants.NEWARRAY:
              {
                break;
              }

            case Constants.MULTIANEWARRAY:
              {
                break;
              }

              // push the value at an index in an array
            case Constants.AALOAD:
            case Constants.BALOAD:
            case Constants.CALOAD:
            case Constants.DALOAD:
            case Constants.FALOAD:
            case Constants.IALOAD:
            case Constants.LALOAD:
            case Constants.SALOAD:
              {
                break;
              }

              // Pop the top of stack into an array location
            case Constants.AASTORE:
            case Constants.BASTORE:
            case Constants.CASTORE:
            case Constants.DASTORE:
            case Constants.FASTORE:
            case Constants.IASTORE:
            case Constants.LASTORE:
            case Constants.SASTORE:
              break;

            case Constants.ARETURN:
            case Constants.DRETURN:
            case Constants.FRETURN:
            case Constants.IRETURN:
            case Constants.LRETURN:
            case Constants.RETURN:
              {
                break;
              }

              // subroutine calls.
            case Constants.INVOKESTATIC:
            case Constants.INVOKEVIRTUAL:
            case Constants.INVOKESPECIAL:
            case Constants.INVOKEINTERFACE:
              break;

              // Throws an exception.
            case Constants.ATHROW:
              break;

              // Opcodes that don't need any modifications.  Here for reference
            case Constants.ACONST_NULL:
            case Constants.ALOAD:
            case Constants.ALOAD_0:
            case Constants.ALOAD_1:
            case Constants.ALOAD_2:
            case Constants.ALOAD_3:
            case Constants.ASTORE:
            case Constants.ASTORE_0:
            case Constants.ASTORE_1:
            case Constants.ASTORE_2:
            case Constants.ASTORE_3:
            case Constants.CHECKCAST:
            case Constants.D2F: // double to float
            case Constants.D2I: // double to integer
            case Constants.D2L: // double to long
            case Constants.DNEG: // Negate double on top of stack
            case Constants.F2D: // float to double
            case Constants.F2I: // float to integer
            case Constants.F2L: // float to long
            case Constants.FNEG: // Negate float on top of stack
            case Constants.GOTO:
            case Constants.GOTO_W:
            case Constants.I2B: // integer to byte
            case Constants.I2C: // integer to char
            case Constants.I2D: // integer to double
            case Constants.I2F: // integer to float
            case Constants.I2L: // integer to long
            case Constants.I2S: // integer to short
            case Constants.IFNONNULL:
            case Constants.IFNULL:
            case Constants.IINC: // increment local variable by a constant
            case Constants.INEG: // negate integer on top of stack
            case Constants.JSR: // pushes return address on the stack,
            case Constants.JSR_W:
            case Constants.L2D: // long to double
            case Constants.L2F: // long to float
            case Constants.L2I: // long to int
            case Constants.LNEG: // negate long on top of stack
            case Constants.MONITORENTER:
            case Constants.MONITOREXIT:
            case Constants.NEW:
            case Constants.NOP:
            case Constants.RET: // this is the internal JSR return
              break;

              // Make sure we didn't miss anything
            default:
              throw new Error("instruction " + inst + " unsupported");
          }
        }
      }
    }
    return result;
  }
Ejemplo n.º 20
0
  public void generate(String inputFileName) throws Exception {
    List<MetaClass> metaClasses = new ArrayList<>();
    List<LifeLine> lifeLines = new ArrayList<>();
    List<MethodInvocation> rootMessages = new ArrayList<>();
    MethodInvocation parentMessage = new MethodInvocation();
    GsonBuilder builder = new GsonBuilder();
    List<MethodInvocation> methodInvocations = new ArrayList<>();
    Package mainPackage = new Package();
    List<Guard> listOfGuards = new ArrayList<>();
    Map<Guard, Instruction> guardToCFMap = new HashMap<>();
    List<Instruction> combinedFragments = new ArrayList<Instruction>();
    List<Operation> operationsList = new ArrayList<>();

    builder.registerTypeAdapter(RefObject.class, new RefObjectJsonDeSerializer());
    Gson gson = builder.create();

    Element myTypes = gson.fromJson(new FileReader(inputFileName), Element.class);
    if (myTypes._type.equals("Project")) {
      List<Element> umlElements =
          myTypes
              .ownedElements
              .stream()
              .filter(f -> f._type.equals("UMLModel"))
              .collect(Collectors.toList());
      if (umlElements.size() > 0) { // There has be to atleast one UMLModel package
        Element element = umlElements.get(0);
        // package that the classes are supposed to be in
        mainPackage.setName(element.name);
        List<Element> umlPackages =
            element
                .ownedElements
                .stream()
                .filter(g -> g._type.equals("UMLPackage"))
                .collect(Collectors.toList());
        if (umlPackages.size()
            > 1) { // There has to be two packages- one for class one for behaviour
          Element classes = umlPackages.get(0);
          Element behaviour = umlPackages.get(1);
          // *--------------------------CLASSES-------------------------------*//
          // in the first pass, get all classes that are defined in the diagram
          // get details that can be directly inferred from the json like, fields and operations,
          // which do not refer to other classes
          for (Element umlClass : classes.getOwnedElements()) {
            MetaClass metaClass = new MetaClass(umlClass.name, umlClass._id);

            // check if class is interface or not because there is no distinction in json
            if (umlClass._type.equals("UMLClass")) {
              metaClass.setInterface(false);
            } else {
              metaClass.setInterface(true);
            }
            if (umlClass.operations != null) {
              metaClass.setOperations(umlClass.operations);
              operationsList.addAll(metaClass.operations);
            }
            if (umlClass.attributes != null) {
              metaClass.setFields(umlClass.attributes);
            }
            metaClasses.add(metaClass);
          }

          // in second pass, define associations and generalizations for these classes
          for (Element umlClass : classes.getOwnedElements()) {
            if (umlClass.ownedElements != null) {
              // find corresponding metaclass, then populate the secondary inferences
              List<MetaClass> correspondingMetaClassList =
                  metaClasses
                      .stream()
                      .filter(f -> f._id.equals(umlClass._id))
                      .collect(Collectors.toList());
              MetaClass correspondingMetaClass = correspondingMetaClassList.get(0);
              List<Element> umlAssociations =
                  umlClass
                      .ownedElements
                      .stream()
                      .filter(f -> f._type.equals("UMLAssociation"))
                      .collect(Collectors.toList());

              if (umlAssociations.size() > 0) {
                correspondingMetaClass.setAssociations(metaClasses, umlAssociations);
              }
              List<Element> umlGeneralization =
                  umlClass
                      .ownedElements
                      .stream()
                      .filter(f -> f._type.equals("UMLGeneralization"))
                      .collect(Collectors.toList());
              if (umlGeneralization.size() > 0) {
                correspondingMetaClass.setGeneralizations(metaClasses, umlGeneralization);
              }
              List<Element> umlRealization =
                  umlClass
                      .ownedElements
                      .stream()
                      .filter(f -> f._type.equals("UMLInterfaceRealization"))
                      .collect(Collectors.toList());
              if (umlRealization.size() > 0) {
                correspondingMetaClass.setInterfaceRealization(metaClasses, umlRealization);
              }
            }
          }

          // *--------------------------CLASSES-------------------------------*//

          // *-----------------------  BEHAVIOUR---------------------------------*//
          for (Element umlCollaboration : behaviour.getOwnedElements()) {
            // Role to Class mapping
            ArrayList<Element> attributes = umlCollaboration.attributes;
            HashMap<String, MetaClass> roleToClassMap = new HashMap<>();
            if (attributes != null) {
              for (Element attribute : attributes) {
                List<MetaClass> roleClass =
                    metaClasses
                        .stream()
                        .filter(f -> f._id.equals(attribute.type.$ref))
                        .collect(Collectors.toList());
                roleToClassMap.put(attribute._id, roleClass.get(0));
              }
            }

            for (Element umlInteraction : umlCollaboration.ownedElements) {

              // mapping lifelines to the classes they correspond
              ArrayList<Element> participants = umlInteraction.participants;
              if (participants != null && participants.size() > 0) {
                for (Element participant : participants) {
                  MetaClass participantClass = roleToClassMap.get(participant.represent.$ref);
                  LifeLine lifeLine = new LifeLine();
                  lifeLine.setName(participant.name);
                  lifeLine.setId(participant._id);
                  lifeLine.setMetaClass(participantClass);
                  lifeLines.add(lifeLine);
                }
              }
              // first parse all the combined fragments and get ready
              if (umlInteraction.fragments != null) {
                for (Element fragment :
                    umlInteraction.fragments) { // depending on the fragment set the class
                  Instruction instruction = null;
                  if (fragment.interactionOperator.equals("loop")) {
                    Loop loop = new Loop();
                    loop.setId(fragment._id);
                    loop.setWeight(0);
                    Guard guard = new Guard(fragment.operands.get(0)._id);
                    // loop can have only one condition--- one condition-- condition is made up of
                    // AND or OR's
                    guard.setCondition(fragment.operands.get(0).guard);
                    loop.setGuard(guard);
                    instruction = loop;
                    combinedFragments.add(loop);
                    listOfGuards.add(guard);
                    guardToCFMap.put(guard, loop);
                  }

                  if (fragment.interactionOperator.equals("alt")) {
                    Conditional c = new Conditional();
                    c.setId(fragment._id);
                    c.setWeight(0);
                    instruction = c;
                    combinedFragments.add(c);

                    Guard consequence = new Guard(fragment.operands.get(0)._id);
                    consequence.setCondition(fragment.operands.get(0).guard);
                    c.setCons(consequence);
                    listOfGuards.add(consequence);
                    guardToCFMap.put(consequence, c);
                    consequence.setConsequence(true);

                    if (fragment.operands.size() > 1) {
                      Guard alternate = new Guard(fragment.operands.get(1)._id);
                      alternate.setCondition(fragment.operands.get(1).guard);
                      c.setAlt(alternate);
                      listOfGuards.add(alternate);
                      guardToCFMap.put(alternate, c);
                      alternate.setAlternative(true);
                    }
                  }

                  if (fragment.tags != null) {
                    for (Element tag : fragment.tags) {
                      if (tag.name.equals("parent")) {
                        List<Instruction> instructionList =
                            combinedFragments
                                .stream()
                                .filter(e -> e.getId().equals(tag.reference.$ref))
                                .collect(Collectors.toList());
                        if (instructionList.size() > 0) {
                          instructionList.get(0).getBlock().add(instruction);
                          instruction.setParent(instructionList.get(0));
                        }
                      }
                    }
                  }
                }
              }

              // parsing the messages and make nodes out them to later build a tree from the
              // lifelines
              ArrayList<Element> messages = umlInteraction.messages;
              Element startMessage = messages.get(0);
              String sourceRef = startMessage.source.$ref;
              String targetRef = startMessage.target.$ref;
              Element endMessage = null;

              LifeLine sourceLifeLine = getLifeLine(lifeLines, sourceRef);
              LifeLine targetLifeLine = getLifeLine(lifeLines, targetRef);

              // First message processing
              parentMessage = new MethodInvocation();
              parentMessage.setAssignmentTarget(startMessage.assignmentTarget);
              parentMessage.setMessageSort(startMessage.messageSort);
              parentMessage.setSource(sourceLifeLine.getMetaClass());
              parentMessage.setTarget(targetLifeLine.getMetaClass());
              parentMessage.setName(startMessage.name);
              parentMessage.setId(startMessage._id);
              if (sourceLifeLine.getId().equals(targetLifeLine.getId())) {
                parentMessage.setCallerObject("this");
              } else {
                parentMessage.setCallerObject(targetLifeLine.getName());
              }
              int weight = 0;
              parentMessage.setWeight(weight++);
              if (startMessage.signature != null) {
                parentMessage.setSignature(startMessage.signature.$ref);
              }

              if (startMessage.tags != null) {
                for (Element tag : startMessage.tags) {
                  //                                    if (tag.name.equals("CF")) {
                  //                                        parentMessage.setInCF(true);
                  //
                  // parentMessage.setCfID(tag.reference.$ref);
                  //                                    }
                  if (tag.name.equals("operand")) {
                    parentMessage.setOperandId(tag.reference.$ref);
                  }
                }
              }

              MethodInvocation rootMessage = parentMessage;
              methodInvocations.add(rootMessage);
              rootMessages.add(rootMessage);
              Iterator<Element> iter = messages.iterator();
              while (iter.hasNext()) {
                if (iter.next() == endMessage) {
                  continue;
                }

                iter.remove();
                List<Element> childMessages = getChildMessages(messages, targetRef);
                for (Element child : childMessages) {

                  LifeLine childSource = getLifeLine(lifeLines, child.source.$ref);
                  LifeLine childTarget = getLifeLine(lifeLines, child.target.$ref);

                  MethodInvocation childMessage = new MethodInvocation();
                  childMessage.setMessageSort(child.messageSort);
                  childMessage.setSource(childSource.getMetaClass());
                  childMessage.setTarget(childTarget.getMetaClass());
                  childMessage.setAssignmentTarget(child.assignmentTarget);
                  childMessage.setName(child.name);
                  childMessage.setId(child._id);
                  childMessage.setWeight(weight++);
                  childMessage.setArguments(child.arguments);

                  if (childSource.getId().equals(childTarget.getId())) {
                    childMessage.setCallerObject("this");
                  } else {
                    childMessage.setCallerObject(childTarget.getName());
                  }

                  if (child.signature != null) {
                    childMessage.setSignature(child.signature.$ref);
                  }

                  if (child.tags != null) {
                    for (Element tag : child.tags) {
                      //                                            if (tag.name.equals("CF")) {
                      //                                                childMessage.setInCF(true);
                      //
                      // childMessage.setCfID(tag.reference.$ref);
                      //                                            }
                      if (tag.name.equals("operand")) {
                        childMessage.setOperandId(tag.reference.$ref);
                      }
                    }
                  }

                  parentMessage.childNodes.add(childMessage);
                  methodInvocations.add(childMessage);
                }

                if (childMessages.size() > 0) {
                  List<MethodInvocation> nextMessage =
                      parentMessage
                          .childNodes
                          .stream()
                          .filter(f -> !f.source.equals(f.target))
                          .collect(Collectors.toList());
                  List<Element> startMessageNext =
                      childMessages
                          .stream()
                          .filter(f -> !f.source.$ref.equals(f.target.$ref))
                          .collect(Collectors.toList());
                  startMessage = startMessageNext.get(0);
                  targetRef = startMessage.target.$ref;
                  sourceRef = startMessage.source.$ref;

                  parentMessage = nextMessage.get(0);

                  if (childMessages.size() > 1) {
                    endMessage = childMessages.get(childMessages.size() - 1);
                  }
                }
              }
            }

            for (MethodInvocation methodInvocation : methodInvocations) {
              List<Operation> matchingOperation =
                  operationsList
                      .stream()
                      .filter(f -> f._id.equals(methodInvocation.getSignature()))
                      .collect(Collectors.toList());
              if (matchingOperation.size() > 0) {
                operationMap.put(methodInvocation, matchingOperation.get(0)._id);
                methodInvocation.setOperation(matchingOperation.get(0));
              }
            }

            Stack stack = new Stack();
            for (MethodInvocation root : methodInvocations) {
              stack.push(root);
              while (!stack.empty()) {
                MethodInvocation methodInvocation = (MethodInvocation) stack.pop();
                Operation currentOperation = methodInvocation.getOperation();

                if (currentOperation != null) {
                  // all child nodes of this node make up its body
                  List<MethodInvocation> childNodes = methodInvocation.childNodes;
                  for (MethodInvocation child : childNodes) {
                    stack.push(child);
                  }
                  for (MethodInvocation childNode : childNodes) {
                    if (childNode.getOperandId() != null) {
                      List<Instruction> combinedFragmentsList =
                          combinedFragments
                              .stream()
                              .filter(f -> f.getId().equals(childNode.getCfID()))
                              .collect(Collectors.toList());

                      List<Guard> guardList =
                          listOfGuards
                              .stream()
                              .filter(f -> f.id.equals(childNode.getOperandId()))
                              .collect(Collectors.toList());

                      if (guardList.size() > 0) {
                        Guard currentGuard = guardList.get(0);
                        Instruction instruction = guardToCFMap.get(guardList.get(0));
                        // get the topmost CF if it is in a tree
                        Instruction parent = instruction.getParent();

                        while (instruction.getParent() != null) {
                          instruction = instruction.getParent();
                        }

                        if (currentGuard.isConsequence) {
                          Conditional conditional = (Conditional) instruction;
                          if (!conditional.getConsequence().contains(childNode)) {
                            conditional.getConsequence().add(childNode);
                          }
                        }
                        if (currentGuard.isAlternative) {
                          Conditional conditional = (Conditional) instruction;
                          if (!conditional.getAlternative().contains(childNode)) {
                            conditional.getAlternative().add(childNode);
                          }
                        }
                        if (!currentGuard.isAlternative && !currentGuard.isConsequence) {
                          Loop loop = (Loop) instruction;
                          loop.getBlock().add(childNode);
                        } else {
                          if (!currentOperation.getBlock().contains(instruction)) {
                            currentOperation.getBlock().add(instruction);
                          }
                        }
                      }
                    } else {
                      if (!currentOperation.getBlock().contains(childNode)) {
                        currentOperation.getBlock().add(childNode);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    //
    ////        printAllData(metaClasses);
    //        while (parentMessage.childNodes != null || parentMessage.childNodes.size() > 0) {
    //            System.out.println("parent " + parentMessage.name);
    //            for (com.cbpro.main.MethodInvocation child : parentMessage.childNodes) {
    //                System.out.println("child " + child.name);
    //            }
    //            if (parentMessage.childNodes.size() > 0) {
    //                parentMessage = parentMessage.childNodes.get(0);
    //            } else {
    //                break;
    //            }
    //        }

    mainPackage.print();
    File dir = new File("/home/ramyashenoy/Desktop/DemoFolder/" + mainPackage.getName());

    boolean successful = dir.mkdir();
    if (successful) {
      System.out.println("directory was created successfully");
      for (MetaClass metaClass : metaClasses) {
        if (metaClass.name.equals("Main")) {
          continue;
        } else {
          String data = metaClass.print();
          BufferedWriter out = null;
          try {
            FileWriter fstream =
                new FileWriter(
                    dir.getPath() + "/" + metaClass.name + ".java",
                    true); // true tells to append data.
            out = new BufferedWriter(fstream);
            out.write(data);
          } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
          } finally {
            if (out != null) {
              out.close();
            }
          }
        }
      }
    } else {
      // creating the directory failed
      System.out.println("failed trying to create the directory");
    }

    mainPackage.setClasses(metaClasses);
  }
Ejemplo n.º 21
0
 /** Get the number of bytes for which this local has a value in the code byte array. */
 public int getLength() {
   if (_end != null) return _end.getByteIndex() + _end.getLength() - _target.getByteIndex();
   return _length;
 }
Ejemplo n.º 22
0
 /**
  * Get the string representation of the specified assembly instruction assuming it is located at
  * the given address.
  *
  * @param addr a virtual address
  * @param instr an assembly instruction
  * @return a string representation of the assembly code at the given address
  */
 public String getInstructionString(AbsoluteAddress addr, Instruction instr) {
   if (instr == null) return "NON_EXISTENT";
   return instr.toString(addr.getValue(), symbolFinder(addr));
 }
Ejemplo n.º 23
0
  /**
   * Inserts residency/update/swizzle checks into a method. Iterates over the bytecodes in the
   * method and inserts the appropriate residency opcode.
   *
   * @param method The method to which to add checks.
   * @see MethodEditor#code
   */
  private static void transform(final MethodEditor method) {
    if (Main.VERBOSE > 1) {
      System.out.println("Decorating method " + method);
    }

    // Optimize initialization of arrays to speed things up.
    CompactArrayInitializer.transform(method);

    final ListIterator iter = method.code().listIterator();

    // Go through the code (Instructions and Labels) in the method
    INST:
    while (iter.hasNext()) {
      final Object ce = iter.next();

      if (Main.VERBOSE > 2) {
        System.out.println("Examining " + ce);
      }

      if (ce instanceof Instruction) {
        final Instruction inst = (Instruction) ce;

        int uctype = Main.NONE; // Type of update check (POINTER or
        // SCALAR)
        boolean insert_sc = false; // Insert swizzle check (aaload
        // only)?

        final int opc = inst.opcodeClass();
        int depth;

        switch (opc) {
          case opcx_arraylength:
          case opcx_athrow:
          case opcx_getfield:
          case opcx_instanceof:
            {
              depth = 0;
              break;
            }
          case opcx_iaload:
          case opcx_laload:
          case opcx_faload:
          case opcx_daload:
          case opcx_baload:
          case opcx_caload:
          case opcx_saload:
            {
              depth = 1;
              break;
            }
          case opcx_aaload:
            {
              depth = 1;
              insert_sc = true;
              break;
            }
          case opcx_iastore:
          case opcx_fastore:
          case opcx_aastore:
          case opcx_bastore:
          case opcx_castore:
          case opcx_sastore:
            {
              depth = 2;
              break;
            }
          case opcx_lastore:
          case opcx_dastore:
            {
              depth = 3;
              break;
            }
          case opcx_putfield:
            {
              final MemberRef ref = (MemberRef) inst.operand();
              depth = ref.type().stackHeight();
              if (ref.type().isReference()) {
                uctype = Main.POINTER;
              } else {
                uctype = Main.SCALAR;
              }
              break;
            }
          case opcx_invokevirtual:
          case opcx_invokespecial:
          case opcx_invokeinterface:
            {
              final MemberRef ref = (MemberRef) inst.operand();
              depth = ref.type().stackHeight();
              break;
            }
          case opcx_rc:
            {
              // Skip any existing residency checks.
              iter.remove();
              continue INST;
            }
          case opcx_aupdate:
            {
              // Skip any existing update checks.
              iter.remove();
              continue INST;
            }
          case opcx_supdate:
            {
              // Skip any existing update checks.
              iter.remove();
              continue INST;
            }
          default:
            {
              continue INST;
            }
        }

        Instruction addInst;

        // Insert a residency check...
        if (Main.RC) {
          Object t;

          // //////////////////////////////////
          // Before...
          // +-----+------+-----------+
          // | ... | inst | afterInst |
          // +-----+------+-----------+
          // ^prev ^next
          //
          // After...
          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next
          // //////////////////////////////////

          // +-----+------+-----------+
          // | ... | inst | afterInst |
          // +-----+------+-----------+
          // ^prev ^next

          t = iter.previous();
          Assert.isTrue(t == inst, t + " != " + inst);

          // +-----+------+-----------+
          // | ... | inst | afterInst |
          // +-----+------+-----------+
          // ^prev ^next

          addInst = new Instruction(Opcode.opcx_rc, new Integer(depth));
          iter.add(addInst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          t = iter.previous();
          Assert.isTrue(t == addInst, t + " != " + addInst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          t = iter.next();
          Assert.isTrue(t == addInst, t + " != " + addInst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          t = iter.next();
          Assert.isTrue(t == inst, t + " != " + inst);

          // +-----+----+------+-----------+
          // | ... | RC | inst | afterInst |
          // +-----+----+------+-----------+
          // ^prev ^next

          if (Main.VERBOSE > 2) {
            System.out.println("Inserting " + addInst + " before " + inst);
          }
        } else {
          if (Main.VERBOSE > 2) {
            System.out.println("Not inserting rc before " + inst);
          }
        }

        // Insert a swizzle check...
        if (insert_sc) {
          if (Main.SC) {
            Object t;

            // ////////////////////////////////////////////
            // Before...
            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next
            //
            // After...
            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next
            // /////////////////////////////////////////////

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            addInst = new Instruction(Opcode.opcx_dup2);
            iter.add(addInst);

            // +-----+------+------+-----------+
            // | ... | dup2 | inst | afterInst |
            // +-----+------+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+------+-----------+
            // | ... | dup2 | inst | afterInst |
            // +-----+------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+------+-----------+
            // | ... | dup2 | inst | afterInst |
            // +-----+------+------+-----------+
            // ^prev ^next

            addInst = new Instruction(Opcode.opcx_aswizzle);
            iter.add(addInst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+------+----------+------+-----------+
            // | ... | dup2 | aswizzle | inst | afterInst |
            // +-----+------+----------+------+-----------+
            // ^prev ^next

            if (Main.VERBOSE > 2) {
              System.out.println("Inserting dup2,aswizzle before " + inst);
            }
          } else {
            if (Main.VERBOSE > 2) {
              System.out.println("Not inserting aswizzle before " + inst);
            }
          }
        }

        // Insert an update check...
        if (uctype != Main.NONE) {
          if (Main.UC) {
            Object t;

            // ////////////////////////////////////////////
            // Before...
            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next
            //
            // After...
            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next
            // /////////////////////////////////////////////

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+------+-----------+
            // | ... | inst | afterInst |
            // +-----+------+-----------+
            // ^prev ^next

            addInst = new Instruction(Opcode.opcx_aupdate, new Integer(depth));
            /*
             * if (uctype == POINTER) { addInst = new
             * Instruction(opcx_aupdate, new Integer(depth)); } else {
             * addInst = new Instruction(opcx_supdate, new
             * Integer(depth)); }
             */

            iter.add(addInst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            t = iter.previous();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == addInst, t + " != " + addInst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            t = iter.next();
            Assert.isTrue(t == inst, t + " != " + inst);

            // +-----+---------+------+-----------+
            // | ... | aupdate | inst | afterInst |
            // +-----+---------+------+-----------+
            // ^prev ^next

            if (Main.VERBOSE > 2) {
              System.out.println("Inserting " + addInst + " before " + inst);
            }
          } else if (Main.VERBOSE > 2) {
            System.out.println("Not inserting uc before " + inst);
          }
        }
      }
    }
  }
Ejemplo n.º 24
0
  private void processInstruction(Instruction instruction, final int currentPosition) {
    instruction.accept(
        new InstructionVisitor() {
          @Override
          public void visitInstructionWithNext(@NotNull InstructionWithNext instruction) {
            instruction.setNext(getNextPosition(currentPosition));
          }

          @Override
          public void visitJump(@NotNull AbstractJumpInstruction instruction) {
            instruction.setResolvedTarget(getJumpTarget(instruction.getTargetLabel()));
          }

          @Override
          public void visitNondeterministicJump(
              @NotNull NondeterministicJumpInstruction instruction) {
            instruction.setNext(getNextPosition(currentPosition));
            List<Label> targetLabels = instruction.getTargetLabels();
            for (Label targetLabel : targetLabels) {
              instruction.setResolvedTarget(targetLabel, getJumpTarget(targetLabel));
            }
          }

          @Override
          public void visitConditionalJump(@NotNull ConditionalJumpInstruction instruction) {
            Instruction nextInstruction = getNextPosition(currentPosition);
            Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
            if (instruction.getOnTrue()) {
              instruction.setNextOnFalse(nextInstruction);
              instruction.setNextOnTrue(jumpTarget);
            } else {
              instruction.setNextOnFalse(jumpTarget);
              instruction.setNextOnTrue(nextInstruction);
            }
            visitJump(instruction);
          }

          @Override
          public void visitLocalFunctionDeclarationInstruction(
              @NotNull LocalFunctionDeclarationInstruction instruction) {
            PseudocodeImpl body = (PseudocodeImpl) instruction.getBody();
            body.setParent(PseudocodeImpl.this);
            body.postProcess();
            instruction.setNext(getSinkInstruction());
          }

          @Override
          public void visitSubroutineExit(@NotNull SubroutineExitInstruction instruction) {
            // Nothing
          }

          @Override
          public void visitSubroutineSink(@NotNull SubroutineSinkInstruction instruction) {
            // Nothing
          }

          @Override
          public void visitInstruction(@NotNull Instruction instruction) {
            throw new UnsupportedOperationException(instruction.toString());
          }
        });
  }
Ejemplo n.º 25
0
  @NotNull
  final RunnerResult analyzeMethod(
      @NotNull PsiElement psiBlock,
      @NotNull InstructionVisitor visitor,
      boolean ignoreAssertions,
      @NotNull Collection<DfaMemoryState> initialStates) {
    if (PsiTreeUtil.findChildOfType(psiBlock, OuterLanguageElement.class) != null)
      return RunnerResult.NOT_APPLICABLE;

    try {
      final ControlFlow flow =
          new ControlFlowAnalyzer(myValueFactory, psiBlock, ignoreAssertions).buildControlFlow();
      if (flow == null) return RunnerResult.NOT_APPLICABLE;
      int[] loopNumber = LoopAnalyzer.calcInLoop(flow);

      int endOffset = flow.getInstructionCount();
      myInstructions = flow.getInstructions();
      myNestedClosures.clear();

      Set<Instruction> joinInstructions = ContainerUtil.newHashSet();
      for (int index = 0; index < myInstructions.length; index++) {
        Instruction instruction = myInstructions[index];
        if (instruction instanceof GotoInstruction) {
          joinInstructions.add(myInstructions[((GotoInstruction) instruction).getOffset()]);
        } else if (instruction instanceof ConditionalGotoInstruction) {
          joinInstructions.add(
              myInstructions[((ConditionalGotoInstruction) instruction).getOffset()]);
        } else if (instruction instanceof MethodCallInstruction
            && !((MethodCallInstruction) instruction).getContracts().isEmpty()) {
          joinInstructions.add(myInstructions[index + 1]);
        }
      }

      if (LOG.isDebugEnabled()) {
        LOG.debug("Analyzing code block: " + psiBlock.getText());
        for (int i = 0; i < myInstructions.length; i++) {
          LOG.debug(i + ": " + myInstructions[i]);
        }
      }
      // for (int i = 0; i < myInstructions.length; i++) System.out.println(i + ": " +
      // myInstructions[i].toString());

      Integer tooExpensiveHash = psiBlock.getUserData(TOO_EXPENSIVE_HASH);
      if (tooExpensiveHash != null && tooExpensiveHash == psiBlock.getText().hashCode()) {
        LOG.debug("Too complex because hasn't changed since being too complex already");
        return RunnerResult.TOO_COMPLEX;
      }

      final StateQueue queue = new StateQueue();
      for (final DfaMemoryState initialState : initialStates) {
        queue.offer(new DfaInstructionState(myInstructions[0], initialState));
      }

      MultiMap<BranchingInstruction, DfaMemoryState> processedStates = MultiMap.createSet();
      MultiMap<BranchingInstruction, DfaMemoryState> incomingStates = MultiMap.createSet();

      long msLimit =
          shouldCheckTimeLimit()
              ? Registry.intValue("ide.dfa.time.limit.online")
              : Registry.intValue("ide.dfa.time.limit.offline");
      WorkingTimeMeasurer measurer = new WorkingTimeMeasurer(msLimit * 1000 * 1000);
      int count = 0;
      while (!queue.isEmpty()) {
        List<DfaInstructionState> states = queue.getNextInstructionStates(joinInstructions);
        for (DfaInstructionState instructionState : states) {
          if (count++ % 1024 == 0 && measurer.isTimeOver()) {
            LOG.debug("Too complex because the analysis took too long");
            psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode());
            return RunnerResult.TOO_COMPLEX;
          }
          ProgressManager.checkCanceled();

          if (LOG.isDebugEnabled()) {
            LOG.debug(instructionState.toString());
          }
          // System.out.println(instructionState.toString());

          Instruction instruction = instructionState.getInstruction();

          if (instruction instanceof BranchingInstruction) {
            BranchingInstruction branching = (BranchingInstruction) instruction;
            Collection<DfaMemoryState> processed = processedStates.get(branching);
            if (processed.contains(instructionState.getMemoryState())) {
              continue;
            }
            if (processed.size() > MAX_STATES_PER_BRANCH) {
              LOG.debug("Too complex because too many different possible states");
              return RunnerResult.TOO_COMPLEX; // Too complex :(
            }
            if (loopNumber[branching.getIndex()] != 0) {
              processedStates.putValue(branching, instructionState.getMemoryState().createCopy());
            }
          }

          DfaInstructionState[] after = acceptInstruction(visitor, instructionState);
          for (DfaInstructionState state : after) {
            Instruction nextInstruction = state.getInstruction();
            if (nextInstruction.getIndex() >= endOffset) {
              continue;
            }
            handleStepOutOfLoop(
                instruction,
                nextInstruction,
                loopNumber,
                processedStates,
                incomingStates,
                states,
                after,
                queue);
            if (nextInstruction instanceof BranchingInstruction) {
              BranchingInstruction branching = (BranchingInstruction) nextInstruction;
              if (processedStates.get(branching).contains(state.getMemoryState())
                  || incomingStates.get(branching).contains(state.getMemoryState())) {
                continue;
              }
              if (loopNumber[branching.getIndex()] != 0) {
                incomingStates.putValue(branching, state.getMemoryState().createCopy());
              }
            }
            queue.offer(state);
          }
        }
      }

      psiBlock.putUserData(TOO_EXPENSIVE_HASH, null);
      LOG.debug("Analysis ok");
      return RunnerResult.OK;
    } catch (ArrayIndexOutOfBoundsException e) {
      LOG.error(psiBlock.getText(), e);
      return RunnerResult.ABORTED;
    } catch (EmptyStackException e) {
      LOG.error(psiBlock.getText(), e);
      return RunnerResult.ABORTED;
    }
  }
Ejemplo n.º 26
0
 private static boolean inSameLoop(
     @NotNull Instruction prevInstruction,
     @NotNull Instruction nextInstruction,
     @NotNull int[] loopNumber) {
   return loopNumber[nextInstruction.getIndex()] == loopNumber[prevInstruction.getIndex()];
 }