[pypy-svn] r34213 - in pypy/dist/pypy: config objspace
arigo at codespeak.net
arigo at codespeak.net
Sun Nov 5 11:29:40 CET 2006
Author: arigo
Date: Sun Nov 5 11:29:38 2006
New Revision: 34213
Added:
pypy/dist/pypy/objspace/dump.py
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
Add the 'dump' object space: a quick hack that dumps all space operations
to a file 'pypy-space-dump'. It's translatable, so we get a pypy-c version
that is maybe useful for debugging small Python programs.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Sun Nov 5 11:29:38 2006
@@ -16,7 +16,7 @@
pypy_optiondescription = OptionDescription("pypy", "All PyPy Options", [
OptionDescription("objspace", "Object Space Option", [
ChoiceOption("name", "Object Space name",
- ["std", "flow", "logic", "thunk", "cpy"], "std",
+ ["std", "flow", "logic", "thunk", "cpy", "dump"], "std",
requires = {
"thunk": [("objspace.geninterp", False)],
"logic": [("objspace.geninterp", False)],
Added: pypy/dist/pypy/objspace/dump.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/dump.py Sun Nov 5 11:29:38 2006
@@ -0,0 +1,205 @@
+import os
+from pypy.objspace.proxy import patch_space_in_place
+from pypy.objspace.std.objspace import StdObjSpace, W_Object
+from pypy.interpreter.error import OperationError
+from pypy.interpreter import baseobjspace
+
+DUMP_FILE_NAME = 'pypy-space-dump'
+DUMP_FILE_MODE = 0600
+
+class Dumper(object):
+ dump_fd = -1
+
+ def __init__(self, space):
+ self.space = space
+ self.dumpspace_reprs = {}
+
+ def open(self):
+ space = self.space
+ self.dumpspace_reprs.update({
+ space.w_None: 'None',
+ space.w_False: 'False',
+ space.w_True: 'True',
+ })
+ if self.dump_fd < 0:
+ self.dump_fd = os.open(DUMP_FILE_NAME,
+ os.O_WRONLY|os.O_CREAT|os.O_TRUNC,
+ DUMP_FILE_MODE)
+
+ def close(self):
+ if self.dump_fd >= 0:
+ os.close(self.dump_fd)
+ self.dump_fd = -1
+ self.dumpspace_reprs.clear()
+
+ def dump_get_repr(self, w_obj):
+ try:
+ return self.dumpspace_reprs[w_obj]
+ except KeyError:
+ saved_fd = self.dump_fd
+ try:
+ self.dump_fd = -1
+ space = self.space
+ if isinstance(w_obj, W_Object):
+ w_type = space.type(w_obj)
+ else:
+ w_type = None
+ if w_type is space.w_int:
+ n = space.int_w(w_obj)
+ s = str(n)
+ elif w_type is space.w_str:
+ s = space.str_w(w_obj)
+ digit2hex = '0123456789abcdef'
+ lst = ["'"]
+ for c in s:
+ if c == '\\':
+ lst.append('\\')
+ if c >= ' ':
+ lst.append(c)
+ else:
+ lst.append('\\')
+ if c == '\n':
+ lst.append('n')
+ elif c == '\t':
+ lst.append('t')
+ else:
+ lst.append('x')
+ lst.append(digit2hex[ord(c) >> 4])
+ lst.append(digit2hex[ord(c) & 0xf])
+ lst.append("'")
+ s = ''.join(lst)
+ elif w_type is space.w_float:
+ n = space.float_w(w_obj)
+ s = str(n)
+ else:
+ s = '%s at 0x%x' % (w_obj, id(w_obj))
+ self.dumpspace_reprs[w_obj] = s
+ finally:
+ self.dump_fd = saved_fd
+ return s
+
+ def dump_enter(self, opname, args_w):
+ if self.dump_fd >= 0:
+ text = '\t'.join([self.dump_get_repr(w_arg) for w_arg in args_w])
+ os.write(self.dump_fd, '%s CALL %s\n' % (opname, text))
+
+ def dump_returned_wrapped(self, opname, w_obj):
+ if self.dump_fd >= 0:
+ s = self.dump_get_repr(w_obj)
+ os.write(self.dump_fd, '%s RETURN %s\n' % (opname, s))
+
+ def dump_returned(self, opname):
+ if self.dump_fd >= 0:
+ os.write(self.dump_fd, '%s RETURN\n' % (opname,))
+
+ def dump_raised(self, opname, e):
+ if self.dump_fd >= 0:
+ if isinstance(e, OperationError):
+ s = e.errorstr(self.space)
+ else:
+ s = '%s' % (e,)
+ os.write(self.dump_fd, '%s RAISE %s\n' % (opname, s))
+
+
+# for now, always make up a wrapped StdObjSpace
+class DumpSpace(StdObjSpace):
+
+ def __init__(self, *args, **kwds):
+ self.dumper = Dumper(self)
+ StdObjSpace.__init__(self, *args, **kwds)
+ patch_space_in_place(self, 'dump', proxymaker)
+
+ def _freeze_(self):
+ # remove strange things from the caches of self.dumper
+ # before we annotate
+ self.dumper.close()
+ return StdObjSpace._freeze_(self)
+
+ def startup(self):
+ StdObjSpace.startup(self)
+ self.dumper.open()
+
+ def finish(self):
+ self.dumper.close()
+ StdObjSpace.finish(self)
+
+ def wrap(self, x):
+ w_res = StdObjSpace.wrap(self, x)
+ self.dumper.dump_returned_wrapped(' wrap', w_res)
+ return w_res
+ wrap._annspecialcase_ = "specialize:wrap"
+
+
+Space = DumpSpace
+
+# __________________________________________________________________________
+
+nb_args = {}
+op_returning_wrapped = {}
+
+def setup():
+ nb_args.update({
+ # ---- irregular operations ----
+ 'wrap': 0,
+ 'str_w': 1,
+ 'int_w': 1,
+ 'float_w': 1,
+ 'uint_w': 1,
+ 'interpclass_w': 1,
+ 'unwrap': 1,
+ 'is_true': 1,
+ 'is_w': 2,
+ 'newtuple': 0,
+ 'newlist': 0,
+ 'newstring': 0,
+ 'newunicode': 0,
+ 'newdict': 0,
+ 'newslice': 0,
+ 'call_args': 1,
+ 'marshal_w': 1,
+ 'log': 1,
+ })
+ op_returning_wrapped.update({
+ 'wrap': True,
+ 'newtuple': True,
+ 'newlist': True,
+ 'newstring': True,
+ 'newunicode': True,
+ 'newdict': True,
+ 'newslice': True,
+ 'call_args': True,
+ })
+ for opname, _, arity, _ in baseobjspace.ObjSpace.MethodTable:
+ nb_args.setdefault(opname, arity)
+ op_returning_wrapped[opname] = True
+ for opname in baseobjspace.ObjSpace.IrregularOpTable:
+ assert opname in nb_args, "missing %r" % opname
+
+setup()
+del setup
+
+# __________________________________________________________________________
+
+def proxymaker(space, opname, parentfn):
+ if opname == 'wrap':
+ return None
+ returns_wrapped = opname in op_returning_wrapped
+ aligned_opname = '%15s' % opname
+ n = nb_args[opname]
+ def proxy(*args):
+ dumper = space.dumper
+ args_w = list(args[:n])
+ dumper.dump_enter(aligned_opname, args_w)
+ try:
+ res = parentfn(*args)
+ except Exception, e:
+ dumper.dump_raised(aligned_opname, e)
+ raise
+ else:
+ if returns_wrapped:
+ dumper.dump_returned_wrapped(aligned_opname, res)
+ else:
+ dumper.dump_returned(aligned_opname)
+ return res
+ proxy.func_name = 'proxy_%s' % (opname,)
+ return proxy
More information about the pypy-svn
mailing list