📄 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 + -