📄 codeattr.java
字号:
pushType(type); } public void emitInstanceof (Type type) { emitCheckcast(type, 193); pushType(Type.boolean_type); } public final void emitThrow () { popType(); reserve(1); put1 (191); // athrow unreachable_here = true; } /** * Compile a method return. */ public final void emitReturn () { if (getMethod().getReturnType() == Type.void_type) { reserve(1); put1(177); // return } else emitTypedOp (172, popType().promote()); } /** Add an exception handler. */ public void addHandler (int start_pc, int end_pc, int handler_pc, int catch_type) { int index = 4 * exception_table_length; if (exception_table == null) { exception_table = new short[20]; } else if (exception_table.length <= index) { short[] new_table = new short[2 * exception_table.length]; System.arraycopy(exception_table, 0, new_table, 0, index); exception_table = new_table; } exception_table[index++] = (short) start_pc; exception_table[index++] = (short) end_pc; exception_table[index++] = (short) handler_pc; exception_table[index++] = (short) catch_type; exception_table_length++; } /** Add an exception handler. */ public void addHandler (int start_pc, int end_pc, int handler_pc, ClassType catch_type, ConstantPool constants) { int catch_type_index; if (catch_type == null) catch_type_index = 0; else catch_type_index = constants.addClass(catch_type).index; addHandler(start_pc, end_pc, handler_pc, catch_type_index); } public void emitTryStart(boolean has_finally, Type result_type) { TryState try_state = new TryState(this); boolean must_save_result = has_finally && result_type != null; if (must_save_result || SP > 0) { pushScope(); if (must_save_result) try_state.saved_result = addLocal(result_type); } if (SP > 0) { try_state.savedStack = new Variable[SP]; int i = 0; while (SP > 0) { Variable var = addLocal(topType()); emitStore(var); try_state.savedStack[i++] = var; } } if (has_finally) try_state.finally_subr = new Label(this); } public void emitTryEnd() { if (try_stack.end_label == null) { if (try_stack.saved_result != null) emitStore(try_stack.saved_result); try_stack.end_label = new Label(this); if (try_stack.finally_subr != null) emitGoto(try_stack.finally_subr, 168); // jsr if (reachableHere()) emitGoto(try_stack.end_label); readPC = PC; try_stack.end_pc = PC; } } public void emitCatchStart(Variable var) { emitTryEnd(); if (try_stack.try_type != null) { emitCatchEnd(); } ClassType type = var == null ? null : (ClassType) var.getType(); try_stack.try_type = type; readPC = PC; addHandler(try_stack.start_pc, try_stack.end_pc, PC, type, getConstants()); if (var != null) { pushType(type); emitStore(var); } } public void emitCatchEnd() { if (reachableHere()) { if (try_stack.saved_result != null) emitStore(try_stack.saved_result); if (try_stack.finally_subr != null) emitGoto(try_stack.finally_subr, 168); // jsr emitGoto(try_stack.end_label); } popScope(); try_stack.try_type = null; } public void emitFinallyStart() { emitTryEnd(); if (try_stack.try_type != null) { emitCatchEnd(); } readPC = PC; try_stack.end_pc = PC; pushScope(); Type except_type = Type.pointer_type; Variable except = addLocal(except_type); emitCatchStart(null); pushType(except_type); emitStore(except); emitGoto(try_stack.finally_subr, 168); // jsr emitLoad(except); emitThrow(); //emitCatchEnd(); //if (try_stack.finally_subr == null) // error(); try_stack.finally_subr.define(this); Type ret_addr_type = Type.pointer_type; try_stack.finally_ret_addr = addLocal(ret_addr_type); pushType(ret_addr_type); emitStore(try_stack.finally_ret_addr); } public void emitFinallyEnd() { emitRet(try_stack.finally_ret_addr); unreachable_here = true; popScope(); try_stack.finally_subr = null; } public void emitTryCatchEnd() { if (try_stack.finally_subr != null) emitFinallyEnd(); try_stack.end_label.define(this); Variable[] vars = try_stack.savedStack; if (vars != null) { for (int i = vars.length; --i >= 0; ) { Variable v = vars[i]; if (v != null) { emitLoad(v); } } } if (try_stack.saved_result != null) emitLoad(try_stack.saved_result); if (try_stack.saved_result != null || vars != null) popScope(); try_stack = try_stack.previous; } /* Make sure the label with oldest fixup is first in labels. */ void reorder_fixups () { Label prev = null; Label cur; Label oldest = null; Label oldest_prev = null; int oldest_fixup = PC+100; for (cur = labels; cur != null; cur = cur.next) { if (cur.fixups != null && cur.fixups[0] < oldest_fixup) { oldest = cur; oldest_prev = prev; oldest_fixup = cur.fixups[0]; } prev = cur; } if (oldest != labels) { oldest_prev.next = oldest.next; oldest.next = labels; labels = oldest; } } public void finalize_labels () { while (labels != null && labels.fixups != null) labels.emit_spring (this); for (Label label = labels; label != null; label = label.next) { if (!label.defined ()) throw new Error ("undefined label"); if (label.fixups != null) throw new Error ("internal error: finalize_labels"); } } public void assignConstants (ClassType cl) { super.assignConstants(cl); Attribute.assignConstants(this, cl); } public final int getLength() { return 12 + getCodeLength() + 8 * exception_table_length + Attribute.getLengthAll(this); } public void write (DataOutputStream dstr) throws java.io.IOException { dstr.writeShort (max_stack); dstr.writeShort (max_locals); dstr.writeInt (PC); dstr.write (code, 0, PC); dstr.writeShort (exception_table_length); int count = exception_table_length; for (int i = 0; --count >= 0; i += 4) { dstr.writeShort(exception_table[i]); dstr.writeShort(exception_table[i+1]); dstr.writeShort(exception_table[i+2]); dstr.writeShort(exception_table[i+3]); } Attribute.writeAll(this, dstr); } public void print (ClassTypeWriter dst) { dst.print("Attribute \""); dst.print(getName()); dst.print("\", length:"); dst.print(getLength()); dst.print(", max_stack:"); dst.print(max_stack); dst.print(", max_locals:"); dst.print(max_locals); dst.print(", code_length:"); int length = getCodeLength(); dst.println(length); disAssemble(dst, 0, length); if (exception_table_length > 0) { dst.print("Exceptions (count: "); dst.print(exception_table_length); dst.println("):"); int count = exception_table_length; for (int i = 0; --count >= 0; i += 4) { dst.print(" start: "); dst.print(exception_table[i] & 0xffff); dst.print(", end: "); dst.print(exception_table[i+1] & 0xffff); dst.print(", handler: "); dst.print(exception_table[i+2] & 0xffff); dst.print(", type: "); int catch_type_index = exception_table[i+3] & 0xffff; if (catch_type_index == 0) dst.print("0 /* finally */"); else { dst.printOptionalIndex(catch_type_index); dst.printConstantTersely(catch_type_index, ConstantPool.CLASS); } dst.println(); } } dst.printAttributes(this); } public void disAssemble (ClassTypeWriter dst, int offset, int length) { boolean wide = false; for (int i = offset; i < length; ) { int oldpc = i++; int op = code[oldpc] & 0xff; String str = Integer.toString(oldpc); int printConstant = 0; int j = str.length(); while (++j <= 3) dst.print(' '); dst.print(str); dst.print(": "); if (op < 120) { if (op < 87) { if (op < 3) print("nop;aconst_null;iconst_m1;", op, dst); else if (op < 9) { dst.print("iconst_"); dst.print(op-3); } else if (op < 16) // op >= 9 [lconst_0] && op <= 15 [dconst_1] { char typ; if (op < 11) { typ = 'l'; op -= 9; } else if (op < 14) { typ = 'f'; op -= 11; } else { typ = 'd'; op -= 14; } dst.print(typ); dst.print("const_"); dst.print(op); } else if (op < 21) { if (op < 18) // op >= 16 [bipush] && op <= 17 [sipush] { print("bipush ;sipush ;", op-16, dst); int constant; if (op == 16) constant = code[i++]; else { constant = (short) readUnsignedShort(i); i+=2;} dst.print(constant); } else // op >= 18 [ldc] && op <= 20 [ldc2_w] { printConstant = op == 18 ? 1 : 2; print("ldc;ldc_w;ldc2_w;", op-18, dst); } } else // op >= 21 && op < 87 { String load_or_store; if (op < 54) { load_or_store = "load"; } else { load_or_store = "store"; op -=(54-21); } int index; // -2 if array op; -1 if index follows if (op < 26) { index = -1; op -= 21; } else if (op < 46) { op -= 26; index = op % 4; op >>= 2; } else { index = -2; op -= 46; } dst.print("ilfdabcs".charAt(op)); if (index == -2) dst.write('a'); dst.print(load_or_store); if (index >= 0) { dst.write('_'); dst.print(index); } else if (index == -1) { if (wide) { index = readUnsignedShort(i); index += 2; } else { index = code[i] & 0xff; i++; } wide = false; dst.print(' '); dst.print(index); } } } else // op >= 87 && op < 120 { if (op < 96) print("pop;pop2;dup;dup_x1;dup_x2;dup2;dup2_x1;dup2_x2;swap;" , op-87, dst); else // op >= 96 [iadd] && op <= 119 [dneg] { dst.print("ilfda".charAt((op-96) % 4)); print("add;sub;mul;div;rem;neg;", (op-96)>>2, dst); } } } else // op >= 120 { if (op < 170) { if (op < 132) // op >= 120 [ishl] && op <= 131 [lxor] { dst.print((op & 1) == 0 ? 'i' : 'l'); print("shl;shr;ushr;and;or;xor;", (op-120)>>1, dst); } else if (op == 132) // iinc { int var_index; int constant; dst.print("iinc"); if (! wide) { var_index = 0xff & code[i++]; constant = code[i++]; } else { var_index = readUnsignedShort(i); i += 2; constant = (short) readUnsignedShort(i); i += 2; wide = false; } dst.print(' '); dst.print(var_index); dst.print(' '); dst.print(constant); } else if (op < 148) // op >= 133 [i2l] && op <= 147 [i2s] { dst.print("ilfdi".charAt((op-133) / 3)); dst.print('2'); dst.print("lfdifdildilfbcs".charAt(op-133)); } else if (op < 153) // op >= 148 [lcmp] && op <= 152 [dcmpg] print("lcmp;fcmpl;fcmpg;dcmpl;dcmpg;", op-148, dst); else { if (op < 159) { dst.print("if"); print("eq;ne;lt;ge;gt;le;", op-153, dst); } else if (op < 167) { if (op < 165) { dst.print("if_icmp"); } else { dst.print("if_acmp"); op -= 165-159; } print("eq;ne;lt;ge;gt;le;", op-159, dst); } else print("goto;jsr;ret;", op-167, dst); int delta = (short) readUnsignedShort(i); i += 2; dst.print(' '); dst.print(oldpc+delta); } } else { if (op < 172) // [tableswitch] or [lookupswitch] { i = (i + 3) & ~3; // skip 0-3 byte padding. int code_offset = readInt(i); i += 4; if (op == 170) { dst.print("tableswitch"); int low = readInt(i); i += 4; int high = readInt(i+4); i += 4; dst.print(" low: "); dst.print(low); dst.print(" high: "); dst.print(high); dst.print(" default: "); dst.print(code_offset); for (; low <= high; low++) { code_offset = readInt(i); i += 4; dst.println(); dst.print(" "); dst.print(low); dst.print(": "); dst.print(oldpc + code_offset); } } else { dst.print("lookupswitch"); int npairs = readInt(i); i += 4; dst.print(" npairs: "); dst.print(npairs); dst.print(" default: "); dst.print(code_offset); while (--npairs >= 0) { int match = readInt(i); i += 4; code_offset = readInt(i); i += 4; dst.println(); dst.print(" "); dst.print(match); dst.print(": "); dst.print(oldpc + code_offset); } } } else if (op < 178) // op >= 172 [ireturn] && op <= 177 [return] { if (op < 177) dst.print("ilfda".charAt(op-172)); dst.print("return"); } else if (op < 182) // op >= 178 [getstatic] && op <= 181 [putfield] { print("getstatic;putstatic;getfield;putfield;", op-178, dst); printConstant = 2; } else if (op < 186) // op >= 182 && op <= 185 [invoke*] { dst.print("invoke"); print("virtual;special;static;interface;", op-182, dst); printConstant = 2; if (op == 185) // invokeinterface i += 2; } else if (op < 196) { print("186;new;newarray;anewarray;arraylength;athrow;checkcast;instanceof;moniorenter;monitorexit;", op-186, dst); if (op == 187 || op == 189 || op == 192 || op == 193) printConstant = 2; else if (op == 188) // newarray { int type = code[i++]; dst.print(' '); if (type >= 4 && type <= 11) print("boolean;char;float;double;byte;short;int;long;", type-4, dst); else dst.print(type); } } else if (op == 196) // wide { dst.print("wide"); wide = true; } else if (op == 197) { dst.print("multianewarray"); int index = readUnsignedShort(i); i += 2; dst.printConstantOperand(index); int dims = 0xff & code[i++]; dst.print(' '); dst.print(dims); } else if (op < 200) { print("ifnull;ifnonnull;", op-198, dst); int delta = (short) readUnsignedShort(i); i += 2; dst.print(' '); dst.print(oldpc+delta); } else if (op < 202) { print("goto_w;jsr_w;", op-200, dst); int delta = readInt(i); i += 4; dst.print(' '); dst.print(oldpc+delta); } else dst.print(op); } } if (printConstant > 0) { int index; if (printConstant == 1) index = 0xff & code[i++]; else { index = readUnsignedShort(i); i += 2; } dst.printConstantOperand(index); } dst.println(); } } private int readUnsignedShort(int offset) { return ((0xff & code[offset]) << 8) | (0xff & code[offset+1]); } private int readInt(int offset) { return (readUnsignedShort(offset) << 16) | readUnsignedShort(offset+2); } /* Print the i'th ';'-delimited substring of str on dst. */ private void print (String str, int i, PrintWriter dst) { int last = 0; int pos = -1; for (; i >= 0; i--) { last = ++pos; pos = str.indexOf(';', last); } dst.write(str, last, pos-last); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -