?? items.java
字號:
} else { load(); if (x >= 0) { makeImmediateItem(syms.intType, new Integer(x)).load(); code.emitop(iadd); } else { makeImmediateItem(syms.intType, new Integer(-x)).load(); code.emitop(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())); this.member = member; } Item load() { code.emitop(getstatic, Code.width(typecode)); code.emit2(pool.put(member)); return stackItem[typecode]; } Item store() { code.emitop(putstatic, -Code.width(typecode)); code.emit2(pool.put(member)); return voidItem; } Item invoke() { MethodType mtype = (MethodType) member.erasure(); int argsize = Code.width(mtype.argtypes); int rescode = Code.typecode(mtype.restype); int sdiff = Code.width(rescode) - argsize; code.emitop(invokestatic, sdiff); code.emit2(pool.put(member)); 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())); this.member = member; this.nonvirtual = nonvirtual; } Item load() { code.emitop(getfield, Code.width(typecode) - 1); code.emit2(pool.put(member)); return stackItem[typecode]; } Item store() { code.emitop(putfield, -Code.width(typecode) - 1); code.emit2(pool.put(member)); return voidItem; } Item invoke() { MethodType mtype = (MethodType) member.externalType(); int argsize = Code.width(mtype.argtypes); int rescode = Code.typecode(mtype.restype); int sdiff = Code.width(rescode) - argsize; if ((member.owner.flags() & Flags.INTERFACE) != 0) { code.emitop(invokeinterface, sdiff - 1); code.emit2(pool.put(member)); code.emit1(argsize + 1); code.emit1(0); } else if (nonvirtual) { code.emitop(invokespecial, sdiff - 1); code.emit2(pool.put(member)); } else { code.emitop(invokevirtual, sdiff - 1); code.emit2(pool.put(member)); } 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.emitop(ldc2w, 2); code.emit2(idx); } else if (idx <= 255) { code.emitop(ldc1, 1); code.emit1(idx); } else { code.emitop(ldc2, 1); code.emit2(idx); } } Item load() { switch (typecode) { case INTcode: case BYTEcode: case SHORTcode: case CHARcode: int ival = ((Number) value).intValue(); if (-1 <= ival && ival <= 5) code.emitop(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.emitop(lconst_0 + (int) lval); else ldc(); break; case FLOATcode: float fval = ((Number) value).floatValue(); if (isPosZero(fval) || fval == 1.0 || fval == 2.0) code.emitop(fconst_0 + (int) fval); else { ldc(); } break; case DOUBLEcode: double dval = ((Number) value).doubleValue(); if (isPosZero(dval) || dval == 1.0) code.emitop(dconst_0 + (int) dval); else ldc(); break; case OBJECTcode: ldc(); break; default: assert false; } return stackItem[typecode]; } /** * 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.0 && 1.0 / x > 0.0; } 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, new Integer(((Number) value).intValue())); case LONGcode: return new ImmediateItem(syms.longType, new Long(((Number) value).longValue())); case FLOATcode: return new ImmediateItem(syms.floatType, new Float(((Number) value).floatValue())); case DOUBLEcode: return new ImmediateItem(syms.doubleType, new Double(((Number) value).doubleValue())); case BYTEcode: return new ImmediateItem(syms.byteType, new Integer((byte)((Number) value).intValue())); case CHARcode: return new ImmediateItem(syms.charType, new Integer((char)((Number) value).intValue())); case SHORTcode: return new ImmediateItem(syms.shortType, new Integer((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; Tree 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 (trueJumps != null || opcode != dontgoto) { code.resolve(trueJumps); code.emitop(iconst_1); trueChain = code.branch(goto_); } if (falseChain != null) { code.resolve(falseChain); code.emitop(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)); 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))); 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() { return -code.stackdiff[opcode]; } 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 + -