Пример #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));
    }
  }
Пример #2
0
  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 + "}";
  }
Пример #3
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;
 }
  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());
    }
  }
Пример #5
0
  /**
   * Read an instruction from (byte code) input stream and return the appropiate object.
   *
   * @param file file to read from
   * @return instruction object being read
   */
  public static final Instruction readInstruction(ByteSequence bytes) throws IOException {
    boolean wide = false;
    short opcode = (short) bytes.readUnsignedByte();
    Instruction obj = null;

    if (opcode == Constants.WIDE) { // Read next opcode after wide byte
      wide = true;
      opcode = (short) bytes.readUnsignedByte();
    }

    if (InstructionConstants.INSTRUCTIONS[opcode] != null)
      return InstructionConstants.INSTRUCTIONS[
          opcode]; // Used predefined immutable object, if available

    /* Find appropiate class, instantiate an (empty) instruction object
     * and initialize it by hand.
     */
    Class clazz;

    try {
      clazz = Class.forName(className(opcode));
    } catch (ClassNotFoundException cnfe) {
      // If a class by that name does not exist, the opcode is illegal.
      // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense.
      throw new ClassGenException("Illegal opcode detected.");
    }

    try {
      obj = (Instruction) clazz.newInstance();

      if (wide
          && !((obj instanceof LocalVariableInstruction)
              || (obj instanceof IINC)
              || (obj instanceof RET))) throw new Exception("Illegal opcode after wide: " + opcode);

      obj.setOpcode(opcode);
      obj.initFromFile(bytes, wide); // Do further initializations, if any
      // Byte code offset set in InstructionList
    } catch (Exception e) {
      throw new ClassGenException(e.toString());
    }

    return obj;
  }
Пример #6
0
  public void paint(Graphics g) {
    super.paint(g);
    if (screen.equalsIgnoreCase("title")) {
      MyPanel.score = 0;
      hs = new Highscore();
      c.removeAll();
      c.add(ts);
      panel = null;
      ts.revalidate();
    } else if (screen.equalsIgnoreCase("instructions")) {
      c.removeAll();
      c.add(instructions);
      instructions.revalidate();
    } else if (screen.equalsIgnoreCase("mode")) {
      c.removeAll();
      c.add(mode);
      mode.revalidate();
    } else if (screen.equalsIgnoreCase("difficulty")) {
      c.removeAll();
      c.add(dif);
      dif.revalidate();
    } else if (screen.equalsIgnoreCase("highscore")) {
      if (hs.returnCount() == 0) {
        c.removeAll();
        c.add(hs);
        c.validate();
      }
    } else if (screen.equalsIgnoreCase("gameover")) {
      if (!once) {
        c.removeAll();
        c.add(gg);
        once = true;
        c.validate();
      }

    } else {
      if (once) {
        c.removeAll();
        panel = new MyPanel(THA.WIDTH, THA.HEIGHT, ai, diff);
        c.setLayout(new BorderLayout());
        c.add(panel.returnNs(), BorderLayout.WEST);
        c.add(panel, BorderLayout.CENTER);
        c.add(btns, BorderLayout.SOUTH);
        c.add(panel.returnAmmo(), BorderLayout.EAST);
        c.validate();
        once = false;
      }
    }
    repaint();
  }
Пример #7
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);
    }
  }
  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);
  }
Пример #9
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);
  }
 /**
  * Creates a new instruction. address is the target of the operation, if one is needed. Otherwise
  * it is not used.
  *
  * @pre 0 <= opcode <= GO.
  */
 public Instruction(String opcode, int address) {
   this(Instruction.toInt(opcode), address);
 }
Пример #11
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);
          }
        }
      }
    }
  }
Пример #12
0
 /** Dump instruction as short code to stream out. */
 public void dump(DataOutputStream out) throws IOException {
   super.dump(out);
   out.writeShort(b);
 }
