?? gen.java
字號:
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), rcond.falseJumps); } else { result = lcond; } } else { Item od = genExpr(tree.lhs, (Type) operator.type.argtypes().head); od.load(); result = completeBinop(tree.lhs, tree.rhs, operator); } } /** * Make a new string buffer. */ void makeStringBuffer(int pos) { code.emitop2(new_, makeRef(pos, syms.stringBufferType)); code.emitop(dup); callMethod(pos, syms.stringBufferType, names.init, Type.emptyList, false); } /** * Append value (on tos) to string buffer (on tos - 1). */ void appendString(Tree tree) { Type t = tree.type; if (t.tag > lastBaseTag && t.tsym != syms.stringType.tsym) { t = syms.objectType; } callMethod(tree.pos, syms.stringBufferType, names.append, Type.emptyList.prepend(t), false); } /** * Add all strings in tree to string buffer. */ void appendStrings(Tree tree) { tree = TreeInfo.skipParens(tree); if (tree.tag == Tree.PLUS && tree.type.constValue == null) { Binary op = (Binary) tree; if (op.operator.kind == MTH && ((OperatorSymbol) op.operator).opcode == string_add) { appendStrings(op.lhs); appendStrings(op.rhs); return; } } genExpr(tree, tree.type).load(); appendString(tree); } /** * Convert string buffer on tos to string. */ void bufferToString(int pos) { callMethod(pos, syms.stringBufferType, names.toString, Type.emptyList, false); } /** * Complete
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -