[pypy-svn] r29907 - in pypy/dist/pypy: objspace/cpy objspace/cpy/test rpython rpython/lltypesystem translator/c
arigo at codespeak.net
arigo at codespeak.net
Sun Jul 9 18:31:56 CEST 2006
Author: arigo
Date: Sun Jul 9 18:31:50 2006
New Revision: 29907
Modified:
pypy/dist/pypy/objspace/cpy/test/test_typedef.py
pypy/dist/pypy/objspace/cpy/typedef.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/rclass.py
pypy/dist/pypy/rpython/rcpy.py
pypy/dist/pypy/translator/c/node.py
Log:
(pedronis, arigo)
Implement and test prebuilt instances of W_Xxx classes.
Modified: pypy/dist/pypy/objspace/cpy/test/test_typedef.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/test/test_typedef.py (original)
+++ pypy/dist/pypy/objspace/cpy/test/test_typedef.py Sun Jul 9 18:31:50 2006
@@ -296,3 +296,48 @@
annotatorpolicy = CPyAnnotatorPolicy(space))
res = fn(expected_extra_mallocs=1)
assert type(res).__name__ == 'MyType'
+
+def test_prebuilt_instance():
+ def mytype_new(space, w_subtype, x):
+ return space.wrap(W_MyType(space, x))
+ mytype_new.unwrap_spec = [ObjSpace, W_Root, int]
+
+ W_MyType.typedef = TypeDef("MyType",
+ __new__ = interp2app(mytype_new))
+ space = CPyObjSpace()
+
+ w_type = space.gettypefor(W_MyType)
+ w_obj = space.call_function(w_type, space.wrap(42))
+ def build():
+ return w_obj
+
+ w_name = space.getattr(space.type(w_obj), space.wrap('__name__'))
+ assert space.unwrap(w_name) == 'MyType'
+
+ fn = compile(build, [],
+ annotatorpolicy = CPyAnnotatorPolicy(space))
+ res = fn(expected_extra_mallocs=0)
+ assert type(res).__name__ == 'MyType'
+
+def test_prebuilt_instance_inside_pyobj():
+ def mytype_new(space, w_subtype, x):
+ return space.wrap(W_MyType(space, x))
+ mytype_new.unwrap_spec = [ObjSpace, W_Root, int]
+
+ W_MyType.typedef = TypeDef("MyType",
+ __new__ = interp2app(mytype_new))
+ space = CPyObjSpace()
+
+ w_type = space.gettypefor(W_MyType)
+ w_obj = space.call_function(w_type, space.wrap(42))
+ w_mydict = space.newdict([])
+ space.setitem(w_mydict, space.wrap('hello'), w_obj)
+ def build():
+ return w_mydict
+
+ fn = compile(build, [],
+ annotatorpolicy = CPyAnnotatorPolicy(space))
+ res = fn(expected_extra_mallocs=0)
+ assert type(res) is dict
+ assert res.keys() == ['hello']
+ assert type(res['hello']).__name__ == 'MyType'
Modified: pypy/dist/pypy/objspace/cpy/typedef.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/typedef.py (original)
+++ pypy/dist/pypy/objspace/cpy/typedef.py Sun Jul 9 18:31:50 2006
@@ -24,9 +24,10 @@
else:
w_x = x.__cpy_wrapper__
if w_x is None:
- w_type = cache.wraptypeintf(x, typeintf)
+ w_type = cache.wraptypeintf(x.__class__, typeintf)
w_x = W_Object(rpython_object.__new__(w_type.value))
- init_rpython_data(w_x, x)
+ init_rpython_data(w_x.value, x)
+ x.__cpy_wrapper__ = w_x
return w_x
rpython2cpython.allow_someobjects = True
rpython2cpython._annspecialcase_ = "specialize:argtype(1)"
@@ -48,7 +49,7 @@
w_obj, result, follow = space.wrap_cache[id(w_obj)]
except KeyError:
if isinstance(w_obj.value, rpython_object):
- result = get_rpython_data(w_obj)
+ result = get_rpython_data(w_obj.value)
else:
result = None
return result
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sun Jul 9 18:31:50 2006
@@ -1168,6 +1168,9 @@
container = parent
return container
+ def _setup_extra_args(self):
+ pass
+
def _struct_variety(flds, cache={}):
flds = list(flds)
flds.sort()
@@ -1256,7 +1259,11 @@
setattr(self, 'item%d' % index, value)
def _setup_extra_args(self, *args):
- getattr(self, self._TYPE._names[0])._setup_extra_args(*args)
+ fieldname, FIELDTYPE = self._TYPE._first_struct()
+ if fieldname is not None:
+ getattr(self, fieldname)._setup_extra_args(*args)
+ else:
+ assert not args
class _array(_parentable):
_kind = "array"
@@ -1492,7 +1499,7 @@
return '<%s>' % (self,)
def __str__(self):
- return "pyobjheader of type %r" % (self.ob_type,)
+ return "pyobjheader of type %r" % (getattr(self, 'ob_type', '???'),)
def malloc(T, n=None, flavor='gc', immortal=False, extra_args=()):
@@ -1504,8 +1511,7 @@
raise TypeError, "malloc for Structs and Arrays only"
if T._gckind != 'gc' and not immortal and flavor.startswith('gc'):
raise TypeError, "gc flavor malloc of a non-GC non-immortal structure"
- if extra_args:
- o._setup_extra_args(*extra_args)
+ o._setup_extra_args(*extra_args)
solid = immortal or not flavor.startswith('gc') # immortal or non-gc case
return _ptr(Ptr(T), o, solid)
Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Sun Jul 9 18:31:50 2006
@@ -393,7 +393,13 @@
return cast_pointer(self.lowleveltype, result)
def create_instance(self):
- return malloc(self.object_type, flavor=self.gcflavor)
+ if self.gcflavor == 'cpy':
+ from pypy.rpython import rcpy
+ extra_args = (rcpy.build_pytypeobject(self),)
+ else:
+ extra_args = ()
+ return malloc(self.object_type, flavor=self.gcflavor,
+ extra_args=extra_args)
def has_wrapper(self):
return self.classdef is not None and (
Modified: pypy/dist/pypy/rpython/rcpy.py
==============================================================================
--- pypy/dist/pypy/rpython/rcpy.py (original)
+++ pypy/dist/pypy/rpython/rcpy.py Sun Jul 9 18:31:50 2006
@@ -22,6 +22,7 @@
def emulate(self, original_class):
"Build a type object that emulates 'self'."
+ assert isinstance(original_class, type)
d = {'__slots__': [], '_rpython_class_': original_class}
for name, value in self.objects.items():
assert lltype.typeOf(value) == PyObjPtr
@@ -271,20 +272,26 @@
pass
class rpython_object(object):
- "NOT_RPYTHON"
+ """NOT_RPYTHON
+ Wrapper object, for emulation.
+ """
__metaclass__ = rpython_meta
__slots__ = ('data',)
rpython_data = rpython_object.data
del rpython_object.data
-def init_rpython_data(w_object, value):
- "NOT_RPYTHON"
- rpython_data.__set__(w_object.value, value)
- value.__cpy_wrapper__ = w_object
-
-def get_rpython_data(w_object):
- "NOT_RPYTHON"
- return rpython_data.__get__(w_object.value)
+def init_rpython_data(wrapperobj, value):
+ """NOT_RPYTHON
+ Set the wrapper object's hidden 'data' slot to point to the original
+ RPython instance 'value'.
+ """
+ rpython_data.__set__(wrapperobj, value)
+
+def get_rpython_data(wrapperobj):
+ """NOT_RPYTHON
+ Get the original RPython instance from the wrapper object.
+ """
+ return rpython_data.__get__(wrapperobj)
class Entry(ExtRegistryEntry):
@@ -298,3 +305,18 @@
classdef = rtyper.annotator.bookkeeper.getuniqueclassdef(rpython_cls)
r_inst = getinstancerepr(rtyper, classdef)
return build_pytypeobject(r_inst)
+
+
+class Entry(ExtRegistryEntry):
+ """Support for translating prebuilt emulated type objects."""
+ _metatype_ = rpython_meta
+
+ def get_ll_pyobjectptr(self, rtyper):
+ from pypy.rpython.rclass import getinstancerepr
+ wrapperobj = self.instance
+ rpython_obj = get_rpython_data(wrapperobj)
+ rpython_cls = rpython_obj.__class__
+ classdef = rtyper.annotator.bookkeeper.getuniqueclassdef(rpython_cls)
+ r_inst = getinstancerepr(rtyper, classdef)
+ pyobj = r_inst.convert_const(rpython_obj)
+ return lltype.cast_pointer(PyObjPtr, pyobj)
Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py (original)
+++ pypy/dist/pypy/translator/c/node.py Sun Jul 9 18:31:50 2006
@@ -771,11 +771,13 @@
def pyobj_initexpr(self):
parent, parentindex = parentlink(self.obj)
- assert typeOf(parent)._hints.get('inline_head')
typenode = self.db.getcontainernode(self.obj.ob_type._obj)
typenode.where_to_copy_me.append('(PyObject **) & %s.ob_type' % (
self.name,))
- return 'PyObject_HEAD_INIT(NULL)'
+ if typeOf(parent)._hints.get('inline_head'):
+ return 'PyObject_HEAD_INIT(NULL)'
+ else:
+ return '{ PyObject_HEAD_INIT(NULL) },'
def objectnode_factory(db, T, obj):
More information about the Pypy-commit
mailing list