[pypy-svn] r10225 - pypy/dist/pypy/translator
arigo at codespeak.net
arigo at codespeak.net
Fri Apr 1 17:50:07 CEST 2005
Author: arigo
Date: Fri Apr 1 17:50:06 2005
New Revision: 10225
Added:
pypy/dist/pypy/translator/genc_pyobj.py
- copied, changed from r10217, pypy/dist/pypy/translator/genc.py
Modified:
pypy/dist/pypy/translator/genc.py
pypy/dist/pypy/translator/genc_funcdef.py
Log:
Moved all the nameof() stuff from genc.py to genc_pyobj.py.
Modified: pypy/dist/pypy/translator/genc.py
==============================================================================
--- pypy/dist/pypy/translator/genc.py (original)
+++ pypy/dist/pypy/translator/genc.py Fri Apr 1 17:50:06 2005
@@ -2,17 +2,14 @@
Generate a C source file from the flowmodel.
"""
-from __future__ import generators
-import autopath, os, sys, __builtin__, marshal, zlib
+import autopath, os
from pypy.objspace.flow.model import Variable, Constant
-from types import FunctionType, CodeType, InstanceType, ClassType
-from pypy.translator.gensupp import builtin_base, uniquemodulename
+from pypy.translator.gensupp import uniquemodulename
from pypy.translator.gensupp import NameManager
-from pypy.objspace.std.restricted_int import r_int, r_uint
-
from pypy.translator.genc_funcdef import FunctionDef, USE_CALL_TRACE
+from pypy.translator.genc_pyobj import CType_PyObject
# ____________________________________________________________
@@ -30,21 +27,6 @@
self.translator = translator
self.modname = (modname or
uniquemodulename(translator.functions[0].__name__))
- self.cnames = {Constant(None).key: 'Py_None',
- Constant(False).key: 'Py_False',
- Constant(True).key: 'Py_True',
- }
- self.seennames = {}
- self.initcode = [ # list of lines for the module's initxxx()
- 'import new, types, sys',
- 'Py_None = None',
- 'Py_False = False',
- 'Py_True = True',
- ]
-
- self.latercode = [] # list of generators generating extra lines
- # for later in initxxx() -- for recursive
- # objects
self.namespace= NameManager()
# keywords cannot be reused. This is the C99 draft's list.
self.namespace.make_reserved_names('''
@@ -64,126 +46,25 @@
self.namespace.make_reserved_names('self args kwds')
self.globaldecl = []
- self.globalobjects = []
self.pendingfunctions = []
self.funcdefs = {}
self.allfuncdefs = []
- self.debugstack = () # linked list of nested nameof()
+ self.ctyperepresenters = {}
+ self.pyobjrepr = self.getrepresenter(CType_PyObject)
self.gen_source()
- def nameof(self, obj, debug=None):
- key = Constant(obj).key
+ def getrepresenter(self, type_cls):
try:
- return self.cnames[key]
+ return self.ctyperepresenters[type_cls]
except KeyError:
- if debug:
- stackentry = debug, obj
- else:
- stackentry = obj
- self.debugstack = (self.debugstack, stackentry)
- obj_builtin_base = builtin_base(obj)
- if obj_builtin_base in (object, int, long) and type(obj) is not obj_builtin_base:
- # assume it's a user defined thingy
- name = self.nameof_instance(obj)
- else:
- for cls in type(obj).__mro__:
- meth = getattr(self,
- 'nameof_' + cls.__name__.replace(' ', ''),
- None)
- if meth:
- break
- else:
- raise Exception, "nameof(%r)" % (obj,)
- name = meth(obj)
- self.debugstack, x = self.debugstack
- assert x is stackentry
- self.cnames[key] = name
- return name
-
- def uniquename(self, basename):
- name = self.namespace.uniquename(basename)
- self.globalobjects.append(name)
- self.globaldecl.append('static PyObject *%s;' % (name,))
- return name
-
- def initcode_python(self, name, pyexpr):
- # generate init code that will evaluate the given Python expression
- #self.initcode.append("print 'setting up', %r" % name)
- self.initcode.append("%s = %s" % (name, pyexpr))
-
- def nameof_object(self, value):
- if type(value) is not object:
- raise Exception, "nameof(%r)" % (value,)
- name = self.uniquename('g_object')
- self.initcode_python(name, "object()")
- return name
-
- def nameof_module(self, value):
- assert value is os or not hasattr(value, "__file__") or \
- not (value.__file__.endswith('.pyc') or
- value.__file__.endswith('.py') or
- value.__file__.endswith('.pyo')), \
- "%r is not a builtin module (probably :)"%value
- name = self.uniquename('mod%s'%value.__name__)
- self.initcode_python(name, "__import__(%r)" % (value.__name__,))
- return name
-
-
- def nameof_int(self, value):
- if value >= 0:
- name = 'gint_%d' % value
- else:
- name = 'gint_minus%d' % abs(value)
- name = self.uniquename(name)
- self.initcode_python(name, repr(value))
- return name
-
- def nameof_long(self, value):
- if value >= 0:
- name = 'glong%d' % value
- else:
- name = 'glong_minus%d' % abs(value)
- name = self.uniquename(name)
- self.initcode_python(name, repr(value))
- return name
-
- def nameof_float(self, value):
- name = 'gfloat_%s' % value
- name = (name.replace('-', 'minus')
- .replace('.', 'dot'))
- name = self.uniquename(name)
- self.initcode_python(name, repr(value))
- return name
-
- def nameof_str(self, value):
- name = self.uniquename('gstr_' + value[:32])
-## if [c for c in value if c<' ' or c>'~' or c=='"' or c=='\\']:
-## # non-printable string
-## s = 'chr_%s' % name
-## self.globaldecl.append('static char %s[] = { %s };' % (
-## s, ', '.join(['%d' % ord(c) for c in value])))
-## else:
-## # printable string
-## s = '"%s"' % value
- self.initcode_python(name, repr(value))
- return name
-
- def skipped_function(self, func):
- # debugging only! Generates a placeholder for missing functions
- # that raises an exception when called.
- if self.translator.frozen:
- warning = 'NOT GENERATING'
- else:
- warning = 'skipped'
- printable_name = '(%s:%d) %s' % (
- func.func_globals.get('__name__', '?'),
- func.func_code.co_firstlineno,
- func.__name__)
- print warning, printable_name
- name = self.uniquename('gskippedfunc_' + func.__name__)
- self.initcode.append('def %s(*a,**k):' % name)
- self.initcode.append(' raise NotImplementedError')
- return name
+ crepr = self.ctyperepresenters[type_cls] = type_cls(self)
+ return crepr
+
+ def nameofconst(self, c, type_cls=None, debug=None):
+ if type_cls is None:
+ type_cls = getattr(c, 'type_cls', CType_PyObject)
+ crepr = self.getrepresenter(type_cls)
+ return crepr.nameof(c.value, debug=debug)
def getfuncdef(self, func):
if func not in self.funcdefs:
@@ -200,269 +81,14 @@
self.pendingfunctions.append(funcdef)
return self.funcdefs[func]
- def nameof_function(self, func, progress=['-\x08', '\\\x08',
- '|\x08', '/\x08']):
- funcdef = self.getfuncdef(func)
- if funcdef is None:
- return self.skipped_function(func)
- if not self.translator.frozen:
- p = progress.pop(0)
- sys.stderr.write(p)
- progress.append(p)
- return funcdef.get_globalobject()
-
- def nameof_staticmethod(self, sm):
- # XXX XXX XXXX
- func = sm.__get__(42.5)
- name = self.uniquename('gsm_' + func.__name__)
- functionname = self.nameof(func)
- self.initcode_python(name, 'staticmethod(%s)' % functionname)
- return name
-
- def nameof_instancemethod(self, meth):
- if meth.im_self is None:
- # no error checking here
- return self.nameof(meth.im_func)
- else:
- ob = self.nameof(meth.im_self)
- func = self.nameof(meth.im_func)
- typ = self.nameof(meth.im_class)
- name = self.uniquename('gmeth_'+meth.im_func.__name__)
- self.initcode_python(name, 'new.instancemethod(%s, %s, %s)' % (
- func, ob, typ))
- return name
-
- def should_translate_attr(self, pbc, attr):
- ann = self.translator.annotator
- if ann is None:
- ignore = getattr(pbc.__class__, 'NOT_RPYTHON_ATTRIBUTES', [])
- if attr in ignore:
- return False
- else:
- return "probably" # True
- classdef = ann.getuserclasses().get(pbc.__class__)
- if classdef and classdef.about_attribute(attr) is not None:
- return True
- return False
-
- def later(self, gen):
- self.latercode.append((gen, self.debugstack))
-
- def nameof_instance(self, instance):
- klass = instance.__class__
- name = self.uniquename('ginst_' + klass.__name__)
- cls = self.nameof(klass)
- if hasattr(klass, '__base__'):
- base_class = builtin_base(instance)
- base = self.nameof(base_class)
- else:
- base_class = None
- base = cls
- def initinstance():
- content = instance.__dict__.items()
- content.sort()
- for key, value in content:
- if self.should_translate_attr(instance, key):
- line = '%s.%s = %s' % (name, key, self.nameof(value))
- yield line
- if hasattr(instance,'__reduce_ex__'):
- import copy_reg
- reduced = instance.__reduce_ex__()
- assert reduced[0] is copy_reg._reconstructor,"not clever enough"
- assert reduced[1][1] is base_class, "not clever enough for %r vs. %r" % (base_class, reduced)
- state = reduced[1][2]
- else:
- state = None
- self.initcode.append('if isinstance(%s, type):' % cls)
- if state is not None:
- self.initcode.append(' %s = %s.__new__(%s, %r)' % (name, base, cls, state))
- else:
- self.initcode.append(' %s = %s.__new__(%s)' % (name, base, cls))
- self.initcode.append('else:')
- self.initcode.append(' %s = new.instance(%s)' % (name, cls))
- self.later(initinstance())
- return name
-
- def nameof_builtin_function_or_method(self, func):
- if func.__self__ is None:
- # builtin function
- # where does it come from? Python2.2 doesn't have func.__module__
- for modname, module in sys.modules.items():
- if hasattr(module, '__file__'):
- if (module.__file__.endswith('.py') or
- module.__file__.endswith('.pyc') or
- module.__file__.endswith('.pyo')):
- continue # skip non-builtin modules
- if func is getattr(module, func.__name__, None):
- break
- else:
- raise Exception, '%r not found in any built-in module' % (func,)
- name = self.uniquename('gbltin_' + func.__name__)
- if modname == '__builtin__':
- self.initcode_python(name, func.__name__)
- else:
- modname = self.nameof(module)
- self.initcode_python(name, '%s.%s' % (modname, func.__name__))
- else:
- # builtin (bound) method
- name = self.uniquename('gbltinmethod_' + func.__name__)
- selfname = self.nameof(func.__self__)
- self.initcode_python(name, '%s.%s' % (selfname, func.__name__))
- return name
-
- def nameof_classobj(self, cls):
- if cls.__doc__ and cls.__doc__.lstrip().startswith('NOT_RPYTHON'):
- raise Exception, "%r should never be reached" % (cls,)
-
- metaclass = "type"
- if issubclass(cls, Exception):
- if cls.__module__ == 'exceptions':
- name = self.uniquename('gexc_' + cls.__name__)
- self.initcode_python(name, cls.__name__)
- return name
- #else:
- # # exceptions must be old-style classes (grr!)
- # metaclass = "&PyClass_Type"
- # For the moment, use old-style classes exactly when the
- # pypy source uses old-style classes, to avoid strange problems.
- if not isinstance(cls, type):
- assert type(cls) is ClassType
- metaclass = "types.ClassType"
-
- name = self.uniquename('gcls_' + cls.__name__)
- basenames = [self.nameof(base) for base in cls.__bases__]
- def initclassobj():
- content = cls.__dict__.items()
- content.sort()
- for key, value in content:
- if key.startswith('__'):
- if key in ['__module__', '__doc__', '__dict__',
- '__weakref__', '__repr__', '__metaclass__']:
- continue
- # XXX some __NAMES__ are important... nicer solution sought
- #raise Exception, "unexpected name %r in class %s"%(key, cls)
- if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen:
- print value
- continue
- if isinstance(value, classmethod) and value.__get__(cls).__doc__.lstrip().startswith("NOT_RPYTHON"):
- continue
- if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen:
- print value
- continue
-
- yield '%s.%s = %s' % (name, key, self.nameof(value))
-
- baseargs = ", ".join(basenames)
- if baseargs:
- baseargs = '(%s)' % baseargs
- self.initcode.append('class %s%s:' % (name, baseargs))
- self.initcode.append(' __metaclass__ = %s' % metaclass)
- self.later(initclassobj())
- return name
-
- nameof_class = nameof_classobj # for Python 2.2
-
- typename_mapping = {
- InstanceType: 'types.InstanceType',
- type(None): 'type(None)',
- CodeType: 'types.CodeType',
- type(sys): 'type(new)',
-
- r_int: 'int', # XXX
- r_uint: 'int', # XXX
-
- # XXX more hacks
- # type 'builtin_function_or_method':
- type(len): 'type(len)',
- # type 'method_descriptor':
- type(list.append): 'type(list.append)',
- # type 'wrapper_descriptor':
- type(type(None).__repr__): 'type(type(None).__repr__)',
- # type 'getset_descriptor':
- type(type.__dict__['__dict__']): "type(type.__dict__['__dict__'])",
- # type 'member_descriptor':
- type(type.__dict__['__basicsize__']): "type(type.__dict__['__basicsize__'])",
- }
-
- def nameof_type(self, cls):
- if cls.__module__ != '__builtin__':
- return self.nameof_classobj(cls) # user-defined type
- name = self.uniquename('gtype_%s' % cls.__name__)
- if getattr(__builtin__, cls.__name__, None) is cls:
- expr = cls.__name__ # type available from __builtin__
- else:
- expr = self.typename_mapping[cls]
- self.initcode_python(name, expr)
- return name
-
- def nameof_tuple(self, tup):
- name = self.uniquename('g%dtuple' % len(tup))
- args = [self.nameof(x) for x in tup]
- args = ', '.join(args)
- if args:
- args += ','
- self.initcode_python(name, '(%s)' % args)
- return name
-
- def nameof_list(self, lis):
- name = self.uniquename('g%dlist' % len(lis))
- def initlist():
- for i in range(len(lis)):
- item = self.nameof(lis[i])
- yield '%s.append(%s)' % (name, item)
- self.initcode_python(name, '[]')
- self.later(initlist())
- return name
-
- def nameof_dict(self, dic):
- assert dic is not __builtins__
- assert '__builtins__' not in dic, 'Seems to be the globals of %s' % (
- dic.get('__name__', '?'),)
- name = self.uniquename('g%ddict' % len(dic))
- def initdict():
- for k in dic:
- if type(k) is str:
- yield '%s[%r] = %s' % (name, k, self.nameof(dic[k]))
- else:
- yield '%s[%s] = %s' % (name, self.nameof(k),
- self.nameof(dic[k]))
- self.initcode_python(name, '{}')
- self.later(initdict())
- return name
-
- # strange prebuilt instances below, don't look too closely
- # XXX oh well.
- def nameof_member_descriptor(self, md):
- name = self.uniquename('gdescriptor_%s_%s' % (
- md.__objclass__.__name__, md.__name__))
- cls = self.nameof(md.__objclass__)
- self.initcode_python(name, '%s.__dict__[%r]' % (cls, md.__name__))
- return name
- nameof_getset_descriptor = nameof_member_descriptor
- nameof_method_descriptor = nameof_member_descriptor
- nameof_wrapper_descriptor = nameof_member_descriptor
-
- def nameof_file(self, fil):
- if fil is sys.stdin:
- name = self.uniquename("gsys_stdin")
- self.initcode_python(name, "sys.stdin")
- return name
- if fil is sys.stdout:
- name = self.uniquename("gsys_stdout")
- self.initcode_python(name, "sys.stdout")
- return name
- if fil is sys.stderr:
- name = self.uniquename("gsys_stderr")
- self.initcode_python(name, "sys.stderr")
- return name
- raise Exception, 'Cannot translate an already-open file: %r' % (fil,)
+ # ____________________________________________________________
def gen_source(self):
f = self.f
info = {
'modname': self.modname,
'entrypointname': self.translator.functions[0].__name__,
- 'entrypoint': self.nameof(self.translator.functions[0]),
+ 'entrypoint': self.pyobjrepr.nameof(self.translator.functions[0]),
}
# header
if USE_CALL_TRACE:
@@ -474,12 +100,9 @@
funcdef = self.pendingfunctions.pop()
self.gen_cfunction(funcdef)
# collect more of the latercode after each function
- while self.latercode:
- gen, self.debugstack = self.latercode.pop()
- #self.initcode.extend(gen) -- eats TypeError! bad CPython!
- for line in gen:
- self.initcode.append(line)
- self.debugstack = ()
+ for crepr in self.ctyperepresenters.values():
+ if hasattr(crepr, 'collect_globals'):
+ crepr.collect_globals()
self.gen_global_declarations()
# after all the ff_xxx() functions we generate the pyff_xxx() wrappers
@@ -489,7 +112,7 @@
# global object table
print >> f, self.C_OBJECT_TABLE
- for name in self.globalobjects:
+ for name in self.pyobjrepr.globalobjects:
if not name.startswith('gfunc_'):
print >> f, '\t{&%s, "%s"},' % (name, name)
print >> f, self.C_TABLE_END
@@ -507,7 +130,7 @@
# frozen init bytecode
print >> f, self.C_FROZEN_BEGIN
- bytecode = self.getfrozenbytecode()
+ bytecode = self.pyobjrepr.getfrozenbytecode()
def char_repr(c):
if c in '\\"': return '\\' + c
if ' ' <= c < '\x7F': return c
@@ -531,27 +154,6 @@
print >> f, line
print >> f
del g[:]
- if self.f2 is not None:
- for line in self.initcode:
- print >> self.f2, line
- del self.initcode[:]
-
- def getfrozenbytecode(self):
- if self.f2 is not None:
- self.f2.seek(0)
- self.initcode.insert(0, self.f2.read())
- self.initcode.append('')
- source = '\n'.join(self.initcode)
- del self.initcode[:]
- co = compile(source, self.modname, 'exec')
- del source
- small = zlib.compress(marshal.dumps(co))
- source = """if 1:
- import zlib, marshal
- exec marshal.loads(zlib.decompress(%r))""" % small
- co = compile(source, self.modname, 'exec')
- del source
- return marshal.dumps(co)
def gen_cfunction(self, funcdef):
## print 'gen_cfunction (%s:%d) %s' % (
Modified: pypy/dist/pypy/translator/genc_funcdef.py
==============================================================================
--- pypy/dist/pypy/translator/genc_funcdef.py (original)
+++ pypy/dist/pypy/translator/genc_funcdef.py Fri Apr 1 17:50:06 2005
@@ -72,7 +72,7 @@
fast_function_header = ('static PyObject *\n'
'%s(%s)' % (self.fast_name, declare_fast_args))
- name_of_defaults = [self.genc.nameof(x, debug=('Default argument of',
+ name_of_defaults = [self.genc.pyobjrepr.nameof(x, debug=('Default argument of',
self))
for x in (func.func_defaults or ())]
@@ -91,7 +91,7 @@
def get_globalobject(self):
if self.globalobject_name is None:
self.wrapper_name = 'py' + self.fast_name
- self.globalobject_name = self.genc.uniquename('gfunc_' +
+ self.globalobject_name = self.genc.pyobjrepr.uniquename('gfunc_' +
self.base_name)
return self.globalobject_name
@@ -105,7 +105,7 @@
if isinstance(v, Variable):
return self.localscope.localname(v.name)
elif isinstance(v, Constant):
- return self.genc.nameof(v.value,
+ return self.genc.nameofconst(v,
debug=('Constant in the graph of', self))
else:
raise TypeError, "expr(%r)" % (v,)
@@ -309,7 +309,7 @@
for link in block.exits[1:]:
assert issubclass(link.exitcase, Exception)
yield 'if (PyErr_ExceptionMatches(%s)) {' % (
- self.genc.nameof(link.exitcase),)
+ self.genc.pyobjrepr.nameof(link.exitcase),)
yield '\tPyObject *exc_cls, *exc_value, *exc_tb;'
yield '\tPyErr_Fetch(&exc_cls, &exc_value, &exc_tb);'
yield '\tif (exc_value == NULL) {'
Copied: pypy/dist/pypy/translator/genc_pyobj.py (from r10217, pypy/dist/pypy/translator/genc.py)
==============================================================================
--- pypy/dist/pypy/translator/genc.py (original)
+++ pypy/dist/pypy/translator/genc_pyobj.py Fri Apr 1 17:50:06 2005
@@ -1,40 +1,25 @@
-"""
-Generate a C source file from the flowmodel.
-
-"""
from __future__ import generators
import autopath, os, sys, __builtin__, marshal, zlib
from pypy.objspace.flow.model import Variable, Constant
+from pypy.translator.gensupp import builtin_base
from types import FunctionType, CodeType, InstanceType, ClassType
-from pypy.translator.gensupp import builtin_base, uniquemodulename
-from pypy.translator.gensupp import NameManager
-
from pypy.objspace.std.restricted_int import r_int, r_uint
-from pypy.translator.genc_funcdef import FunctionDef, USE_CALL_TRACE
-# ____________________________________________________________
+class CType_PyObject:
+ """The PyObject* C type.
+ This class contains all the nameof_xxx() methods that allow a wild variety
+ of Python objects to be 'pickled' as Python source code that will
+ reconstruct them.
+ """
-#def go_figure_out_this_name(source):
-# # ahem
-# return 'PyRun_String("%s", Py_eval_input, PyEval_GetGlobals(), NULL)' % (
-# source, )
-
-class GenC:
- MODNAMES = {}
-
- def __init__(self, f, translator, modname=None, f2=None):
- self.f = f
- self.f2 = f2
- self.translator = translator
- self.modname = (modname or
- uniquemodulename(translator.functions[0].__name__))
+ def __init__(self, genc):
+ self.genc = genc
self.cnames = {Constant(None).key: 'Py_None',
Constant(False).key: 'Py_False',
Constant(True).key: 'Py_True',
}
- self.seennames = {}
self.initcode = [ # list of lines for the module's initxxx()
'import new, types, sys',
'Py_None = None',
@@ -45,31 +30,8 @@
self.latercode = [] # list of generators generating extra lines
# for later in initxxx() -- for recursive
# objects
- self.namespace= NameManager()
- # keywords cannot be reused. This is the C99 draft's list.
- self.namespace.make_reserved_names('''
- auto enum restrict unsigned
- break extern return void
- case float short volatile
- char for signed while
- const goto sizeof _Bool
- continue if static _Complex
- default inline struct _Imaginary
- do int switch
- double long typedef
- else register union
- ''')
- # these names are used in function headers,
- # therefore pseudo-preserved in scope 1:
- self.namespace.make_reserved_names('self args kwds')
-
- self.globaldecl = []
self.globalobjects = []
- self.pendingfunctions = []
- self.funcdefs = {}
- self.allfuncdefs = []
self.debugstack = () # linked list of nested nameof()
- self.gen_source()
def nameof(self, obj, debug=None):
key = Constant(obj).key
@@ -101,9 +63,9 @@
return name
def uniquename(self, basename):
- name = self.namespace.uniquename(basename)
+ name = self.genc.namespace.uniquename(basename)
self.globalobjects.append(name)
- self.globaldecl.append('static PyObject *%s;' % (name,))
+ self.genc.globaldecl.append('static PyObject *%s;' % (name,))
return name
def initcode_python(self, name, pyexpr):
@@ -171,7 +133,7 @@
def skipped_function(self, func):
# debugging only! Generates a placeholder for missing functions
# that raises an exception when called.
- if self.translator.frozen:
+ if self.genc.translator.frozen:
warning = 'NOT GENERATING'
else:
warning = 'skipped'
@@ -185,27 +147,12 @@
self.initcode.append(' raise NotImplementedError')
return name
- def getfuncdef(self, func):
- if func not in self.funcdefs:
- if self.translator.frozen:
- if func not in self.translator.flowgraphs:
- return None
- else:
- if (func.func_doc and
- func.func_doc.lstrip().startswith('NOT_RPYTHON')):
- return None
- funcdef = FunctionDef(func, self)
- self.funcdefs[func] = funcdef
- self.allfuncdefs.append(funcdef)
- self.pendingfunctions.append(funcdef)
- return self.funcdefs[func]
-
def nameof_function(self, func, progress=['-\x08', '\\\x08',
'|\x08', '/\x08']):
- funcdef = self.getfuncdef(func)
+ funcdef = self.genc.getfuncdef(func)
if funcdef is None:
return self.skipped_function(func)
- if not self.translator.frozen:
+ if not self.genc.translator.frozen:
p = progress.pop(0)
sys.stderr.write(p)
progress.append(p)
@@ -233,7 +180,7 @@
return name
def should_translate_attr(self, pbc, attr):
- ann = self.translator.annotator
+ ann = self.genc.translator.annotator
if ann is None:
ignore = getattr(pbc.__class__, 'NOT_RPYTHON_ATTRIBUTES', [])
if attr in ignore:
@@ -245,9 +192,6 @@
return True
return False
- def later(self, gen):
- self.latercode.append((gen, self.debugstack))
-
def nameof_instance(self, instance):
klass = instance.__class__
name = self.uniquename('ginst_' + klass.__name__)
@@ -341,12 +285,12 @@
continue
# XXX some __NAMES__ are important... nicer solution sought
#raise Exception, "unexpected name %r in class %s"%(key, cls)
- if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen:
+ if isinstance(value, staticmethod) and value.__get__(1) not in self.genc.translator.flowgraphs and self.genc.translator.frozen:
print value
continue
if isinstance(value, classmethod) and value.__get__(cls).__doc__.lstrip().startswith("NOT_RPYTHON"):
continue
- if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen:
+ if isinstance(value, FunctionType) and value not in self.genc.translator.flowgraphs and self.genc.translator.frozen:
print value
continue
@@ -457,150 +401,35 @@
return name
raise Exception, 'Cannot translate an already-open file: %r' % (fil,)
- def gen_source(self):
- f = self.f
- info = {
- 'modname': self.modname,
- 'entrypointname': self.translator.functions[0].__name__,
- 'entrypoint': self.nameof(self.translator.functions[0]),
- }
- # header
- if USE_CALL_TRACE:
- print >> f, '#define USE_CALL_TRACE'
- print >> f, self.C_HEADER
-
- # function implementations
- while self.pendingfunctions:
- funcdef = self.pendingfunctions.pop()
- self.gen_cfunction(funcdef)
- # collect more of the latercode after each function
- while self.latercode:
- gen, self.debugstack = self.latercode.pop()
- #self.initcode.extend(gen) -- eats TypeError! bad CPython!
- for line in gen:
- self.initcode.append(line)
- self.debugstack = ()
- self.gen_global_declarations()
-
- # after all the ff_xxx() functions we generate the pyff_xxx() wrappers
- for funcdef in self.allfuncdefs:
- if funcdef.wrapper_name is not None:
- funcdef.gen_wrapper(f)
-
- # global object table
- print >> f, self.C_OBJECT_TABLE
- for name in self.globalobjects:
- if not name.startswith('gfunc_'):
- print >> f, '\t{&%s, "%s"},' % (name, name)
- print >> f, self.C_TABLE_END
-
- # global function table
- print >> f, self.C_FUNCTION_TABLE
- for funcdef in self.allfuncdefs:
- if funcdef.globalobject_name is not None:
- print >> f, ('\t{&%s, {"%s", (PyCFunction)%s, '
- 'METH_VARARGS|METH_KEYWORDS}},' % (
- funcdef.globalobject_name,
- funcdef.base_name,
- funcdef.wrapper_name))
- print >> f, self.C_TABLE_END
-
- # frozen init bytecode
- print >> f, self.C_FROZEN_BEGIN
- bytecode = self.getfrozenbytecode()
- def char_repr(c):
- if c in '\\"': return '\\' + c
- if ' ' <= c < '\x7F': return c
- return '\\%03o' % ord(c)
- for i in range(0, len(bytecode), 32):
- print >> f, ''.join([char_repr(c) for c in bytecode[i:i+32]])+'\\'
- if (i+32) % 1024 == 0:
- print >> f, self.C_FROZEN_BETWEEN
- print >> f, self.C_FROZEN_END
- print >> f, "#define FROZEN_INITCODE_SIZE %d" % len(bytecode)
-
- # the footer proper: the module init function */
- print >> f, self.C_FOOTER % info
-
- def gen_global_declarations(self):
- g = self.globaldecl
- if g:
- f = self.f
- print >> f, '/* global declaration%s */' % ('s'*(len(g)>1))
- for line in g:
- print >> f, line
- print >> f
- del g[:]
- if self.f2 is not None:
+
+ def later(self, gen):
+ self.latercode.append((gen, self.debugstack))
+
+ def collect_globals(self):
+ while self.latercode:
+ gen, self.debugstack = self.latercode.pop()
+ #self.initcode.extend(gen) -- eats TypeError! bad CPython!
+ for line in gen:
+ self.initcode.append(line)
+ self.debugstack = ()
+ if self.genc.f2 is not None:
for line in self.initcode:
- print >> self.f2, line
+ print >> self.genc.f2, line
del self.initcode[:]
def getfrozenbytecode(self):
- if self.f2 is not None:
- self.f2.seek(0)
- self.initcode.insert(0, self.f2.read())
+ if self.genc.f2 is not None:
+ self.genc.f2.seek(0)
+ self.initcode.insert(0, self.genc.f2.read())
self.initcode.append('')
source = '\n'.join(self.initcode)
del self.initcode[:]
- co = compile(source, self.modname, 'exec')
+ co = compile(source, self.genc.modname, 'exec')
del source
small = zlib.compress(marshal.dumps(co))
source = """if 1:
import zlib, marshal
exec marshal.loads(zlib.decompress(%r))""" % small
- co = compile(source, self.modname, 'exec')
+ co = compile(source, self.genc.modname, 'exec')
del source
return marshal.dumps(co)
-
- def gen_cfunction(self, funcdef):
-## print 'gen_cfunction (%s:%d) %s' % (
-## func.func_globals.get('__name__', '?'),
-## func.func_code.co_firstlineno,
-## func.__name__)
-
- # compute the whole body
- body = list(funcdef.cfunction_body())
-
- # generate the source now
- self.gen_global_declarations() #.. before the body where they are needed
- funcdef.gen_cfunction(self.f, body)
-
- # this is only to keep the RAM consumption under control
- funcdef.clear()
- if not self.translator.frozen:
- del self.translator.flowgraphs[funcdef.func]
- Variable.instances.clear()
-
-# ____________________________________________________________
-
- C_HEADER = '#include "genc.h"\n'
-
- C_SEP = "/************************************************************/"
-
- C_OBJECT_TABLE = C_SEP + '''
-
-/* Table of global objects */
-static globalobjectdef_t globalobjectdefs[] = {'''
-
- C_FUNCTION_TABLE = '''
-/* Table of functions */
-static globalfunctiondef_t globalfunctiondefs[] = {'''
-
- C_TABLE_END = '\t{ NULL }\t/* Sentinel */\n};'
-
- C_FROZEN_BEGIN = '''
-/* Frozen Python bytecode: the initialization code */
-static char *frozen_initcode[] = {"\\'''
-
- C_FROZEN_BETWEEN = '''", "\\'''
-
- C_FROZEN_END = '''"};\n'''
-
- C_FOOTER = C_SEP + '''
-
-MODULE_INITFUNC(%(modname)s)
-{
-\tSETUP_MODULE(%(modname)s)
-\tPyModule_AddObject(m, "%(entrypointname)s", %(entrypoint)s);
-}'''
More information about the Pypy-commit
mailing list