[pypy-svn] r26553 - in pypy/branch/picklesupport: doc/discussion interpreter interpreter/test module/__builtin__ module/_pickle_support objspace/flow rpython rpython/lltypesystem rpython/ootypesystem rpython/rctypes rpython/rctypes/test rpython/rctypes/tool rpython/test
ericvrp at codespeak.net
ericvrp at codespeak.net
Sat Apr 29 06:22:09 CEST 2006
Author: ericvrp
Date: Sat Apr 29 06:21:31 2006
New Revision: 26553
Added:
pypy/branch/picklesupport/doc/discussion/cli-optimizations.txt
- copied unchanged from r26551, pypy/dist/pypy/doc/discussion/cli-optimizations.txt
Modified:
pypy/branch/picklesupport/interpreter/test/test_pickle.py
pypy/branch/picklesupport/interpreter/typedef.py
pypy/branch/picklesupport/module/__builtin__/__init__.py
pypy/branch/picklesupport/module/__builtin__/app_functional.py
pypy/branch/picklesupport/module/_pickle_support/maker.py
pypy/branch/picklesupport/objspace/flow/model.py
pypy/branch/picklesupport/rpython/llinterp.py
pypy/branch/picklesupport/rpython/lltypesystem/lloperation.py
pypy/branch/picklesupport/rpython/lltypesystem/rstr.py
pypy/branch/picklesupport/rpython/ootypesystem/ootype.py
pypy/branch/picklesupport/rpython/ootypesystem/rstr.py
pypy/branch/picklesupport/rpython/rctypes/rpointer.py
pypy/branch/picklesupport/rpython/rctypes/rstringbuf.py
pypy/branch/picklesupport/rpython/rctypes/rvoid_p.py
pypy/branch/picklesupport/rpython/rctypes/test/test_rfunc.py
pypy/branch/picklesupport/rpython/rctypes/test/test_rstruct.py
pypy/branch/picklesupport/rpython/rctypes/tool/ctypes_platform.py
pypy/branch/picklesupport/rpython/robject.py
pypy/branch/picklesupport/rpython/rstr.py
pypy/branch/picklesupport/rpython/test/test_rstr.py
Log:
get changes from the trunk
Modified: pypy/branch/picklesupport/interpreter/test/test_pickle.py
==============================================================================
--- pypy/branch/picklesupport/interpreter/test/test_pickle.py (original)
+++ pypy/branch/picklesupport/interpreter/test/test_pickle.py Sat Apr 29 06:21:31 2006
@@ -128,15 +128,39 @@
def test_pickle_method(self):
skip("work in progress")
- class C(object):
+ class myclass(object):
def f(self):
pass
import pickle
- method = C.f
+ method = myclass.f
pckl = pickle.dumps(method)
result = pickle.loads(pckl)
assert method == result
+ def test_pickle_staticmethod(self):
+ skip("work in progress")
+ class myclass(object):
+ def f(self):
+ pass
+ f = staticmethod(f)
+ import pickle
+ method = myclass.f
+ pckl = pickle.dumps(method)
+ result = pickle.loads(pckl)
+ assert method == result
+
+ def test_pickle_classmethod(self):
+ skip("work in progress")
+ class myclass(object):
+ def f(self):
+ pass
+ f = classmethod(f)
+ import pickle
+ method = myclass.f
+ pckl = pickle.dumps(method)
+ result = pickle.loads(pckl)
+ assert method == result
+
def test_pickle_dictiter(self):
skip("work in progress")
import pickle
@@ -146,7 +170,7 @@
assert diter == result
def test_pickle_enum(self):
- skip("work in progress")
+ #skip("work in progress")
import pickle
e = enumerate([])
pckl = pickle.dumps(e)
@@ -170,12 +194,14 @@
assert liter == result
def test_pickle_xrangeiter(self):
- skip("work in progress")
import pickle
riter = iter(xrange(5))
+ riter.next()
+ riter.next()
pckl = pickle.dumps(riter)
result = pickle.loads(pckl)
- assert riter == result
+ assert type(riter) is type(result)
+ assert list(result) == [2,3,4]
def test_pickle_generator(self):
skip("work in progress")
Modified: pypy/branch/picklesupport/interpreter/typedef.py
==============================================================================
--- pypy/branch/picklesupport/interpreter/typedef.py (original)
+++ pypy/branch/picklesupport/interpreter/typedef.py Sat Apr 29 06:21:31 2006
@@ -23,20 +23,20 @@
# xxx used by faking
self.fakedcpytype = None
self.add_entries(**rawdict)
-
+
def add_entries(self, **rawdict):
# xxx fix the names of the methods to match what app-level expects
for key, value in rawdict.items():
if isinstance(value, (interp2app, GetSetProperty)):
value.name = key
self.rawdict.update(rawdict)
-
+
def _freeze_(self):
# hint for the annotator: track individual constant instances of TypeDef
return True
-def get_unique_interplevel_subclass(cls, hasdict, wants_slots, needsdel=False):
+def get_unique_interplevel_subclass(cls, hasdict, wants_slots, needsdel=False):
key = cls, hasdict, wants_slots, needsdel
try:
return _subclass_cache[key]
@@ -53,10 +53,10 @@
def _buildusercls(cls, hasdict, wants_slots, wants_del):
"NOT_RPYTHON: initialization-time only"
typedef = cls.typedef
-
+
if hasdict and typedef.hasdict:
return get_unique_interplevel_subclass(cls, False, wants_slots, wants_del)
-
+
name = ['User']
if not hasdict:
name.append('NoDict')
@@ -65,9 +65,9 @@
if wants_del:
name.append('WithDel')
name.append(cls.__name__)
-
+
name = ''.join(name)
-
+
if wants_del:
supercls = get_unique_interplevel_subclass(cls, hasdict, wants_slots, False)
class Proto(object):
@@ -79,29 +79,29 @@
e.clear(self.space) # break up reference cycles
elif wants_slots:
supercls = get_unique_interplevel_subclass(cls, hasdict, False, False)
-
+
class Proto(object):
def user_setup_slots(self, nslots):
- self.slots_w = [None] * nslots
-
+ self.slots_w = [None] * nslots
+
def setslotvalue(self, index, w_value):
self.slots_w[index] = w_value
-
+
def getslotvalue(self, index):
return self.slots_w[index]
elif hasdict:
supercls = get_unique_interplevel_subclass(cls, False, False, False)
-
+
class Proto(object):
def getdict(self):
return self.w__dict__
-
+
def setdict(self, space, w_dict):
if not space.is_true(space.isinstance(w_dict, space.w_dict)):
raise OperationError(space.w_TypeError,
space.wrap("setting dictionary to a non-dict"))
self.w__dict__ = w_dict
-
+
def user_setup(self, space, w_subtype, nslots):
self.space = space
self.w__class__ = w_subtype
@@ -111,29 +111,29 @@
supercls = cls
class Proto(object):
-
+
def getclass(self, space):
return self.w__class__
-
+
def setclass(self, space, w_subtype):
# only used by descr_set___class__
self.w__class__ = w_subtype
-
-
+
+
def user_setup(self, space, w_subtype, nslots):
self.space = space
self.w__class__ = w_subtype
self.user_setup_slots(nslots)
-
+
def user_setup_slots(self, nslots):
assert nslots == 0
-
+
body = dict([(key, value)
for key, value in Proto.__dict__.items()
if not key.startswith('_') or key == '__del__'])
subcls = type(name, (supercls,), body)
-
+
return subcls
def make_descr_typecheck_wrapper(func, extraargs=(), cls=None):
@@ -144,7 +144,7 @@
if hasattr(func, 'im_func'):
assert func.im_class is cls
func = func.im_func
-
+
miniglobals = {
func.__name__: func,
'OperationError': OperationError
@@ -171,12 +171,12 @@
return %(name)s(space, obj, %(extra)s)
"""
miniglobals[cls_name] = cls
-
+
name = func.__name__
extra = ', '.join(extraargs)
source = py.code.Source(source % locals())
exec source.compile() in miniglobals
- return miniglobals['descr_typecheck_%s' % func.__name__]
+ return miniglobals['descr_typecheck_%s' % func.__name__]
def unknown_objclass_getter(space):
raise OperationError(space.w_TypeError,
@@ -213,16 +213,16 @@
def __init__(self, fget, fset=None, fdel=None, doc=None, cls=None):
"NOT_RPYTHON: initialization-time only"
objclass_getter, cls = make_objclass_getter(fget, cls)
- fget = make_descr_typecheck_wrapper(fget, cls=cls)
+ fget = make_descr_typecheck_wrapper(fget, cls=cls)
fset = make_descr_typecheck_wrapper(fset, ('w_value',), cls=cls)
- fdel = make_descr_typecheck_wrapper(fdel, cls=cls)
+ fdel = make_descr_typecheck_wrapper(fdel, cls=cls)
self.fget = fget
self.fset = fset
self.fdel = fdel
self.doc = doc
self.name = '<generic property>'
self.objclass_getter = objclass_getter
-
+
def descr_property_get(space, property, w_obj, w_cls=None):
"""property.__get__(obj[, type]) -> value
Read the value of the property of the given obj."""
@@ -233,7 +233,7 @@
return space.wrap(property)
else:
return property.fget(space, w_obj)
-
+
def descr_property_set(space, property, w_obj, w_value):
"""property.__set__(obj, value)
Change the value of the property of the given obj."""
@@ -242,7 +242,7 @@
raise OperationError(space.w_TypeError,
space.wrap("readonly attribute"))
fset(space, w_obj, w_value)
-
+
def descr_property_del(space, property, w_obj):
"""property.__delete__(obj)
Delete the value of the property from the given obj."""
@@ -251,7 +251,7 @@
raise OperationError(space.w_AttributeError,
space.wrap("cannot delete attribute"))
fdel(space, w_obj)
-
+
def descr_get_objclass(space, property):
return property.objclass_getter(space)
@@ -268,8 +268,8 @@
if w_value is None:
return space.w_None
else:
- return w_value
-
+ return w_value
+
return GetSetProperty(fget, cls=cls)
GetSetProperty.typedef = TypeDef(
@@ -294,13 +294,13 @@
self.index = index
self.name = name
self.w_cls = w_cls
-
+
def typecheck(self, space, w_obj):
if not space.is_true(space.isinstance(w_obj, self.w_cls)):
raise OperationError(space.w_TypeError,
space.wrap("descriptor '%s' for '%s' objects doesn't apply to '%s' object" %
(self.name, self.w_cls.name, space.type(w_obj).name)))
-
+
def descr_member_get(space, member, w_obj, w_w_cls=None):
"""member.__get__(obj[, type]) -> value
Read the slot 'member' of the given 'obj'."""
@@ -314,14 +314,14 @@
raise OperationError(space.w_AttributeError,
space.wrap(self.name)) # XXX better message
return w_result
-
+
def descr_member_set(space, member, w_obj, w_value):
"""member.__set__(obj, value)
Write into the slot 'member' of the given 'obj'."""
self = member
self.typecheck(space, w_obj)
w_obj.setslotvalue(self.index, w_value)
-
+
def descr_member_del(space, member, w_obj):
"""member.__delete__(obj)
Delete the value of the slot 'member' from the given 'obj'."""
@@ -355,7 +355,7 @@
from pypy.interpreter.function import Function, Method, StaticMethod
from pypy.interpreter.function import BuiltinFunction, descr_function_get
from pypy.interpreter.pytraceback import PyTraceback
-from pypy.interpreter.generator import GeneratorIterator
+from pypy.interpreter.generator import GeneratorIterator
from pypy.interpreter.nestedscope import Cell
from pypy.interpreter.special import NotImplemented, Ellipsis
@@ -415,7 +415,7 @@
__new__ = interp2app(PyCode.descr_code__new__.im_func),
__eq__ = interp2app(PyCode.descr_code__eq__),
__ne__ = descr_generic_ne,
- __reduce__ = interp2app(PyCode.descr__reduce__,
+ __reduce__ = interp2app(PyCode.descr__reduce__,
unwrap_spec=['self', ObjSpace]),
co_argcount = interp_attrproperty('co_argcount', cls=PyCode),
co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode),
@@ -438,7 +438,7 @@
f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno),
f_back = GetSetProperty(PyFrame.fget_f_back),
f_lasti = GetSetProperty(PyFrame.fget_f_lasti),
- f_trace = GetSetProperty(PyFrame.fget_f_trace, PyFrame.fset_f_trace,
+ f_trace = GetSetProperty(PyFrame.fget_f_trace, PyFrame.fset_f_trace,
PyFrame.fdel_f_trace),
f_exc_type = GetSetProperty(PyFrame.fget_f_exc_type),
f_exc_value = GetSetProperty(PyFrame.fget_f_exc_value),
@@ -450,7 +450,7 @@
__new__ = interp2app(Module.descr_module__new__.im_func,
unwrap_spec=[ObjSpace, W_Root, Arguments]),
__init__ = interp2app(Module.descr_module__init__),
- __reduce__ = interp2app(Module.descr__reduce__,
+ __reduce__ = interp2app(Module.descr__reduce__,
unwrap_spec=['self', ObjSpace]),
__dict__ = GetSetProperty(descr_get_dict, cls=Module), # module dictionaries are readonly attributes
__doc__ = 'module(name[, doc])\n\nCreate a module object.\nThe name must be a string; the optional doc argument can have any type.'
@@ -480,14 +480,14 @@
getset_func_dict = GetSetProperty(descr_get_dict, descr_set_dict, cls=Function)
Function.typedef = TypeDef("function",
- __new__ = interp2app(Function.descr_method__new__.im_func),
+ __new__ = interp2app(Function.descr_method__new__.im_func),
__call__ = interp2app(Function.descr_function_call,
unwrap_spec=['self', Arguments]),
__get__ = interp2app(descr_function_get),
__repr__ = interp2app(Function.descr_function_repr),
- __reduce__ = interp2app(Function.descr_function__reduce__,
+ __reduce__ = interp2app(Function.descr_function__reduce__,
unwrap_spec=['self', ObjSpace]),
- func_code = getset_func_code,
+ func_code = getset_func_code,
func_doc = getset_func_doc,
func_name = getset_func_name,
func_dict = getset_func_dict,
@@ -506,16 +506,16 @@
__call__ = interp2app(Method.descr_method_call,
unwrap_spec=['self', Arguments]),
__get__ = interp2app(Method.descr_method_get),
- im_func = interp_attrproperty_w('w_function', cls=Method),
- im_self = interp_attrproperty_w('w_instance', cls=Method),
+ im_func = interp_attrproperty_w('w_function', cls=Method),
+ im_self = interp_attrproperty_w('w_instance', cls=Method),
im_class = interp_attrproperty_w('w_class', cls=Method),
__getattribute__ = interp2app(Method.descr_method_getattribute),
__eq__ = interp2app(Method.descr_method_eq),
__ne__ = descr_generic_ne,
- __repr__ = interp2app(Method.descr_method_repr),
- __reduce__ = interp2app(Method.descr_method__reduce__,
- unwrap_spec=['self', ObjSpace]),
- # XXX getattribute/setattribute etc.pp
+ __repr__ = interp2app(Method.descr_method_repr),
+ __reduce__ = interp2app(Method.descr_method__reduce__,
+ unwrap_spec=['self', ObjSpace]),
+ # XXX getattribute/setattribute etc.pp
)
StaticMethod.typedef = TypeDef("staticmethod",
@@ -543,31 +543,29 @@
GeneratorIterator.typedef = TypeDef("generator",
next = interp2app(GeneratorIterator.descr_next),
__iter__ = interp2app(GeneratorIterator.descr__iter__),
- gi_running = interp_attrproperty('running', cls=GeneratorIterator),
- gi_frame = interp_attrproperty('frame', cls=GeneratorIterator),
+ gi_running = interp_attrproperty('running', cls=GeneratorIterator),
+ gi_frame = interp_attrproperty('frame', cls=GeneratorIterator),
)
Cell.typedef = TypeDef("cell",
__eq__ = interp2app(Cell.descr__eq__,
unwrap_spec=['self', ObjSpace, W_Root]),
__ne__ = descr_generic_ne,
- __reduce__ = interp2app(Cell.descr__reduce__,
+ __reduce__ = interp2app(Cell.descr__reduce__,
unwrap_spec=['self', ObjSpace]),
__setstate__ = interp2app(Cell.descr__setstate__,
- unwrap_spec=['self', ObjSpace, W_Root]),
+ unwrap_spec=['self', ObjSpace, W_Root]),
)
-Ellipsis.typedef = TypeDef("Ellipsis",
+Ellipsis.typedef = TypeDef("Ellipsis",
__repr__ = interp2app(Ellipsis.descr__repr__),
)
-NotImplemented.typedef = TypeDef("NotImplemented",
- __repr__ = interp2app(NotImplemented.descr__repr__),
+NotImplemented.typedef = TypeDef("NotImplemented",
+ __repr__ = interp2app(NotImplemented.descr__repr__),
)
ControlFlowException.typedef = TypeDef("ControlFlowException")
interptypes = [ val.typedef for name,val in globals().items() if hasattr(val,'__bases__') and hasattr(val,'typedef') ]
-
-
Modified: pypy/branch/picklesupport/module/__builtin__/__init__.py
==============================================================================
--- pypy/branch/picklesupport/module/__builtin__/__init__.py (original)
+++ pypy/branch/picklesupport/module/__builtin__/__init__.py Sat Apr 29 06:21:31 2006
@@ -31,6 +31,8 @@
'any' : 'app_functional.any',
'enumerate' : 'app_functional.enumerate',
'xrange' : 'app_functional.xrange',
+ '_install_pickle_support_for_xrange_iterator':
+ 'app_functional._install_pickle_support_for_xrange_iterator',
'sorted' : 'app_functional.sorted',
'reversed' : 'app_functional.reversed',
@@ -137,3 +139,15 @@
builtin = module.Module(space, None)
space.setitem(builtin.w_dict, space.wrap('None'), space.w_None)
return builtin
+
+ def setup_after_space_initialization(self):
+ """NOT_RPYTHON"""
+ space = self.space
+ # call installations for pickle support
+ for name in self.loaders.keys():
+ if name.startswith('_install_pickle_support_for_'):
+ w_install = self.get(name)
+ space.call_function(w_install)
+ # xxx hide the installer
+ space.delitem(self.w_dict, space.wrap(name))
+ del self.loaders[name]
\ No newline at end of file
Modified: pypy/branch/picklesupport/module/__builtin__/app_functional.py
==============================================================================
--- pypy/branch/picklesupport/module/__builtin__/app_functional.py (original)
+++ pypy/branch/picklesupport/module/__builtin__/app_functional.py Sat Apr 29 06:21:31 2006
@@ -362,6 +362,18 @@
def __len__(self):
return self._remaining
+ def __reduce__(self):
+ tup = (self._current, self._remaining, self._step)
+ return (make_xrange_iterator, tup)
+
+def make_xrange_iterator(*args):
+ return xrange_iterator(*args)
+
+def _install_pickle_support_for_xrange_iterator():
+ import _pickle_support
+ make_xrange_iterator.__module__ = '_pickle_support'
+ _pickle_support.make_xrange_iterator = make_xrange_iterator
+
# ____________________________________________________________
def sorted(lst, cmp=None, key=None, reverse=None):
Modified: pypy/branch/picklesupport/module/_pickle_support/maker.py
==============================================================================
--- pypy/branch/picklesupport/module/_pickle_support/maker.py (original)
+++ pypy/branch/picklesupport/module/_pickle_support/maker.py Sat Apr 29 06:21:31 2006
@@ -24,11 +24,11 @@
return space.call_args(w_type, __args__)
func_new.unwrap_spec = [ObjSpace, Arguments]
-def module_new(space, w_name, w_dict): #XXX untested
+def module_new(space, w_name, w_dict):
new_mod = Module(space, w_name, w_dict)
return space.wrap(new_mod)
-def method_new(space, __args__): #XXX untested
+def method_new(space, __args__):
w_type = space.gettypeobject(Method.typedef)
return space.call_args(w_type, __args__)
method_new.unwrap_spec = [ObjSpace, Arguments]
Modified: pypy/branch/picklesupport/objspace/flow/model.py
==============================================================================
--- pypy/branch/picklesupport/objspace/flow/model.py (original)
+++ pypy/branch/picklesupport/objspace/flow/model.py Sat Apr 29 06:21:31 2006
@@ -67,12 +67,14 @@
return getsource(self.func)
source = roproperty(getsource)
- def __repr__(self):
+ def __str__(self):
if hasattr(self, 'func'):
- fnrepr = nice_repr_for_func(self.func, self.name)
+ return nice_repr_for_func(self.func, self.name)
else:
- fnrepr = self.name
- return '<FunctionGraph of %s at 0x%x>' % (fnrepr, uid(self))
+ return self.name
+
+ def __repr__(self):
+ return '<FunctionGraph of %s at 0x%x>' % (self, uid(self))
def iterblocks(self):
block = self.startblock
Modified: pypy/branch/picklesupport/rpython/llinterp.py
==============================================================================
--- pypy/branch/picklesupport/rpython/llinterp.py (original)
+++ pypy/branch/picklesupport/rpython/llinterp.py Sat Apr 29 06:21:31 2006
@@ -36,6 +36,8 @@
class LLInterpreter(object):
""" low level interpreter working with concrete values. """
+ TRACING = True
+
def __init__(self, typer, heap=lltype):
self.bindings = {}
self.typer = typer
@@ -47,19 +49,41 @@
if hasattr(heap, "prepare_graphs_and_create_gc"):
flowgraphs = typer.annotator.translator.graphs
self.gc = heap.prepare_graphs_and_create_gc(self, flowgraphs)
+ if self.TRACING:
+ self.tracer = Tracer()
+ else:
+ self.tracer = None
def eval_graph(self, graph, args=()):
llframe = LLFrame(graph, args, self)
+ if self.tracer:
+ self.tracer.start()
+ retval = None
try:
- return llframe.eval()
- except LLException, e:
- log.error("LLEXCEPTION: %s" % (e, ))
- self.print_traceback()
- raise
- except Exception, e:
- log.error("AN ERROR OCCURED: %s" % (e, ))
- self.print_traceback()
- raise
+ try:
+ retval = llframe.eval()
+ except LLException, e:
+ log.error("LLEXCEPTION: %s" % (e, ))
+ self.print_traceback()
+ if self.tracer:
+ self.tracer.dump('LLException: %s\n' % (e,))
+ raise
+ except Exception, e:
+ log.error("AN ERROR OCCURED: %s" % (e, ))
+ self.print_traceback()
+ if self.tracer:
+ line = str(e)
+ if line:
+ line = ': ' + line
+ line = '* %s' % (e.__class__.__name__,) + line
+ self.tracer.dump(line + '\n')
+ raise
+ finally:
+ if self.tracer:
+ if retval is not None:
+ self.tracer.dump(' ---> %r\n' % (retval,))
+ self.tracer.stop()
+ return retval
def print_traceback(self):
frame = self.active_frame
@@ -68,11 +92,12 @@
frames.append(frame)
frame = frame.f_back
frames.reverse()
+ lines = []
for frame in frames:
logline = frame.graph.name
if frame.curr_block is None:
logline += " <not running yet>"
- log.traceback(logline)
+ lines.append(logline)
continue
try:
logline += " " + self.typer.annotator.annotated[frame.curr_block].__module__
@@ -80,13 +105,19 @@
# if the graph is from the GC it was not produced by the same
# translator :-(
logline += " <unknown module>"
- log.traceback(logline)
+ lines.append(logline)
for i, operation in enumerate(frame.curr_block.operations):
if i == frame.curr_operation_index:
logline = "E %s"
else:
logline = " %s"
- log.traceback(logline % (operation, ))
+ lines.append(logline % (operation, ))
+ if self.tracer:
+ self.tracer.dump('Traceback\n', bold=True)
+ for line in lines:
+ self.tracer.dump(line + '\n')
+ for line in lines:
+ log.traceback(line)
def find_roots(self):
#log.findroots("starting")
@@ -204,19 +235,25 @@
def eval(self):
self.llinterpreter.active_frame = self
graph = self.graph
- #log.frame("evaluating", graph.name)
- nextblock = graph.startblock
- args = self.args
- while 1:
- self.clear()
- self.fillvars(nextblock, args)
- nextblock, args = self.eval_block(nextblock)
- if nextblock is None:
- self.llinterpreter.active_frame = self.f_back
- for obj in self.alloca_objects:
- #XXX slighly unclean
- obj._setobj(None)
- return args
+ tracer = self.llinterpreter.tracer
+ if tracer:
+ tracer.enter(graph)
+ try:
+ nextblock = graph.startblock
+ args = self.args
+ while 1:
+ self.clear()
+ self.fillvars(nextblock, args)
+ nextblock, args = self.eval_block(nextblock)
+ if nextblock is None:
+ self.llinterpreter.active_frame = self.f_back
+ for obj in self.alloca_objects:
+ #XXX slighly unclean
+ obj._setobj(None)
+ return args
+ finally:
+ if tracer:
+ tracer.leave()
def eval_block(self, block):
""" return (nextblock, values) tuple. If nextblock
@@ -237,16 +274,20 @@
# determine nextblock and/or return value
if len(block.exits) == 0:
# return block
+ tracer = self.llinterpreter.tracer
if len(block.inputargs) == 2:
# exception
+ if tracer:
+ tracer.dump('raise')
etypevar, evaluevar = block.getvariables()
etype = self.getval(etypevar)
evalue = self.getval(evaluevar)
# watch out, these are _ptr's
raise LLException(etype, evalue)
+ if tracer:
+ tracer.dump('return')
resultvar, = block.getvariables()
result = self.getval(resultvar)
- #log.operation("returning", repr(result))
return None, result
elif block.exitswitch is None:
# single-exit block
@@ -283,7 +324,9 @@
return link.target, [self.getval(x) for x in link.args]
def eval_operation(self, operation):
- #log.operation("considering", operation)
+ tracer = self.llinterpreter.tracer
+ if tracer:
+ tracer.dump(str(operation))
ophandler = self.getoperationhandler(operation.opname)
# XXX slighly unnice but an important safety check
if operation.opname == 'direct_call':
@@ -313,6 +356,11 @@
else:
self.handle_cleanup(operation)
self.setvar(operation.result, retval)
+ if tracer:
+ if retval is None:
+ tracer.dump('\n')
+ else:
+ tracer.dump(' ---> %r\n' % (retval,))
def handle_cleanup(self, operation, exception=False):
cleanup = getattr(operation, 'cleanup', None)
@@ -953,6 +1001,86 @@
def op_ooidentityhash(self, inst):
return ootype.ooidentityhash(inst)
+
+class Tracer(object):
+ Counter = 0
+ file = None
+
+ HEADER = """<html><head>
+ <script language=javascript type='text/javascript'>
+ function togglestate(name) {
+ item = document.getElementById(name)
+ if (item.style.display == 'none')
+ item.style.display = 'block';
+ else
+ item.style.display = 'none';
+ }
+ </script>
+ </head>
+
+ <body><pre>
+ """
+
+ FOOTER = """</pre></body></html>"""
+
+ ENTER = ('''\n\t<a href="javascript:togglestate('div%d')">%s</a>'''
+ '''\n<div id="div%d" style="display: %s">\t''')
+ LEAVE = '''\n</div>\t'''
+
+ def htmlquote(self, s, text_to_html={}):
+ # HTML quoting, lazily initialized
+ if not text_to_html:
+ import htmlentitydefs
+ for key, value in htmlentitydefs.entitydefs.items():
+ text_to_html[value] = '&' + key + ';'
+ return ''.join([text_to_html.get(c, c) for c in s])
+
+ def start(self):
+ # start of a dump file
+ from pypy.tool.udir import udir
+ n = Tracer.Counter
+ Tracer.Counter += 1
+ self.file = udir.join('llinterp_trace_%d.html' % n).open('w')
+ print >> self.file, self.HEADER
+ self.count = 0
+ self.indentation = ''
+
+ def stop(self):
+ # end of a dump file
+ if self.file:
+ print >> self.file, self.FOOTER
+ self.file.close()
+ self.file = None
+
+ def enter(self, graph):
+ # enter evaluation of a graph
+ if self.file:
+ s = self.htmlquote(str(graph))
+ i = s.rfind(')')
+ s = s[:i+1] + '<b>' + s[i+1:] + '</b>'
+ if self.count == 0:
+ display = 'block'
+ else:
+ display = 'none'
+ text = self.ENTER % (self.count, s, self.count, display)
+ self.indentation += ' '
+ self.file.write(text.replace('\t', self.indentation))
+ self.count += 1
+
+ def leave(self):
+ # leave evaluation of a graph
+ if self.file:
+ self.indentation = self.indentation[:-4]
+ self.file.write(self.LEAVE.replace('\t', self.indentation))
+
+ def dump(self, text, bold=False):
+ if self.file:
+ text = self.htmlquote(text)
+ if bold:
+ text = '<b>%s</b>' % (text,)
+ self.file.write(text.replace('\n', '\n'+self.indentation))
+
+
# by default we route all logging messages to nothingness
# e.g. tests can then switch on logging to get more help
# for failing tests
Modified: pypy/branch/picklesupport/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/picklesupport/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/picklesupport/rpython/lltypesystem/lloperation.py Sat Apr 29 06:21:31 2006
@@ -317,6 +317,7 @@
'same_as': LLOp(canfold=True),
'hint': LLOp(),
'check_no_more_arg': LLOp(canraise=(Exception,)),
+ 'check_self_nonzero': LLOp(canraise=(Exception,)),
'decode_arg': LLOp(canraise=(Exception,)),
'decode_arg_def': LLOp(canraise=(Exception,)),
'getslice': LLOp(canraise=(Exception,)),
Modified: pypy/branch/picklesupport/rpython/lltypesystem/rstr.py
==============================================================================
--- pypy/branch/picklesupport/rpython/lltypesystem/rstr.py (original)
+++ pypy/branch/picklesupport/rpython/lltypesystem/rstr.py Sat Apr 29 06:21:31 2006
@@ -1,6 +1,9 @@
-from pypy.rpython.rstr import AbstractStringRepr, STR, AbstractStringIteratorRepr, \
- ll_strconcat
-from pypy.rpython.lltypesystem.lltype import malloc, GcStruct, Ptr, Signed
+from weakref import WeakValueDictionary
+from pypy.rpython.rstr import AbstractStringRepr, char_repr, STR, AbstractStringIteratorRepr, \
+ ll_strconcat, do_stringformat, ll_strhash
+from pypy.rpython.lltypesystem.lltype import malloc, GcStruct, Ptr, nullptr, Signed
+
+CONST_STR_CACHE = WeakValueDictionary()
class StringRepr(AbstractStringRepr):
@@ -13,6 +16,22 @@
self.ll_lower = ll_lower
self.ll_join = ll_join
+ def convert_const(self, value):
+ if value is None:
+ return nullptr(STR)
+ #value = getattr(value, '__self__', value) # for bound string methods
+ if not isinstance(value, str):
+ raise TyperError("not a str: %r" % (value,))
+ try:
+ return CONST_STR_CACHE[value]
+ except KeyError:
+ p = malloc(STR, len(value))
+ for i in range(len(value)):
+ p.chars[i] = value[i]
+ ll_strhash(p) # precompute the hash
+ CONST_STR_CACHE[value] = p
+ return p
+
def make_iterator_repr(self):
return string_iterator_repr
@@ -115,6 +134,11 @@
i += 1
return result
+char_repr.ll_strip = ll_strip
+char_repr.ll_upper = ll_upper
+char_repr.ll_lower = ll_lower
+char_repr.ll_join = ll_join
+
string_repr = StringRepr()
emptystr = string_repr.convert_const("")
Modified: pypy/branch/picklesupport/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/branch/picklesupport/rpython/ootypesystem/ootype.py (original)
+++ pypy/branch/picklesupport/rpython/ootypesystem/ootype.py Sat Apr 29 06:21:31 2006
@@ -181,6 +181,13 @@
StaticMethod.__init__(self, args, result)
+class String(OOType):
+
+ def _defl(self):
+ return ""
+
+String = String()
+
class BuiltinType(OOType):
def _example(self):
@@ -642,6 +649,10 @@
else:
instance_impl = _instance
+def make_string(value):
+ assert isinstance(value, str)
+ return _string(value)
+
def make_instance(INSTANCE):
inst = _instance(INSTANCE)
if STATICNESS:
@@ -724,6 +735,9 @@
callb, checked_args = self.meth._checkargs(args)
return callb(self.inst, *checked_args)
+class _string(str):
+ _TYPE = String
+
class _builtin_type(object):
def __getattribute__(self, name):
TYPE = object.__getattribute__(self, "_TYPE")
Modified: pypy/branch/picklesupport/rpython/ootypesystem/rstr.py
==============================================================================
--- pypy/branch/picklesupport/rpython/ootypesystem/rstr.py (original)
+++ pypy/branch/picklesupport/rpython/ootypesystem/rstr.py Sat Apr 29 06:21:31 2006
@@ -1,10 +1,18 @@
from pypy.rpython.rstr import AbstractStringRepr, STR, AbstractStringIteratorRepr
from pypy.rpython.lltypesystem.lltype import Ptr
-from pypy.rpython.ootypesystem.ootype import Signed, Record
+from pypy.rpython.ootypesystem.ootype import Signed, Record, String, make_string
class StringRepr(AbstractStringRepr):
- lowleveltype = Ptr(STR)
+ lowleveltype = String
+
+ def convert_const(self, value):
+ # XXX what do we do about null strings?
+ #if value is None:
+ # return nullptr(STR)
+ if not isinstance(value, str):
+ raise TyperError("not a str: %r" % (value,))
+ return make_string(value)
def make_iterator_repr(self):
return string_iterator_repr
Modified: pypy/branch/picklesupport/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rctypes/rpointer.py (original)
+++ pypy/branch/picklesupport/rpython/rctypes/rpointer.py Sat Apr 29 06:21:31 2006
@@ -9,20 +9,27 @@
class PointerRepr(CTypesValueRepr):
def __init__(self, rtyper, s_pointer):
- ptr_ctype = s_pointer.knowntype
- ref_ctype = ptr_ctype._type_
+ # For recursive types, getting the r_contents is delayed until
+ # _setup_repr().
+ ll_contents = lltype.Ptr(lltype.ForwardReference())
+ self.keepalive_box_type = lltype.GcForwardReference()
+ super(PointerRepr, self).__init__(rtyper, s_pointer, ll_contents)
+ def _setup_repr(self):
# Find the repr and low-level type of the contents from its ctype
+ rtyper = self.rtyper
+ ref_ctype = self.ctype._type_
self.r_contents = rtyper.getrepr(SomeCTypesObject(ref_ctype,
SomeCTypesObject.MEMORYALIAS))
-
- ll_contents = lltype.Ptr(self.r_contents.c_data_type)
-
- super(PointerRepr, self).__init__(rtyper, s_pointer, ll_contents)
+ if isinstance(self.ll_type.TO, lltype.ForwardReference):
+ self.ll_type.TO.become(self.r_contents.c_data_type)
+ if isinstance(self.keepalive_box_type, lltype.GcForwardReference):
+ self.keepalive_box_type.become(
+ self.r_contents.r_memoryowner.lowleveltype.TO)
def get_content_keepalive_type(self):
"Keepalive for the box that holds the data that 'self' points to."
- return self.r_contents.r_memoryowner.lowleveltype
+ return lltype.Ptr(self.keepalive_box_type)
def setkeepalive(self, llops, v_box, v_owner):
inputargs = [v_box, inputconst(lltype.Void, 'keepalive'),
Modified: pypy/branch/picklesupport/rpython/rctypes/rstringbuf.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rctypes/rstringbuf.py (original)
+++ pypy/branch/picklesupport/rpython/rctypes/rstringbuf.py Sat Apr 29 06:21:31 2006
@@ -4,7 +4,7 @@
from pypy.rpython.rctypes.rmodel import CTypesRefRepr
from pypy.objspace.flow.model import Constant
from pypy.rpython.rslice import AbstractSliceRepr
-from pypy.rpython.rstr import string_repr
+from pypy.rpython.lltypesystem.rstr import string_repr
class StringBufRepr(CTypesRefRepr):
Modified: pypy/branch/picklesupport/rpython/rctypes/rvoid_p.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rctypes/rvoid_p.py (original)
+++ pypy/branch/picklesupport/rpython/rctypes/rvoid_p.py Sat Apr 29 06:21:31 2006
@@ -1,5 +1,30 @@
-from pypy.rpython.rctypes.rmodel import CTypesValueRepr
-
+from pypy.rpython.rctypes.rmodel import CTypesValueRepr, C_ZERO
+from pypy.rpython.rctypes.rstringbuf import StringBufRepr
+from pypy.annotation.pairtype import pairtype
+from pypy.rpython.rctypes.rchar_p import CCharPRepr
+from pypy.rpython.lltypesystem import llmemory
class CVoidPRepr(CTypesValueRepr):
pass # No operations supported on c_void_p instances so far
+
+class __extend__(pairtype(StringBufRepr, CVoidPRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ # warning: no keepalives, only for short-lived conversions like
+ # in argument passing
+ r_temp = r_to.r_memoryowner
+ v_owned_box = r_temp.allocate_instance(llops)
+ v_c_array = r_from.get_c_data_of_item(llops, v, C_ZERO)
+ v_adr = llops.genop('cast_ptr_to_adr', [v_c_array],
+ resulttype = llmemory.Address)
+ r_temp.setvalue(llops, v_owned_box, v_adr)
+ return llops.convertvar(v_owned_box, r_temp, r_to)
+ # XXX some code duplication above
+
+class __extend__(pairtype(CCharPRepr, CVoidPRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ v_ptr = r_from.getvalue(llops, v)
+ v_adr = llops.genop('cast_ptr_to_adr', [v_ptr],
+ resulttype = llmemory.Address)
+
+ return r_to.return_value(llops, v_adr)
+
Modified: pypy/branch/picklesupport/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rctypes/test/test_rfunc.py (original)
+++ pypy/branch/picklesupport/rpython/rctypes/test/test_rfunc.py Sat Apr 29 06:21:31 2006
@@ -11,10 +11,11 @@
from pypy.translator.c.test.test_genc import compile
from pypy import conftest
from pypy.rpython.lltypesystem.rstr import string_repr
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from ctypes import cdll, pythonapi, PyDLL, _FUNCFLAG_PYTHONAPI
-from ctypes import c_int, c_long, c_char_p, c_char, create_string_buffer
+from ctypes import c_int, c_long, c_char_p, c_void_p, c_char
+from ctypes import create_string_buffer, cast
from ctypes import POINTER, py_object, byref, Structure
from pypy.rpython.rctypes.tool import util # ctypes.util from 0.9.9.6
@@ -63,6 +64,18 @@
##PyIntIntCallback = CALLBACK_FUNCTYPE(c_int, c_int, callconv=PyDLL)
##pycallback = PyIntIntCallback(mycallback)
+def ll_memcpy(dst, src, length):
+ C_ARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
+ c_src = llmemory.cast_adr_to_ptr(src, C_ARRAY)
+ c_dst = llmemory.cast_adr_to_ptr(dst, C_ARRAY)
+ for i in range(length):
+ c_dst[i] = c_src[i]
+ return dst
+
+memcpy = mylib.memcpy
+memcpy.argtypes = [c_void_p, c_void_p, c_long]
+memcpy.restype = c_void_p
+memcpy.llinterp_friendly_version = ll_memcpy
def test_labs(n=6):
assert labs(n) == abs(n)
@@ -159,6 +172,18 @@
a.build_types(ep, [])
if conftest.option.view:
a.translator.view()
+ def test_annotate_call_void_p_arg_with_stringbuf(self):
+ string = 'abc xyz'
+ def f(x):
+ buf = create_string_buffer(len(string) + 1)
+ res = memcpy(buf, string, len(string))
+ return buf.value
+ a = RPythonAnnotator()
+ s = a.build_types(f, [int])
+ if conftest.option.view:
+ a.translator.view()
+ assert s.knowntype == str
+
## def test_annotate_callback(self):
## def fn(n):
@@ -232,6 +257,17 @@
res = interpret(fn, [11])
assert res == 42
+ def test_specialize_call_void_p_arg_with_stringbuf(self):
+ string = 'abc xyz'
+ def f():
+ buf = create_string_buffer(len(string) + 1)
+ res = memcpy(buf, c_char_p(string), len(string))
+ return buf.value
+ assert f() == string
+ res = interpret(f, [])
+ assert ''.join(res.chars) == string
+
+
class Test_compile:
def test_compile_labs(self):
fn = compile(test_labs, [int])
@@ -300,3 +336,14 @@
s1 = time.ctime(N)
s2 = fn(N)
assert s1.strip() == s2.strip()
+
+ def test_compile_call_void_p_arg_with_stringbuf(self):
+ string = 'abc xyz'
+ def f():
+ buf = create_string_buffer(len(string) + 1)
+ res = memcpy(buf, c_char_p(string), len(string))
+ return buf.value
+ assert f() == string
+ fn = compile(f, [])
+ assert fn() == string
+
Modified: pypy/branch/picklesupport/rpython/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rctypes/test/test_rstruct.py (original)
+++ pypy/branch/picklesupport/rpython/rctypes/test/test_rstruct.py Sat Apr 29 06:21:31 2006
@@ -13,7 +13,7 @@
from pypy.rpython.test.test_llinterp import interpret
from ctypes import c_int, c_short, Structure, POINTER, pointer, c_char_p
-from ctypes import c_char
+from ctypes import c_char, SetPointerType
class tagpoint(Structure):
_fields_ = [("x", c_int),
@@ -151,6 +151,23 @@
res = interpret(func, [])
assert res == 121
+ def test_struct_with_pointer_to_self(self):
+ PS = POINTER('S')
+ class S(Structure):
+ _fields_ = [('l', PS), ('r', PS)]
+ SetPointerType(PS, S)
+
+ def func():
+ s0 = S()
+ s0.r.contents = s0
+ s0.l.contents = S()
+ s0.l.contents.r.contents = s0
+
+ return bool(s0.r.contents.l.contents.l)
+ assert not func()
+ res = interpret(func, [])
+ assert res is False
+
def test_specialize_keepalive(self):
class S(Structure):
_fields_ = [('x', c_int)]
Modified: pypy/branch/picklesupport/rpython/rctypes/tool/ctypes_platform.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rctypes/tool/ctypes_platform.py (original)
+++ pypy/branch/picklesupport/rpython/rctypes/tool/ctypes_platform.py Sat Apr 29 06:21:31 2006
@@ -187,7 +187,7 @@
for i, cell in enumerate(layout):
if cell is not None:
continue
- layout_addfield(layout, i, ctypes.c_char, '_pad%d' % (n,))
+ layout_addfield(layout, i, ctypes.c_char, 'pad%d' % (n,))
n += 1
# build the ctypes Structure
Modified: pypy/branch/picklesupport/rpython/robject.py
==============================================================================
--- pypy/branch/picklesupport/rpython/robject.py (original)
+++ pypy/branch/picklesupport/rpython/robject.py Sat Apr 29 06:21:31 2006
@@ -1,7 +1,7 @@
from pypy.annotation.pairtype import pairtype
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem.lltype import \
- PyObject, Ptr, Void, pyobjectptr, nullptr
+ PyObject, Ptr, Void, pyobjectptr, nullptr, Bool
from pypy.rpython.rmodel import Repr, VoidRepr, inputconst
from pypy.rpython import rclass
from pypy.tool.sourcetools import func_with_new_name
@@ -69,3 +69,10 @@
for opname in annmodel.BINARY_OPERATIONS:
make_operation(opname, pairtype(PyObjRepr, Repr))
make_operation(opname, pairtype(Repr, PyObjRepr))
+
+
+class __extend__(pairtype(PyObjRepr, PyObjRepr)):
+ def rtype_contains((r_seq, r_item), hop):
+ v_seq, v_item = hop.inputargs(r_seq, r_item)
+ return hop.llops.gencapicall('PySequence_Contains_with_exc',
+ [v_seq, v_item], resulttype=Bool)
Modified: pypy/branch/picklesupport/rpython/rstr.py
==============================================================================
--- pypy/branch/picklesupport/rpython/rstr.py (original)
+++ pypy/branch/picklesupport/rpython/rstr.py Sat Apr 29 06:21:31 2006
@@ -247,7 +247,8 @@
return hop.gendirectcall(llfn, v_str, v_index)
def rtype_mod(_, hop):
- return do_stringformat(hop, [(hop.args_v[1], hop.args_r[1])])
+ rstr = hop.rtyper.type_system.rstr
+ return rstr.do_stringformat(hop, [(hop.args_v[1], hop.args_r[1])])
class __extend__(pairtype(AbstractStringRepr, SliceRepr)):
@@ -313,7 +314,8 @@
resulttype=Bool)
def rtype_mod(_, hop):
- return do_stringformat(hop, [(hop.args_v[1], hop.args_r[1])])
+ rstr = hop.rtyper.type_system.rstr
+ return rstr.do_stringformat(hop, [(hop.args_v[1], hop.args_r[1])])
class __extend__(pairtype(AbstractStringRepr, CharRepr)):
def rtype_contains(_, hop):
@@ -410,7 +412,8 @@
resulttype=r_arg)
sourcevars.append((vitem, r_arg))
- return do_stringformat(hop, sourcevars)
+ rstr = hop.rtyper.type_system.rstr
+ return rstr.do_stringformat(hop, sourcevars)
class __extend__(CharRepr):
Modified: pypy/branch/picklesupport/rpython/test/test_rstr.py
==============================================================================
--- pypy/branch/picklesupport/rpython/test/test_rstr.py (original)
+++ pypy/branch/picklesupport/rpython/test/test_rstr.py Sat Apr 29 06:21:31 2006
@@ -302,6 +302,9 @@
res = interpret(lambda: ''.join(['abc', 'de', 'fghi']), [])
assert ''.join(res.chars) == "abcdefghi"
+
+ res = interpret(lambda: '.'.join(['abc', 'def']), [])
+ assert ''.join(res.chars) == 'abc.def'
def fn(i, j):
s1 = [ '', ',', ' and ']
More information about the Pypy-commit
mailing list