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(";"); } } }
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())); } }
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(); } }