📄 gen.java
字号:
}
public void visitBinary(Binary tree) {
complexity += 1;
if (tree.type.constValue == null)
super.visitBinary(tree);
}
public void visitTypeTest(TypeTest tree) {
super.visitTypeTest(tree);
complexity += 1;
}
public void visitIndexed(Indexed tree) {
super.visitIndexed(tree);
complexity += 1;
}
public void visitSelect(Select tree) {
super.visitSelect(tree);
if (tree.sym.kind == VAR)
complexity += 1;
}
public void visitIdent(Ident tree) {
if (tree.sym.kind == VAR) {
complexity += 1;
if (tree.type.constValue == null && tree.sym.owner.kind == TYP)
complexity += 1;
}
}
public void visitLiteral(Literal tree) {
complexity += 1;
}
public void visitTree(Tree tree) {
}
}
ComplexityScanner scanner = new ComplexityScanner();
tree.accept(scanner);
return scanner.complexity;
}
public void visitIf(If tree) {
int limit = code.nextreg;
Chain thenExit = null;
CondItem c = genCond(TreeInfo.skipParens(tree.cond), CRT_FLOW_CONTROLLER);
Chain elseChain = c.jumpFalse();
if (!c.isFalse()) {
code.resolve(c.trueJumps);
genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
thenExit = code.branch(goto_);
}
if (elseChain != null) {
code.resolve(elseChain);
if (tree.elsepart != null)
genStat(tree.elsepart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
}
code.resolve(thenExit);
code.endScopes(limit);
}
public void visitExec(Exec tree) {
if (tree.expr.tag == Tree.POSTINC)
tree.expr.tag = Tree.PREINC;
else if (tree.expr.tag == Tree.POSTDEC)
tree.expr.tag = Tree.PREDEC;
genExpr(tree.expr, tree.expr.type).drop();
}
public void visitBreak(Break tree) {
Env targetEnv = unwind(tree.target, env);
assert code.stacksize == 0;
((Gen.GenContext) targetEnv.info).addExit(code.branch(goto_));
endFinalizerGaps(env, targetEnv);
}
public void visitContinue(Continue tree) {
Env targetEnv = unwind(tree.target, env);
assert code.stacksize == 0;
((Gen.GenContext) targetEnv.info).addCont(code.branch(goto_));
endFinalizerGaps(env, targetEnv);
}
public void visitReturn(Return tree) {
int limit = code.nextreg;
final Env targetEnv;
if (tree.expr != null) {
Item r = genExpr(tree.expr, pt).load();
if (hasFinally(env.enclMethod, env)) {
r = makeTemp(pt);
r.store();
}
targetEnv = unwind(env.enclMethod, env);
r.load();
code.emitop(ireturn + Code.truncate(Code.typecode(pt)));
} else {
targetEnv = unwind(env.enclMethod, env);
code.emitop(return_);
}
endFinalizerGaps(env, targetEnv);
code.endScopes(limit);
}
public void visitThrow(Throw tree) {
genExpr(tree.expr, tree.expr.type).load();
code.emitop(athrow);
}
public void visitApply(Apply tree) {
Item m = genExpr(tree.meth, methodType);
genArgs(tree.args, TreeInfo.symbol(tree.meth).externalType().argtypes());
result = m.invoke();
}
public void visitConditional(Conditional tree) {
Chain thenExit = null;
CondItem c = genCond(tree.cond, CRT_FLOW_CONTROLLER);
Chain elseChain = c.jumpFalse();
if (!c.isFalse()) {
code.resolve(c.trueJumps);
int startpc = genCrt ? code.curPc() : 0;
genExpr(tree.truepart, pt).load();
if (genCrt)
code.crt.put(tree.truepart, CRT_FLOW_TARGET, startpc, code.curPc());
thenExit = code.branch(goto_);
}
if (elseChain != null) {
code.resolve(elseChain);
int startpc = genCrt ? code.curPc() : 0;
genExpr(tree.falsepart, pt).load();
if (genCrt)
code.crt.put(tree.falsepart, CRT_FLOW_TARGET, startpc, code.curPc());
}
code.resolve(thenExit);
result = items.makeStackItem(pt);
}
public void visitNewClass(NewClass tree) {
assert tree.encl == null && tree.def == null;
code.emitop2(new_, makeRef(tree.pos, tree.type));
code.emitop(dup);
genArgs(tree.args, tree.constructor.externalType().argtypes());
items.makeMemberItem(tree.constructor, true).invoke();
result = items.makeStackItem(tree.type);
}
public void visitNewArray(NewArray tree) {
if (tree.elems != null) {
Type elemtype = tree.type.elemtype();
loadIntConst(tree.elems.length());
Item arr = makeNewArray(tree.pos, tree.type, 1);
int i = 0;
for (List l = tree.elems; l.nonEmpty(); l = l.tail) {
arr.duplicate();
loadIntConst(i);
i++;
genExpr((Tree) l.head, elemtype).load();
items.makeIndexedItem(elemtype).store();
}
result = arr;
} else {
for (List l = tree.dims; l.nonEmpty(); l = l.tail) {
genExpr((Tree) l.head, syms.intType).load();
}
result = makeNewArray(tree.pos, tree.type, tree.dims.length());
}
}
/**
* Generate code to create an array with given element type and number
* of dimensions.
*/
Item makeNewArray(int pos, Type type, int ndims) {
Type elemtype = type.elemtype();
if (elemtype.dimensions() + ndims > ClassFile.MAX_DIMENSIONS) {
log.error(pos, "limit.dimensions");
nerrs++;
}
int elemcode = Code.arraycode(elemtype);
if (elemcode == 0 || (elemcode == 1 && ndims == 1)) {
code.emitop2(anewarray, makeRef(pos, elemtype));
} else if (elemcode == 1) {
code.emitop(multianewarray, 1 - ndims);
code.emit2(makeRef(pos, type));
code.emit1(ndims);
} else {
code.emitop1(newarray, elemcode);
}
return items.makeStackItem(type);
}
public void visitParens(Parens tree) {
result = genExpr(tree.expr, tree.expr.type);
}
public void visitAssign(Assign tree) {
Item l = genExpr(tree.lhs, tree.lhs.type);
genExpr(tree.rhs, tree.lhs.type).load();
result = items.makeAssignItem(l);
}
public void visitAssignop(Assignop tree) {
OperatorSymbol operator = (OperatorSymbol) tree.operator;
Item l;
if (operator.opcode == string_add) {
makeStringBuffer(tree.pos);
l = genExpr(tree.lhs, tree.lhs.type);
if (l.width() > 0) {
code.emitop(dup_x1 + 3 * (l.width() - 1));
}
l.load();
appendString(tree.lhs);
appendStrings(tree.rhs);
bufferToString(tree.pos);
} else {
l = genExpr(tree.lhs, tree.lhs.type);
if ((tree.tag == Tree.PLUS_ASG || tree.tag == Tree.MINUS_ASG) &&
l instanceof LocalItem && tree.lhs.type.tag <= INT &&
tree.rhs.type.tag <= INT && tree.rhs.type.constValue != null) {
int ival = ((Number) tree.rhs.type.constValue).intValue();
if (tree.tag == Tree.MINUS_ASG)
ival = -ival;
if (-128 <= ival && ival <= 127) {
((LocalItem) l).incr(ival);
result = l;
return;
}
}
l.duplicate();
l.coerce((Type) operator.type.argtypes().head).load();
completeBinop(tree.lhs, tree.rhs, operator).coerce(tree.lhs.type);
}
result = items.makeAssignItem(l);
}
public void visitUnary(Unary tree) {
OperatorSymbol operator = (OperatorSymbol) tree.operator;
if (tree.tag == Tree.NOT) {
CondItem od = genCond(tree.arg, false);
result = od.negate();
} else {
Item od = genExpr(tree.arg, (Type) operator.type.argtypes().head);
switch (tree.tag) {
case Tree.POS:
result = od.load();
break;
case Tree.NEG:
result = od.load();
code.emitop(operator.opcode);
break;
case Tree.COMPL:
result = od.load();
emitMinusOne(od.typecode);
code.emitop(operator.opcode);
break;
case Tree.PREINC:
case Tree.PREDEC:
od.duplicate();
if (od instanceof LocalItem &&
(operator.opcode == iadd || operator.opcode == isub)) {
((LocalItem) od).incr(tree.tag == Tree.PREINC ? 1 : -1);
result = od;
} else {
od.load();
code.emitop(one(od.typecode));
code.emitop(operator.opcode);
if (od.typecode != INTcode &&
Code.truncate(od.typecode) == INTcode)
code.emitop(int2byte + od.typecode - BYTEcode);
result = items.makeAssignItem(od);
}
break;
case Tree.POSTINC:
case Tree.POSTDEC:
od.duplicate();
if (od instanceof LocalItem && operator.opcode == iadd) {
Item res = od.load();
((LocalItem) od).incr(tree.tag == Tree.POSTINC ? 1 : -1);
result = res;
} else {
Item res = od.load();
od.stash(od.typecode);
code.emitop(one(od.typecode));
code.emitop(operator.opcode);
if (od.typecode != INTcode &&
Code.truncate(od.typecode) == INTcode)
code.emitop(int2byte + od.typecode - BYTEcode);
od.store();
result = res;
}
break;
case Tree.NULLCHK:
result = od.load();
code.emitop(dup);
genNullCheck(tree.pos);
break;
default:
assert false;
}
}
}
/**
* Generate a null check from the object value at stack top.
*/
private void genNullCheck(int pos) {
callMethod(pos, syms.objectType, names.getClass, Type.emptyList, false);
code.emitop(pop);
}
public void visitBinary(Binary tree) {
OperatorSymbol operator = (OperatorSymbol) tree.operator;
if (operator.opcode == string_add) {
makeStringBuffer(tree.pos);
appendStrings(tree);
bufferToString(tree.pos);
result = items.makeStackItem(syms.stringType);
} else if (tree.tag == Tree.AND) {
CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);
if (!lcond.isFalse()) {
Chain falseJumps = lcond.jumpFalse();
code.resolve(lcond.trueJumps);
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
result = items.makeCondItem(rcond.opcode, rcond.trueJumps,
code.mergeChains(falseJumps, rcond.falseJumps));
} else {
result = lcond;
}
} else if (tree.tag == Tree.OR) {
CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);
if (!lcond.isTrue()) {
Chain trueJumps = lcond.jumpTrue();
code.resolve(lcond.falseJumps);
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
result = items.makeCondItem(rcond.opcode,
code.mergeChains(trueJumps, rcond.trueJumps),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -