From: <zy...@us...> - 2009-02-12 04:38:08
|
Revision: 6025 http://jython.svn.sourceforge.net/jython/?rev=6025&view=rev Author: zyasoft Date: 2009-02-12 04:38:04 +0000 (Thu, 12 Feb 2009) Log Message: ----------- Beginning of PBC compilation support. Pretty much a shell for now. Added Paths: ----------- branches/pbcvm/src/org/python/compiler/pbc/ branches/pbcvm/src/org/python/compiler/pbc/Bytecode.java branches/pbcvm/src/org/python/compiler/pbc/BytecodeCompiler.java Added: branches/pbcvm/src/org/python/compiler/pbc/Bytecode.java =================================================================== --- branches/pbcvm/src/org/python/compiler/pbc/Bytecode.java (rev 0) +++ branches/pbcvm/src/org/python/compiler/pbc/Bytecode.java 2009-02-12 04:38:04 UTC (rev 6025) @@ -0,0 +1,555 @@ +package org.python.compiler.pbc; + +// Copyright (c) 2009 Jython Developers +// +// ported from peak.util.assembler (BytecodeAssembler): +// Copyright (C) 1996-2004 by Phillip J. Eby and Tyler C. Sarna. +// All rights reserved. This software may be used under the same terms +// as Zope or Python. (http://cvs.eby-sarna.com/*checkout*/PEAK/README.txt) +// +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.python.core.Py; +import org.python.core.Opcode; +import org.python.core.PyBaseCode; +import org.python.core.PyBytecode; +import org.python.core.PyObject; + +// must be thread confined, as might be expected +class Bytecode { + + private int co_argcount = 0; + private int co_stacksize = 0; + private int co_flags = PyBaseCode.CO_OPTIMIZED | PyBaseCode.CO_NEWLOCALS; // typical usage +// co_filename = '<generated code>' +// co_name = '<lambda>' +// co_firstlineno = 0 +// co_freevars = () +// co_cellvars = () +// _last_lineofs = 0 +// _ss = 0 +// _tmp_level = 0 +// + + public Bytecode(int co_flags) { + this.co_flags = co_flags; + co_const.put(Py.None, 0); + } +// def __init__(self): +// self.co_code = array('B') +// self.co_names = [] +// self.co_varnames = [] +// self.blocks = [] + private final List<Integer> stack_history = new ArrayList<Integer>(); + private final List<Integer> co_code = new ArrayList<Integer>(); + private final List<Integer> co_lnotab = new ArrayList<Integer>(); + private final Map<PyObject, Integer> co_const = new HashMap<PyObject, Integer>(); + + private void emit(int opcode) { + assert (opcode >= 0 && opcode <= 0xFF); // at this point we should verify we are only emitting unsigned bytes + co_code.add(opcode); + } + + private void emit(int opcode, int oparg) { + if (oparg > 0xFFFF) { + emit(Opcode.EXTENDED_ARG); + emit((oparg >> 16) & 0xFF); + emit((oparg >> 24) & 0xFF); + } + emit(opcode); + emit(oparg & 0xFF); + emit((oparg >> 8) & 0xFF); + } + + private void LOAD_CONST(PyObject constant) { + int arg; + if (co_const.containsKey(constant)) { + arg = co_const.get(constant); + } else { + arg = co_const.size() + 1; + co_const.put(constant, arg); + } + stackchange(0, 1); + emit(Opcode.LOAD_CONST, arg); + } + + private void RETURN_VALUE() { + stackchange(1, 0); + emit(Opcode.RETURN_VALUE); + stack_unknown(); + } + + public void code() { +// return new PyBytecode(); + } + + +// + +// +// def locals_written(self): +// vn = self.co_varnames +// hl = dict.fromkeys([STORE_FAST, DELETE_FAST]) +// return dict.fromkeys([vn[arg] for ofs, op, arg in self if op in hl]) +// +// +// +// + public void set_lineno(int lno) { +// if not self.co_firstlineno: +// self.co_firstlineno = self._last_line = lno +// return +// +// append = self.co_lnotab.append +// incr_line = lno - self._last_line +// incr_addr = len(self.co_code) - self._last_lineofs +// if not incr_line: +// return +// +// assert incr_addr>=0 and incr_line>=0 +// +// while incr_addr>255: +// append(255) +// append(0) +// incr_addr -= 255 +// +// while incr_line>255: +// append(incr_addr) +// append(255) +// incr_line -= 255 +// incr_addr = 0 +// +// if incr_addr or incr_line: +// append(incr_addr) +// append(incr_line) +// +// self._last_line = lno +// self._last_lineofs = len(self.co_code) + } + // + + public void YIELD_VALUE() { + stackchange(1, 1); + co_flags |= PyBaseCode.CO_GENERATOR; + emit(Opcode.YIELD_VALUE); + } + + // defaults? def CALL_FUNCTION(self, argc=0, kwargc=0, op=CALL_FUNCTION, extra=0): + public void CALL_FUNCTION(int argc, int kwargc, int op, int extra) { + stackchange(1 + argc + 2 * kwargc + extra, 1); + emit(op); + emit(argc); + emit(kwargc); + } +// +// def CALL_FUNCTION_VAR(self, argc=0, kwargc=0): +// self.CALL_FUNCTION(argc,kwargc,CALL_FUNCTION_VAR, 1) # 1 for *args +// +// def CALL_FUNCTION_KW(self, argc=0, kwargc=0): +// self.CALL_FUNCTION(argc,kwargc,CALL_FUNCTION_KW, 1) # 1 for **kw +// +// def CALL_FUNCTION_VAR_KW(self, argc=0, kwargc=0): +// self.CALL_FUNCTION(argc,kwargc,CALL_FUNCTION_VAR_KW, 2) # 2 *args,**kw +// + + public void BUILD_TUPLE(int count) { + stackchange(count, 1); + emit(Opcode.BUILD_TUPLE, count); + } + + public void BUILD_LIST(int count) { + stackchange(count, 1); + emit(Opcode.BUILD_LIST, count); + } + + public void UNPACK_SEQUENCE(int count) { + stackchange(1, count); + emit(Opcode.UNPACK_SEQUENCE, count); + } + + public void BUILD_SLICE(int count) { + if (count != 2 && count != 3) { + throw Py.AssertionError("Invalid number of arguments for BUILD_SLICE"); + } + stackchange(count, 1); + emit(Opcode.BUILD_SLICE, count); + } + + public void DUP_TOPX(int count) { + stackchange(count, count * 2); + emit(Opcode.DUP_TOPX, count); + } + + public void RAISE_VARARGS(int argc) { + if (0 <= argc && argc <= 3) { + throw Py.AssertionError("Invalid number of arguments for RAISE_VARARGS"); + } + stackchange(argc, 0); + emit(Opcode.RAISE_VARARGS, argc); + } + + public void MAKE_FUNCTION(int ndefaults) { + stackchange(1 + ndefaults, 1); + emit(Opcode.MAKE_FUNCTION, ndefaults); + } + + public void MAKE_CLOSURE(int ndefaults, int freevars) { + freevars = 1; + stackchange(1 + freevars + ndefaults, 1); + emit(Opcode.MAKE_CLOSURE, ndefaults); + } + + public int here() { + return co_code.size(); + } + private int _ss = -1; + + public void set_stack_size(int size) { + if (size < 0) { + throw Py.AssertionError("Stack underflow"); + } + if (size > co_stacksize) { + co_stacksize = size; + } + int bytes = co_code.size() - stack_history.size() + 1; + if (bytes > 0) { + for (int i = 0; i < bytes; i++) { + stack_history.add(_ss); + } + } + _ss = size; + } + + public int get_stack_size() { + return _ss; + } + + public void stackchange(int inputs, int outputs) { + if (_ss == -1) { + throw Py.AssertionError("Unknown stack size at this location"); + } + set_stack_size(get_stack_size() - inputs); // check underflow + set_stack_size(get_stack_size() + outputs); // update maximum height + + } + + public void stack_unknown() { + _ss = -1; + } + + public void branch_stack(int location, int expected) { + if (location >= stack_history.size()) { + if (location > co_code.size()) { + throw Py.AssertionError(String.format( + "Forward-looking stack prediction! %d, %d", location, co_code.size())); + } + int actual = get_stack_size(); + if (actual == -1) { + actual = expected; + set_stack_size(actual); + stack_history.set(location, actual); + } else { + actual = stack_history.get(location); + if (actual == -1) { + actual = expected; + stack_history.set(location, actual); + } + if (actual != expected) { + throw Py.AssertionError(String.format( + "Stack level mismatch: actual=%d expected=%d", actual, expected)); + } + } + } + } + +// def jump(self, op, arg=None): +// def jump_target(offset): +// target = offset +// if op not in hasjabs: +// target = target - (posn+3) +// assert target>=0, "Relative jumps can't go backwards" +// if target>0xFFFF: +// target = offset - (posn+6) +// return target +// +// def backpatch(offset): +// target = jump_target(offset) +// if target>0xFFFF: +// raise AssertionError("Forward jump span must be <64K bytes") +// self.patch_arg(posn, 0, target) +// self.branch_stack(offset, old_level) +// +// if op==FOR_ITER: +// old_level = self.stack_size = self.stack_size - 1 +// self.stack_size += 2 +// else: +// old_level = self.stack_size +// posn = self.here() +// +// if arg is not None: +// self.emit_arg(op, jump_target(arg)) +// self.branch_stack(arg, old_level) +// lbl = None +// else: +// self.emit_arg(op, 0) +// def lbl(code=None): +// backpatch(self.here()) +// if op in (JUMP_FORWARD, JUMP_ABSOLUTE, CONTINUE_LOOP): +// self.stack_unknown() +// return lbl +// +// def COMPARE_OP(self, op): +// self.stackchange((2,1)) +// self.emit_arg(COMPARE_OP, compares[op]) +// +// +// def setup_block(self, op): +// jmp = self.jump(op) +// self.blocks.append((op,self.stack_size,jmp)) +// return jmp +// +// def SETUP_EXCEPT(self): +// ss = self.stack_size +// self.stack_size = ss+3 # simulate the level at "except:" time +// self.setup_block(SETUP_EXCEPT) +// self.stack_size = ss # restore the current level +// +// def SETUP_FINALLY(self): +// ss = self.stack_size +// self.stack_size = ss+3 # allow for exceptions +// self.stack_size = ss+1 # simulate the level after the None is pushed +// self.setup_block(SETUP_FINALLY) +// self.stack_size = ss # restore original level +// +// def SETUP_LOOP(self): +// self.setup_block(SETUP_LOOP) +// +// def POP_BLOCK(self): +// if not self.blocks: +// raise AssertionError("Not currently in a block") +// +// why, level, fwd = self.blocks.pop() +// self.emit(POP_BLOCK) +// +// if why!=SETUP_LOOP: +// if why==SETUP_FINALLY: +// self.LOAD_CONST(None) +// fwd() +// else: +// self.stack_size = level-3 # stack level resets here +// else_ = self.JUMP_FORWARD() +// fwd() +// return else_ +// else: +// return fwd +// +// +// def assert_loop(self): +// for why,level,fwd in self.blocks: +// if why==SETUP_LOOP: +// return +// raise AssertionError("Not inside a loop") +// +// def BREAK_LOOP(self): +// self.assert_loop(); self.emit(BREAK_LOOP) +// self.stack_unknown() +// +// def CONTINUE_LOOP(self, label): +// self.assert_loop() +// if self.blocks[-1][0]==SETUP_LOOP: +// op = JUMP_ABSOLUTE # more efficient if not in a nested block +// else: +// op = CONTINUE_LOOP +// return self.jump(op, label) +// +// def __call__(self, *args): +// last = None +// for ob in args: +// if callable(ob): +// last = ob(self) +// else: +// try: +// f = generate_types[type(ob)] +// except KeyError: +// raise TypeError("Can't generate", ob) +// else: +// last = f(self, ob) +// return last +// +// def return_(self, ob=None): +// return self(ob, Code.RETURN_VALUE) +// +// decorate(classmethod) +// def from_function(cls, function, copy_lineno=False): +// code = cls.from_code(function.func_code, copy_lineno) +// return code +// +// +// decorate(classmethod) +// def from_code(cls, code, copy_lineno=False): +// import inspect +// self = cls.from_spec(code.co_name, *inspect.getargs(code)) +// if copy_lineno: +// self.set_lineno(code.co_firstlineno) +// self.co_filename = code.co_filename +// self.co_freevars = code.co_freevars # XXX untested! +// return self +// +// decorate(classmethod) +// def from_spec(cls, name='<lambda>', args=(), var=None, kw=None): +// self = cls() +// self.co_name = name +// self.co_argcount = len(args) +// self.co_varnames.extend(args) +// if var: +// self.co_varnames.append(var) +// self.co_flags |= CO_VARARGS +// if kw: +// self.co_varnames.append(kw) +// self.co_flags |= CO_VARKEYWORDS +// +// def tuple_arg(args): +// self.UNPACK_SEQUENCE(len(args)) +// for arg in args: +// if not isinstance(arg, basestring): +// tuple_arg(arg) +// else: +// self.STORE_FAST(arg) +// +// for narg, arg in enumerate(args): +// if not isinstance(arg, basestring): +// dummy_name = '.'+str(narg) +// self.co_varnames[narg] = dummy_name +// self.LOAD_FAST(dummy_name) +// tuple_arg(arg) +// +// return self +// +// +// def patch_arg(self, offset, oldarg, newarg): +// code = self.co_code +// if (oldarg>0xFFFF) != (newarg>0xFFFF): +// raise AssertionError("Can't change argument size", oldarg, newarg) +// code[offset+1] = newarg & 255 +// code[offset+2] = (newarg>>8) & 255 +// if newarg>0xFFFF: +// newarg >>=16 +// code[offset-2] = newarg & 255 +// code[offset-1] = (newarg>>8) & 255 +// +// def nested(self, name='<lambda>', args=(), var=None, kw=None, cls=None): +// if cls is None: +// cls = Code +// code = cls.from_spec(name, args, var, kw) +// code.co_filename=self.co_filename +// return code +// +// def __iter__(self): +// i = 0 +// extended_arg = 0 +// code = self.co_code +// n = len(code) +// while i < n: +// op = code[i] +// if op >= HAVE_ARGUMENT: +// oparg = code[i+1] + code[i+2]*256 + extended_arg +// extended_arg = 0 +// if op == EXTENDED_ARG: +// extended_arg = oparg*65536 +// i+=3 +// continue +// yield i, op, oparg +// i += 3 +// else: +// yield i, op, None +// i += 1 +// +// +// +// +// def makefree(self, names): +// nowfree = dict.fromkeys(self.co_freevars) +// newfree = [n for n in names if n not in nowfree] +// if newfree: +// self.co_freevars += tuple(newfree) +// self._locals_to_cells() +// +// def makecells(self, names): +// nowcells = dict.fromkeys(self.co_cellvars+self.co_freevars) +// newcells = [n for n in names if n not in nowcells] +// if newcells: +// if not (self.co_flags & CO_OPTIMIZED): +// raise AssertionError("Can't use cellvars in unoptimized scope") +// cc = len(self.co_cellvars) +// nc = len(newcells) +// self.co_cellvars += tuple(newcells) +// if self.co_freevars: +// self._patch( +// deref_to_deref, +// dict([(n+cc,n+cc+nc)for n in range(len(self.co_freevars))]) +// ) +// self._locals_to_cells() +// +// def _locals_to_cells(self): +// freemap = dict( +// [(n,p) for p,n in enumerate(self.co_cellvars+self.co_freevars)] +// ) +// argmap = dict( +// [(p,freemap[n]) for p,n in enumerate(self.co_varnames) +// if n in freemap] +// ) +// if argmap: +// for ofs, op, arg in self: +// if op==DELETE_FAST and arg in argmap: +// raise AssertionError( +// "Can't delete local %r used in nested scope" +// % self.co_varnames[arg] +// ) +// self._patch(fast_to_deref, argmap) +// +// +// def _patch(self, opmap, argmap={}): +// code = self.co_code +// for ofs, op, arg in self: +// if op in opmap: +// if arg in argmap: +// self.patch_arg(ofs, arg, argmap[arg]) +// elif arg is not None: +// continue +// code[ofs] = opmap[op] +// +// def code(self, parent=None): +// if self.blocks: +// raise AssertionError("%d unclosed block(s)" % len(self.blocks)) +// +// flags = self.co_flags & ~CO_NOFREE +// if parent is not None: +// locals_written = self.locals_written() +// self.makefree([ +// n for n in self.co_varnames[ +// self.co_argcount +// + ((self.co_flags & CO_VARARGS)==CO_VARARGS) +// + ((self.co_flags & CO_VARKEYWORDS)==CO_VARKEYWORDS) +// : +// ] if n not in locals_written +// ]) +// +// if not self.co_freevars and not self.co_cellvars: +// flags |= CO_NOFREE +// elif parent is not None and self.co_freevars: +// parent.makecells(self.co_freevars) +// +// return code( +// self.co_argcount, len(self.co_varnames), +// self.co_stacksize, flags, self.co_code.tostring(), +// tuple(self.co_consts), tuple(self.co_names), +// tuple(self.co_varnames), +// self.co_filename, self.co_name, self.co_firstlineno, +// self.co_lnotab.tostring(), self.co_freevars, self.co_cellvars +// ) +} Added: branches/pbcvm/src/org/python/compiler/pbc/BytecodeCompiler.java =================================================================== --- branches/pbcvm/src/org/python/compiler/pbc/BytecodeCompiler.java (rev 0) +++ branches/pbcvm/src/org/python/compiler/pbc/BytecodeCompiler.java 2009-02-12 04:38:04 UTC (rev 6025) @@ -0,0 +1,2419 @@ +// Copyright (c) Corporation for National Research Initiatives + +// should be able to use ScopesCompiler pretty much *as is* + +// needs to construct a PyBytecode object, include +// co_code, co_const, co_cellvars, co_freevars, co_stacksize (use something like compile.opcode_stack_effect) +// etc. + +package org.python.compiler.pbc; + +import org.python.compiler.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +//import java.util.Stack; +//import java.util.Vector; +// +import org.python.antlr.ParseException; +import org.python.antlr.PythonTree; +import org.python.antlr.Visitor; +import org.python.antlr.ast.Assert; +import org.python.antlr.ast.Assign; +import org.python.antlr.ast.Attribute; +import org.python.antlr.ast.AugAssign; +import org.python.antlr.ast.BinOp; +import org.python.antlr.ast.BoolOp; +import org.python.antlr.ast.Break; +import org.python.antlr.ast.Call; +import org.python.antlr.ast.ClassDef; +import org.python.antlr.ast.Compare; +import org.python.antlr.ast.Continue; +import org.python.antlr.ast.Delete; +import org.python.antlr.ast.Dict; +import org.python.antlr.ast.Ellipsis; +import org.python.antlr.ast.ExceptHandler; +import org.python.antlr.ast.Exec; +import org.python.antlr.ast.Expr; +import org.python.antlr.ast.Expression; +import org.python.antlr.ast.ExtSlice; +import org.python.antlr.ast.For; +import org.python.antlr.ast.FunctionDef; +import org.python.antlr.ast.GeneratorExp; +import org.python.antlr.ast.Global; +import org.python.antlr.ast.If; +import org.python.antlr.ast.IfExp; +import org.python.antlr.ast.Import; +import org.python.antlr.ast.ImportFrom; +import org.python.antlr.ast.Index; +import org.python.antlr.ast.Interactive; +import org.python.antlr.ast.Lambda; +import org.python.antlr.ast.List; +import org.python.antlr.ast.ListComp; +import org.python.antlr.ast.Name; +import org.python.antlr.ast.Num; +import org.python.antlr.ast.Pass; +import org.python.antlr.ast.Print; +import org.python.antlr.ast.Raise; +import org.python.antlr.ast.Repr; +import org.python.antlr.ast.Return; +import org.python.antlr.ast.Slice; +import org.python.antlr.ast.Str; +import org.python.antlr.ast.Subscript; +import org.python.antlr.ast.Suite; +import org.python.antlr.ast.TryExcept; +import org.python.antlr.ast.TryFinally; +import org.python.antlr.ast.Tuple; +import org.python.antlr.ast.UnaryOp; +import org.python.antlr.ast.While; +import org.python.antlr.ast.With; +import org.python.antlr.ast.Yield; +import org.python.antlr.ast.alias; +import org.python.antlr.ast.cmpopType; +import org.python.antlr.ast.comprehension; +import org.python.antlr.ast.expr_contextType; +import org.python.antlr.ast.keyword; +import org.python.antlr.ast.operatorType; +import org.python.antlr.base.expr; +import org.python.antlr.base.mod; +import org.python.antlr.base.stmt; +import org.python.core.CompilerFlags; +import org.python.core.PyComplex; +import org.python.core.PyFloat; +import org.python.core.PyInteger; +import org.python.core.PyLong; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyUnicode; + +public class BytecodeCompiler extends Visitor +{ +// + 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 ClassWriter cw; +// public Code code; +// public CodeCompiler mrefs; +// public CompilerFlags cflags; +// +// int temporary; +// expr_contextType augmode; +// int augtmp1; +// int augtmp2; +// int augtmp3; +// int augtmp4; +// +// public boolean fast_locals, print_results; +// +// public Map<String, SymInfo> tbl; +// public ScopeInfo my_scope; +// +// boolean optimizeGlobals = true; +// public Vector names; + public String className; +// +// public Stack continueLabels, breakLabels; +// public Stack exceptionHandlers; +// public Vector yields = new Vector(); +// +// /* break/continue finally's level. +// * This is the lowest level in the exceptionHandlers 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 the exceptionHandlers are executed. +// */ + public int bcfLevel = 0; +// + int yield_count = 0; + + private int stackDepth = 0; +// + public BytecodeCompiler(Module module, boolean print_results) { +// this.module = module; +// this.print_results = print_results; +// +// mrefs = this; +// cw = module.classfile.cw; +// +// continueLabels = new Stack(); +// breakLabels = new Stack(); +// exceptionHandlers = new Stack(); + } +// +//// public void getNone() throws IOException { +//// code.getstatic("org/python/core/Py", "None", $pyObj); +//// } +//// +//// public void loadFrame() throws Exception { +//// code.aload(1); +//// } +// +//// public void setLastI(int idx) throws Exception { +//// loadFrame(); +//// code.iconst(idx); +//// code.putfield("org/python/core/PyFrame", "f_lasti", "I"); +//// } +//// +//// private void loadf_back() throws Exception { +//// code.getfield("org/python/core/PyFrame", "f_back", $pyFrame); +//// } +//// +// public int storeTop() throws Exception { +////// int tmp = code.getLocal("org/python/core/PyObject"); +////// code.astore(tmp); +////// return tmp; +// } +//// + public void setline(int line) throws Exception { +//// if (module.linenumbers) { +//// code.setline(line); +//// loadFrame(); +//// code.iconst(line); +//// code.invokevirtual("org/python/core/PyFrame", "setline", "(I)V"); +//// } + } +//// + public void setline(PythonTree node) throws Exception { +//// setline(node.getLine()); + } +//// + public void set(PythonTree node) throws Exception { +//// int tmp = storeTop(); +//// set(node, tmp); +//// code.aconst_null(); +//// code.astore(tmp); +//// code.freeLocal(tmp); + } +// +// + public void set(PythonTree node, int tmp) throws Exception { +//// temporary = tmp; +//// visit(node); + } +//// +//// +//// private void saveAugTmps(PythonTree node, int count) throws Exception { +//// if (count >= 4) { +//// augtmp4 = code.getLocal("Lorg/python/core/PyObject;"); +//// code.astore(augtmp4); +//// } +//// if (count >= 3) { +//// augtmp3 = code.getLocal("Lorg/python/core/PyObject;"); +//// code.astore(augtmp3); +//// } +//// if (count >= 2) { +//// augtmp2 = code.getLocal("Lorg/python/core/PyObject;"); +//// code.astore(augtmp2); +//// } +//// augtmp1 = code.getLocal("Lorg/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(PythonTree 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(mod 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; +// this.cflags = cflags; +// +// my_scope = scope; +// names = scope.names; +// +// tbl = scope.tbl; +// optimizeGlobals = fast_locals&&!scope.exec&&!scope.from_import_star; +// +// if (scope.max_with_count > 0) { +// // allocate for all the with-exits we will have in the frame; +// // this allows yield and with to happily co-exist +// loadFrame(); +// code.iconst(scope.max_with_count); +// code.anewarray("org/python/core/PyObject"); +// code.putfield("org/python/core/PyFrame", "f_exits", $pyObjArr); +// } +// +// Object exit = visit(node); +// +// if (classBody) { +// loadFrame(); +// code.invokevirtual("org/python/core/PyFrame", "getf_locals", "()" + $pyObj); +// code.areturn(); +// } else { +// if (exit == null) { +// setLastI(-1); +// +// getNone(); +// code.areturn(); +// } +// } +// } +// +// @Override +// public Object visitInteractive(Interactive node) throws Exception { +// traverse(node); +// return null; +// } +// +// @Override +// public Object visitModule(org.python.antlr.ast.Module suite) +// throws Exception +// { +// if (suite.getInternalBody().size() > 0 && +// suite.getInternalBody().get(0) instanceof Expr && +// ((Expr) suite.getInternalBody().get(0)).getInternalValue() instanceof Str) +// { +// loadFrame(); +// code.ldc("__doc__"); +// visit(((Expr) suite.getInternalBody().get(0)).getInternalValue()); +// code.invokevirtual("org/python/core/PyFrame", "setglobal", "(" +$str + $pyObj + ")V"); +// } +// traverse(suite); +// return null; +// } +// +// @Override +// public Object visitExpression(Expression node) throws Exception { +// if (my_scope.generator && node.getInternalBody() != null) { +// module.error("'return' with argument inside generator", +// true, node); +// } +// return visitReturn(new Return(node,node.getInternalBody()), true); +// } +// +// public int makeArray(java.util.List<? extends PythonTree> nodes) throws Exception { +// int n; +// +// if (nodes == null) +// n = 0; +// else +// n = nodes.size(); +// +// int array = code.getLocal("[Lorg/python/core/PyObject;"); +// if (n == 0) { +// code.getstatic("org/python/core/Py", "EmptyObjects", $pyObjArr); +// code.astore(array); +// } else { +// code.iconst(n); +// code.anewarray("org/python/core/PyObject"); +// code.astore(array); +// +// for(int i=0; i<n; i++) { +// visit(nodes.get(i)); +// code.aload(array); +// code.swap(); +// code.iconst(i); +// code.swap(); +// code.aastore(); +// } +// } +// return array; +// } +// + public void getDocString(java.util.List<stmt> suite) throws Exception { +// if (suite.size() > 0 && suite.get(0) instanceof Expr && +// ((Expr) suite.get(0)).getInternalValue() instanceof Str) +// { +// visit(((Expr) suite.get(0)).getInternalValue()); +// } else { +// code.aconst_null(); +// } + } +// + public boolean makeClosure(ScopeInfo scope) throws Exception { +// if (scope == null || scope.freevars == null) return false; +// int n = scope.freevars.size(); +// if (n == 0) return false; +// +// int tmp = code.getLocal("[Lorg/python/core/PyObject;"); +// code.iconst(n); +// code.anewarray("org/python/core/PyObject"); +// code.astore(tmp); +// Map<String, SymInfo> upTbl = scope.up.tbl; +// for(int i=0; i<n; i++) { +// code.aload(tmp); +// code.iconst(i); +// loadFrame(); +// for(int j = 1; j < scope.distance; j++) { +// loadf_back(); +// } +// SymInfo symInfo = upTbl.get(scope.freevars.elementAt(i)); +// code.iconst(symInfo.env_index); +// code.invokevirtual("org/python/core/PyFrame", "getclosure", "(I)" + $pyObj); +// code.aastore(); +// } +// +// code.aload(tmp); +// code.freeLocal(tmp); +// + return true; + } +// + @Override + public Object visitFunctionDef(FunctionDef node) throws Exception { + String name = getName(node.getInternalName()); +// +// setline(node); +// +// ScopeInfo scope = module.getScopeInfo(node); +// +// int defaults = makeArray(scope.ac.getDefaults()); +// +// code.new_("org/python/core/PyFunction"); +// code.dup(); +// loadFrame(); +// code.getfield("org/python/core/PyFrame", "f_globals", $pyObj); +// code.aload(defaults); +// code.freeLocal(defaults); +// +// scope.setup_closure(); +// scope.dump(); +// module.PyCode(new Suite(node,node.getInternalBody()), name, true, +// className, false, false, +// node.getLine(), scope, cflags).get(code); +// +// getDocString(node.getInternalBody()); +// +// if (!makeClosure(scope)) { +// code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + ")V"); +// } else { +// code.invokespecial( "org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")V"); +// } +// + set(new Name(node,node.getInternalName(), expr_contextType.Store)); + doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); + return null; + } +// + private void doDecorators(stmt node, java.util.List<expr> decs, String name) throws Exception { + if (decs.size() > 0) { + expr currentExpr = new Name(node, name, expr_contextType.Load); + for (int i=decs.size() - 1;i > -1;i--) { + java.util.List args = new ArrayList(); + args.add(currentExpr); + currentExpr = new Call(node, decs.get(i), args, new ArrayList<keyword>(), null, null); + } + visit(currentExpr); + set(new Name(node, name, expr_contextType.Store)); + } + } +// +// @Override +// public Object visitExpr(Expr node) throws Exception { +// setline(node); +// visit(node.getInternalValue()); +// +// if (print_results) { +// code.invokestatic("org/python/core/Py", "printResult", "(" + $pyObj + ")V"); +// } else { +// code.pop(); +// } +// return null; +// } +// +// @Override +// public Object visitAssign(Assign node) throws Exception { +// setline(node); +// visit(node.getInternalValue()); +// if (node.getInternalTargets().size() == 1) { +// set(node.getInternalTargets().get(0)); +// } else { +// int tmp = storeTop(); +// for (expr target : node.getInternalTargets()) { +// set(target, tmp); +// } +// code.freeLocal(tmp); +// } +// return null; +// } +// +// @Override +// public Object visitPrint(Print node) throws Exception { +// setline(node); +// int tmp = -1; +// +// if (node.getInternalDest() != null) { +// visit(node.getInternalDest()); +// tmp = storeTop(); +// } +// if (node.getInternalValues() == null || node.getInternalValues().size() == 0) { +// if (node.getInternalDest() != null) { +// code.aload(tmp); +// code.invokestatic("org/python/core/Py", "printlnv", "(" + $pyObj + ")V"); +// } else { +// code.invokestatic("org/python/core/Py", "println", "()V"); +// } +// } else { +// for (int i = 0; i < node.getInternalValues().size(); i++) { +// if (node.getInternalDest() != null) { +// code.aload(tmp); +// visit(node.getInternalValues().get(i)); +// if (node.getInternalNl() && i == node.getInternalValues().size() - 1) { +// code.invokestatic("org/python/core/Py", "println", "(" + $pyObj + $pyObj + ")V"); +// } else { +// code.invokestatic("org/python/core/Py", "printComma", "(" + $pyObj + $pyObj + ")V"); +// } +// } else { +// visit(node.getInternalValues().get(i)); +// if (node.getInternalNl() && i == node.getInternalValues().size() - 1) { +// code.invokestatic("org/python/core/Py", "println", "(" + $pyObj + ")V"); +// } else { +// code.invokestatic("org/python/core/Py", "printComma", "(" + $pyObj + ")V"); +// } +// +// } +// } +// } +// if (node.getInternalDest() != null) { +// code.freeLocal(tmp); +// } +// return null; +// } +// +// @Override +// public Object visitDelete(Delete node) throws Exception { +// setline(node); +// traverse(node); +// return null; +// } +// +// @Override +// public Object visitPass(Pass node) throws Exception { +// setline(node); +// return null; +// } +// +// @Override +// public Object visitBreak(Break node) throws Exception { +// //setline(node); Not needed here... +// if (breakLabels.empty()) { +// throw new ParseException("'break' outside loop", node); +// } +// +// doFinallysDownTo(bcfLevel); +// +// code.goto_((Label)breakLabels.peek()); +// return null; +// } +// +// @Override +// public Object visitContinue(Continue node) throws Exception { +// //setline(node); Not needed here... +// if (continueLabels.empty()) { +// throw new ParseException("'continue' not properly in loop", node); +// } +// +// doFinallysDownTo(bcfLevel); +// +// code.goto_((Label)continueLabels.peek()); +// return Exit; +// } +// +// @Override +// public Object visitYield(Yield node) throws Exception { +// setline(node); +// if (!fast_locals) { +// throw new ParseException("'yield' outside function", node); +// } +// +// int stackState = saveStack(); +// +// if (node.getInternalValue() != null) { +// visit(node.getInternalValue()); +// } else { +// getNone(); +// } +// +// setLastI(++yield_count); +// +// saveLocals(); +// code.areturn(); +// +// Label restart = new Label(); +// yields.addElement(restart); +// code.label(restart); +// restoreLocals(); +// restoreStack(stackState); +// +// loadFrame(); +// code.invokevirtual("org/python/core/PyFrame", "getGeneratorInput", "()" + $obj); +// code.dup(); +// code.instanceof_("org/python/core/PyException"); +// Label done2 = new Label(); +// code.ifeq(done2); +// code.checkcast("java/lang/Throwable"); +// code.athrow(); +// code.label(done2); +// code.checkcast("org/python/core/PyObject"); +// +// return null; +// } +// +// private void stackProduce() { +// stackDepth++; +// } +// +// private void stackConsume() { +// stackDepth--; +// } +// +// private void stackConsume(int numItems) { +// stackDepth -= numItems; +// } +// +// private int saveStack() throws Exception { +// if (stackDepth > 0) { +// int array = code.getLocal("[Lorg/python/core/PyObject;"); +// code.iconst(stackDepth); +// code.anewarray("org/python/core/PyObject"); +// code.astore(array); +// for (int i = 0; i < stackDepth; i++) { +// code.aload(array); +// // Stack: |- ... value array +// code.swap(); +// code.iconst(i); +// code.swap(); +// // Stack: |- ... array index value +// code.aastore(); +// // Stack: |- ... +// } +// return array; +// } else { +// return -1; +// } +// } +// +// private void restoreStack(int array) throws Exception { +// if (stackDepth > 0) { +// for (int i = stackDepth - 1; i >= 0; i--) { +// code.aload(array); +// // Stack: |- ... array +// code.iconst(i); +// code.aaload(); +// // Stack: |- ... value +// } +// code.freeLocal(array); +// } +// } +// +// private void restoreLocals() throws Exception { +// endExceptionHandlers(); +// +// Vector v = code.getActiveLocals(); +// +// loadFrame(); +// code.getfield("org/python/core/PyFrame", "f_savedlocals", "[Ljava/lang/Object;"); +// +// int locals = code.getLocal("[Ljava/lang/Object;"); +// code.astore(locals); +// +// for (int i = 0; i < v.size(); i++) { +// String type = (String) v.elementAt(i); +// if (type == null) +// continue; +// code.aload(locals); +// code.iconst(i); +// code.aaload(); +// code.checkcast(type); +// code.astore(i); +// } +// code.freeLocal(locals); +// +// restartExceptionHandlers(); +// } +// +// /** +// * Close all the open exception handler ranges. This should be paired +// * with restartExceptionHandlers to delimit internal code that +// * shouldn't be handled by user handlers. This allows us to set +// * variables without the verifier thinking we might jump out of our +// * handling with an exception. +// */ +// private void endExceptionHandlers() +// { +// Label end = new Label(); +// code.label(end); +// for (int i = 0; i < exceptionHandlers.size(); ++i) { +// ExceptionHandler handler = +// (ExceptionHandler)exceptionHandlers.elementAt(i); +// handler.exceptionEnds.addElement(end); +// } +// } +// +// private void restartExceptionHandlers() +// { +// Label start = new Label(); +// code.label(start); +// for (int i = 0; i < exceptionHandlers.size(); ++i) { +// ExceptionHandler handler = +// (ExceptionHandler)exceptionHandlers.elementAt(i); +// handler.exceptionStarts.addElement(start); +// } +// } +// +// private void saveLocals() throws Exception { +// Vector v = code.getActiveLocals(); +// code.iconst(v.size()); +// code.anewarray("java/lang/Object"); +// int locals = code.getLocal("[Ljava/lang/Object;"); +// code.astore(locals); +// +// for (int i = 0; i < v.size(); i++) { +// String type = (String) v.elementAt(i); +// if (type == null) +// continue; +// code.aload(locals); +// code.iconst(i); +// //code.checkcast(code.pool.Class("java/lang/Object")); +// if (i == 2222) { +// code.aconst_null(); +// } else +// code.aload(i); +// code.aastore(); +// } +// +// loadFrame(); +// code.aload(locals); +// code.putfield("org/python/core/PyFrame", "f_savedlocals", "[Ljava/lang/Object;"); +// code.freeLocal(locals); +// } +// +// +// @Override +// public Object visitReturn(Return node) throws Exception { +// return visitReturn(node, false); +// } +// +// public Object visitReturn(Return node, boolean inEval) throws Exception { +// setline(node); +// if (!inEval && !fast_locals) { +// throw new ParseException("'return' outside function", node); +// } +// int tmp = 0; +// if (node.getInternalValue() != null) { +// if (my_scope.generator) +// throw new ParseException("'return' with argument " + +// "inside generator", node); +// visit(node.getInternalValue()); +// tmp = code.getReturnLocal(); +// code.astore(tmp); +// } +// doFinallysDownTo(0); +// +// setLastI(-1); +// +// if (node.getInternalValue() != null) { +// code.aload(tmp); +// } else { +// getNone(); +// } +// code.areturn(); +// return Exit; +// } +// +// @Override +// public Object visitRaise(Raise node) throws Exception { +// setline(node); +// if (node.getInternalType() != null) { visit(node.getInternalType()); stackProduce(); } +// if (node.getInternalInst() != null) { visit(node.getInternalInst()); stackProduce(); } +// if (node.getInternalTback() != null) { visit(node.getInternalTback()); stackProduce(); } +// if (node.getInternalType() == null) { +// code.invokestatic("org/python/core/Py", "makeException", "()" + $pyExc); +// } else if (node.getInternalInst() == null) { +// stackConsume(); +// code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + ")" + $pyExc); +// } else if (node.getInternalTback() == null) { +// stackConsume(2); +// code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + $pyObj + ")" + $pyExc); +// } else { +// stackConsume(3); +// code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + $pyObj + $pyObj + ")" + $pyExc); +// } +// code.athrow(); +// return Exit; +// } +// +// @Override +// public Object visitImport(Import node) throws Exception { +// setline(node); +// for (alias a : node.getInternalNames()) { +// String asname = null; +// if (a.getInternalAsname() != null) { +// String name = a.getInternalName(); +// asname = a.getInternalAsname(); +// code.ldc(name); +// loadFrame(); +// code.invokestatic("org/python/core/imp", "importOneAs", "(" + $str + $pyFrame + ")" + $pyObj); +// } else { +// String name = a.getInternalName(); +// asname = name; +// if (asname.indexOf('.') > 0) +// asname = asname.substring(0, asname.indexOf('.')); +// code.ldc(name); +// loadFrame(); +// code.invokestatic("org/python/core/imp", "importOne", "(" + $str + $pyFrame + ")" + $pyObj); +// } +// set(new Name(a, asname, expr_contextType.Store)); +// } +// return null; +// } +// +// +// @Override +// public Object visitImportFrom(ImportFrom node) throws Exception { +// Future.checkFromFuture(node); // future stmt support +// setline(node); +// code.ldc(node.getInternalModule()); +// java.util.List<alias> names = node.getInternalNames(); +// if (names == null || names.size() == 0) { +// throw new ParseException("Internel parser error", node); +// } else if (names.size() == 1 && names.get(0).getInternalName().equals("*")) { +// if (node.getInternalLevel() > 0) { +// throw new ParseException("'import *' not allowed with 'from .'", node); +// } +// if (my_scope.func_level > 0) { +// module.error("import * only allowed at module level", false, node); +// +// if (my_scope.contains_ns_free_vars) { +// module.error("import * is not allowed in function '" + +// my_scope.scope_name + +// "' because it contains a nested function with free variables", +// true, node); +// } +// } +// if (my_scope.func_level > 1) { +// module.error("import * is not allowed in function '" + +// my_scope.scope_name + +// "' because it is a nested function", +// true, node); +// } +// +// loadFrame(); +// code.invokestatic("org/python/core/imp", "importAll", "(" + $str + $pyFrame + ")V"); +// } else { +// java.util.List<String> fromNames = new ArrayList<String>();//[names.size()]; +// java.util.List<String> asnames = new ArrayList<String>();//[names.size()]; +// for (int i = 0; i < names.size(); i++) { +// fromNames.add(names.get(i).getInternalName()); +// asnames.add(names.get(i).getInternalAsname()); +// if (asnames.get(i) == null) +// asnames.set(i, fromNames.get(i)); +// } +// int strArray = makeStrings(code, fromNames); +// code.aload(strArray); +// code.freeLocal(strArray); +// +// loadFrame(); +// +// if (node.getInternalLevel() == 0) { +// if (module.getFutures().isAbsoluteImportOn()) { +// code.iconst_0(); +// } else { +// code.iconst_m1(); +// } +// } else { +// code.iconst(node.getInternalLevel()); +// } +// code.invokestatic("org/python/core/imp", "importFrom", "(" + $str + $strArr + $pyFrame + "I" + ")" + $pyObjArr); +// int tmp = storeTop(); +// for (int i = 0; i < names.size(); i++) { +// code.aload(tmp); +// code.iconst(i); +// code.aaload(); +// set(new Name(names.get(i), asnames.get(i), expr_contextType.Store)); +// } +// code.freeLocal(tmp); +// } +// return null; +// } +// +// @Override +// public Object visitGlobal(Global node) throws Exception { +// return null; +// } +// +// @Override +// public Object visitExec(Exec node) throws Exception { +// setline(node); +// visit(node.getInternalBody()); +// stackProduce(); +// +// if (node.getInternalGlobals() != null) { +// visit(node.getInternalGlobals()); +// } else { +// code.aconst_null(); +// } +// stackProduce(); +// +// if (node.getInternalLocals() != null) { +// visit(node.getInternalLocals()); +// } else { +// code.aconst_null(); +// } +// stackProduce(); +// +// //do the real work here +// stackConsume(3); +// code.invokestatic("org/python/core/Py", "exec", "(" + $pyObj + $pyObj + $pyObj + ")V"); +// return null; +// } +// +// @Override +// public Object visitAssert(Assert node) throws Exception { +// setline(node); +// Label end_of_assert = new Label(); +// +// /* First do an if __debug__: */ +// loadFrame(); +// emitGetGlobal("__debug__"); +// +// code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z"); +// +// code.ifeq(end_of_assert); +// +// /* Now do the body of the assert. If PyObject.__nonzero__ is true, +// then the assertion succeeded, the message portion should not be +// processed. Otherwise, the message will be processed. */ +// visit(node.getInternalTest()); +// code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z"); +// +// /* If evaluation is false, then branch to end of method */ +// code.ifne(end_of_assert); +// +// /* Visit the message part of the assertion, or pass Py.None */ +// if( node.getInternalMsg() != null ) { +// visit(node.getInternalMsg()); +// } else { +// getNone(); +// } +// +// /* Push exception type onto stack(Py.AssertionError) */ +// code.getstatic("org/python/core/Py", "AssertionError", "Lorg/python/core/PyObject;"); +// +// code.swap(); // The type is the first argument, but the message could be a yield +// +// code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + $pyObj + ")" + $pyExc); +// +// /* Raise assertion error. Only executes this logic if assertion +// failed */ +// code.athrow(); +// +// /* And finally set the label for the end of it all */ +// code.label(end_of_assert); +// +// return null; +// } +// +// public Object doTest(Label end_of_if, If node, int index) +// throws Exception +// { +// Label end_of_suite = new Label(); +// +// setline(node.getInternalTest()); +// visit(node.getInternalTest()); +// code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z"); +// +// code.ifeq(end_of_suite); +// +// Object exit = suite(node.getInternalBody()); +// +// if (end_of_if != null && exit == null) +// code.goto_(end_of_if); +// +// code.label(end_of_suite); +// +// if (node.getInternalOrelse() != null) { +// return suite(node.getInternalOrelse()) != null ? exit : null; +// } else { +// return null; +// } +// } +// +// @Override +// public Object visitIf(If node) throws Exception { +// Label end_of_if = null; +// if (node.getInternalOrelse() != null) +// end_of_if = new Label(); +// +// Object exit = doTest(end_of_if, node, 0); +// if (end_of_if != null) +// code.label(end_of_if); +// return exit; +// } +// +// @Override +// public Object visitIfExp(IfExp node) throws Exception { +// setline(node.getInternalTest()); +// Label end = new Label(); +// Label end_of_else = new Label(); +// +// visit(node.getInternalTest()); +// code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z"); +// +// code.ifeq(end_of_else); +// visit(node.getInternalBody()); +// code.goto_(end); +// +// code.label(end_of_else); +// visit(node.getInternalOrelse()); +// +// code.label(end); +// +// return null; +// } +// +// public int beginLoop() { +// continueLabels.push(new Label()); +// breakLabels.push(new Label()); +// int savebcf = bcfLevel; +// bcfLevel = exceptionHandlers.size(); +// return savebcf; +// } +// +// public void finishLoop(int savebcf) { +// continueLabels.pop(); +// breakLabels.pop(); +// bcfLevel = savebcf; +// } +// +// +// @Override +// 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 = new Label(); +// +// code.goto_(continue_loop); +// code.label(start_loop); +// +// //Do suite +// suite(node.getInternalBody()); +// +// code.label(continue_loop); +// setline(node); +// +// //Do test +// visit(node.getInternalTest()); +// code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z"); +// code.ifne(start_loop); +// +// finishLoop(savebcf); +// +// if (node.getInternalOrelse() != null) { +// //Do else +// suite(node.getInternalOrelse()); +// } +// code.label(break_loop); +// +// // Probably need to detect "guaranteed exits" +// return null; +// } +// +// @Override +// 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 = new Label(); +// Label next_loop = new Label(); +// +// 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.getInternalIter()); +// +// //set up the loop iterator +// code.invokevirtual("org/python/core/PyObject", "__iter__", "()Lorg/python/core/PyObject;"); +// code.astore(iter_tmp); +// +// //do check at end of loop. Saves one opcode ;-) +// code.goto_(next_loop); +// +// code.label(start_loop); +// //set iter variable to current entry in list +// set(node.getInternalTarget(), expr_tmp); +// +// //evaluate for body +// suite(node.getInternalBody()); +// +// code.label(continue_loop); +// +// code.label(next_loop); +// setline(node); +// //get the next element from the list +// code.aload(iter_tmp); +// code.invokevirtual("org/python/core/PyObject", "__iternext__", "()" + $pyObj); +// +// code.astore(expr_tmp); +// code.aload(expr_tmp); +// //if no more elements then fall through +// code.ifnonnull(start_loop); +// +// finishLoop(savebcf); +// +// if (node.getInternalOrelse() != null) { +// //Do else clause if provided +// suite(node.getInternalOrelse()); +// } +// +// code.label(break_loop); +// +// code.freeLocal(iter_tmp); +// code.freeLocal(expr_tmp); +// +// // Probably need to detect "guaranteed exits" +// return null; +// } +// +// public void exceptionTest(int exc, Label end_of_exceptions, +// TryExcept node, int index) +// throws Exception +// { +// for (int i = 0; i < node.getInternalHandlers().size(); i++) { +// ExceptHandler handler = (ExceptHandler)node.getInternalHandlers().get(i); +// +// //setline(name); +// Label end_of_self = new Label(); +// +// if (handler.getInternalType() != null) { +// code.aload(exc); +// //get specific exception +// visit(handler.getInternalType()); +// code.invokestatic("org/python/core/Py", "matchException", "(" + $pyExc + $pyObj + ")Z"); +// code.ifeq(end_of_self); +// } else { +// if (i != node.getInternalHandlers().size()-1) { +// throw new ParseException( +// "default 'except:' must be last", handler); +// } +// } +// +// if (handler.getInternalName() != null) { +// code.aload(exc); +// code.getfield("org/python/core/PyException", "value", "Lorg/python/core/PyObject;"); +// set(handler.getInternalName()); +// } +// +// //do exception body +// suite(handler.getInternalBody()); +// code.goto_(end_of_exceptions); +// code.label(end_of_self); +// } +// code.aload(exc); +// code.athrow(); +// } +// +// +// @Override +// public Object visitTryFinally(TryFinally node) throws Exception +// { +// Label start = new Label(); +// Label end = new Label(); +// Label handlerStart = new Label(); +// Label finallyEnd = new Label(); +// +// Object ret; +// +// ExceptionHandler inFinally = new ExceptionHandler(node); +// +// // Do protected suite +// exceptionHandlers.push(inFinally); +// +// int excLocal = code.getLocal("java/lang/Throwable"); +// code.aconst_null(); +// code.astore(excLocal); +// +// code.label(start); +// inFinally.exceptionStarts.addElement(start); +// +// ret = suite(node.getInternalBody()); +// +// code.label(end); +// inFinally.exceptionEnds.addElement(end); +// inFinally.bodyDone = true; +// +// exceptionHandlers.pop(); +// +// if (ret == NoExit) { +// inlineFinally(inFinally); +// code.goto_(finallyEnd); +// } +// +// // Handle any exceptions that get thrown in suite +// code.label(handlerStart); +// code.astore(excLocal); +// +// code.aload(excLocal); +// loa... [truncated message content] |