📄 createbcode.jrag
字号:
} } public void ArrayTypeAccess.createBCode(CodeGeneration gen) { getAccess().createBCode(gen); } public void ArrayTypeWithSizeAccess.createBCode(CodeGeneration gen) { getAccess().createBCode(gen); getExpr().createBCode(gen); } syn String TypeDecl.arrayTypeDescriptor() { throw new Error("Operation not supported"); } eq ArrayDecl.arrayTypeDescriptor() = typeDescriptor(); eq ClassDecl.arrayTypeDescriptor() = constantPoolName(); eq InterfaceDecl.arrayTypeDescriptor() = constantPoolName(); syn int TypeDecl.arrayPrimitiveTypeDescriptor() { error(); return -1; } eq BooleanType.arrayPrimitiveTypeDescriptor() = 4; // T_BOOLEAN eq CharType.arrayPrimitiveTypeDescriptor() = 5; // T_CHAR eq FloatType.arrayPrimitiveTypeDescriptor() = 6; // T_FLOAT eq DoubleType.arrayPrimitiveTypeDescriptor() = 7; // T_DOUBLE eq ByteType.arrayPrimitiveTypeDescriptor() = 8; // T_BYTE eq ShortType.arrayPrimitiveTypeDescriptor() = 9; // T_SHORT eq IntType.arrayPrimitiveTypeDescriptor() = 10; // T_INT eq LongType.arrayPrimitiveTypeDescriptor() = 11; // T_LONG public void Unary.createBCode(CodeGeneration gen) { super.createBCode(gen); emitOperation(gen); } public void CastExpr.createBCode(CodeGeneration gen) { getExpr().createBCode(gen); getExpr().type().emitCastTo(gen, type()); } // TODO: consider using IINC or WIDE,IINC public void Unary.emitPostfix(CodeGeneration gen, int constant) { Expr operand = getOperand(); while(operand instanceof ParExpr) operand = ((ParExpr)operand).getExpr(); Access access = ((Access)operand).lastAccess(); access.createAssignLoadDest(gen); if(needsPush()) access.createPushAssignmentResult(gen); TypeDecl type = access.type().binaryNumericPromotion(typeInt()); type.emitPushConstant(gen, constant); type.add(gen); type.emitCastTo(gen, access.type()); access.emitStore(gen); } public void PostIncExpr.createBCode(CodeGeneration gen) { emitPostfix(gen, 1); } public void PostDecExpr.createBCode(CodeGeneration gen) { emitPostfix(gen, -1); } public void Unary.emitPrefix(CodeGeneration gen, int constant) { Expr operand = getOperand(); while(operand instanceof ParExpr) operand = ((ParExpr)operand).getExpr(); Access access = ((Access)operand).lastAccess(); access.createAssignLoadDest(gen); TypeDecl type = access.type().binaryNumericPromotion(typeInt()); type.emitPushConstant(gen, constant); type.add(gen); type.emitCastTo(gen, access.type()); if(needsPush()) access.createPushAssignmentResult(gen); access.emitStore(gen); } public void PreIncExpr.createBCode(CodeGeneration gen) { emitPrefix(gen, 1); } public void PreDecExpr.createBCode(CodeGeneration gen) { emitPrefix(gen, -1); } public void Binary.createBCode(CodeGeneration gen) { getLeftOperand().createBCode(gen); getLeftOperand().type().emitCastTo(gen, type()); // Binary numeric promotion getRightOperand().createBCode(gen); getRightOperand().type().emitCastTo(gen, type()); // Binary numeric promotion emitOperation(gen); } public void Binary.emitShiftExpr(CodeGeneration gen) { getLeftOperand().createBCode(gen); getLeftOperand().type().emitCastTo(gen, type()); // Binary numeric promotion getRightOperand().createBCode(gen); getRightOperand().type().emitCastTo(gen, typeInt()); emitOperation(gen); } public void LShiftExpr.createBCode(CodeGeneration gen) { emitShiftExpr(gen); } public void RShiftExpr.createBCode(CodeGeneration gen) { emitShiftExpr(gen); } public void URShiftExpr.createBCode(CodeGeneration gen) { emitShiftExpr(gen); } public void AddExpr.createBCode(CodeGeneration gen) { if(!type().isString()) super.createBCode(gen); else if(isConstant()) { StringLiteral.push(gen, constant().stringValue()); } else { TypeDecl stringBuffer = lookupType("java.lang", "StringBuffer"); String classname = stringBuffer.constantPoolName(); String desc; int index; TypeDecl argumentType; if(firstStringAddPart()) { stringBuffer.emitNew(gen); // new StringBuffer gen.emitDup(); // dup desc = "()V"; index = gen.constantPool().addMethodref(classname, "<init>", desc); gen.emit(Bytecode.INVOKESPECIAL, -1).add2(index); // invokespecial StringBuffer() getLeftOperand().createBCode(gen); // left argumentType = getLeftOperand().type().stringPromotion(); desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); index = gen.constantPool().addMethodref(classname, "append", desc); gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append } else { getLeftOperand().createBCode(gen); } getRightOperand().createBCode(gen); // right argumentType = getRightOperand().type().stringPromotion(); desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); index = gen.constantPool().addMethodref(classname, "append", desc); gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append if(lastStringAddPart()) { desc = "()" + type().typeDescriptor(); index = gen.constantPool().addMethodref(classname, "toString", desc); gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); // StringBuffer.toString } } } // branch to this label if the expression is false syn lazy int Expr.false_label() = getParent().definesLabel() ? condition_false_label() : hostType().constantPool().newLabel(); // branch to this label if the expression is true syn lazy int Expr.true_label() = getParent().definesLabel() ? condition_true_label() : hostType().constantPool().newLabel(); // these nodes defines labels for their children syn boolean ASTNode.definesLabel() = false; eq Opt.definesLabel() = getParent().definesLabel(); eq List.definesLabel() = getParent().definesLabel(); eq AbstractDot.definesLabel() = getParent().definesLabel(); eq ParExpr.definesLabel() = getParent().definesLabel(); eq LogNotExpr.definesLabel() = true; eq ConditionalExpr.definesLabel() = true; eq RelationalExpr.definesLabel() = false; eq LogicalExpr.definesLabel() = true; eq IfStmt.definesLabel() = true; eq WhileStmt.definesLabel() = true; eq DoStmt.definesLabel() = true; eq ForStmt.definesLabel() = true; // provide labels for these control statement conditions eq IfStmt.getCondition().condition_false_label() = else_branch_label(); eq IfStmt.getCondition().condition_true_label() = then_branch_label(); eq WhileStmt.getCondition().condition_false_label() = end_label(); eq WhileStmt.getCondition().condition_true_label() = stmt_label(); eq DoStmt.getCondition().condition_false_label() = end_label(); eq DoStmt.getCondition().condition_true_label() = begin_label(); eq ForStmt.getCondition().condition_false_label() = end_label(); eq ForStmt.getCondition().condition_true_label() = begin_label(); // propagate labels downwards for complex boolean expressions inh int Expr.condition_false_label(); eq Program.getChild(int i).condition_false_label() { throw new Error("condition_false_label not implemented"); } inh int Expr.condition_true_label(); eq Program.getChild(int i).condition_true_label() { throw new Error("condition_true_label not implemented"); } eq LogNotExpr.getOperand().condition_false_label() = true_label(); eq LogNotExpr.getOperand().condition_true_label() = false_label(); eq ConditionalExpr.getCondition().condition_false_label() = else_branch_label(); eq ConditionalExpr.getCondition().condition_true_label() = then_branch_label(); eq ConditionalExpr.getTrueExpr().condition_false_label() = false_label(); eq ConditionalExpr.getTrueExpr().condition_true_label() = true_label(); eq ConditionalExpr.getFalseExpr().condition_false_label() = false_label(); eq ConditionalExpr.getFalseExpr().condition_true_label() = true_label(); eq RelationalExpr.getLeftOperand().condition_false_label() = false_label(); eq RelationalExpr.getLeftOperand().condition_true_label() = true_label(); eq RelationalExpr.getRightOperand().condition_false_label() = false_label(); eq RelationalExpr.getRightOperand().condition_true_label() = true_label(); eq AndLogicalExpr.getLeftOperand().condition_false_label() = false_label(); eq AndLogicalExpr.getLeftOperand().condition_true_label() = next_test_label(); eq AndLogicalExpr.getRightOperand().condition_false_label() = false_label(); eq AndLogicalExpr.getRightOperand().condition_true_label() = true_label(); eq OrLogicalExpr.getLeftOperand().condition_false_label() = next_test_label(); eq OrLogicalExpr.getLeftOperand().condition_true_label() = true_label(); eq OrLogicalExpr.getRightOperand().condition_false_label() = false_label(); eq OrLogicalExpr.getRightOperand().condition_true_label() = true_label(); syn boolean Expr.canBeTrue() = !isFalse(); eq ParExpr.canBeTrue() = getExpr().canBeTrue(); eq AbstractDot.canBeTrue() = lastAccess().canBeTrue(); eq OrLogicalExpr.canBeTrue() = getLeftOperand().canBeTrue() || getRightOperand().canBeTrue(); eq AndLogicalExpr.canBeTrue() = getLeftOperand().canBeTrue() && getRightOperand().canBeTrue(); eq ConditionalExpr.canBeTrue() = type().isBoolean() && (getTrueExpr().canBeTrue() && getFalseExpr().canBeTrue() || getCondition().isTrue() && getTrueExpr().canBeTrue() || getCondition().isFalse() && getFalseExpr().canBeTrue()); eq LogNotExpr.canBeTrue() = getOperand().canBeFalse(); syn boolean Expr.canBeFalse() = !isTrue(); eq ParExpr.canBeFalse() = getExpr().canBeFalse(); eq AbstractDot.canBeFalse() = lastAccess().canBeFalse(); eq OrLogicalExpr.canBeFalse() = getLeftOperand().canBeFalse() && getRightOperand().canBeFalse(); eq AndLogicalExpr.canBeFalse() = getLeftOperand().canBeFalse() || getRightOperand().canBeFalse(); eq ConditionalExpr.canBeFalse() = type().isBoolean() && (getTrueExpr().canBeFalse() && getFalseExpr().canBeFalse() || getCondition().isTrue() && getTrueExpr().canBeFalse() || getCondition().isFalse() && getFalseExpr().canBeFalse()); eq LogNotExpr.canBeFalse() = getOperand().canBeTrue(); public void RelationalExpr.createBCode(CodeGeneration gen) { emitBooleanCondition(gen); } public void LogNotExpr.createBCode(CodeGeneration gen) { emitBooleanCondition(gen); } public void LogicalExpr.createBCode(CodeGeneration gen) { emitBooleanCondition(gen); } protected void Expr.emitBooleanCondition(CodeGeneration gen) { emitEvalBranch(gen); int end_label = hostType().constantPool().newLabel(); gen.addLabel(false_label()); BooleanLiteral.push(gen, false); gen.emitGoto(end_label); gen.changeStackDepth(-1); // discard false from stack depth computation gen.addLabel(true_label()); BooleanLiteral.push(gen, true); gen.addLabel(end_label); } public void ConditionalExpr.createBCode(CodeGeneration gen) { if(type().isBoolean()) emitBooleanCondition(gen); else { int endBranch = hostType().constantPool().newLabel(); getCondition().emitEvalBranch(gen); if(getCondition().canBeTrue()) { gen.addLabel(then_branch_label()); getTrueExpr().createBCode(gen); getTrueExpr().type().emitCastTo(gen, type()); if(getCondition().canBeFalse()) { gen.changeStackDepth(-type().variableSize()); gen.emitGoto(endBranch); } } if(getCondition().canBeFalse()) { gen.addLabel(else_branch_label()); getFalseExpr().createBCode(gen); getFalseExpr().type().emitCastTo(gen, type()); } gen.addLabel(endBranch); } } syn lazy int ConditionalExpr.else_branch_label() = hostType().constantPool().newLabel(); syn lazy int ConditionalExpr.then_branch_label() = hostType().constantPool().newLabel(); public void Expr.emitEvalBranch(CodeGeneration gen) { if(isTrue()) gen.emitGoto(true_label()); else if(isFalse()) gen.emitGoto(false_label()); else { createBCode(gen); gen.emitCompare(Bytecode.IFNE, true_label()); gen.emitGoto(false_label()); //gen.emitCompare(Bytecode.IFEQ, false_label()); //gen.emitGoto(true_label()); } } public void ParExpr.emitEvalBranch(CodeGeneration gen) { getExpr().emitEvalBranch(gen); } public void AbstractDot.emitEvalBranch(CodeGeneration gen) { lastAccess().emitEvalBranch(gen); } public void LogNotExpr.emitEvalBranch(CodeGeneration gen) { getOperand().emitEvalBranch(gen); } public void AndLogicalExpr.emitEvalBranch(CodeGeneration gen) { getLeftOperand().emitEvalBranch(gen); gen.addLabel(next_test_label()); if(getLeftOperand().canBeTrue()) { getRightOperand().emitEvalBranch(gen); if(getRightOperand().canBeTrue()) gen.emitGoto(true_label()); } } syn lazy int AndLogicalExpr.next_test_label() = hostType().constantPool().newLabel(); public void OrLogicalExpr.emitEvalBranch(CodeGeneration gen) { getLeftOperand().emitEvalBranch(gen); gen.addLabel(next_test_label()); if(getLeftOperand().canBeFalse()) { getRightOperand().emitEvalBranch(gen); if(getRightOperand().canBeFalse()) gen.emitGoto(false_label()); } } syn lazy int OrLogicalExpr.next_test_label() = hostType().constantPool().newLabel(); public void ConditionalExpr.emitEvalBranch(CodeGeneration gen) { int endBranch = hostType().constantPool().newLabel(); getCondition().emitEvalBranch(gen); gen.addLabel(then_branch_label()); if(getCondition().canBeTrue()) { getTrueExpr().emitEvalBranch(gen); gen.emitGoto(true_label()); } gen.addLabel(else_branch_label()); if(getCondition().canBeFalse()) { getFalseExpr().emitEvalBranch(gen); gen.emitGoto(true_label()); } } public void RelationalExpr.emitEvalBranch(CodeGeneration gen) { if(isTrue()) gen.emitGoto(true_label()); else if(isFalse()) gen.emitGoto(false_label()); else { TypeDecl type = getLeftOperand().type(); if(type.isNumericType()) { type = binaryNumericPromotedType(); getLeftOperand().createBCode(gen); getLeftOperand().type().emitCastTo(gen, type); // Binary numeric promotion getRightOperand().createBCode(gen); getRightOperand().type().emitCastTo(gen, type); // Binary numeric promotion } else { getLeftOperand().createBCode(gen); getRightOperand().createBCode(gen); } compareBranch(gen, true_label(), type); gen.emitGoto(false_label()); // compareNotBranch does not work for float comparison with NaN //compareNotBranch(gen, false_label(), type); //gen.emitGoto(true_label()); } } public void RelationalExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { throw new Error("compareBranch not supported for " + getClass().getName()); } public void LTExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchLT(gen, label); } public void LEExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchLE(gen, label); } public void GEExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchGE(gen, label); } public void GTExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchGT(gen, label); } public void EQExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchEQ(gen, label); } public void NEExpr.compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchNE(gen, label); } public void RelationalExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { throw new Error("compareBranch not supported for " + getClass().getName()); } public void LTExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchGE(gen, label); } public void LEExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchGT(gen, label); } public void GEExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchLT(gen, label); } public void GTExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchLE(gen, label); } public void EQExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchNE(gen, label); } public void NEExpr.compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) { typeDecl.branchEQ(gen, label); } public void InstanceOfExpr.createBCode(CodeGeneration gen) { getExpr().createBCode(gen); gen.emitInstanceof(getTypeAccess().type()); } public void Stmt.createBCode(CodeGeneration gen) { gen.addLineNumberEntryAtCurrentPC(this); } public void Block.createBCode(CodeGeneration gen) { //super.createBCode(gen); for(int i = 0; i < getNumStmt(); i++) { try { getStmt(i).createBCode(gen); } catch (Exception e) { e.printStackTrace(); throw new Error("Error generating code for " + errorPrefix() + " " + getStmt(i)); } } gen.addVariableScopeLabel(variableScopeEndLabel(gen)); } public void EmptyStmt.createBCode(CodeGeneration gen) { super.createBCode(gen); } syn lazy int LabeledStmt.label() = hostType().constantPool().newLabel(); syn lazy int LabeledStmt.end_label() = hostType().constantPool().newLabel(); public void LabeledStmt.createBCode(CodeGeneration gen) { super.createBCode(gen); gen.addLabel(label()); getStmt().createBCode(gen); gen.addLabel(end_label()); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -