From: <zy...@us...> - 2009-01-26 05:02:26
|
Revision: 5984 http://jython.svn.sourceforge.net/jython/?rev=5984&view=rev Author: zyasoft Date: 2009-01-26 05:02:21 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Added extract tool (to be run by CPython) for creating test modules. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Added Paths: ----------- branches/pbcvm/Tools/pbcvm/ branches/pbcvm/Tools/pbcvm/extract.py Added: branches/pbcvm/Tools/pbcvm/extract.py =================================================================== --- branches/pbcvm/Tools/pbcvm/extract.py (rev 0) +++ branches/pbcvm/Tools/pbcvm/extract.py 2009-01-26 05:02:21 UTC (rev 5984) @@ -0,0 +1,106 @@ +"""Given a module, codegens a new module where all functions imported +from it (using __all__ ?) are replaced with functions tied to +PyBytecode, including references to code objs in co_consts. Other +objects are simply imported from the original object. Hopefully this +provides an opportunity to test something two different ways, which +seems nice.""" + +import inspect +import sys +from collections import defaultdict + +attrs = ["co_" + x for x in """ + argcount nlocals stacksize flags + code consts names varnames + filename name firstlineno lnotab +""".split()] # add freevars cellvars? + +# this has to be instantiated per module! so simply move into a class +_codeobjs = {} +_codeobjs_names = {} +counters = defaultdict(int) + +# XXX - need to capture with a toposort the dependencies of +# recursive code objects and emit in that order + +def extract(mod): + functionobjs = candidate_functions(mod) + for name, f in functionobjs: + #print >> sys.stderr, "Extracting", f + extract_code_obj(f) + codes = {} + for code, definition in _codeobjs.iteritems(): + codes[_codeobjs_names[code]] = definition + print "from %s import *" % mod.__name__ + print "from org.python.core import PyBytecode, PyFunction" + print + print "_codeobjs = {}" + print + for name, obj in sorted(codes.iteritems()): + print "_codeobjs[%r] = %s" % (name, obj) + print + for name, f in functionobjs: + print "%s.func_code = _codeobjs[%r]" % (name, _codeobjs_names[f.func_code]) + + print + print 'if __name__ == "__main__":' + print ' test_main()' + + +def candidate_functions(mod): + """functions and methods we will retrieve code objects""" + + functions = inspect.getmembers(mod, inspect.isfunction) + functions = [(name, f) for (name, f) in functions if not inspect.isbuiltin(f)] + + classes = inspect.getmembers(mod, inspect.isclass) + for classname, cls in classes: + #print >> sys.stderr, "Extracting from", cls + for methodname, method in inspect.getmembers(cls, inspect.ismethod): + #print >> sys.stderr, "Extracting method", method + if inspect.getmodule(method) == mod: + functions.append(("%s.%s" % (classname, methodname), method)) + return functions + +# what if we are passed a builtin? need to identify that signature +def extract_code_obj(f_or_code): + if inspect.iscode(f_or_code): + code = f_or_code + else: + code = f_or_code.func_code + extract_def(code) + +def extract_def(code): + if code in _codeobjs_names: + print >> sys.stderr, "Already seen", code + return "_codeobjs[%r]" % (_codeobjs_names[code],) + + co_name = code.co_name + print >> sys.stderr, "Processing", code + name = co_name + "." + str(counters[co_name]) + counters[co_name] += 1 + _codeobjs_names[code] = name + # need to treat co_consts specially - maybe use pickling if repr is not suitable? + values = [] + for attr in attrs: + if attr == 'co_consts': + co_consts = [] + for const in getattr(code, attr): + if inspect.iscode(const): + print >> sys.stderr, "Extracting code const " + str(const) + co_consts.append(extract_def(const)) + else: + co_consts.append(repr(const)) + values.append("["+', '.join(co_consts)+"]") + elif attr == 'co_lnotab': + values.append(repr(None)) + else: + values.append(repr(getattr(code, attr))) + _codeobjs[code] = "PyBytecode(\n" + ',\n'.join([' '* 4 + v for v in values])+")" + return "_codeobjs[%r]" % (name,) + + +if __name__ == '__main__': + modname = sys.argv[1] + mod = __import__(modname) + extract(mod) Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-26 03:36:25 UTC (rev 5983) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-26 05:02:21 UTC (rev 5984) @@ -38,7 +38,7 @@ // follows new.code's interface public PyBytecode(int argcount, int nlocals, int stacksize, int flags, String codestring, PyObject[] constants, String[] names, String varnames[], - String filename, String name, int firstlineno, PyObject[] lnotab) { + String filename, String name, int firstlineno, String lnotab) { this(argcount, nlocals, stacksize, flags, codestring, constants, names, varnames, filename, name, firstlineno, lnotab, null, null); @@ -46,7 +46,7 @@ public PyBytecode(int argcount, int nlocals, int stacksize, int flags, String codestring, PyObject[] constants, String[] names, String varnames[], - String filename, String name, int firstlineno, PyObject[] lnotab, + String filename, String name, int firstlineno, String lnotab, String[] cellvars, String[] freevars) { co_argcount = nargs = argcount; co_varnames = varnames; @@ -56,18 +56,6 @@ co_cellvars = cellvars; co_freevars = freevars; co_name = name; - -// need to look at how this is used, since it's not part of the standard new.code interface -// this.varargs = varargs; -// if (varargs) { -// co_argcount -= 1; -// co_flags |= CO_VARARGS; -// } -// this.varkwargs = varkwargs; -// if (varkwargs) { -// co_argcount -= 1; -// co_flags |= CO_VARKEYWORDS; -// } varargs = (flags & CO_VARARGS) != 0; varkwargs = (flags & CO_VARKEYWORDS) != 0; co_flags |= flags; @@ -76,8 +64,9 @@ co_consts = constants; co_names = names; co_code = codestring.toCharArray(); - co_lnotab = lnotab; + co_lnotab = null; // ignore } + private static final String[] __members__ = { "co_name", "co_argcount", "co_varnames", "co_filename", "co_firstlineno", This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |