[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