?? codecompiler.java
字號:
} public int assert1, assert2; public Object visitAssert(Assert node) throws Exception { setline(node); Label end_of_assert = code.getLabel(); /* First do an if __debug__: */ loadFrame(); emitGetGlobal("__debug__"); if (mrefs.nonzero == 0) { mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", "__nonzero__", "()Z"); } code.invokevirtual(mrefs.nonzero); code.ifeq(end_of_assert); /* Now do the body of the assert */ visit(node.test); if (node.msg != null) { visit(node.msg); if (mrefs.assert2 == 0) { mrefs.assert2 = code.pool.Methodref( "org/python/core/Py", "assert_", "(" + $pyObj + $pyObj + ")V"); } code.invokestatic(mrefs.assert2); } else { if (mrefs.assert1 == 0) { mrefs.assert1 = code.pool.Methodref( "org/python/core/Py", "assert_", "(" + $pyObj + ")V"); } code.invokestatic(mrefs.assert1); } /* And finally set the label for the end of it all */ end_of_assert.setPosition(); return null; } public int nonzero; public Object doTest(Label end_of_if, If node, int index) throws Exception { Label end_of_suite = code.getLabel(); setline(node.test); visit(node.test); if (mrefs.nonzero == 0) { mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", "__nonzero__", "()Z"); } code.invokevirtual(mrefs.nonzero); code.ifeq(end_of_suite); Object exit = suite(node.body); if (end_of_if != null && exit == null) code.goto_(end_of_if); end_of_suite.setPosition(); if (node.orelse != null) { return suite(node.orelse) != null ? exit : null; } else { return null; } } public Object visitIf(If node) throws Exception { Label end_of_if = null; if (node.orelse != null) end_of_if = code.getLabel(); Object exit = doTest(end_of_if, node, 0); if (end_of_if != null) end_of_if.setPosition(); return exit; } public int beginLoop() { continueLabels.push(code.getLabel()); breakLabels.push(code.getLabel()); int savebcf = bcfLevel; bcfLevel = finallyLabels.size(); return savebcf; } public void finishLoop(int savebcf) { continueLabels.pop(); breakLabels.pop(); bcfLevel = savebcf; } public Object visitWhile(While node) throws Exception { int savebcf = beginLoop(); Label continue_loop = (Label)continueLabels.peek(); Label break_loop = (Label)breakLabels.peek(); Label start_loop = code.getLabel(); code.goto_(continue_loop); start_loop.setPosition(); //Do suite suite(node.body); continue_loop.setPosition(); setline(node); //Do test visit(node.test); if (mrefs.nonzero == 0) { mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", "__nonzero__", "()Z"); } code.invokevirtual(mrefs.nonzero); code.ifne(start_loop); finishLoop(savebcf); if (node.orelse != null) { //Do else suite(node.orelse); } break_loop.setPosition(); // Probably need to detect "guaranteed exits" return null; } public int iter=0; public int iternext=0; public Object visitFor(For node) throws Exception { int savebcf = beginLoop(); Label continue_loop = (Label)continueLabels.peek(); Label break_loop = (Label)breakLabels.peek(); Label start_loop = code.getLabel(); Label next_loop = code.getLabel(); int iter_tmp = code.getLocal("org/python/core/PyObject"); int expr_tmp = code.getLocal("org/python/core/PyObject"); setline(node); //parse the list visit(node.iter); //set up the loop iterator if (mrefs.iter == 0) { mrefs.iter = code.pool.Methodref( "org/python/core/PyObject", "__iter__", "()" + $pyObj); } code.invokevirtual(mrefs.iter); code.astore(iter_tmp); //do check at end of loop. Saves one opcode ;-) code.goto_(next_loop); start_loop.setPosition(); //set iter variable to current entry in list set(node.target, expr_tmp); //evaluate for body suite(node.body); continue_loop.setPosition(); next_loop.setPosition(); setline(node); //get the next element from the list code.aload(iter_tmp); if (mrefs.iternext == 0) { mrefs.iternext = code.pool.Methodref( "org/python/core/PyObject", "__iternext__", "()" + $pyObj); } code.invokevirtual(mrefs.iternext); code.astore(expr_tmp); code.aload(expr_tmp); //if no more elements then fall through code.ifnonnull(start_loop); finishLoop(savebcf); if (node.orelse != null) { //Do else clause if provided suite(node.orelse); } break_loop.setPosition(); code.freeLocal(iter_tmp); code.freeLocal(expr_tmp); // Probably need to detect "guaranteed exits" return null; } public int match_exception; public void exceptionTest(int exc, Label end_of_exceptions, TryExcept node, int index) throws Exception { for (int i = 0; i < node.handlers.length; i++) { excepthandlerType handler = node.handlers[i]; //setline(name); Label end_of_self = code.getLabel(); if (handler.type != null) { code.aload(exc); //get specific exception visit(handler.type); if (mrefs.match_exception == 0) { mrefs.match_exception = code.pool.Methodref( "org/python/core/Py", "matchException", "(" + $pyExc + $pyObj + ")Z"); } code.invokestatic(mrefs.match_exception); code.ifeq(end_of_self); } else { if (i != node.handlers.length-1) { throw new ParseException( "bare except must be last except clause", handler.type); } } if (handler.name != null) { code.aload(exc); code.getfield(code.pool.Fieldref("org/python/core/PyException", "value", "Lorg/python/core/PyObject;")); set(handler.name); } //do exception body suite(handler.body); code.goto_(end_of_exceptions); end_of_self.setPosition(); } code.aload(exc); code.athrow(); } public int add_traceback; public Object visitTryFinally(TryFinally node) throws Exception { Label start = code.getLabel(); Label end = code.getLabel(); Label handlerStart = code.getLabel(); Label finallyEnd = code.getLabel(); Label skipSuite = code.getLabel(); Object ret; // Do protected suite int yieldCount = 0; if (my_scope.generator) { YieldChecker checker = new YieldChecker(); checker.visit(node.finalbody); yieldCount = checker.yieldCount; } if (yieldCount > 0) { throw new ParseException("'yield' in finally not yet supported", node); } InFinally inFinally = new InFinally(yieldCount + 1); finallyLabels.push(inFinally); int excLocal = code.getLocal("java/lang/Throwable"); code.aconst_null(); code.astore(excLocal); start.setPosition(); ret = suite(node.body); end.setPosition(); if (ret == null) { doFinallyPart(inFinally); code.goto_(finallyEnd); } finallyLabels.pop(); // Handle any exceptions that get thrown in suite handlerStart.setPosition(); code.stack = 1; code.astore(excLocal); code.aload(excLocal); loadFrame(); if (mrefs.add_traceback == 0) { mrefs.add_traceback = code.pool.Methodref( "org/python/core/Py", "addTraceback", "(" + $throwable + $pyFrame + ")V"); } code.invokestatic(mrefs.add_traceback); doFinallyPart(inFinally); code.aload(excLocal); code.checkcast(code.pool.Class("java/lang/Throwable")); code.athrow(); // Do finally suite inFinally.labels[0].setPosition(); code.stack = 1; inFinally.retLocal = code.getFinallyLocal("ret"); code.astore(inFinally.retLocal); // Trick the JVM verifier into thinking this code might not // be executed //code.iconst(1); //code.ifeq(skipSuite); inFinallyLabels.push(inFinally); // The actual finally suite is always executed (since 1 != 0) ret = suite(node.finalbody); inFinallyLabels.pop(); // Fake jump to here to pretend this could always happen //skipSuite.setPosition(); code.ret(inFinally.retLocal); code.freeFinallyLocal(inFinally.retLocal); finallyEnd.setPosition(); code.freeLocal(excLocal); code.addExceptionHandler(start, end, handlerStart, code.pool.Class("java/lang/Throwable")); // According to any JVM verifiers, this code block might not return return null; } private void doFinallyPart(InFinally inFinally) throws Exception { if (inFinally.labels.length == 1) { code.jsr(inFinally.labels[0]); } else { Label endOfFinal = code.getLabel(); for (int i = 0; i < inFinally.labels.length; i++) { setLastI(++yield_count); code.jsr(inFinally.labels[i]); //code.areturn(); if (i < inFinally.labels.length-1) { code.goto_(endOfFinal); Label restart = code.getLabel(); yields.addElement(restart); restart.setPosition(); } } endOfFinal.setPosition(); } } class YieldChecker extends Visitor { public int yieldCount = 0; public Object visitYield(Yield node) throws Exception { yieldCount++; return super.visitYield(node); } } public int set_exception; public Object visitTryExcept(TryExcept node) throws Exception { Label start = code.getLabel(); Label end = code.getLabel(); Label handler_start = code.getLabel(); Label handler_end = code.getLabel(); start.setPosition(); //Do suite Object exit = suite(node.body); //System.out.println("exit: "+exit+", "+(exit != null)); end.setPosition(); if (exit == null) code.goto_(handler_end); handler_start.setPosition(); //Stack has eactly one item at start of handler code.stack = 1; loadFrame(); if (mrefs.set_exception == 0) { mrefs.set_exception = code.pool.Methodref( "org/python/core/Py", "setException", "(" + $throwable + $pyFrame + ")" + $pyExc); } code.invokestatic(mrefs.set_exception); int exc = code.getFinallyLocal("java/lang/Throwable"); code.astore(exc); if (node.orelse == null) { //No else clause to worry about exceptionTest(exc, handler_end, node, 1); handler_end.setPosition(); } else { //Have else clause Label else_end = code.getLabel();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -