/** Generate code */ public void write(Environment env, DataOutputStream out, MemberDefinition field, ConstantPool tab) throws IOException { // listing(System.out); if ((field != null) && field.getArguments() != null) { int sum = 0; Vector v = field.getArguments(); for (Enumeration e = v.elements(); e.hasMoreElements(); ) { MemberDefinition f = ((MemberDefinition) e.nextElement()); sum += f.getType().stackSize(); } maxvar = sum; } // Make sure the stack balances. Also calculate maxvar and maxstack try { balance(first, 0); } catch (CompilerError e) { System.out.println("ERROR: " + e); listing(System.out); throw e; } // Assign PCs int pc = 0, nexceptions = 0; for (Instruction inst = first; inst != null; inst = inst.next) { inst.pc = pc; int sz = inst.size(tab); if (pc < 65536 && (pc + sz) >= 65536) { env.error(inst.where, "warn.method.too.long"); } pc += sz; if (inst.opc == opc_try) { nexceptions += ((TryData) inst.value).catches.size(); } } // Write header out.writeShort(maxdepth); out.writeShort(maxvar); out.writeInt(maxpc = pc); // Generate code for (Instruction inst = first.next; inst != null; inst = inst.next) { inst.write(out, tab); } // write exceptions out.writeShort(nexceptions); if (nexceptions > 0) { // listing(System.out); writeExceptions(env, out, tab, first, last); } }
/** Write the exceptions table */ void writeExceptions( Environment env, DataOutputStream out, ConstantPool tab, Instruction first, Instruction last) throws IOException { for (Instruction inst = first; inst != last.next; inst = inst.next) { if (inst.opc == opc_try) { TryData td = (TryData) inst.value; writeExceptions(env, out, tab, inst.next, td.getEndLabel()); for (Enumeration e = td.catches.elements(); e.hasMoreElements(); ) { CatchData cd = (CatchData) e.nextElement(); // System.out.println("EXCEPTION: " + env.getSource() + ", pc=" + inst.pc + ", end=" + // td.getEndLabel().pc + ", hdl=" + cd.getLabel().pc + ", tp=" + cd.getType()); out.writeShort(inst.pc); out.writeShort(td.getEndLabel().pc); out.writeShort(cd.getLabel().pc); if (cd.getType() != null) { out.writeShort(tab.index(cd.getType())); } else { out.writeShort(0); } } inst = td.getEndLabel(); } } }