📄 items.java
字号:
code.emitop1w(istore + Code.truncate(typecode), reg); code.setDefined(reg); } void incr(int x) { if (typecode == INTcode && x >= -32768 && x <= 32767) { code.emitop1w(iinc, reg, x); } else { load(); if (x >= 0) { makeImmediateItem(syms.intType, x).load(); code.emitop0(iadd); } else { makeImmediateItem(syms.intType, -x).load(); code.emitop0(isub); } makeStackItem(syms.intType).coerce(typecode); store(); } } public String toString() { return "localItem(type=" + type + "; reg=" + reg + ")"; } } /** An item representing a static variable or method. */ class StaticItem extends Item { /** The represented symbol. */ Symbol member; StaticItem(Symbol member) { super(Code.typecode(member.erasure(types))); this.member = member; } Item load() { code.emitop2(getstatic, pool.put(member)); return stackItem[typecode]; } void store() { code.emitop2(putstatic, pool.put(member)); } Item invoke() { MethodType mtype = (MethodType)member.erasure(types); int argsize = Code.width(mtype.argtypes); int rescode = Code.typecode(mtype.restype); int sdiff = Code.width(rescode) - argsize; code.emitInvokestatic(pool.put(member), mtype); return stackItem[rescode]; } public String toString() { return "static(" + member + ")"; } } /** An item representing an instance variable or method. */ class MemberItem extends Item { /** The represented symbol. */ Symbol member; /** Flag that determines whether or not access is virtual. */ boolean nonvirtual; MemberItem(Symbol member, boolean nonvirtual) { super(Code.typecode(member.erasure(types))); this.member = member; this.nonvirtual = nonvirtual; } Item load() { code.emitop2(getfield, pool.put(member)); return stackItem[typecode]; } void store() { code.emitop2(putfield, pool.put(member)); } Item invoke() { MethodType mtype = (MethodType)member.externalType(types); int rescode = Code.typecode(mtype.restype); if ((member.owner.flags() & Flags.INTERFACE) != 0) { code.emitInvokeinterface(pool.put(member), mtype); } else if (nonvirtual) { code.emitInvokespecial(pool.put(member), mtype); } else { code.emitInvokevirtual(pool.put(member), mtype); } return stackItem[rescode]; } void duplicate() { stackItem[OBJECTcode].duplicate(); } void drop() { stackItem[OBJECTcode].drop(); } void stash(int toscode) { stackItem[OBJECTcode].stash(toscode); } int width() { return 1; } public String toString() { return "member(" + member + (nonvirtual ? " nonvirtual)" : ")"); } } /** An item representing a literal. */ class ImmediateItem extends Item { /** The literal's value. */ Object value; ImmediateItem(Type type, Object value) { super(Code.typecode(type)); this.value = value; } private void ldc() { int idx = pool.put(value); if (typecode == LONGcode || typecode == DOUBLEcode) { code.emitop2(ldc2w, idx); } else if (idx <= 255) { code.emitop1(ldc1, idx); } else { code.emitop2(ldc2, idx); } } Item load() { switch (typecode) { case INTcode: case BYTEcode: case SHORTcode: case CHARcode: int ival = ((Number)value).intValue(); if (-1 <= ival && ival <= 5) code.emitop0(iconst_0 + ival); else if (Byte.MIN_VALUE <= ival && ival <= Byte.MAX_VALUE) code.emitop1(bipush, ival); else if (Short.MIN_VALUE <= ival && ival <= Short.MAX_VALUE) code.emitop2(sipush, ival); else ldc(); break; case LONGcode: long lval = ((Number)value).longValue(); if (lval == 0 || lval == 1) code.emitop0(lconst_0 + (int)lval); else ldc(); break; case FLOATcode: float fval = ((Number)value).floatValue(); if (isPosZero(fval) || fval == 1.0 || fval == 2.0) code.emitop0(fconst_0 + (int)fval); else { ldc(); } break; case DOUBLEcode: double dval = ((Number)value).doubleValue(); if (isPosZero(dval) || dval == 1.0) code.emitop0(dconst_0 + (int)dval); else ldc(); break; case OBJECTcode: ldc(); break; default: assert false; } return stackItem[typecode]; } //where /** Return true iff float number is positive 0. */ private boolean isPosZero(float x) { return x == 0.0f && 1.0f / x > 0.0f; } /** Return true iff double number is positive 0. */ private boolean isPosZero(double x) { return x == 0.0d && 1.0d / x > 0.0d; } CondItem mkCond() { int ival = ((Number)value).intValue(); return makeCondItem(ival != 0 ? goto_ : dontgoto); } Item coerce(int targetcode) { if (typecode == targetcode) { return this; } else { switch (targetcode) { case INTcode: if (Code.truncate(typecode) == INTcode) return this; else return new ImmediateItem( syms.intType, ((Number)value).intValue()); case LONGcode: return new ImmediateItem( syms.longType, ((Number)value).longValue()); case FLOATcode: return new ImmediateItem( syms.floatType, ((Number)value).floatValue()); case DOUBLEcode: return new ImmediateItem( syms.doubleType, ((Number)value).doubleValue()); case BYTEcode: return new ImmediateItem( syms.byteType, (int)(byte)((Number)value).intValue()); case CHARcode: return new ImmediateItem( syms.charType, (int)(char)((Number)value).intValue()); case SHORTcode: return new ImmediateItem( syms.shortType, (int)(short)((Number)value).intValue()); default: return super.coerce(targetcode); } } } public String toString() { return "immediate(" + value + ")"; } } /** An item representing an assignment expressions. */ class AssignItem extends Item { /** The item representing the assignment's left hand side. */ Item lhs; AssignItem(Item lhs) { super(lhs.typecode); this.lhs = lhs; } Item load() { lhs.stash(typecode); lhs.store(); return stackItem[typecode]; } void duplicate() { load().duplicate(); } void drop() { lhs.store(); } void stash(int toscode) { assert false; } int width() { return lhs.width() + Code.width(typecode); } public String toString() { return "assign(lhs = " + lhs + ")"; } } /** An item representing a conditional or unconditional jump. */ class CondItem extends Item { /** A chain encomassing all jumps that can be taken * if the condition evaluates to true. */ Chain trueJumps; /** A chain encomassing all jumps that can be taken * if the condition evaluates to false. */ Chain falseJumps; /** The jump's opcode. */ int opcode; /* * An abstract syntax tree of this item. It is needed * for branch entries in 'CharacterRangeTable' attribute. */ JCTree tree; CondItem(int opcode, Chain truejumps, Chain falsejumps) { super(BYTEcode); this.opcode = opcode; this.trueJumps = truejumps; this.falseJumps = falsejumps; } Item load() { Chain trueChain = null; Chain falseChain = jumpFalse(); if (!isFalse()) { code.resolve(trueJumps); code.emitop0(iconst_1); trueChain = code.branch(goto_); } if (falseChain != null) { code.resolve(falseChain); code.emitop0(iconst_0); } code.resolve(trueChain); return stackItem[typecode]; } void duplicate() { load().duplicate(); } void drop() { load().drop(); } void stash(int toscode) { assert false; } CondItem mkCond() { return this; } Chain jumpTrue() { if (tree == null) return code.mergeChains(trueJumps, code.branch(opcode)); // we should proceed further in -Xjcov mode only int startpc = code.curPc(); Chain c = code.mergeChains(trueJumps, code.branch(opcode)); code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc()); return c; } Chain jumpFalse() { if (tree == null) return code.mergeChains(falseJumps, code.branch(code.negate(opcode))); // we should proceed further in -Xjcov mode only int startpc = code.curPc(); Chain c = code.mergeChains(falseJumps, code.branch(code.negate(opcode))); code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc()); return c; } CondItem negate() { CondItem c = new CondItem(code.negate(opcode), falseJumps, trueJumps); c.tree = tree; return c; } int width() { // a CondItem doesn't have a size on the stack per se. throw new AssertionError(); } boolean isTrue() { return falseJumps == null && opcode == goto_; } boolean isFalse() { return trueJumps == null && opcode == dontgoto; } public String toString() { return "cond(" + Code.mnem(opcode) + ")"; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -