?? codecompiler.java
字號:
// Copyright (c) Corporation for National Research Initiativespackage org.python.compiler;import org.python.parser.*;import org.python.parser.ast.*;import org.python.parser.ast.Attribute;import org.python.core.Py;import org.python.core.PyObject;import org.python.core.PyInteger;import org.python.core.PyFloat;import org.python.core.PyLong;import org.python.core.PyComplex;import org.python.core.PyException;import org.python.core.CompilerFlags;import java.io.IOException;import java.util.Stack;import java.util.Hashtable;import java.util.Vector;public class CodeCompiler extends Visitor implements ClassConstants //, PythonGrammarTreeConstants{ public static final Object Exit=new Integer(1); public static final Object NoExit=null; public static final int GET=0; public static final int SET=1; public static final int DEL=2; public static final int AUGGET=3; public static final int AUGSET=4; public Module module; public Code code; public ConstantPool pool; public CodeCompiler mrefs; int temporary; int augmode; int augtmp1; int augtmp2; int augtmp3; int augtmp4; public boolean fast_locals, print_results; public Hashtable tbl; public ScopeInfo my_scope; boolean optimizeGlobals = true; public Vector names; public String className; public Stack continueLabels, breakLabels, finallyLabels; public Stack inFinallyLabels; public Vector yields = new Vector(); /* break/continue finally's level. * This is the lowest level in finallyLabels which should * be executed at break or continue. * It is saved/updated/restored when compiling loops. * A similar level for returns is not needed because a new CodeCompiler * is used for each PyCode, ie. each 'function'. * When returning through finally's all finallyLabels are executed. */ public int bcfLevel = 0; public CodeCompiler(Module module, boolean print_results) { this.module = module; mrefs = this; pool = module.classfile.pool; continueLabels = new Stack(); breakLabels = new Stack(); finallyLabels = new Stack(); inFinallyLabels = new Stack(); this.print_results = print_results; } public int PyNone; public void getNone() throws IOException { if (mrefs.PyNone == 0) { mrefs.PyNone = pool.Fieldref("org/python/core/Py", "None", $pyObj); } code.getstatic(mrefs.PyNone); } public void loadFrame() throws Exception { code.aload(1); } int f_lasti; public void setLastI(int idx) throws Exception { if (mrefs.f_lasti == 0) { mrefs.f_lasti = code.pool.Fieldref( "org/python/core/PyFrame", "f_lasti", "I"); } loadFrame(); code.iconst(idx); code.putfield(mrefs.f_lasti); } public int storeTop() throws Exception { int tmp = code.getLocal("org/python/core/PyObject"); code.astore(tmp); return tmp; } public int setline; public void setline(int line) throws Exception { //System.out.println("line: "+line+", "+code.stack); if (module.linenumbers) { code.setline(line); loadFrame(); code.iconst(line); if (mrefs.setline == 0) { mrefs.setline = pool.Methodref("org/python/core/PyFrame", "setline", "(I)V"); } code.invokevirtual(mrefs.setline); } } public void setline(SimpleNode node) throws Exception { setline(node.beginLine); } public void set(SimpleNode node) throws Exception { int tmp = storeTop(); set(node, tmp); code.aconst_null(); code.astore(tmp); code.freeLocal(tmp); } boolean inSet = false; public void set(SimpleNode node, int tmp) throws Exception { //System.out.println("tmp: "+tmp); if (inSet) { System.out.println("recurse set: "+tmp+", "+temporary); } temporary = tmp; visit(node); } private void saveAugTmps(SimpleNode node, int count) throws Exception { if (count >= 4) { augtmp4 = code.getLocal("org/python/core/PyObject"); code.astore(augtmp4); } if (count >= 3) { augtmp3 = code.getLocal("org/python/core/PyObject"); code.astore(augtmp3); } if (count >= 2) { augtmp2 = code.getLocal("org/python/core/PyObject"); code.astore(augtmp2); } augtmp1 = code.getLocal("org/python/core/PyObject"); code.astore(augtmp1); code.aload(augtmp1); if (count >= 2) code.aload(augtmp2); if (count >= 3) code.aload(augtmp3); if (count >= 4) code.aload(augtmp4); } private void restoreAugTmps(SimpleNode node, int count) throws Exception { code.aload(augtmp1); code.freeLocal(augtmp1); if (count == 1) return; code.aload(augtmp2); code.freeLocal(augtmp2); if (count == 2) return; code.aload(augtmp3); code.freeLocal(augtmp3); if (count == 3) return; code.aload(augtmp4); code.freeLocal(augtmp4); } public void parse(modType node, Code code, boolean fast_locals, String className, boolean classBody, ScopeInfo scope,CompilerFlags cflags) throws Exception { this.fast_locals = fast_locals; this.className = className; this.code = code; my_scope = scope; names = scope.names; tbl = scope.tbl; optimizeGlobals = fast_locals&&!scope.exec&&!scope.from_import_star; Object exit = visit(node); //System.out.println("exit: "+exit+", "+(exit==null)); if (classBody) { loadFrame(); code.invokevirtual("org/python/core/PyFrame", "getf_locals", "()" + $pyObj); code.areturn(); } else { if (exit == null) { //System.out.println("no exit"); setLastI(-1); getNone(); code.areturn(); } } } public Object visitInteractive(Interactive node) throws Exception { traverse(node); return null; } public Object visitModule(org.python.parser.ast.Module suite) throws Exception { if (mrefs.setglobal == 0) { mrefs.setglobal = code.pool.Methodref( "org/python/core/PyFrame", "setglobal", "(" +$str + $pyObj + ")V"); } if (suite.body.length > 0 && suite.body[0] instanceof Expr && ((Expr)suite.body[0]).value instanceof Str) { loadFrame(); code.ldc("__doc__"); visit(((Expr) suite.body[0]).value); code.invokevirtual(mrefs.setglobal); } if (module.setFile) { loadFrame(); code.ldc("__file__"); module.filename.get(code); code.invokevirtual(mrefs.setglobal); } traverse(suite); return null; } public Object visitExpression(Expression node) throws Exception { if (my_scope.generator && node.body != null) { module.error("'return' with argument inside generator", true, node); } return visitReturn(new Return(node.body, node), true); } public int EmptyObjects; public void makeArray(SimpleNode[] nodes) throws Exception { int n; if (nodes == null) n = 0; else n = nodes.length; if (n == 0) { if (mrefs.EmptyObjects == 0) { mrefs.EmptyObjects = code.pool.Fieldref( "org/python/core/Py", "EmptyObjects", $pyObjArr); } code.getstatic(mrefs.EmptyObjects); } else { int tmp = code.getLocal("[org/python/core/PyObject"); code.iconst(n); code.anewarray(code.pool.Class("org/python/core/PyObject")); code.astore(tmp); for(int i=0; i<n; i++) { code.aload(tmp); code.iconst(i); visit(nodes[i]); code.aastore(); } code.aload(tmp); code.freeLocal(tmp); } } public void getDocString(stmtType[] suite) throws Exception { //System.out.println("doc: "+suite.getChild(0)); if (suite.length > 0 && suite[0] instanceof Expr && ((Expr) suite[0]).value instanceof Str) { visit(((Expr) suite[0]).value); } else { code.aconst_null(); } } int getclosure; public boolean makeClosure(Vector freenames) throws Exception { if (freenames == null) return false; int n = freenames.size(); if (n == 0) return false; if (mrefs.getclosure == 0) { mrefs.getclosure = code.pool.Methodref( "org/python/core/PyFrame", "getclosure", "(I)" + $pyObj); } int tmp = code.getLocal("[org/python/core/PyObject"); code.iconst(n); code.anewarray(code.pool.Class("org/python/core/PyObject")); code.astore(tmp); for(int i=0; i<n; i++) { code.aload(tmp); code.iconst(i); code.aload(1); // get frame code.iconst(((SymInfo)tbl.get(freenames.elementAt(i))).env_index); code.invokevirtual(getclosure); code.aastore(); } code.aload(tmp); code.freeLocal(tmp); return true; } int f_globals, PyFunction_init, PyFunction_closure_init; public Object visitFunctionDef(FunctionDef node) throws Exception { String name = getName(node.name); setline(node); code.new_(code.pool.Class("org/python/core/PyFunction")); code.dup(); loadFrame(); if (mrefs.f_globals == 0) { mrefs.f_globals = code.pool.Fieldref( "org/python/core/PyFrame", "f_globals", $pyObj); } code.getfield(mrefs.f_globals); ScopeInfo scope = module.getScopeInfo(node); makeArray(scope.ac.getDefaults()); scope.setup_closure(my_scope); scope.dump(); module.PyCode(new Suite(node.body, node), name, true, className, false, false, node.beginLine, scope).get(code); Vector freenames = scope.freevars; getDocString(node.body); if (!makeClosure(freenames)) { if (mrefs.PyFunction_init == 0) { mrefs.PyFunction_init = code.pool.Methodref( "org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + ")V"); } code.invokespecial(mrefs.PyFunction_init); } else { if (mrefs.PyFunction_closure_init == 0) { mrefs.PyFunction_closure_init = code.pool.Methodref( "org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")V"); } code.invokespecial(mrefs.PyFunction_closure_init); } set(new Name(node.name, Name.Store, node)); return null; } public int printResult; public Object visitExpr(Expr node) throws Exception { setline(node); visit(node.value); if (print_results) { if (mrefs.printResult == 0) { mrefs.printResult = code.pool.Methodref( "org/python/core/Py", "printResult", "(" + $pyObj + ")V"); } code.invokestatic(mrefs.printResult); } else { code.pop(); } return null; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -