// Copyright (c) Corporation for National Research Initiatives package org.python.core; /** * An implementation of PyCode where the actual executable content * is stored as a PyFunctionTable instance and an integer index. */ public class PyTableCode extends PyCode { public int co_argcount; int nargs; public int co_firstlineno = -1; public String co_varnames[]; public String co_cellvars[]; public int jy_npurecell; // internal: jython specific public String co_freevars[]; public String co_filename; public int co_flags; public int co_nlocals; public boolean args, keywords; PyFunctionTable funcs; int func_id; final public static int CO_OPTIMIZED = 0x0001; //final public static int CO_NEWLOCALS = 0x0002 final public static int CO_VARARGS = 0x0004; final public static int CO_VARKEYWORDS = 0x0008; final public static int CO_GENERATOR = 0x0020; final public static int CO_NESTED = 0x0010; final public static int CO_GENERATOR_ALLOWED = 0x1000; final public static int CO_FUTUREDIVISION = 0x2000; final public static int CO_ALL_FEATURES = CO_NESTED|CO_GENERATOR_ALLOWED|CO_FUTUREDIVISION; public PyTableCode(int argcount, String varnames[], String filename, String name, int firstlineno, boolean args, boolean keywords, PyFunctionTable funcs, int func_id) { this(argcount, varnames, filename, name, firstlineno, args, keywords, funcs, func_id, null, null, 0, 0); } public PyTableCode(int argcount, String varnames[], String filename, String name, int firstlineno, boolean args, boolean keywords, PyFunctionTable funcs, int func_id, String[] cellvars, String[] freevars, int npurecell, int moreflags) // may change { co_argcount = nargs = argcount; co_varnames = varnames; co_nlocals = varnames.length; co_filename = filename; co_firstlineno = firstlineno; co_cellvars = cellvars; co_freevars = freevars; this.jy_npurecell = npurecell; this.args = args; co_name = name; if (args) { co_argcount -= 1; co_flags |= CO_VARARGS; } this.keywords = keywords; if (keywords) { co_argcount -= 1; co_flags |= CO_VARKEYWORDS; } co_flags |= moreflags; this.funcs = funcs; this.func_id = func_id; } private static final String[] __members__ = { "co_name", "co_argcount", "co_varnames", "co_filename", "co_firstlineno", "co_flags","co_cellvars","co_freevars","co_nlocals" // not supported: co_code, co_consts, co_names, // co_lnotab, co_stacksize }; public PyObject __dir__() { PyString members[] = new PyString[__members__.length]; for (int i = 0; i < __members__.length; i++) members[i] = new PyString(__members__[i]); return new PyList(members); } private void throwReadonly(String name) { for (int i = 0; i < __members__.length; i++) if (__members__[i] == name) throw Py.TypeError("readonly attribute"); throw Py.AttributeError(name); } public void __setattr__(String name, PyObject value) { // no writable attributes throwReadonly(name); } public void __delattr__(String name) { throwReadonly(name); } private static PyTuple toPyStringTuple(String[] ar) { if (ar == null) return Py.EmptyTuple; int sz = ar.length; PyString[] pystr = new PyString[sz]; for (int i = 0; i < sz; i++) { pystr[i] = new PyString(ar[i]); } return new PyTuple(pystr); } public PyObject __findattr__(String name) { // have to craft co_varnames specially if (name == "co_varnames") return toPyStringTuple(co_varnames); if (name == "co_cellvars") return toPyStringTuple(co_cellvars); if (name == "co_freevars") return toPyStringTuple(co_freevars); return super.__findattr__(name); } public PyObject call(PyFrame frame, PyObject closure) { // System.err.println("tablecode call: "+co_name); ThreadState ts = Py.getThreadState(); if (ts.systemState == null) { ts.systemState = Py.defaultSystemState; } //System.err.println("got ts: "+ts+", "+ts.systemState); // Cache previously defined exception PyException previous_exception = ts.exception; // Push frame frame.f_back = ts.frame; if (frame.f_builtins == null) { if (frame.f_back != null) { frame.f_builtins = frame.f_back.f_builtins; } else { //System.err.println("ts: "+ts); //System.err.println("ss: "+ts.systemState); frame.f_builtins = ts.systemState.builtins; } } // nested scopes: setup env with closure int env_j = 0; int ncells = frame.f_ncells; int nfreevars = frame.f_nfreevars; PyCell[] env = frame.f_env; PyTuple freevars = (PyTuple)closure; for (int i = 0; i < ncells; i++,env_j++) { env[env_j] = new PyCell(); } for (int i=0; i co_argcount) plain_args = co_argcount; actual_args = my_frame.f_fastlocals; if (plain_args > 0) System.arraycopy(call_args, 0, actual_args, 0, plain_args); if (!((call_keywords == null || call_keywords.length == 0) && call_args.length == co_argcount && !keywords && !args)) { if (keywords) extra_keywords = new PyDictionary(); for (i=0; i co_argcount) { if (!args) throw Py.TypeError( prefix()+ "too many arguments; expected "+ co_argcount+" got "+ (call_args.length-call_keywords.length)); extra_args = new PyObject[call_args.length- call_keywords.length- co_argcount]; for (i=0; i defaults.length) { int min = co_argcount-defaults.length; throw Py.TypeError( prefix()+ "takes at least " + min + (min == 1 ? " argument (" : " arguments (") + (call_args.length-call_keywords.length)+ " given)"); } actual_args[i] = defaults[defaults.length-(co_argcount-i)]; } } if (args) { if (extra_args == null) actual_args[co_argcount] = Py.EmptyTuple; else actual_args[co_argcount] = new PyTuple(extra_args); } if (extra_keywords != null) { actual_args[nargs-1] = extra_keywords; } } if ((co_flags & CO_GENERATOR) != 0) { return new PyGenerator(my_frame, closure); } return call(my_frame, closure); } public String toString() { return ""; } }