0001: // Copyright (c) Corporation for National Research Initiatives
0002:
0003: package org.python.compiler;
0004:
0005: import java.io.IOException;
0006: import java.util.Hashtable;
0007: import java.util.Stack;
0008: import java.util.Vector;
0009:
0010: import org.python.core.CompilerFlags;
0011: import org.python.core.PyComplex;
0012: import org.python.core.PyFloat;
0013: import org.python.core.PyInteger;
0014: import org.python.core.PyLong;
0015: import org.python.core.PyObject;
0016: import org.python.parser.ParseException;
0017: import org.python.parser.SimpleNode;
0018: import org.python.parser.Visitor;
0019: import org.python.parser.ast.Assert;
0020: import org.python.parser.ast.Assign;
0021: import org.python.parser.ast.Attribute;
0022: import org.python.parser.ast.AugAssign;
0023: import org.python.parser.ast.BinOp;
0024: import org.python.parser.ast.BoolOp;
0025: import org.python.parser.ast.Break;
0026: import org.python.parser.ast.Call;
0027: import org.python.parser.ast.ClassDef;
0028: import org.python.parser.ast.Compare;
0029: import org.python.parser.ast.Continue;
0030: import org.python.parser.ast.Delete;
0031: import org.python.parser.ast.Dict;
0032: import org.python.parser.ast.Ellipsis;
0033: import org.python.parser.ast.Exec;
0034: import org.python.parser.ast.Expr;
0035: import org.python.parser.ast.Expression;
0036: import org.python.parser.ast.ExtSlice;
0037: import org.python.parser.ast.For;
0038: import org.python.parser.ast.FunctionDef;
0039: import org.python.parser.ast.Global;
0040: import org.python.parser.ast.If;
0041: import org.python.parser.ast.Import;
0042: import org.python.parser.ast.ImportFrom;
0043: import org.python.parser.ast.Index;
0044: import org.python.parser.ast.Interactive;
0045: import org.python.parser.ast.Lambda;
0046: import org.python.parser.ast.List;
0047: import org.python.parser.ast.ListComp;
0048: import org.python.parser.ast.Name;
0049: import org.python.parser.ast.Num;
0050: import org.python.parser.ast.Pass;
0051: import org.python.parser.ast.Print;
0052: import org.python.parser.ast.Raise;
0053: import org.python.parser.ast.Repr;
0054: import org.python.parser.ast.Return;
0055: import org.python.parser.ast.Slice;
0056: import org.python.parser.ast.Str;
0057: import org.python.parser.ast.Subscript;
0058: import org.python.parser.ast.Suite;
0059: import org.python.parser.ast.TryExcept;
0060: import org.python.parser.ast.TryFinally;
0061: import org.python.parser.ast.Tuple;
0062: import org.python.parser.ast.UnaryOp;
0063: import org.python.parser.ast.Unicode;
0064: import org.python.parser.ast.While;
0065: import org.python.parser.ast.Yield;
0066: import org.python.parser.ast.excepthandlerType;
0067: import org.python.parser.ast.exprType;
0068: import org.python.parser.ast.expr_contextType;
0069: import org.python.parser.ast.keywordType;
0070: import org.python.parser.ast.listcompType;
0071: import org.python.parser.ast.modType;
0072: import org.python.parser.ast.stmtType;
0073:
0074: public class CodeCompiler extends Visitor implements ClassConstants //, PythonGrammarTreeConstants
0075: {
0076:
0077: public static final Object Exit = new Integer(1);
0078: public static final Object NoExit = null;
0079:
0080: public static final int GET = 0;
0081: public static final int SET = 1;
0082: public static final int DEL = 2;
0083: public static final int AUGGET = 3;
0084: public static final int AUGSET = 4;
0085:
0086: public Module module;
0087: public Code code;
0088: public ConstantPool pool;
0089: public CodeCompiler mrefs;
0090: public CompilerFlags cflags;
0091:
0092: int temporary;
0093: int augmode;
0094: int augtmp1;
0095: int augtmp2;
0096: int augtmp3;
0097: int augtmp4;
0098:
0099: public boolean fast_locals, print_results;
0100:
0101: public Hashtable tbl;
0102: public ScopeInfo my_scope;
0103:
0104: boolean optimizeGlobals = true;
0105: public Vector names;
0106: public String className;
0107:
0108: public Stack continueLabels, breakLabels;
0109: public Stack exceptionHandlers;
0110: public Vector yields = new Vector();
0111:
0112: /* break/continue finally's level.
0113: * This is the lowest level in the exceptionHandlers which should
0114: * be executed at break or continue.
0115: * It is saved/updated/restored when compiling loops.
0116: * A similar level for returns is not needed because a new CodeCompiler
0117: * is used for each PyCode, ie. each 'function'.
0118: * When returning through finally's all the exceptionHandlers are executed.
0119: */
0120: public int bcfLevel = 0;
0121:
0122: public CodeCompiler(Module module, boolean print_results) {
0123: this .module = module;
0124: this .print_results = print_results;
0125:
0126: mrefs = this ;
0127: pool = module.classfile.pool;
0128:
0129: continueLabels = new Stack();
0130: breakLabels = new Stack();
0131: exceptionHandlers = new Stack();
0132: }
0133:
0134: public int PyNone;
0135:
0136: public void getNone() throws IOException {
0137: if (mrefs.PyNone == 0) {
0138: mrefs.PyNone = pool.Fieldref("org/python/core/Py", "None",
0139: $pyObj);
0140: }
0141: code.getstatic(mrefs.PyNone);
0142: }
0143:
0144: public void loadFrame() throws Exception {
0145: code.aload(1);
0146: }
0147:
0148: int f_lasti;
0149:
0150: public void setLastI(int idx) throws Exception {
0151: if (mrefs.f_lasti == 0) {
0152: mrefs.f_lasti = code.pool.Fieldref(
0153: "org/python/core/PyFrame", "f_lasti", "I");
0154: }
0155: loadFrame();
0156: code.iconst(idx);
0157: code.putfield(mrefs.f_lasti);
0158: }
0159:
0160: int f_back;
0161:
0162: private void loadf_back() throws Exception {
0163: if (mrefs.f_back == 0) {
0164: mrefs.f_back = code.pool.Fieldref(
0165: "org/python/core/PyFrame", "f_back", $pyFrame);
0166: }
0167: code.getfield(f_back);
0168: }
0169:
0170: public int storeTop() throws Exception {
0171: int tmp = code.getLocal("org/python/core/PyObject");
0172: code.astore(tmp);
0173: return tmp;
0174: }
0175:
0176: public int setline;
0177:
0178: public void setline(int line) throws Exception {
0179: //System.out.println("line: "+line+", "+code.stack);
0180: if (module.linenumbers) {
0181: code.setline(line);
0182: loadFrame();
0183: code.iconst(line);
0184: if (mrefs.setline == 0) {
0185: mrefs.setline = pool.Methodref(
0186: "org/python/core/PyFrame", "setline", "(I)V");
0187: }
0188: code.invokevirtual(mrefs.setline);
0189: }
0190: }
0191:
0192: public void setline(SimpleNode node) throws Exception {
0193: setline(node.beginLine);
0194: }
0195:
0196: public void set(SimpleNode node) throws Exception {
0197: int tmp = storeTop();
0198: set(node, tmp);
0199: code.aconst_null();
0200: code.astore(tmp);
0201: code.freeLocal(tmp);
0202: }
0203:
0204: boolean inSet = false;
0205:
0206: public void set(SimpleNode node, int tmp) throws Exception {
0207: //System.out.println("tmp: "+tmp);
0208: if (inSet) {
0209: System.out
0210: .println("recurse set: " + tmp + ", " + temporary);
0211: }
0212: temporary = tmp;
0213: visit(node);
0214: }
0215:
0216: private void saveAugTmps(SimpleNode node, int count)
0217: throws Exception {
0218: if (count >= 4) {
0219: augtmp4 = code.getLocal("org/python/core/PyObject");
0220: code.astore(augtmp4);
0221: }
0222: if (count >= 3) {
0223: augtmp3 = code.getLocal("org/python/core/PyObject");
0224: code.astore(augtmp3);
0225: }
0226: if (count >= 2) {
0227: augtmp2 = code.getLocal("org/python/core/PyObject");
0228: code.astore(augtmp2);
0229: }
0230: augtmp1 = code.getLocal("org/python/core/PyObject");
0231: code.astore(augtmp1);
0232:
0233: code.aload(augtmp1);
0234: if (count >= 2)
0235: code.aload(augtmp2);
0236: if (count >= 3)
0237: code.aload(augtmp3);
0238: if (count >= 4)
0239: code.aload(augtmp4);
0240: }
0241:
0242: private void restoreAugTmps(SimpleNode node, int count)
0243: throws Exception {
0244: code.aload(augtmp1);
0245: code.freeLocal(augtmp1);
0246: if (count == 1)
0247: return;
0248: code.aload(augtmp2);
0249: code.freeLocal(augtmp2);
0250: if (count == 2)
0251: return;
0252: code.aload(augtmp3);
0253: code.freeLocal(augtmp3);
0254: if (count == 3)
0255: return;
0256: code.aload(augtmp4);
0257: code.freeLocal(augtmp4);
0258: }
0259:
0260: public void parse(modType node, Code code, boolean fast_locals,
0261: String className, boolean classBody, ScopeInfo scope,
0262: CompilerFlags cflags) throws Exception {
0263: this .fast_locals = fast_locals;
0264: this .className = className;
0265: this .code = code;
0266: this .cflags = cflags;
0267:
0268: my_scope = scope;
0269: names = scope.names;
0270:
0271: tbl = scope.tbl;
0272: optimizeGlobals = fast_locals && !scope.exec
0273: && !scope.from_import_star;
0274:
0275: Object exit = visit(node);
0276: //System.out.println("exit: "+exit+", "+(exit==null));
0277:
0278: if (classBody) {
0279: loadFrame();
0280: code.invokevirtual("org/python/core/PyFrame",
0281: "getf_locals", "()" + $pyObj);
0282: code.areturn();
0283: } else {
0284: if (exit == null) {
0285: //System.out.println("no exit");
0286: setLastI(-1);
0287:
0288: getNone();
0289: code.areturn();
0290: }
0291: }
0292: }
0293:
0294: public Object visitInteractive(Interactive node) throws Exception {
0295: traverse(node);
0296: return null;
0297: }
0298:
0299: public Object visitModule(org.python.parser.ast.Module suite)
0300: throws Exception {
0301: if (mrefs.setglobal == 0) {
0302: mrefs.setglobal = code.pool.Methodref(
0303: "org/python/core/PyFrame", "setglobal", "(" + $str
0304: + $pyObj + ")V");
0305: }
0306:
0307: if (suite.body.length > 0 && suite.body[0] instanceof Expr
0308: && ((Expr) suite.body[0]).value instanceof Str) {
0309: loadFrame();
0310: code.ldc("__doc__");
0311: visit(((Expr) suite.body[0]).value);
0312: code.invokevirtual(mrefs.setglobal);
0313: }
0314: if (module.setFile) {
0315: loadFrame();
0316: code.ldc("__file__");
0317: module.filename.get(code);
0318: code.invokevirtual(mrefs.setglobal);
0319: }
0320: traverse(suite);
0321: return null;
0322: }
0323:
0324: public Object visitExpression(Expression node) throws Exception {
0325: if (my_scope.generator && node.body != null) {
0326: module.error("'return' with argument inside generator",
0327: true, node);
0328: }
0329: return visitReturn(new Return(node.body, node), true);
0330: }
0331:
0332: public int EmptyObjects;
0333:
0334: public void makeArray(SimpleNode[] nodes) throws Exception {
0335: int n;
0336:
0337: if (nodes == null)
0338: n = 0;
0339: else
0340: n = nodes.length;
0341:
0342: if (n == 0) {
0343: if (mrefs.EmptyObjects == 0) {
0344: mrefs.EmptyObjects = code.pool
0345: .Fieldref("org/python/core/Py", "EmptyObjects",
0346: $pyObjArr);
0347: }
0348: code.getstatic(mrefs.EmptyObjects);
0349: } else {
0350: int tmp = code.getLocal("[org/python/core/PyObject");
0351: code.iconst(n);
0352: code.anewarray(code.pool.Class("org/python/core/PyObject"));
0353: code.astore(tmp);
0354:
0355: for (int i = 0; i < n; i++) {
0356: code.aload(tmp);
0357: code.iconst(i);
0358: visit(nodes[i]);
0359: code.aastore();
0360: }
0361: code.aload(tmp);
0362: code.freeLocal(tmp);
0363: }
0364: }
0365:
0366: public void getDocString(stmtType[] suite) throws Exception {
0367: //System.out.println("doc: "+suite.getChild(0));
0368: if (suite.length > 0 && suite[0] instanceof Expr
0369: && ((Expr) suite[0]).value instanceof Str) {
0370: visit(((Expr) suite[0]).value);
0371: } else {
0372: code.aconst_null();
0373: }
0374: }
0375:
0376: int getclosure;
0377:
0378: public boolean makeClosure(ScopeInfo scope) throws Exception {
0379: if (scope == null || scope.freevars == null)
0380: return false;
0381: int n = scope.freevars.size();
0382: if (n == 0)
0383: return false;
0384:
0385: if (mrefs.getclosure == 0) {
0386: mrefs.getclosure = code.pool.Methodref(
0387: "org/python/core/PyFrame", "getclosure", "(I)"
0388: + $pyObj);
0389: }
0390:
0391: int tmp = code.getLocal("[org/python/core/PyObject");
0392: code.iconst(n);
0393: code.anewarray(code.pool.Class("org/python/core/PyObject"));
0394: code.astore(tmp);
0395: Hashtable upTbl = scope.up.tbl;
0396: for (int i = 0; i < n; i++) {
0397: code.aload(tmp);
0398: code.iconst(i);
0399: loadFrame();
0400: for (int j = 1; j < scope.distance; j++) {
0401: loadf_back();
0402: }
0403: SymInfo symInfo = (SymInfo) upTbl.get(scope.freevars
0404: .elementAt(i));
0405: code.iconst(symInfo.env_index);
0406: code.invokevirtual(getclosure);
0407: code.aastore();
0408: }
0409:
0410: code.aload(tmp);
0411: code.freeLocal(tmp);
0412:
0413: return true;
0414: }
0415:
0416: int f_globals, PyFunction_init, PyFunction_closure_init;
0417:
0418: public Object visitFunctionDef(FunctionDef node) throws Exception {
0419: String name = getName(node.name);
0420:
0421: setline(node);
0422:
0423: code.new_(code.pool.Class("org/python/core/PyFunction"));
0424: code.dup();
0425: loadFrame();
0426: if (mrefs.f_globals == 0) {
0427: mrefs.f_globals = code.pool.Fieldref(
0428: "org/python/core/PyFrame", "f_globals", $pyObj);
0429: }
0430: code.getfield(mrefs.f_globals);
0431:
0432: ScopeInfo scope = module.getScopeInfo(node);
0433:
0434: makeArray(scope.ac.getDefaults());
0435:
0436: scope.setup_closure();
0437: scope.dump();
0438: module.PyCode(new Suite(node.body, node), name, true,
0439: className, false, false, node.beginLine, scope, cflags)
0440: .get(code);
0441:
0442: getDocString(node.body);
0443:
0444: if (!makeClosure(scope)) {
0445: if (mrefs.PyFunction_init == 0) {
0446: mrefs.PyFunction_init = code.pool.Methodref(
0447: "org/python/core/PyFunction", "<init>", "("
0448: + $pyObj + $pyObjArr + $pyCode + $pyObj
0449: + ")V");
0450: }
0451: code.invokespecial(mrefs.PyFunction_init);
0452: } else {
0453: if (mrefs.PyFunction_closure_init == 0) {
0454: mrefs.PyFunction_closure_init = code.pool.Methodref(
0455: "org/python/core/PyFunction", "<init>", "("
0456: + $pyObj + $pyObjArr + $pyCode + $pyObj
0457: + $pyObjArr + ")V");
0458: }
0459: code.invokespecial(mrefs.PyFunction_closure_init);
0460:
0461: }
0462:
0463: set(new Name(node.name, Name.Store, node));
0464: return null;
0465: }
0466:
0467: public int printResult;
0468:
0469: public Object visitExpr(Expr node) throws Exception {
0470: setline(node);
0471: visit(node.value);
0472:
0473: if (print_results) {
0474: if (mrefs.printResult == 0) {
0475: mrefs.printResult = code.pool.Methodref(
0476: "org/python/core/Py", "printResult", "("
0477: + $pyObj + ")V");
0478: }
0479: code.invokestatic(mrefs.printResult);
0480: } else {
0481: code.pop();
0482: }
0483: return null;
0484: }
0485:
0486: public Object visitAssign(Assign node) throws Exception {
0487: setline(node);
0488: visit(node.value);
0489: if (node.targets.length == 1) {
0490: set(node.targets[0]);
0491: return null;
0492: }
0493: int tmp = storeTop();
0494: for (int i = node.targets.length - 1; i >= 0; i--) {
0495: set(node.targets[i], tmp);
0496: }
0497: code.freeLocal(tmp);
0498: return null;
0499: }
0500:
0501: public int print1, print2, print3, print4, print5, print6;
0502:
0503: public Object visitPrint(Print node) throws Exception {
0504: setline(node);
0505: int tmp = -1;
0506: int printcomma, printlnv, println;
0507:
0508: if (node.dest != null) {
0509: visit(node.dest);
0510: tmp = storeTop();
0511: if (mrefs.print4 == 0) {
0512: mrefs.print4 = pool.Methodref("org/python/core/Py",
0513: "printComma", "(" + $pyObj + $pyObj + ")V");
0514: }
0515: printcomma = mrefs.print4;
0516: if (mrefs.print5 == 0) {
0517: mrefs.print5 = pool.Methodref("org/python/core/Py",
0518: "println", "(" + $pyObj + $pyObj + ")V");
0519: }
0520: println = mrefs.print5;
0521: if (mrefs.print6 == 0) {
0522: mrefs.print6 = pool.Methodref("org/python/core/Py",
0523: "printlnv", "(" + $pyObj + ")V");
0524: }
0525: printlnv = mrefs.print6;
0526: } else {
0527: if (mrefs.print1 == 0) {
0528: mrefs.print1 = pool.Methodref("org/python/core/Py",
0529: "printComma", "(" + $pyObj + ")V");
0530: }
0531: printcomma = mrefs.print1;
0532: if (mrefs.print2 == 0) {
0533: mrefs.print2 = pool.Methodref("org/python/core/Py",
0534: "println", "(" + $pyObj + ")V");
0535: }
0536: println = mrefs.print2;
0537: if (mrefs.print3 == 0) {
0538: mrefs.print3 = pool.Methodref("org/python/core/Py",
0539: "println", "()V");
0540: }
0541: printlnv = mrefs.print3;
0542: }
0543:
0544: if (node.values == null || node.values.length == 0) {
0545: if (node.dest != null)
0546: code.aload(tmp);
0547: code.invokestatic(printlnv);
0548: } else {
0549: for (int i = 0; i < node.values.length; i++) {
0550: if (node.dest != null)
0551: code.aload(tmp);
0552: visit(node.values[i]);
0553: if (node.nl && i == node.values.length - 1) {
0554: code.invokestatic(println);
0555: } else {
0556: code.invokestatic(printcomma);
0557: }
0558: }
0559: }
0560: if (node.dest != null)
0561: code.freeLocal(tmp);
0562: return null;
0563: }
0564:
0565: public Object visitDelete(Delete node) throws Exception {
0566: setline(node);
0567: traverse(node);
0568: return null;
0569: }
0570:
0571: public Object visitPass(Pass node) throws Exception {
0572: setline(node);
0573: return null;
0574: }
0575:
0576: public Object visitBreak(Break node) throws Exception {
0577: //setline(node); Not needed here...
0578: if (breakLabels.empty()) {
0579: throw new ParseException("'break' outside loop", node);
0580: }
0581:
0582: doFinallysDownTo(bcfLevel);
0583:
0584: code.goto_((Label) breakLabels.peek());
0585: return null;
0586: }
0587:
0588: public Object visitContinue(Continue node) throws Exception {
0589: //setline(node); Not needed here...
0590: if (continueLabels.empty()) {
0591: throw new ParseException("'continue' not properly in loop",
0592: node);
0593: }
0594:
0595: doFinallysDownTo(bcfLevel);
0596:
0597: code.goto_((Label) continueLabels.peek());
0598: return Exit;
0599: }
0600:
0601: int yield_count = 0;
0602:
0603: int f_savedlocals;
0604:
0605: public Object visitYield(Yield node) throws Exception {
0606: setline(node);
0607: if (!fast_locals) {
0608: throw new ParseException("'yield' outside function", node);
0609: }
0610:
0611: if (inFinallyBody()) {
0612: throw new ParseException("'yield' not allowed in a 'try' "
0613: + "block with a 'finally' clause", node);
0614: }
0615:
0616: saveLocals();
0617: visit(node.value);
0618: setLastI(++yield_count);
0619: code.areturn();
0620:
0621: Label restart = code.getLabel();
0622: yields.addElement(restart);
0623: restart.setPosition();
0624: restoreLocals();
0625: return null;
0626: }
0627:
0628: private boolean inFinallyBody() {
0629: for (int i = 0; i < exceptionHandlers.size(); ++i) {
0630: ExceptionHandler handler = (ExceptionHandler) exceptionHandlers
0631: .elementAt(i);
0632: if (handler.isFinallyHandler()) {
0633: return true;
0634: }
0635: }
0636: return false;
0637: }
0638:
0639: private void restoreLocals() throws Exception {
0640: endExceptionHandlers();
0641:
0642: Vector v = code.getActiveLocals();
0643:
0644: loadFrame();
0645: if (mrefs.f_savedlocals == 0) {
0646: mrefs.f_savedlocals = code.pool.Fieldref(
0647: "org/python/core/PyFrame", "f_savedlocals",
0648: "[Ljava/lang/Object;");
0649: }
0650: code.getfield(mrefs.f_savedlocals);
0651:
0652: int locals = code.getLocal("[java/lang/Object");
0653: code.astore(locals);
0654:
0655: for (int i = 0; i < v.size(); i++) {
0656: String type = (String) v.elementAt(i);
0657: if (type == null)
0658: continue;
0659: code.aload(locals);
0660: code.iconst(i);
0661: code.aaload();
0662: code.checkcast(code.pool.Class(type));
0663: code.astore(i);
0664: }
0665: code.freeLocal(locals);
0666:
0667: restartExceptionHandlers();
0668: }
0669:
0670: /**
0671: * Close all the open exception handler ranges. This should be paired
0672: * with restartExceptionHandlers to delimit internal code that
0673: * shouldn't be handled by user handlers. This allows us to set
0674: * variables without the verifier thinking we might jump out of our
0675: * handling with an exception.
0676: */
0677: private void endExceptionHandlers() {
0678: Label end = code.getLabelAtPosition();
0679: for (int i = 0; i < exceptionHandlers.size(); ++i) {
0680: ExceptionHandler handler = (ExceptionHandler) exceptionHandlers
0681: .elementAt(i);
0682: handler.exceptionEnds.addElement(end);
0683: }
0684: }
0685:
0686: private void restartExceptionHandlers() {
0687: Label start = code.getLabelAtPosition();
0688: for (int i = 0; i < exceptionHandlers.size(); ++i) {
0689: ExceptionHandler handler = (ExceptionHandler) exceptionHandlers
0690: .elementAt(i);
0691: handler.exceptionStarts.addElement(start);
0692: }
0693: }
0694:
0695: private void saveLocals() throws Exception {
0696: Vector v = code.getActiveLocals();
0697: //System.out.println("bs:" + bs);
0698: code.iconst(v.size());
0699: //code.anewarray(code.pool.Class("org/python/core/PyObject"));
0700: code.anewarray(code.pool.Class("java/lang/Object"));
0701: int locals = code.getLocal("[java/lang/Object");
0702: code.astore(locals);
0703:
0704: for (int i = 0; i < v.size(); i++) {
0705: String type = (String) v.elementAt(i);
0706: if (type == null)
0707: continue;
0708: code.aload(locals);
0709: code.iconst(i);
0710: //code.checkcast(code.pool.Class("java/lang/Object"));
0711: if (i == 2222) {
0712: code.aconst_null();
0713: } else
0714: code.aload(i);
0715: code.aastore();
0716: }
0717:
0718: if (mrefs.f_savedlocals == 0) {
0719: mrefs.f_savedlocals = code.pool.Fieldref(
0720: "org/python/core/PyFrame", "f_savedlocals",
0721: "[Ljava/lang/Object;");
0722: }
0723:
0724: loadFrame();
0725: code.aload(locals);
0726: code.putfield(mrefs.f_savedlocals);
0727: code.freeLocal(locals);
0728: }
0729:
0730: public Object visitReturn(Return node) throws Exception {
0731: return visitReturn(node, false);
0732: }
0733:
0734: public Object visitReturn(Return node, boolean inEval)
0735: throws Exception {
0736: setline(node);
0737: if (!inEval && !fast_locals) {
0738: throw new ParseException("'return' outside function", node);
0739: }
0740: int tmp = 0;
0741: if (node.value != null) {
0742: if (my_scope.generator)
0743: throw new ParseException("'return' with argument "
0744: + "inside generator", node);
0745: visit(node.value);
0746: tmp = code.getReturnLocal();
0747: code.astore(tmp);
0748: }
0749: doFinallysDownTo(0);
0750:
0751: setLastI(-1);
0752:
0753: if (node.value != null) {
0754: code.aload(tmp);
0755: } else {
0756: getNone();
0757: }
0758: code.areturn();
0759: return Exit;
0760: }
0761:
0762: public int makeException0, makeException1, makeException2,
0763: makeException3;
0764:
0765: public Object visitRaise(Raise node) throws Exception {
0766: setline(node);
0767: traverse(node);
0768: if (node.type == null) {
0769: if (mrefs.makeException0 == 0) {
0770: mrefs.makeException0 = code.pool.Methodref(
0771: "org/python/core/Py", "makeException", "()"
0772: + $pyExc);
0773: }
0774: code.invokestatic(mrefs.makeException0);
0775: } else if (node.inst == null) {
0776: if (mrefs.makeException1 == 0) {
0777: mrefs.makeException1 = code.pool.Methodref(
0778: "org/python/core/Py", "makeException", "("
0779: + $pyObj + ")" + $pyExc);
0780: }
0781: code.invokestatic(mrefs.makeException1);
0782: } else if (node.tback == null) {
0783: if (mrefs.makeException2 == 0) {
0784: mrefs.makeException2 = code.pool.Methodref(
0785: "org/python/core/Py", "makeException", "("
0786: + $pyObj + $pyObj + ")" + $pyExc);
0787: }
0788: code.invokestatic(mrefs.makeException2);
0789: } else {
0790: if (mrefs.makeException3 == 0) {
0791: mrefs.makeException3 = code.pool.Methodref(
0792: "org/python/core/Py", "makeException", "("
0793: + $pyObj + $pyObj + $pyObj + ")"
0794: + $pyExc);
0795: }
0796: code.invokestatic(mrefs.makeException3);
0797: }
0798: code.athrow();
0799: return Exit;
0800: }
0801:
0802: public int importOne, importOneAs;
0803:
0804: public Object visitImport(Import node) throws Exception {
0805: setline(node);
0806: for (int i = 0; i < node.names.length; i++) {
0807: String asname = null;
0808: if (node.names[i].asname != null) {
0809: String name = node.names[i].name;
0810: asname = node.names[i].asname;
0811: code.ldc(name);
0812: loadFrame();
0813: if (mrefs.importOneAs == 0) {
0814: mrefs.importOneAs = code.pool.Methodref(
0815: "org/python/core/imp", "importOneAs", "("
0816: + $str + $pyFrame + ")" + $pyObj);
0817: }
0818: code.invokestatic(mrefs.importOneAs);
0819: } else {
0820: String name = node.names[i].name;
0821: asname = name;
0822: if (asname.indexOf('.') > 0)
0823: asname = asname.substring(0, asname.indexOf('.'));
0824: code.ldc(name);
0825: loadFrame();
0826: if (mrefs.importOne == 0) {
0827: mrefs.importOne = code.pool.Methodref(
0828: "org/python/core/imp", "importOne", "("
0829: + $str + $pyFrame + ")" + $pyObj);
0830: }
0831: code.invokestatic(mrefs.importOne);
0832: }
0833: set(new Name(asname, Name.Store, node));
0834: }
0835: return null;
0836: }
0837:
0838: public int importAll, importFrom;
0839:
0840: public Object visitImportFrom(ImportFrom node) throws Exception {
0841: Future.checkFromFuture(node); // future stmt support
0842: setline(node);
0843: code.ldc(node.module);
0844: if (node.names.length > 0) {
0845: String[] names = new String[node.names.length];
0846: String[] asnames = new String[node.names.length];
0847: for (int i = 0; i < node.names.length; i++) {
0848: names[i] = node.names[i].name;
0849: asnames[i] = node.names[i].asname;
0850: if (asnames[i] == null)
0851: asnames[i] = names[i];
0852: }
0853: makeStrings(code, names, names.length);
0854:
0855: loadFrame();
0856: if (mrefs.importFrom == 0) {
0857: mrefs.importFrom = code.pool.Methodref(
0858: "org/python/core/imp", "importFrom", "(" + $str
0859: + $strArr + $pyFrame + ")" + $pyObjArr);
0860: }
0861: code.invokestatic(mrefs.importFrom);
0862: int tmp = storeTop();
0863: for (int i = 0; i < node.names.length; i++) {
0864: code.aload(tmp);
0865: code.iconst(i);
0866: code.aaload();
0867: set(new Name(asnames[i], Name.Store, node));
0868: }
0869: code.freeLocal(tmp);
0870: } else {
0871: loadFrame();
0872: if (mrefs.importAll == 0) {
0873: mrefs.importAll = code.pool.Methodref(
0874: "org/python/core/imp", "importAll", "(" + $str
0875: + $pyFrame + ")V");
0876: }
0877: code.invokestatic(mrefs.importAll);
0878: }
0879: return null;
0880: }
0881:
0882: public Object visitGlobal(Global node) throws Exception {
0883: return null;
0884: }
0885:
0886: public int exec;
0887:
0888: public Object visitExec(Exec node) throws Exception {
0889: setline(node);
0890: visit(node.body);
0891:
0892: if (node.globals != null) {
0893: visit(node.globals);
0894: } else {
0895: code.aconst_null();
0896: }
0897:
0898: if (node.locals != null) {
0899: visit(node.locals);
0900: } else {
0901: code.aconst_null();
0902: }
0903:
0904: //do the real work here
0905: if (mrefs.exec == 0) {
0906: mrefs.exec = code.pool.Methodref("org/python/core/Py",
0907: "exec", "(" + $pyObj + $pyObj + $pyObj + ")V");
0908: }
0909: code.invokestatic(mrefs.exec);
0910: return null;
0911: }
0912:
0913: public int asserttype;
0914:
0915: public Object visitAssert(Assert node) throws Exception {
0916: setline(node);
0917: Label end_of_assert = code.getLabel();
0918:
0919: /* First do an if __debug__: */
0920: loadFrame();
0921: emitGetGlobal("__debug__");
0922:
0923: if (mrefs.nonzero == 0) {
0924: mrefs.nonzero = code.pool.Methodref(
0925: "org/python/core/PyObject", "__nonzero__", "()Z");
0926: }
0927: code.invokevirtual(mrefs.nonzero);
0928:
0929: code.ifeq(end_of_assert);
0930:
0931: /* Now do the body of the assert. If PyObject.__nonzero__ is true,
0932: then the assertion succeeded, the message portion should not be
0933: processed. Otherwise, the message will be processed. */
0934: visit(node.test);
0935: code.invokevirtual(mrefs.nonzero);
0936:
0937: /* If evaluation is false, then branch to end of method */
0938: code.ifne(end_of_assert);
0939:
0940: /* Push exception type onto stack(Py.AssertionError) */
0941: if (mrefs.asserttype == 0) {
0942: mrefs.asserttype = code.pool.Fieldref("org/python/core/Py",
0943: "AssertionError", "Lorg/python/core/PyObject;");
0944: }
0945:
0946: code.getstatic(mrefs.asserttype);
0947:
0948: /* Visit the message part of the assertion, or pass Py.None */
0949: if (node.msg != null) {
0950: visit(node.msg);
0951: } else {
0952: getNone();
0953: }
0954:
0955: if (mrefs.makeException2 == 0) {
0956: mrefs.makeException2 = code.pool.Methodref(
0957: "org/python/core/Py", "makeException", "(" + $pyObj
0958: + $pyObj + ")" + $pyExc);
0959: }
0960: code.invokestatic(mrefs.makeException2);
0961:
0962: /* Raise assertion error. Only executes this logic if assertion
0963: failed */
0964: code.athrow();
0965:
0966: /* And finally set the label for the end of it all */
0967: end_of_assert.setPosition();
0968:
0969: return null;
0970: }
0971:
0972: public int nonzero;
0973:
0974: public Object doTest(Label end_of_if, If node, int index)
0975: throws Exception {
0976: Label end_of_suite = code.getLabel();
0977:
0978: setline(node.test);
0979: visit(node.test);
0980: if (mrefs.nonzero == 0) {
0981: mrefs.nonzero = code.pool.Methodref(
0982: "org/python/core/PyObject", "__nonzero__", "()Z");
0983: }
0984: code.invokevirtual(mrefs.nonzero);
0985: code.ifeq(end_of_suite);
0986:
0987: Object exit = suite(node.body);
0988:
0989: if (end_of_if != null && exit == null)
0990: code.goto_(end_of_if);
0991:
0992: end_of_suite.setPosition();
0993:
0994: if (node.orelse != null) {
0995: return suite(node.orelse) != null ? exit : null;
0996: } else {
0997: return null;
0998: }
0999: }
1000:
1001: public Object visitIf(If node) throws Exception {
1002: Label end_of_if = null;
1003: if (node.orelse != null)
1004: end_of_if = code.getLabel();
1005:
1006: Object exit = doTest(end_of_if, node, 0);
1007: if (end_of_if != null)
1008: end_of_if.setPosition();
1009: return exit;
1010: }
1011:
1012: public int beginLoop() {
1013: continueLabels.push(code.getLabel());
1014: breakLabels.push(code.getLabel());
1015: int savebcf = bcfLevel;
1016: bcfLevel = exceptionHandlers.size();
1017: return savebcf;
1018: }
1019:
1020: public void finishLoop(int savebcf) {
1021: continueLabels.pop();
1022: breakLabels.pop();
1023: bcfLevel = savebcf;
1024: }
1025:
1026: public Object visitWhile(While node) throws Exception {
1027: int savebcf = beginLoop();
1028: Label continue_loop = (Label) continueLabels.peek();
1029: Label break_loop = (Label) breakLabels.peek();
1030:
1031: Label start_loop = code.getLabel();
1032:
1033: code.goto_(continue_loop);
1034: start_loop.setPosition();
1035:
1036: //Do suite
1037: suite(node.body);
1038:
1039: continue_loop.setPosition();
1040: setline(node);
1041:
1042: //Do test
1043: visit(node.test);
1044: if (mrefs.nonzero == 0) {
1045: mrefs.nonzero = code.pool.Methodref(
1046: "org/python/core/PyObject", "__nonzero__", "()Z");
1047: }
1048: code.invokevirtual(mrefs.nonzero);
1049: code.ifne(start_loop);
1050:
1051: finishLoop(savebcf);
1052:
1053: if (node.orelse != null) {
1054: //Do else
1055: suite(node.orelse);
1056: }
1057: break_loop.setPosition();
1058:
1059: // Probably need to detect "guaranteed exits"
1060: return null;
1061: }
1062:
1063: public int iter = 0;
1064: public int iternext = 0;
1065:
1066: public Object visitFor(For node) throws Exception {
1067: int savebcf = beginLoop();
1068: Label continue_loop = (Label) continueLabels.peek();
1069: Label break_loop = (Label) breakLabels.peek();
1070: Label start_loop = code.getLabel();
1071: Label next_loop = code.getLabel();
1072:
1073: int iter_tmp = code.getLocal("org/python/core/PyObject");
1074: int expr_tmp = code.getLocal("org/python/core/PyObject");
1075:
1076: setline(node);
1077:
1078: //parse the list
1079: visit(node.iter);
1080:
1081: //set up the loop iterator
1082: if (mrefs.iter == 0) {
1083: mrefs.iter = code.pool.Methodref(
1084: "org/python/core/PyObject", "__iter__", "()"
1085: + $pyObj);
1086: }
1087: code.invokevirtual(mrefs.iter);
1088: code.astore(iter_tmp);
1089:
1090: //do check at end of loop. Saves one opcode ;-)
1091: code.goto_(next_loop);
1092:
1093: start_loop.setPosition();
1094: //set iter variable to current entry in list
1095: set(node.target, expr_tmp);
1096:
1097: //evaluate for body
1098: suite(node.body);
1099:
1100: continue_loop.setPosition();
1101:
1102: next_loop.setPosition();
1103: setline(node);
1104: //get the next element from the list
1105: code.aload(iter_tmp);
1106: if (mrefs.iternext == 0) {
1107: mrefs.iternext = code.pool.Methodref(
1108: "org/python/core/PyObject", "__iternext__", "()"
1109: + $pyObj);
1110: }
1111: code.invokevirtual(mrefs.iternext);
1112: code.astore(expr_tmp);
1113: code.aload(expr_tmp);
1114: //if no more elements then fall through
1115: code.ifnonnull(start_loop);
1116:
1117: finishLoop(savebcf);
1118:
1119: if (node.orelse != null) {
1120: //Do else clause if provided
1121: suite(node.orelse);
1122: }
1123:
1124: break_loop.setPosition();
1125:
1126: code.freeLocal(iter_tmp);
1127: code.freeLocal(expr_tmp);
1128:
1129: // Probably need to detect "guaranteed exits"
1130: return null;
1131: }
1132:
1133: public int match_exception;
1134:
1135: public void exceptionTest(int exc, Label end_of_exceptions,
1136: TryExcept node, int index) throws Exception {
1137: for (int i = 0; i < node.handlers.length; i++) {
1138: excepthandlerType handler = node.handlers[i];
1139:
1140: //setline(name);
1141: Label end_of_self = code.getLabel();
1142:
1143: if (handler.type != null) {
1144: code.aload(exc);
1145: //get specific exception
1146: visit(handler.type);
1147: if (mrefs.match_exception == 0) {
1148: mrefs.match_exception = code.pool.Methodref(
1149: "org/python/core/Py", "matchException", "("
1150: + $pyExc + $pyObj + ")Z");
1151: }
1152: code.invokestatic(mrefs.match_exception);
1153: code.ifeq(end_of_self);
1154: } else {
1155: if (i != node.handlers.length - 1) {
1156: throw new ParseException(
1157: "bare except must be last except clause",
1158: handler.type);
1159: }
1160: }
1161:
1162: if (handler.name != null) {
1163: code.aload(exc);
1164: code.getfield(code.pool.Fieldref(
1165: "org/python/core/PyException", "value",
1166: "Lorg/python/core/PyObject;"));
1167: set(handler.name);
1168: }
1169:
1170: //do exception body
1171: suite(handler.body);
1172: code.goto_(end_of_exceptions);
1173: end_of_self.setPosition();
1174: }
1175: code.aload(exc);
1176: code.athrow();
1177: }
1178:
1179: public int add_traceback;
1180:
1181: public Object visitTryFinally(TryFinally node) throws Exception {
1182: Label start = code.getLabel();
1183: Label end = code.getLabel();
1184: Label handlerStart = code.getLabel();
1185: Label finallyEnd = code.getLabel();
1186:
1187: Object ret;
1188:
1189: ExceptionHandler inFinally = new ExceptionHandler(node);
1190:
1191: // Do protected suite
1192: exceptionHandlers.push(inFinally);
1193:
1194: int excLocal = code.getLocal("java/lang/Throwable");
1195: code.aconst_null();
1196: code.astore(excLocal);
1197:
1198: start.setPosition();
1199: inFinally.exceptionStarts.addElement(start);
1200:
1201: ret = suite(node.body);
1202:
1203: end.setPosition();
1204: inFinally.exceptionEnds.addElement(end);
1205: inFinally.bodyDone = true;
1206:
1207: exceptionHandlers.pop();
1208:
1209: if (ret == NoExit) {
1210: inlineFinally(inFinally);
1211: code.goto_(finallyEnd);
1212: }
1213:
1214: // Handle any exceptions that get thrown in suite
1215: handlerStart.setPosition();
1216: code.stack = 1;
1217: code.astore(excLocal);
1218:
1219: code.aload(excLocal);
1220: loadFrame();
1221:
1222: if (mrefs.add_traceback == 0) {
1223: mrefs.add_traceback = code.pool.Methodref(
1224: "org/python/core/Py", "addTraceback", "("
1225: + $throwable + $pyFrame + ")V");
1226: }
1227: code.invokestatic(mrefs.add_traceback);
1228:
1229: inlineFinally(inFinally);
1230: code.aload(excLocal);
1231: code.checkcast(code.pool.Class("java/lang/Throwable"));
1232: code.athrow();
1233:
1234: finallyEnd.setPosition();
1235:
1236: code.freeLocal(excLocal);
1237:
1238: inFinally.addExceptionHandlers(handlerStart);
1239: // According to any JVM verifiers, this code block might not return
1240: return null;
1241: }
1242:
1243: private void inlineFinally(ExceptionHandler handler)
1244: throws Exception {
1245: if (!handler.bodyDone) {
1246: // end the previous exception block so inlined finally code doesn't
1247: // get covered by our exception handler.
1248: handler.exceptionEnds.addElement(code.getLabelAtPosition());
1249: // also exiting the try: portion of this particular finally
1250: }
1251: if (handler.isFinallyHandler()) {
1252: suite(handler.node.finalbody);
1253: }
1254: }
1255:
1256: private void reenterProtectedBody(ExceptionHandler handler)
1257: throws Exception {
1258: // restart exception coverage
1259: handler.exceptionStarts.addElement(code.getLabelAtPosition());
1260: }
1261:
1262: /**
1263: * Inline the finally handling code for levels down to the levelth parent
1264: * (0 means all). This takes care to avoid having more nested finallys
1265: * catch exceptions throw by the parent finally code. This also pops off
1266: * all the handlers above level temporarily.
1267: */
1268: private void doFinallysDownTo(int level) throws Exception {
1269: Stack poppedHandlers = new Stack();
1270: while (exceptionHandlers.size() > level) {
1271: ExceptionHandler handler = (ExceptionHandler) exceptionHandlers
1272: .pop();
1273: inlineFinally(handler);
1274: poppedHandlers.push(handler);
1275: }
1276: while (poppedHandlers.size() > 0) {
1277: ExceptionHandler handler = (ExceptionHandler) poppedHandlers
1278: .pop();
1279: reenterProtectedBody(handler);
1280: exceptionHandlers.push(handler);
1281: }
1282: }
1283:
1284: public int set_exception;
1285:
1286: public Object visitTryExcept(TryExcept node) throws Exception {
1287: Label start = code.getLabel();
1288: Label end = code.getLabel();
1289: Label handler_start = code.getLabel();
1290: Label handler_end = code.getLabel();
1291: ExceptionHandler handler = new ExceptionHandler();
1292:
1293: start.setPosition();
1294: handler.exceptionStarts.addElement(start);
1295: exceptionHandlers.push(handler);
1296: //Do suite
1297: Object exit = suite(node.body);
1298: //System.out.println("exit: "+exit+", "+(exit != null));
1299: exceptionHandlers.pop();
1300: end.setPosition();
1301: handler.exceptionEnds.addElement(end);
1302:
1303: if (exit == null)
1304: code.goto_(handler_end);
1305:
1306: handler_start.setPosition();
1307: //Stack has eactly one item at start of handler
1308: code.stack = 1;
1309:
1310: loadFrame();
1311:
1312: if (mrefs.set_exception == 0) {
1313: mrefs.set_exception = code.pool.Methodref(
1314: "org/python/core/Py", "setException", "("
1315: + $throwable + $pyFrame + ")" + $pyExc);
1316: }
1317: code.invokestatic(mrefs.set_exception);
1318:
1319: int exc = code.getFinallyLocal("java/lang/Throwable");
1320: code.astore(exc);
1321:
1322: if (node.orelse == null) {
1323: //No else clause to worry about
1324: exceptionTest(exc, handler_end, node, 1);
1325: handler_end.setPosition();
1326: } else {
1327: //Have else clause
1328: Label else_end = code.getLabel();
1329: exceptionTest(exc, else_end, node, 1);
1330: handler_end.setPosition();
1331:
1332: //do else clause
1333: suite(node.orelse);
1334: else_end.setPosition();
1335: }
1336:
1337: code.freeFinallyLocal(exc);
1338: handler.addExceptionHandlers(handler_start);
1339: return null;
1340: }
1341:
1342: public Object visitSuite(Suite node) throws Exception {
1343: return suite(node.body);
1344: }
1345:
1346: public Object suite(stmtType[] stmts) throws Exception {
1347: int n = stmts.length;
1348: for (int i = 0; i < n; i++) {
1349: Object exit = visit(stmts[i]);
1350: //System.out.println("exit: "+exit+", "+n+", "+(exit != null));
1351: if (exit != null)
1352: return Exit;
1353: }
1354: return null;
1355: }
1356:
1357: public Object visitBoolOp(BoolOp node) throws Exception {
1358: Label end = code.getLabel();
1359: visit(node.values[0]);
1360: for (int i = 1; i < node.values.length; i++) {
1361: code.dup();
1362: if (mrefs.nonzero == 0) {
1363: mrefs.nonzero = code.pool.Methodref(
1364: "org/python/core/PyObject", "__nonzero__",
1365: "()Z");
1366: }
1367: code.invokevirtual(mrefs.nonzero);
1368: switch (node.op) {
1369: case BoolOp.Or:
1370: code.ifne(end);
1371: break;
1372: case BoolOp.And:
1373: code.ifeq(end);
1374: break;
1375: }
1376: code.pop();
1377: visit(node.values[i]);
1378: }
1379: end.setPosition();
1380: return null;
1381: }
1382:
1383: public Object visitCompare(Compare node) throws Exception {
1384: int tmp1 = code.getLocal("org/python/core/PyObject");
1385: int tmp2 = code.getLocal("org/python/core/PyObject");
1386: int op;
1387:
1388: if (mrefs.nonzero == 0) {
1389: mrefs.nonzero = code.pool.Methodref(
1390: "org/python/core/PyObject", "__nonzero__", "()Z");
1391: }
1392:
1393: Label end = code.getLabel();
1394:
1395: visit(node.left);
1396:
1397: int n = node.ops.length;
1398: for (int i = 0; i < n - 1; i++) {
1399: visit(node.comparators[i]);
1400: code.dup();
1401: code.astore(tmp1);
1402: code.invokevirtual(make_cmpop(node.ops[i]));
1403: code.dup();
1404: code.astore(tmp2);
1405: code.invokevirtual(mrefs.nonzero);
1406: code.ifeq(end);
1407: code.aload(tmp1);
1408: }
1409:
1410: visit(node.comparators[n - 1]);
1411: code.invokevirtual(make_cmpop(node.ops[n - 1]));
1412:
1413: if (n > 1) {
1414: code.astore(tmp2);
1415: end.setPosition();
1416: code.aload(tmp2);
1417: }
1418: code.freeLocal(tmp1);
1419: code.freeLocal(tmp2);
1420: return null;
1421: }
1422:
1423: int[] compare_ops = new int[11];
1424:
1425: public int make_cmpop(int op) throws Exception {
1426: if (compare_ops[op] == 0) {
1427: String name = null;
1428: switch (op) {
1429: case Compare.Eq:
1430: name = "_eq";
1431: break;
1432: case Compare.NotEq:
1433: name = "_ne";
1434: break;
1435: case Compare.Lt:
1436: name = "_lt";
1437: break;
1438: case Compare.LtE:
1439: name = "_le";
1440: break;
1441: case Compare.Gt:
1442: name = "_gt";
1443: break;
1444: case Compare.GtE:
1445: name = "_ge";
1446: break;
1447: case Compare.Is:
1448: name = "_is";
1449: break;
1450: case Compare.IsNot:
1451: name = "_isnot";
1452: break;
1453: case Compare.In:
1454: name = "_in";
1455: break;
1456: case Compare.NotIn:
1457: name = "_notin";
1458: break;
1459: }
1460: compare_ops[op] = code.pool.Methodref(
1461: "org/python/core/PyObject", name, "(" + $pyObj
1462: + ")" + $pyObj);
1463: }
1464: return compare_ops[op];
1465: }
1466:
1467: static String[] bin_methods = new String[] { null, "_add", "_sub",
1468: "_mul", "_div", "_mod", "_pow", "_lshift", "_rshift",
1469: "_or", "_xor", "_and", "_floordiv", };
1470:
1471: int[] bin_ops = new int[13];
1472:
1473: public int make_binop(int op) throws Exception {
1474: if (bin_ops[op] == 0) {
1475: String name = bin_methods[op];
1476: if (op == BinOp.Div && module.getFutures().areDivisionOn()) {
1477: name = "_truediv";
1478: }
1479: bin_ops[op] = code.pool.Methodref(
1480: "org/python/core/PyObject", name, "(" + $pyObj
1481: + ")" + $pyObj);
1482: }
1483: return bin_ops[op];
1484: }
1485:
1486: public Object visitBinOp(BinOp node) throws Exception {
1487: visit(node.left);
1488: visit(node.right);
1489: code.invokevirtual(make_binop(node.op));
1490: return null;
1491: }
1492:
1493: static String[] unary_methods = new String[] { null, "__invert__",
1494: "__not__", "__pos__", "__neg__", };
1495:
1496: int[] unary_ops = new int[unary_methods.length];
1497:
1498: public int make_unaryop(int op) throws Exception {
1499: if (unary_ops[op] == 0) {
1500: String name = unary_methods[op];
1501: unary_ops[op] = code.pool.Methodref(
1502: "org/python/core/PyObject", name, "()" + $pyObj);
1503: }
1504: return unary_ops[op];
1505: }
1506:
1507: public Object visitUnaryOp(UnaryOp node) throws Exception {
1508: visit(node.operand);
1509: code.invokevirtual(make_unaryop(node.op));
1510: return null;
1511: }
1512:
1513: static String[] aug_methods = new String[] { null, "__iadd__",
1514: "__isub__", "__imul__", "__idiv__", "__imod__", "__ipow__",
1515: "__ilshift__", "__irshift__", "__ior__", "__ixor__",
1516: "__iand__", "__ifloordiv__", };
1517:
1518: int[] augbin_ops = new int[aug_methods.length];
1519:
1520: public int make_augbinop(int op) throws Exception {
1521: if (augbin_ops[op] == 0) {
1522: String name = aug_methods[op];
1523: if (op == BinOp.Div && module.getFutures().areDivisionOn()) {
1524: name = "__itruediv__";
1525: }
1526: augbin_ops[op] = code.pool.Methodref(
1527: "org/python/core/PyObject", name, "(" + $pyObj
1528: + ")" + $pyObj);
1529: }
1530: return augbin_ops[op];
1531: }
1532:
1533: public Object visitAugAssign(AugAssign node) throws Exception {
1534: visit(node.value);
1535: int tmp = storeTop();
1536:
1537: augmode = expr_contextType.Load;
1538: visit(node.target);
1539:
1540: code.aload(tmp);
1541: code.invokevirtual(make_augbinop(node.op));
1542: code.freeLocal(tmp);
1543:
1544: temporary = storeTop();
1545: augmode = expr_contextType.Store;
1546: visit(node.target);
1547: code.freeLocal(temporary);
1548:
1549: return null;
1550: }
1551:
1552: public static void makeStrings(Code c, String[] names, int n)
1553: throws IOException {
1554: c.iconst(n);
1555: c.anewarray(c.pool.Class("java/lang/String"));
1556: int strings = c.getLocal("[java/lang/String");
1557: c.astore(strings);
1558: for (int i = 0; i < n; i++) {
1559: c.aload(strings);
1560: c.iconst(i);
1561: c.ldc(names[i]);
1562: c.aastore();
1563: }
1564: c.aload(strings);
1565: c.freeLocal(strings);
1566: }
1567:
1568: public int invokea0, invokea1, invokea2;
1569: public int invoke2;
1570:
1571: public Object Invoke(Attribute node, SimpleNode[] values)
1572: throws Exception {
1573: String name = getName(node.attr);
1574: visit(node.value);
1575: code.ldc(name);
1576:
1577: //System.out.println("invoke: "+name+": "+values.length);
1578:
1579: switch (values.length) {
1580: case 0:
1581: if (mrefs.invokea0 == 0) {
1582: mrefs.invokea0 = code.pool.Methodref(
1583: "org/python/core/PyObject", "invoke", "("
1584: + $str + ")" + $pyObj);
1585: }
1586: code.invokevirtual(mrefs.invokea0);
1587: break;
1588: case 1:
1589: if (mrefs.invokea1 == 0) {
1590: mrefs.invokea1 = code.pool.Methodref(
1591: "org/python/core/PyObject", "invoke", "("
1592: + $str + $pyObj + ")" + $pyObj);
1593: }
1594: visit(values[0]);
1595: code.invokevirtual(mrefs.invokea1);
1596: break;
1597: case 2:
1598: if (mrefs.invokea2 == 0) {
1599: mrefs.invokea2 = code.pool
1600: .Methodref("org/python/core/PyObject",
1601: "invoke", "(" + $str + $pyObj + $pyObj
1602: + ")" + $pyObj);
1603: }
1604: visit(values[0]);
1605: visit(values[1]);
1606: code.invokevirtual(mrefs.invokea2);
1607: break;
1608: default:
1609: makeArray(values);
1610: if (mrefs.invoke2 == 0) {
1611: mrefs.invoke2 = code.pool.Methodref(
1612: "org/python/core/PyObject", "invoke", "("
1613: + $str + $pyObjArr + ")" + $pyObj);
1614: }
1615: code.invokevirtual(mrefs.invoke2);
1616: break;
1617: }
1618:
1619: return null;
1620: }
1621:
1622: public int callextra;
1623: public int call1, call2;
1624: public int calla0, calla1, calla2, calla3, calla4;
1625:
1626: public Object visitCall(Call node) throws Exception {
1627: String[] keys = new String[node.keywords.length];
1628: exprType[] values = new exprType[node.args.length + keys.length];
1629: for (int i = 0; i < node.args.length; i++) {
1630: values[i] = node.args[i];
1631: }
1632: for (int i = 0; i < node.keywords.length; i++) {
1633: keys[i] = node.keywords[i].arg;
1634: values[node.args.length + i] = node.keywords[i].value;
1635: }
1636:
1637: // Detect a method invocation with no keywords
1638: if ((node.keywords == null || node.keywords.length == 0)
1639: && node.starargs == null && node.kwargs == null
1640: && node.func instanceof Attribute) {
1641: return Invoke((Attribute) node.func, values);
1642: }
1643:
1644: visit(node.func);
1645:
1646: if (node.starargs != null || node.kwargs != null) {
1647: makeArray(values);
1648: makeStrings(code, keys, keys.length);
1649: if (node.starargs == null)
1650: code.aconst_null();
1651: else
1652: visit(node.starargs);
1653: if (node.kwargs == null)
1654: code.aconst_null();
1655: else
1656: visit(node.kwargs);
1657:
1658: if (mrefs.callextra == 0) {
1659: mrefs.callextra = code.pool.Methodref(
1660: "org/python/core/PyObject", "_callextra", "("
1661: + $pyObjArr + $strArr + $pyObj + $pyObj
1662: + ")" + $pyObj);
1663: }
1664: code.invokevirtual(mrefs.callextra);
1665: } else if (keys.length > 0) {
1666: makeArray(values);
1667: makeStrings(code, keys, keys.length);
1668:
1669: if (mrefs.call1 == 0) {
1670: mrefs.call1 = code.pool.Methodref(
1671: "org/python/core/PyObject", "__call__", "("
1672: + $pyObjArr + $strArr + ")" + $pyObj);
1673: }
1674: code.invokevirtual(mrefs.call1);
1675: } else {
1676: switch (values.length) {
1677: case 0:
1678: if (mrefs.calla0 == 0) {
1679: mrefs.calla0 = code.pool.Methodref(
1680: "org/python/core/PyObject", "__call__",
1681: "()" + $pyObj);
1682: }
1683: code.invokevirtual(mrefs.calla0);
1684: break;
1685: case 1:
1686: if (mrefs.calla1 == 0) {
1687: mrefs.calla1 = code.pool.Methodref(
1688: "org/python/core/PyObject", "__call__", "("
1689: + $pyObj + ")" + $pyObj);
1690: }
1691: visit(values[0]);
1692: code.invokevirtual(mrefs.calla1);
1693: break;
1694: case 2:
1695: if (mrefs.calla2 == 0) {
1696: mrefs.calla2 = code.pool.Methodref(
1697: "org/python/core/PyObject", "__call__", "("
1698: + $pyObj + $pyObj + ")" + $pyObj);
1699: }
1700: visit(values[0]);
1701: visit(values[1]);
1702: code.invokevirtual(mrefs.calla2);
1703: break;
1704: case 3:
1705: if (mrefs.calla3 == 0) {
1706: mrefs.calla3 = code.pool.Methodref(
1707: "org/python/core/PyObject", "__call__", "("
1708: + $pyObj + $pyObj + $pyObj + ")"
1709: + $pyObj);
1710: }
1711: visit(values[0]);
1712: visit(values[1]);
1713: visit(values[2]);
1714: code.invokevirtual(mrefs.calla3);
1715: break;
1716: case 4:
1717: if (mrefs.calla4 == 0) {
1718: mrefs.calla4 = code.pool.Methodref(
1719: "org/python/core/PyObject", "__call__", "("
1720: + $pyObj + $pyObj + $pyObj + $pyObj
1721: + ")" + $pyObj);
1722: }
1723: visit(values[0]);
1724: visit(values[1]);
1725: visit(values[2]);
1726: visit(values[3]);
1727: code.invokevirtual(mrefs.calla4);
1728: break;
1729: default:
1730: makeArray(values);
1731: if (mrefs.call2 == 0) {
1732: mrefs.call2 = code.pool.Methodref(
1733: "org/python/core/PyObject", "__call__", "("
1734: + $pyObjArr + ")" + $pyObj);
1735: }
1736: code.invokevirtual(mrefs.call2);
1737: break;
1738: }
1739: }
1740: return null;
1741: }
1742:
1743: public int getslice, setslice, delslice;
1744:
1745: public Object Slice(Subscript node, Slice slice) throws Exception {
1746: int ctx = node.ctx;
1747: if (ctx == node.AugStore && augmode == node.Store) {
1748: restoreAugTmps(node, 4);
1749: ctx = node.Store;
1750: } else {
1751: visit(node.value);
1752: if (slice.lower != null)
1753: visit(slice.lower);
1754: else
1755: code.aconst_null();
1756: if (slice.upper != null)
1757: visit(slice.upper);
1758: else
1759: code.aconst_null();
1760: if (slice.step != null)
1761: visit(slice.step);
1762: else
1763: code.aconst_null();
1764:
1765: if (node.ctx == node.AugStore && augmode == node.Load) {
1766: saveAugTmps(node, 4);
1767: ctx = node.Load;
1768: }
1769: }
1770:
1771: switch (ctx) {
1772: case Subscript.Del:
1773: if (mrefs.delslice == 0) {
1774: mrefs.delslice = code.pool.Methodref(
1775: "org/python/core/PyObject", "__delslice__", "("
1776: + $pyObj + $pyObj + $pyObj + ")V");
1777: }
1778: code.invokevirtual(mrefs.delslice);
1779: return null;
1780: case Subscript.Load:
1781: if (mrefs.getslice == 0) {
1782: mrefs.getslice = code.pool.Methodref(
1783: "org/python/core/PyObject", "__getslice__", "("
1784: + $pyObj + $pyObj + $pyObj + ")"
1785: + $pyObj);
1786: }
1787: code.invokevirtual(mrefs.getslice);
1788: return null;
1789: case Subscript.Store:
1790: code.aload(temporary);
1791: if (mrefs.setslice == 0) {
1792: mrefs.setslice = code.pool.Methodref(
1793: "org/python/core/PyObject", "__setslice__", "("
1794: + $pyObj + $pyObj + $pyObj + $pyObj
1795: + ")V");
1796: }
1797: code.invokevirtual(mrefs.setslice);
1798: return null;
1799: }
1800: return null;
1801:
1802: }
1803:
1804: public int getitem, delitem, setitem;
1805:
1806: public Object visitSubscript(Subscript node) throws Exception {
1807: if (node.slice instanceof Slice) {
1808: return Slice(node, (Slice) node.slice);
1809: }
1810:
1811: int ctx = node.ctx;
1812: if (node.ctx == node.AugStore && augmode == node.Store) {
1813: restoreAugTmps(node, 2);
1814: ctx = node.Store;
1815: } else {
1816: visit(node.value);
1817: visit(node.slice);
1818:
1819: if (node.ctx == node.AugStore && augmode == node.Load) {
1820: saveAugTmps(node, 2);
1821: ctx = node.Load;
1822: }
1823: }
1824:
1825: switch (ctx) {
1826: case Subscript.Del:
1827: if (mrefs.delitem == 0) {
1828: mrefs.delitem = code.pool.Methodref(
1829: "org/python/core/PyObject", "__delitem__", "("
1830: + $pyObj + ")V");
1831: }
1832: code.invokevirtual(mrefs.delitem);
1833: return null;
1834: case Subscript.Load:
1835: if (mrefs.getitem == 0) {
1836: mrefs.getitem = code.pool.Methodref(
1837: "org/python/core/PyObject", "__getitem__", "("
1838: + $pyObj + ")" + $pyObj);
1839: }
1840: code.invokevirtual(mrefs.getitem);
1841: return null;
1842: case Subscript.Store:
1843: code.aload(temporary);
1844: if (mrefs.setitem == 0) {
1845: mrefs.setitem = code.pool.Methodref(
1846: "org/python/core/PyObject", "__setitem__", "("
1847: + $pyObj + $pyObj + ")V");
1848: }
1849: code.invokevirtual(mrefs.setitem);
1850: return null;
1851: }
1852: return null;
1853: }
1854:
1855: public Object visitIndex(Index node) throws Exception {
1856: traverse(node);
1857: return null;
1858: }
1859:
1860: public Object visitExtSlice(ExtSlice node) throws Exception {
1861: code.new_(code.pool.Class("org/python/core/PyTuple"));
1862: code.dup();
1863: makeArray(node.dims);
1864: if (mrefs.PyTuple_init == 0) {
1865: mrefs.PyTuple_init = code.pool.Methodref(
1866: "org/python/core/PyTuple", "<init>", "("
1867: + $pyObjArr + ")V");
1868: }
1869: code.invokespecial(mrefs.PyTuple_init);
1870: return null;
1871: }
1872:
1873: public int getattr, delattr, setattr;
1874:
1875: public Object visitAttribute(Attribute node) throws Exception {
1876:
1877: int ctx = node.ctx;
1878: if (node.ctx == node.AugStore && augmode == node.Store) {
1879: restoreAugTmps(node, 2);
1880: ctx = node.Store;
1881: } else {
1882: visit(node.value);
1883: code.ldc(getName(node.attr));
1884:
1885: if (node.ctx == node.AugStore && augmode == node.Load) {
1886: saveAugTmps(node, 2);
1887: ctx = node.Load;
1888: }
1889: }
1890:
1891: switch (ctx) {
1892: case Attribute.Del:
1893: if (mrefs.delattr == 0) {
1894: mrefs.delattr = code.pool.Methodref(
1895: "org/python/core/PyObject", "__delattr__", "("
1896: + $str + ")V");
1897: }
1898: code.invokevirtual(mrefs.delattr);
1899: return null;
1900: case Attribute.Load:
1901: if (mrefs.getattr == 0) {
1902: mrefs.getattr = code.pool.Methodref(
1903: "org/python/core/PyObject", "__getattr__", "("
1904: + $str + ")" + $pyObj);
1905: }
1906: code.invokevirtual(mrefs.getattr);
1907: return null;
1908: case Attribute.Store:
1909: code.aload(temporary);
1910: if (mrefs.setattr == 0) {
1911: mrefs.setattr = code.pool.Methodref(
1912: "org/python/core/PyObject", "__setattr__", "("
1913: + $str + $pyObj + ")V");
1914: }
1915: code.invokevirtual(mrefs.setattr);
1916: return null;
1917: }
1918: return null;
1919: }
1920:
1921: public int getitem2, unpackSequence;
1922:
1923: public Object seqSet(exprType[] nodes) throws Exception {
1924: if (mrefs.unpackSequence == 0) {
1925: mrefs.unpackSequence = code.pool.Methodref(
1926: "org/python/core/Py", "unpackSequence", "("
1927: + $pyObj + "I)" + $pyObjArr);
1928: }
1929:
1930: code.aload(temporary);
1931: code.iconst(nodes.length);
1932: code.invokestatic(mrefs.unpackSequence);
1933:
1934: int tmp = code.getLocal("[org/python/core/PyObject");
1935: code.astore(tmp);
1936:
1937: for (int i = 0; i < nodes.length; i++) {
1938: code.aload(tmp);
1939: code.iconst(i);
1940: code.aaload();
1941: set(nodes[i]);
1942: }
1943: code.freeLocal(tmp);
1944:
1945: return null;
1946: }
1947:
1948: public Object seqDel(exprType[] nodes) throws Exception {
1949: for (int i = 0; i < nodes.length; i++) {
1950: visit(nodes[i]);
1951: }
1952: return null;
1953: }
1954:
1955: public int PyTuple_init, PyList_init, PyDictionary_init;
1956:
1957: public Object visitTuple(Tuple node) throws Exception {
1958: /* if (mode ==AUGSET)
1959: throw new ParseException(
1960: "augmented assign to tuple not possible", node); */
1961: if (node.ctx == node.Store)
1962: return seqSet(node.elts);
1963: if (node.ctx == node.Del)
1964: return seqDel(node.elts);
1965:
1966: code.new_(code.pool.Class("org/python/core/PyTuple"));
1967: code.dup();
1968: makeArray(node.elts);
1969: if (mrefs.PyTuple_init == 0) {
1970: mrefs.PyTuple_init = code.pool.Methodref(
1971: "org/python/core/PyTuple", "<init>", "("
1972: + $pyObjArr + ")V");
1973: }
1974: code.invokespecial(mrefs.PyTuple_init);
1975: return null;
1976: }
1977:
1978: /*
1979: public Object fplist(SimpleNode node) throws Exception {
1980: if (mode == SET) return seqSet(node);
1981: throw new ParseException("in fplist node", node);
1982: }
1983: */
1984:
1985: public Object visitList(List node) throws Exception {
1986: /* if (mode ==AUGSET)
1987: throw new ParseException(
1988: "augmented assign to list not possible", node); */
1989:
1990: if (node.ctx == node.Store)
1991: return seqSet(node.elts);
1992: if (node.ctx == node.Del)
1993: return seqDel(node.elts);
1994:
1995: code.new_(code.pool.Class("org/python/core/PyList"));
1996: code.dup();
1997: makeArray(node.elts);
1998: if (mrefs.PyList_init == 0) {
1999: mrefs.PyList_init = code.pool.Methodref(
2000: "org/python/core/PyList", "<init>", "(" + $pyObjArr
2001: + ")V");
2002: }
2003: code.invokespecial(mrefs.PyList_init);
2004: return null;
2005: }
2006:
2007: int list_comprehension_count = 0;
2008:
2009: public int PyList_init2;
2010:
2011: public Object visitListComp(ListComp node) throws Exception {
2012: code.new_(code.pool.Class("org/python/core/PyList"));
2013: code.dup();
2014: if (mrefs.PyList_init2 == 0) {
2015: mrefs.PyList_init2 = code.pool.Methodref(
2016: "org/python/core/PyList", "<init>", "()V");
2017: }
2018: code.invokespecial(mrefs.PyList_init2);
2019:
2020: code.dup();
2021:
2022: code.ldc("append");
2023:
2024: if (mrefs.getattr == 0) {
2025: mrefs.getattr = code.pool.Methodref(
2026: "org/python/core/PyObject", "__getattr__", "("
2027: + $str + ")" + $pyObj);
2028: }
2029: code.invokevirtual(mrefs.getattr);
2030:
2031: String tmp_append = "_[" + (++list_comprehension_count) + "]";
2032:
2033: set(new Name(tmp_append, Name.Store, node));
2034:
2035: stmtType n = new Expr(new Call(new Name(tmp_append, Name.Load,
2036: node), new exprType[] { node.elt }, new keywordType[0],
2037: null, null, node), node);
2038:
2039: for (int i = node.generators.length - 1; i >= 0; i--) {
2040: listcompType lc = node.generators[i];
2041: for (int j = lc.ifs.length - 1; j >= 0; j--) {
2042: n = new If(lc.ifs[j], new stmtType[] { n }, null,
2043: lc.ifs[j]);
2044: }
2045: n = new For(lc.target, lc.iter, new stmtType[] { n }, null,
2046: lc);
2047: }
2048: visit(n);
2049: visit(new Delete(
2050: new exprType[] { new Name(tmp_append, Name.Del) }));
2051:
2052: return null;
2053: }
2054:
2055: public Object visitDict(Dict node) throws Exception {
2056: code.new_(code.pool.Class("org/python/core/PyDictionary"));
2057: code.dup();
2058: SimpleNode[] elts = new SimpleNode[node.keys.length * 2];
2059: for (int i = 0; i < node.keys.length; i++) {
2060: elts[i * 2] = node.keys[i];
2061: elts[i * 2 + 1] = node.values[i];
2062: }
2063: makeArray(elts);
2064: if (mrefs.PyDictionary_init == 0) {
2065: mrefs.PyDictionary_init = code.pool.Methodref(
2066: "org/python/core/PyDictionary", "<init>", "("
2067: + $pyObjArr + ")V");
2068: }
2069: code.invokespecial(mrefs.PyDictionary_init);
2070: return null;
2071: }
2072:
2073: public Object visitRepr(Repr node) throws Exception {
2074: visit(node.value);
2075: code.invokevirtual("org/python/core/PyObject", "__repr__", "()"
2076: + $pyStr);
2077: return null;
2078: }
2079:
2080: public int PyFunction_init1, PyFunction_closure_init1;
2081:
2082: public Object visitLambda(Lambda node) throws Exception {
2083: String name = "<lambda>";
2084:
2085: //Add a return node onto the outside of suite;
2086: modType retSuite = new Suite(new stmtType[] { new Return(
2087: node.body, node) }, node);
2088:
2089: setline(node);
2090:
2091: code.new_(code.pool.Class("org/python/core/PyFunction"));
2092: code.dup();
2093: loadFrame();
2094: if (mrefs.f_globals == 0) {
2095: mrefs.f_globals = code.pool.Fieldref(
2096: "org/python/core/PyFrame", "f_globals", $pyObj);
2097: }
2098: code.getfield(mrefs.f_globals);
2099:
2100: ScopeInfo scope = module.getScopeInfo(node);
2101:
2102: makeArray(scope.ac.getDefaults());
2103:
2104: scope.setup_closure();
2105: scope.dump();
2106: module.PyCode(retSuite, name, true, className, false, false,
2107: node.beginLine, scope, cflags).get(code);
2108:
2109: if (!makeClosure(scope)) {
2110: if (mrefs.PyFunction_init1 == 0) {
2111: mrefs.PyFunction_init1 = code.pool.Methodref(
2112: "org/python/core/PyFunction", "<init>", "("
2113: + $pyObj + $pyObjArr + $pyCode + ")V");
2114: }
2115: code.invokespecial(mrefs.PyFunction_init1);
2116: } else {
2117: if (mrefs.PyFunction_closure_init1 == 0) {
2118: mrefs.PyFunction_closure_init1 = code.pool.Methodref(
2119: "org/python/core/PyFunction", "<init>", "("
2120: + $pyObj + $pyObjArr + $pyCode
2121: + $pyObjArr + ")V");
2122: }
2123: code.invokespecial(mrefs.PyFunction_closure_init1);
2124: }
2125:
2126: return null;
2127: }
2128:
2129: public int Ellipsis;
2130:
2131: public Object visitEllipsis(Ellipsis node) throws Exception {
2132: if (mrefs.Ellipsis == 0) {
2133: mrefs.Ellipsis = code.pool.Fieldref("org/python/core/Py",
2134: "Ellipsis", "Lorg/python/core/PyObject;");
2135: }
2136: code.getstatic(mrefs.Ellipsis);
2137: return null;
2138: }
2139:
2140: public int PySlice_init;
2141:
2142: public Object visitSlice(Slice node) throws Exception {
2143: code.new_(code.pool.Class("org/python/core/PySlice"));
2144: code.dup();
2145: if (node.lower == null)
2146: getNone();
2147: else
2148: visit(node.lower);
2149: if (node.upper == null)
2150: getNone();
2151: else
2152: visit(node.upper);
2153: if (node.step == null)
2154: getNone();
2155: else
2156: visit(node.step);
2157: if (mrefs.PySlice_init == 0) {
2158: mrefs.PySlice_init = code.pool.Methodref(
2159: "org/python/core/PySlice", "<init>", "(" + $pyObj
2160: + $pyObj + $pyObj + ")V");
2161: }
2162: code.invokespecial(mrefs.PySlice_init);
2163: return null;
2164: }
2165:
2166: public int makeClass, makeClass_closure;
2167:
2168: public Object visitClassDef(ClassDef node) throws Exception {
2169: setline(node);
2170:
2171: //Get class name
2172: String name = getName(node.name);
2173: //System.out.println("name: "+name);
2174: code.ldc(name);
2175:
2176: makeArray(node.bases);
2177:
2178: ScopeInfo scope = module.getScopeInfo(node);
2179:
2180: scope.setup_closure();
2181: scope.dump();
2182: //Make code object out of suite
2183: module.PyCode(new Suite(node.body, node), name, false, name,
2184: true, false, node.beginLine, scope, cflags).get(code);
2185:
2186: //Get doc string (if there)
2187: getDocString(node.body);
2188:
2189: //Make class out of name, bases, and code
2190: if (!makeClosure(scope)) {
2191: if (mrefs.makeClass == 0) {
2192: mrefs.makeClass = code.pool.Methodref(
2193: "org/python/core/Py", "makeClass", "(" + $str
2194: + $pyObjArr + $pyCode + $pyObj + ")"
2195: + $pyObj);
2196: }
2197: code.invokestatic(mrefs.makeClass);
2198: } else {
2199: if (mrefs.makeClass_closure == 0) {
2200: mrefs.makeClass_closure = code.pool.Methodref(
2201: "org/python/core/Py", "makeClass", "(" + $str
2202: + $pyObjArr + $pyCode + $pyObj
2203: + $pyObjArr + ")" + $pyObj);
2204: }
2205: code.invokestatic(mrefs.makeClass_closure);
2206: }
2207:
2208: //Assign this new class to the given name
2209: set(new Name(node.name, Name.Store, node));
2210: return null;
2211: }
2212:
2213: public Object visitNum(Num node) throws Exception {
2214: if (node.n instanceof PyInteger) {
2215: module.PyInteger(((PyInteger) node.n).getValue()).get(code);
2216: } else if (node.n instanceof PyLong) {
2217: module.PyLong(((PyObject) node.n).__str__().toString())
2218: .get(code);
2219: } else if (node.n instanceof PyFloat) {
2220: module.PyFloat(((PyFloat) node.n).getValue()).get(code);
2221: } else if (node.n instanceof PyComplex) {
2222: module.PyComplex(((PyComplex) node.n).imag).get(code);
2223: }
2224: return null;
2225: }
2226:
2227: private String getName(String name) {
2228: if (className != null && name.startsWith("__")
2229: && !name.endsWith("__")) {
2230: //remove leading '_' from classname
2231: int i = 0;
2232: while (className.charAt(i) == '_')
2233: i++;
2234: return "_" + className.substring(i) + name;
2235: }
2236: return name;
2237: }
2238:
2239: int getglobal, getlocal1, getlocal2;
2240: int setglobal, setlocal1, setlocal2;
2241: int delglobal, dellocal1, dellocal2;
2242: int getderef, setderef;
2243:
2244: void emitGetGlobal(String name) throws Exception {
2245: code.ldc(name);
2246: if (mrefs.getglobal == 0) {
2247: mrefs.getglobal = code.pool.Methodref(
2248: "org/python/core/PyFrame", "getglobal", "(" + $str
2249: + ")" + $pyObj);
2250: }
2251: code.invokevirtual(mrefs.getglobal);
2252: }
2253:
2254: public Object visitName(Name node) throws Exception {
2255: String name;
2256: if (fast_locals)
2257: name = node.id;
2258: else
2259: name = getName(node.id);
2260:
2261: SymInfo syminf = (SymInfo) tbl.get(name);
2262:
2263: int ctx = node.ctx;
2264: if (ctx == node.AugStore) {
2265: ctx = augmode;
2266: }
2267:
2268: switch (ctx) {
2269: case Name.Load:
2270: loadFrame();
2271: if (syminf != null) {
2272: int flags = syminf.flags;
2273: if ((flags & ScopeInfo.GLOBAL) != 0
2274: || optimizeGlobals
2275: && (flags & (ScopeInfo.BOUND | ScopeInfo.CELL | ScopeInfo.FREE)) == 0) {
2276: emitGetGlobal(name);
2277: return null;
2278: }
2279: if (fast_locals) {
2280: if ((flags & ScopeInfo.CELL) != 0) {
2281: code.iconst(syminf.env_index);
2282: if (mrefs.getderef == 0) {
2283: mrefs.getderef = code.pool.Methodref(
2284: "org/python/core/PyFrame",
2285: "getderef", "(I)" + $pyObj);
2286: }
2287: code.invokevirtual(mrefs.getderef);
2288: return null;
2289: }
2290: if ((flags & ScopeInfo.BOUND) != 0) {
2291: code.iconst(syminf.locals_index);
2292: if (mrefs.getlocal2 == 0) {
2293: mrefs.getlocal2 = code.pool.Methodref(
2294: "org/python/core/PyFrame",
2295: "getlocal", "(I)" + $pyObj);
2296: }
2297: code.invokevirtual(mrefs.getlocal2);
2298: return null;
2299: }
2300: }
2301: if ((flags & ScopeInfo.FREE) != 0
2302: && (flags & ScopeInfo.BOUND) == 0) {
2303: code.iconst(syminf.env_index);
2304: if (mrefs.getderef == 0) {
2305: mrefs.getderef = code.pool.Methodref(
2306: "org/python/core/PyFrame", "getderef",
2307: "(I)" + $pyObj);
2308: }
2309: code.invokevirtual(mrefs.getderef);
2310: return null;
2311: }
2312: }
2313: code.ldc(name);
2314: if (mrefs.getlocal1 == 0) {
2315: mrefs.getlocal1 = code.pool.Methodref(
2316: "org/python/core/PyFrame", "getname", "("
2317: + $str + ")" + $pyObj);
2318: }
2319: code.invokevirtual(mrefs.getlocal1);
2320: return null;
2321:
2322: case Name.Store:
2323: loadFrame();
2324: if (syminf != null
2325: && (syminf.flags & ScopeInfo.GLOBAL) != 0) {
2326: code.ldc(name);
2327: code.aload(temporary);
2328: if (mrefs.setglobal == 0) {
2329: mrefs.setglobal = code.pool.Methodref(
2330: "org/python/core/PyFrame", "setglobal", "("
2331: + $str + $pyObj + ")V");
2332: }
2333: code.invokevirtual(mrefs.setglobal);
2334: } else {
2335: if (!fast_locals) {
2336: code.ldc(name);
2337: code.aload(temporary);
2338: if (mrefs.setlocal1 == 0) {
2339: mrefs.setlocal1 = code.pool.Methodref(
2340: "org/python/core/PyFrame", "setlocal",
2341: "(" + $str + $pyObj + ")V");
2342: }
2343: code.invokevirtual(mrefs.setlocal1);
2344: } else {
2345: if (syminf == null) {
2346: System.err.println("internal compiler error: "
2347: + node);
2348: }
2349: if ((syminf.flags & ScopeInfo.CELL) != 0) {
2350: code.iconst(syminf.env_index);
2351: code.aload(temporary);
2352: if (mrefs.setderef == 0) {
2353: mrefs.setderef = code.pool.Methodref(
2354: "org/python/core/PyFrame",
2355: "setderef", "(I" + $pyObj + ")V");
2356: }
2357: code.invokevirtual(mrefs.setderef);
2358: } else {
2359: code.iconst(syminf.locals_index);
2360: code.aload(temporary);
2361: if (mrefs.setlocal2 == 0) {
2362: mrefs.setlocal2 = code.pool.Methodref(
2363: "org/python/core/PyFrame",
2364: "setlocal", "(I" + $pyObj + ")V");
2365: }
2366: code.invokevirtual(mrefs.setlocal2);
2367: }
2368: }
2369: }
2370: return null;
2371: case Name.Del: {
2372: loadFrame();
2373: if (syminf != null
2374: && (syminf.flags & ScopeInfo.GLOBAL) != 0) {
2375: code.ldc(name);
2376: if (mrefs.delglobal == 0) {
2377: mrefs.delglobal = code.pool.Methodref(
2378: "org/python/core/PyFrame", "delglobal", "("
2379: + $str + ")V");
2380: }
2381: code.invokevirtual(mrefs.delglobal);
2382: } else {
2383: if (!fast_locals) {
2384: code.ldc(name);
2385: if (mrefs.dellocal1 == 0) {
2386: mrefs.dellocal1 = code.pool.Methodref(
2387: "org/python/core/PyFrame", "dellocal",
2388: "(" + $str + ")V");
2389: }
2390: code.invokevirtual(mrefs.dellocal1);
2391: } else {
2392: if (syminf == null) {
2393: System.err.println("internal compiler error: "
2394: + node);
2395: }
2396: if ((syminf.flags & ScopeInfo.CELL) != 0) {
2397: module.error("can not delete variable '" + name
2398: + "' referenced in nested scope", true,
2399: node);
2400: }
2401: code.iconst(syminf.locals_index);
2402: if (mrefs.dellocal2 == 0) {
2403: mrefs.dellocal2 = code.pool.Methodref(
2404: "org/python/core/PyFrame", "dellocal",
2405: "(I)V");
2406: }
2407: code.invokevirtual(mrefs.dellocal2);
2408: }
2409: }
2410: return null;
2411: }
2412: }
2413: return null;
2414: }
2415:
2416: public Object visitUnicode(Unicode node) throws Exception {
2417: String s = node.s;
2418: if (s.length() > 32767) {
2419: throw new ParseException(
2420: "string constant too large (more than 32767 characters)",
2421: node);
2422: }
2423: module.PyUnicode(s).get(code);
2424: return null;
2425: }
2426:
2427: public Object visitStr(Str node) throws Exception {
2428: String s = node.s;
2429: if (s.length() > 32767) {
2430: throw new ParseException(
2431: "string constant too large (more than 32767 characters)",
2432: node);
2433: }
2434: module.PyString(s).get(code);
2435: return null;
2436: }
2437:
2438: protected Object unhandled_node(SimpleNode node) throws Exception {
2439: throw new Exception("Unhandled node " + node);
2440: }
2441:
2442: /**
2443: * Data about a given exception range whether a try:finally: or a
2444: * try:except:. The finally needs to inline the finally block for
2445: * each exit of the try: section, so we carry around that data for it.
2446: *
2447: * Both of these need to stop exception coverage of an area that is either
2448: * the inlined finally of a parent try:finally: or the reentry block after
2449: * a yield. Thus we keep around a set of exception ranges that the
2450: * catch block will eventually handle.
2451: */
2452: class ExceptionHandler {
2453: /**
2454: * Each handler gets several exception ranges, this is because inlined
2455: * finally exit code shouldn't be covered by the exception handler of
2456: * that finally block. Thus each time we inline the finally code, we
2457: * stop one range and then enter a new one.
2458: *
2459: * We also need to stop coverage for the recovery of the locals after
2460: * a yield.
2461: */
2462: public Vector exceptionStarts = new Vector();
2463: public Vector exceptionEnds = new Vector();
2464:
2465: public boolean bodyDone = false;
2466:
2467: public TryFinally node = null;
2468:
2469: public ExceptionHandler() {
2470: }
2471:
2472: public ExceptionHandler(TryFinally n) {
2473: node = n;
2474: }
2475:
2476: public boolean isFinallyHandler() {
2477: return node != null;
2478: }
2479:
2480: public void addExceptionHandlers(Label handlerStart)
2481: throws Exception {
2482: int throwable = code.pool.Class("java/lang/Throwable");
2483: for (int i = 0; i < exceptionStarts.size(); ++i) {
2484: Label start = (Label) exceptionStarts.elementAt(i);
2485: Label end = (Label) exceptionEnds.elementAt(i);
2486: if (start.getPosition() != end.getPosition()) {
2487: code.addExceptionHandler((Label) exceptionStarts
2488: .elementAt(i), (Label) exceptionEnds
2489: .elementAt(i), handlerStart, throwable);
2490: }
2491: }
2492: }
2493: }
2494: }
|