Пример #1
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(";");
      }
    }
  }
Пример #2
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()));
    }
  }
Пример #3
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();
    }
  }