Пример #13
0
  static private void oneInstruction(Instruction instr) {

    int raw;
    int nextLoadReg = 0; 	
    int nextLoadValue = 0; 	// record delayed load operation, to apply
				// in the future

    // Fetch instruction 
    try {
      instr.value = readMem(registers[PCReg], 4);
    } catch (MachineException e) {
      return;			// exception occurred
    }
    instr.decode();

    String str = Instruction.opStrings[instr.opCode];
    byte args[] = Instruction.opRegs[instr.opCode];
    Debug.ASSERT(instr.opCode <= Instruction.MaxOpcode);
    if (Debug.isEnabled('m')) {
      Debug.printf('m', "At PC = 0x%x: ", new Integer(registers[PCReg]));
      Debug.printf('m',  str + "\n", 
		   new Integer(instr.typeToReg(args[0])),
		   new Integer(instr.typeToReg(args[1])),
		   new Integer(instr.typeToReg(args[2])));
    }

    // Compute next pc, but don't install in case there's an error or branch.
    int pcAfter = registers[NextPCReg] + 4;
    int sum, diff, tmp, value;
    long rs, rt, imm;

    // Execute the instruction (cf. Kane's book)
    switch (instr.opCode) {
	
      case Instruction.OP_ADD:
	sum = registers[instr.rs] + registers[instr.rt];
	if (((registers[instr.rs] ^ registers[instr.rt]) & SIGN_BIT) == 0 &&
	    ((registers[instr.rs] ^ sum) & SIGN_BIT) != 0) {
	    raiseException(OverflowException, 0);
	    return;
	}
	registers[instr.rd] = sum;
	break;
	
      case Instruction.OP_ADDI:
	sum = registers[instr.rs] + instr.extra;
	if (((registers[instr.rs] ^ instr.extra) & SIGN_BIT) == 0 &&
	    ((instr.extra ^ sum) & SIGN_BIT) != 0) {
	    raiseException(OverflowException, 0);
	    return;
	}
	registers[instr.rt] = sum;
	break;
	
      case Instruction.OP_ADDIU:
	// the registers are int, so we have to do them unsigned.
	// Now, precisely *WHY* didn't java give us unsigned types, again?

	rs = registers[instr.rs] & LOW32BITS;
	imm = instr.extra & LOW32BITS;
	rt = rs + imm;
	
	registers[instr.rt] = (int)rt;
	break;
	
      case Instruction.OP_ADDU:

	rs = registers[instr.rs] & LOW32BITS;
	rt = registers[instr.rt] & LOW32BITS;
		
	registers[instr.rd] = (int)(rs + rt);
	break;
	
      case Instruction.OP_AND:
	registers[instr.rd] = registers[instr.rs] & registers[instr.rt];
	break;
	
      case Instruction.OP_ANDI:
	registers[instr.rt] = registers[instr.rs] & (instr.extra & 0xffff);
	break;
	
      case Instruction.OP_BEQ:
	if (registers[instr.rs] == registers[instr.rt])
	    pcAfter = registers[NextPCReg] + (instr.extra << 2);
	break;
	
      case Instruction.OP_BGEZAL:
	registers[R31] = registers[NextPCReg] + 4;
      case Instruction.OP_BGEZ:
	if ((registers[instr.rs] & SIGN_BIT) == 0)
	    pcAfter = registers[NextPCReg] + (instr.extra << 2);
	break;
	
      case Instruction.OP_BGTZ:
	if (registers[instr.rs] > 0)
	    pcAfter = registers[NextPCReg] + (instr.extra << 2);
	break;
	
      case Instruction.OP_BLEZ:
	if (registers[instr.rs] <= 0)
	    pcAfter = registers[NextPCReg] + (instr.extra << 2);
	break;
	
      case Instruction.OP_BLTZAL:
	registers[R31] = registers[NextPCReg] + 4;
      case Instruction.OP_BLTZ:
	if ((registers[instr.rs] & SIGN_BIT) != 0)
	    pcAfter = registers[NextPCReg] + (instr.extra << 2);
	break;
	
      case Instruction.OP_BNE:
	if (registers[instr.rs] != registers[instr.rt])
	    pcAfter = registers[NextPCReg] + (instr.extra << 2);
	break;
	
      case Instruction.OP_DIV:
	if (registers[instr.rt] == 0) {
	    registers[LoReg] = 0;
	    registers[HiReg] = 0;
	} else {
	    registers[LoReg] =  registers[instr.rs] / registers[instr.rt];
	    registers[HiReg] = registers[instr.rs] % registers[instr.rt];
	}
	break;
	
      case Instruction.OP_DIVU:
	// don't sign extend
	rs = (registers[instr.rs] & LOW32BITS);
	rt = (registers[instr.rt] & LOW32BITS);
	if (rt == 0) {
	  registers[LoReg] = 0;
	  registers[HiReg] = 0;
	} else {
	  tmp = (int) (rs / rt);
	  registers[LoReg] = tmp;
	  tmp = (int) (rs % rt);
	  registers[HiReg] = tmp;
	}
	break;
	
      case Instruction.OP_JAL:
	registers[R31] = registers[NextPCReg] + 4;
      case Instruction.OP_J:
	pcAfter = (pcAfter & 0xf0000000) | instr.extra << 2;
	break;
	
      case Instruction.OP_JALR:
	registers[instr.rd] = registers[NextPCReg] + 4;
      case Instruction.OP_JR:
	pcAfter = registers[instr.rs];
	break;
	
      case Instruction.OP_LB:
      case Instruction.OP_LBU:
	tmp = registers[instr.rs] + instr.extra;
	try {
	  value = readMem(tmp, 1);
	} catch (MachineException e) {
	  return;			// exception occurred
	}

	if ((value & 0x80) != 0 && (instr.opCode == Instruction.OP_LB))
	    value |= 0xffffff00;
	else
	    value &= 0xff;
	nextLoadReg = instr.rt;
	nextLoadValue = value;
	break;
	
      case Instruction.OP_LH:
      case Instruction.OP_LHU:
	tmp = registers[instr.rs] + instr.extra;
	if ((tmp & 0x1) != 0) {
	    raiseException(AddressErrorException, tmp);
	    return;
	}
	try {
	  value = readMem(tmp, 2);
	} catch (MachineException e) {
	  return;			// exception occurred
	}

	if ((value & 0x8000) != 0 && (instr.opCode == Instruction.OP_LH))
	    value |= 0xffff0000;
	else
	    value &= 0xffff;
	nextLoadReg = instr.rt;
	nextLoadValue = value;
	break;
      	
      case Instruction.OP_LUI:
	
	if (Debug.isEnabled('m')) 
	  Debug.printf('m', "Executing: LUI r%d,%d\n", 
		       new Integer(instr.rt), new Integer(instr.extra));
	registers[instr.rt] = instr.extra << 16;
	break;
	
      case Instruction.OP_LW:
	tmp = registers[instr.rs] + instr.extra;
	if ((tmp & 0x3) != 0) {
	    raiseException(AddressErrorException, tmp);
	    return;
	}
	try {
	  value = readMem(tmp, 4);
	} catch (MachineException e) {
	  return;			// exception occurred
	}
	nextLoadReg = instr.rt;
	nextLoadValue = value;
	break;
    	
      case Instruction.OP_LWL:	  
	tmp = registers[instr.rs] + instr.extra;

	// ReadMem assumes all 4 byte requests are aligned on an even 
	// word boundary.  Also, the little endian/big endian swap code would
        // fail (I think) if the other cases are ever exercised.
	Debug.ASSERT((tmp & 0x3) == 0);  

	try {
	  value = readMem(tmp, 4);
	} catch (MachineException e) {
	  return;			// exception occurred
	}	
	if (registers[LoadReg] == instr.rt)
	    nextLoadValue = registers[LoadValueReg];
	else
	    nextLoadValue = registers[instr.rt];
	switch (tmp & 0x3) {
	  case 0:
	    nextLoadValue = value;
	    break;
	  case 1:
	    nextLoadValue = (nextLoadValue & 0xff) | (value << 8);
	    break;
	  case 2:
	    nextLoadValue = (nextLoadValue & 0xffff) | (value << 16);
	    break;
	  case 3:
	    nextLoadValue = (nextLoadValue & 0xffffff) | (value << 24);
	    break;
	}
	nextLoadReg = instr.rt;
	break;
      	
      case Instruction.OP_LWR:
	tmp = registers[instr.rs] + instr.extra;

	// ReadMem assumes all 4 byte requests are aligned on an even 
	// word boundary.  Also, the little endian/big endian swap code would
        // fail (I think) if the other cases are ever exercised.
	Debug.ASSERT((tmp & 0x3) == 0);  

	try {
	  value = readMem(tmp, 4);
	} catch (MachineException e) {
	  return;			// exception occurred
	}	
	if (registers[LoadReg] == instr.rt)
	    nextLoadValue = registers[LoadValueReg];
	else
	    nextLoadValue = registers[instr.rt];
	switch (tmp & 0x3) {
	  case 0:
	    nextLoadValue = (nextLoadValue & 0xffffff00) |
		((value >> 24) & 0xff);
	    break;
	  case 1:
	    nextLoadValue = (nextLoadValue & 0xffff0000) |
		((value >> 16) & 0xffff);
	    break;
	  case 2:
	    nextLoadValue = (nextLoadValue & 0xff000000)
		| ((value >> 8) & 0xffffff);
	    break;
	  case 3:
	    nextLoadValue = value;
	    break;
	}
	nextLoadReg = instr.rt;
	break;
    	
      case Instruction.OP_MFHI:
	registers[instr.rd] = registers[HiReg];
	break;
	
      case Instruction.OP_MFLO:
	registers[instr.rd] = registers[LoReg];
	break;
	
      case Instruction.OP_MTHI:
	registers[HiReg] = registers[instr.rs];
	break;
	
      case Instruction.OP_MTLO:
	registers[LoReg] = registers[instr.rs];
	break;
	
      case Instruction.OP_MULT:
	mult(registers[instr.rs], registers[instr.rt], true,
	     mresult);
	registers[HiReg] = mresult[0];
	registers[LoReg] = mresult[1];
	break;
	
      case Instruction.OP_MULTU:
	mult(registers[instr.rs], registers[instr.rt], false,
	     mresult);
	registers[HiReg] = mresult[0];
	registers[LoReg] = mresult[1];
	break;
	
      case Instruction.OP_NOR:
	registers[instr.rd] = ~(registers[instr.rs] | registers[instr.rt]);
	break;
	
      case Instruction.OP_OR:
	registers[instr.rd] = registers[instr.rs] | registers[instr.rt];
	break;
	
      case Instruction.OP_ORI:
	registers[instr.rt] = registers[instr.rs] | (instr.extra & 0xffff);
	break;
	
      case Instruction.OP_SB:
	if (!writeMem(
		(registers[instr.rs] + instr.extra), 1, registers[instr.rt]))
	    return;
	break;
	
      case Instruction.OP_SH:
	if (!writeMem(
		(registers[instr.rs] + instr.extra), 2, registers[instr.rt]))
	    return;
	break;
	
      case Instruction.OP_SLL:
	registers[instr.rd] = registers[instr.rt] << instr.extra;
	break;
	
      case Instruction.OP_SLLV:
	registers[instr.rd] = registers[instr.rt] <<
	    (registers[instr.rs] & 0x1f);
	break;
	
      case Instruction.OP_SLT:
	if (registers[instr.rs] < registers[instr.rt])
	    registers[instr.rd] = 1;
	else
	    registers[instr.rd] = 0;
	break;
	
      case Instruction.OP_SLTI:
	if (registers[instr.rs] < instr.extra)
	    registers[instr.rt] = 1;
	else
	    registers[instr.rt] = 0;
	break;
	
      case Instruction.OP_SLTIU:	  
	rs = (registers[instr.rs] & LOW32BITS);
	imm = (instr.extra & LOW32BITS);
	if (rs < imm)
	    registers[instr.rt] = 1;
	else
	    registers[instr.rt] = 0;
	break;
      	
      case Instruction.OP_SLTU:	  
	rs = registers[instr.rs] & LOW32BITS;
	rt = registers[instr.rt] & LOW32BITS;
	if (rs < rt)
	    registers[instr.rd] = 1;
	else
	    registers[instr.rd] = 0;
	break;
      	
      case Instruction.OP_SRA:
	registers[instr.rd] = registers[instr.rt] >> instr.extra;
	break;
	
      case Instruction.OP_SRAV:
	registers[instr.rd] = registers[instr.rt] >>
	    (registers[instr.rs] & 0x1f);
	break;
	
      case Instruction.OP_SRL:
	tmp = registers[instr.rt];
	tmp >>= instr.extra;
	registers[instr.rd] = tmp;
	break;
	
      case Instruction.OP_SRLV:
	tmp = registers[instr.rt];
	tmp >>= (registers[instr.rs] & 0x1f);
	registers[instr.rd] = tmp;
	break;
	
      case Instruction.OP_SUB:	  
	diff = registers[instr.rs] - registers[instr.rt];
	if (((registers[instr.rs] ^ registers[instr.rt]) & SIGN_BIT) != 0 &&
	    ((registers[instr.rs] ^ diff) & SIGN_BIT) != 0) {
	    raiseException(OverflowException, 0);
	    return;
	}
	registers[instr.rd] = diff;
	break;
      	
      case Instruction.OP_SUBU:
	
	rs = (registers[instr.rs] & LOW32BITS);
	rt = (registers[instr.rt] & LOW32BITS);
	
	registers[instr.rd] = (int)(rs - rt);
	break;
	
      case Instruction.OP_SW:
	if (!writeMem(
		(registers[instr.rs] + instr.extra), 4, registers[instr.rt]))
	    return;
	break;
	
      case Instruction.OP_SWL:	  
	tmp = registers[instr.rs] + instr.extra;

	// The little endian/big endian swap code would
        // fail (I think) if the other cases are ever exercised.
	Debug.ASSERT((tmp & 0x3) == 0);  

	try {
	  value = readMem((tmp & ~0x3), 4);
	} catch (MachineException e) {
	  return;			// exception occurred
	}	
	switch (tmp & 0x3) {
	  case 0:
	    value = registers[instr.rt];
	    break;
	  case 1:
	    value = (value & 0xff000000) | ((registers[instr.rt] >> 8) &
					    0xffffff);
	    break;
	  case 2:
	    value = (value & 0xffff0000) | ((registers[instr.rt] >> 16) &
					    0xffff);
	    break;
	  case 3:
	    value = (value & 0xffffff00) | ((registers[instr.rt] >> 24) &
					    0xff);
	    break;
	}
	if (!writeMem((tmp & ~0x3), 4, value))
	    return;
	break;
    	
      case Instruction.OP_SWR:	  
	tmp = registers[instr.rs] + instr.extra;

	// The little endian/big endian swap code would
        // fail (I think) if the other cases are ever exercised.
	Debug.ASSERT((tmp & 0x3) == 0);  

	try {
	  value = readMem((tmp & ~0x3), 4);
	} catch (MachineException e) {
	  return;			// exception occurred
	}	
	switch (tmp & 0x3) {
	  case 0:
	    value = (value & 0xffffff) | (registers[instr.rt] << 24);
	    break;
	  case 1:
	    value = (value & 0xffff) | (registers[instr.rt] << 16);
	    break;
	  case 2:
	    value = (value & 0xff) | (registers[instr.rt] << 8);
	    break;
	  case 3:
	    value = registers[instr.rt];
	    break;
	}
	if (!writeMem((tmp & ~0x3), 4, value))
	    return;
	break;
    	
      case Instruction.OP_SYSCALL:
	raiseException(SyscallException, 0);
	return; 
	
      case Instruction.OP_XOR:
	registers[instr.rd] = registers[instr.rs] ^ registers[instr.rt];
	break;
	
      case Instruction.OP_XORI:
	registers[instr.rt] = registers[instr.rs] ^ (instr.extra & 0xffff);
	break;
	
      case Instruction.OP_RES:
      case Instruction.OP_UNIMP:
	raiseException(IllegalInstrException, 0);
	return;
	
      default:
	System.out.println("Bogus opcode, should not happen");
	return;
    }
    
    // Now we have successfully executed the instruction.
    
    // Do any delayed load operation
    delayedLoad(nextLoadReg, nextLoadValue);
    
    // Advance program counters.
    registers[PrevPCReg] = registers[PCReg];	// for debugging, in case we
						// are jumping into lala-land
    registers[PCReg] = registers[NextPCReg];
    registers[NextPCReg] = pcAfter;
  }
Пример #14
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;
 }
Пример #15
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;
  }