/** * Branching code generation for == operation. * * @param output the code emitter (basically an abstraction for producing the .class file). * @param targetLabel target for generated branch instruction. * @param onTrue should we branch on true? */ public void codegen(CLEmitter output, String targetLabel, boolean onTrue) { lhs.codegen(output); rhs.codegen(output); if (lhs.type().isReference()) { output.addBranchInstruction(onTrue ? IF_ACMPEQ : IF_ACMPNE, targetLabel); } else { output.addBranchInstruction(onTrue ? IF_ICMPEQ : IF_ICMPNE, targetLabel); } }
/** * The semantics of j-- require that we implement short-circuiting branching in implementing the * logical AND. * * @param output the code emitter (basically an abstraction for producing the .class file). * @param targetLabel target for generated branch instruction. * @param onTrue should we branch on true? */ public void codegen(CLEmitter output, String targetLabel, boolean onTrue) { if (onTrue) { String falseLabel = output.createLabel(); lhs.codegen(output, falseLabel, false); rhs.codegen(output, targetLabel, true); output.addLabel(falseLabel); } else { lhs.codegen(output, targetLabel, false); rhs.codegen(output, targetLabel, false); } }
/** * Generate code for the case where we actually want a boolean value (true or false) computed onto * the stack, eg for assignment to a boolean variable. * * @param output the code emitter (basically an abstraction for producing the .class file). */ public void codegen(CLEmitter output) { String elseLabel = output.createLabel(); String endIfLabel = output.createLabel(); this.codegen(output, elseLabel, false); output.addNoArgInstruction(ICONST_1); // true output.addBranchInstruction(GOTO, endIfLabel); output.addLabel(elseLabel); output.addNoArgInstruction(ICONST_0); // false output.addLabel(endIfLabel); }
/** * Declare fields in the parent's (partial) class. * * @param context the parent (class) context. * @param partial the code emitter (basically an abstraction for producing the partial class). */ public void preAnalyze(Context context, CLEmitter partial) { // Fields may not be declared abstract. if (mods.contains("abstract")) { JAST.compilationUnit.reportSemanticError(line(), "Field cannot be declared abstract"); } for (JVariableDeclarator decl : decls) { // Add field to (partial) class decl.setType(decl.type().resolve(context)); partial.addField(mods, decl.name(), decl.type().toDescriptor(), false); } }
/** * Code generation for field declaration involves generate field the header. * * @param output the code emitter (basically an abstraction for producing the .class file). */ public void codegen(CLEmitter output) { for (JVariableDeclarator decl : decls) { // Add field to class output.addField(mods, decl.name(), decl.type().toDescriptor(), false); } }