[pypy-svn] r29905 - in pypy/dist/pypy: module/_demo objspace/cpy rpython rpython/rctypes translator/c translator/c/src

arigo at codespeak.net arigo at codespeak.net
Sun Jul 9 17:38:27 CEST 2006


Author: arigo
Date: Sun Jul  9 17:38:20 2006
New Revision: 29905

Modified:
   pypy/dist/pypy/module/_demo/__init__.py
   pypy/dist/pypy/objspace/cpy/typedef.py
   pypy/dist/pypy/rpython/rcpy.py
   pypy/dist/pypy/rpython/rctypes/rpyobject.py
   pypy/dist/pypy/translator/c/database.py
   pypy/dist/pypy/translator/c/pyobj.py
   pypy/dist/pypy/translator/c/src/module.h
Log:
(pedronis, arigo)

Make exporting type objects from CPython-compiled mixedmodules work.


Modified: pypy/dist/pypy/module/_demo/__init__.py
==============================================================================
--- pypy/dist/pypy/module/_demo/__init__.py	(original)
+++ pypy/dist/pypy/module/_demo/__init__.py	Sun Jul  9 17:38:20 2006
@@ -6,7 +6,7 @@
     interpleveldefs = {
         'measuretime'      : 'demo.measuretime',
         'sieve'            : 'demo.sieve',
-        #'MyType'           : 'demo.W_MyType'
+        'MyType'           : 'demo.W_MyType',
     }
 
     appleveldefs = {

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 17:38:20 2006
@@ -10,25 +10,11 @@
 from pypy.interpreter.typedef import GetSetProperty
 from pypy.rpython.objectmodel import we_are_translated
 from pypy.rpython.rcpy import CPyTypeInterface, cpy_export, cpy_import
-from pypy.rpython.rcpy import cpy_typeobject
+from pypy.rpython.rcpy import cpy_typeobject, rpython_object
+from pypy.rpython.rcpy import init_rpython_data, get_rpython_data
 from pypy.rpython.lltypesystem import lltype
 
 
-class rpython_object(object):
-    "NOT_RPYTHON"
-    __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 rpython2cpython(space, x):
     cache = space.fromcache(TypeDefCache)
     typeintf = cache.getorbuild(x.typedef)
@@ -38,7 +24,7 @@
     else:
         w_x = x.__cpy_wrapper__
         if w_x is None:
-            w_type = cache.wraptypeintf(x.typedef, typeintf)
+            w_type = cache.wraptypeintf(x, typeintf)
             w_x = W_Object(rpython_object.__new__(w_type.value))
             init_rpython_data(w_x, x)
         return w_x
@@ -52,7 +38,7 @@
         cpytype = cpy_typeobject(typeintf, Cls)
         return W_Object(cpytype)        
     else:
-        return cache.wraptypeintf(Cls.typedef, typeintf)
+        return cache.wraptypeintf(Cls, typeintf)
 rpython2cpytype.allow_someobjects = True
 rpython2cpytype._annspecialcase_ = "specialize:arg(1)"
     
@@ -113,16 +99,17 @@
         typeintf = CPyTypeInterface(typedef.name, objects)
         return typeintf
 
-    def wraptypeintf(cache, typedef, typeintf):
+    def wraptypeintf(cache, cls, typeintf):
         "NOT_RPYTHON.  Not available after translation."
         try:
-            return cache.wrappedtypes[typeintf]
+            return cache.wrappedtypes[cls]
         except KeyError:
+            typedef = cls.typedef
             space = cache.space
-            newtype = typeintf.emulate(rpython_object)
+            newtype = typeintf.emulate(cls)
             w_result = W_Object(newtype)
             space.wrap_cache[id(w_result)] = w_result, typedef, follow_annotations
-            cache.wrappedtypes[typeintf] = w_result
+            cache.wrappedtypes[cls] = w_result
             return w_result
 
 def follow_annotations(bookkeeper, w_type):

Modified: pypy/dist/pypy/rpython/rcpy.py
==============================================================================
--- pypy/dist/pypy/rpython/rcpy.py	(original)
+++ pypy/dist/pypy/rpython/rcpy.py	Sun Jul  9 17:38:20 2006
@@ -20,14 +20,14 @@
     def _freeze_(self):
         return True
 
-    def emulate(self, rootbase):
+    def emulate(self, original_class):
         "Build a type object that emulates 'self'."
-        d = {'__slots__': []}
+        d = {'__slots__': [], '_rpython_class_': original_class}
         for name, value in self.objects.items():
             assert lltype.typeOf(value) == PyObjPtr
             assert isinstance(value._obj, lltype._pyobject)
             d[name] = value._obj.value
-        t = type(self.name, (rootbase,), d)
+        t = type(self.name, (rpython_object,), d)
         return t
 
 
@@ -261,3 +261,40 @@
 # for CPython's GC (see PyObject_GC_Malloc); it needs to Py_INCREF the
 # type if it's a heap type; and it needs to PyObject_GC_Track() the object.
 # Also, tp_dealloc needs to untrack the object.
+
+
+# ____________________________________________________________
+# Emulation support, to have user-defined classes and instances
+# work nicely on top of CPython running the CPyObjSpace
+
+class rpython_meta(type):
+    pass
+
+class rpython_object(object):
+    "NOT_RPYTHON"
+    __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)
+
+
+class Entry(ExtRegistryEntry):
+    """Support for translating prebuilt emulated type objects."""
+    _type_ = rpython_meta
+
+    def get_ll_pyobjectptr(self, rtyper):
+        from pypy.rpython.rclass import getinstancerepr
+        emulated_cls = self.instance
+        rpython_cls = emulated_cls._rpython_class_
+        classdef = rtyper.annotator.bookkeeper.getuniqueclassdef(rpython_cls)
+        r_inst = getinstancerepr(rtyper, classdef)
+        return build_pytypeobject(r_inst)

Modified: pypy/dist/pypy/rpython/rctypes/rpyobject.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpyobject.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rpyobject.py	Sun Jul  9 17:38:20 2006
@@ -3,6 +3,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.rctypes.rmodel import CTypesValueRepr
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
+from pypy.rpython import extregistry
 
 
 class CTypesPyObjRepr(CTypesValueRepr):
@@ -16,6 +17,11 @@
     def initialize_const(self, p, value):
         if isinstance(value, self.ctype):
             value = value.value
+        if extregistry.is_registered(value):
+            entry = extregistry.lookup(value)
+            if hasattr(entry, 'get_ll_pyobjectptr'):
+                p.c_data[0] = entry.get_ll_pyobjectptr(self.rtyper)
+                return
         p.c_data[0] = lltype.pyobjectptr(value)
 
     def rtype_getattr(self, hop):

Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Sun Jul  9 17:38:20 2006
@@ -44,7 +44,7 @@
         self.namespace = CNameManager()
         if not standalone:
             from pypy.translator.c.pyobj import PyObjMaker
-            self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator)
+            self.pyobjmaker = PyObjMaker(self.namespace, self, translator)
 
         gcpolicy = gcpolicy or conftest.option.gcpolicy or 'ref'
         if isinstance(gcpolicy, str):

Modified: pypy/dist/pypy/translator/c/pyobj.py
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj.py	(original)
+++ pypy/dist/pypy/translator/c/pyobj.py	Sun Jul  9 17:38:20 2006
@@ -26,9 +26,9 @@
     reconstruct them.
     """
 
-    def __init__(self, namespace, getvalue, translator=None):
+    def __init__(self, namespace, db, translator=None):
         self.namespace = namespace
-        self.getvalue = getvalue
+        self.db = db
         self.translator = translator
         self.initcode = [      # list of lines for the module's initxxx()
             'import new, types, sys',
@@ -52,10 +52,21 @@
             stackentry = obj
         self.debugstack = (self.debugstack, stackentry)
         try:
-            return self.getvalue(pyobjectptr(obj))
+            try:
+                self.translator.rtyper   # check for presence
+                entry = extregistry.lookup(obj)
+                getter = entry.get_ll_pyobjectptr
+            except (KeyError, AttributeError):
+                # common case: 'p' is a _pyobject
+                p = pyobjectptr(obj)
+            else:
+                # 'p' should be a PyStruct pointer, i.e. a _pyobjheader
+                p = getter(self.translator.rtyper)
+            node = self.db.getcontainernode(p._obj)
         finally:
             self.debugstack, x = self.debugstack
             assert x is stackentry
+        return node.exported_name
 
     def computenameof(self, obj):
         obj_builtin_base = builtin_base(obj)
@@ -225,7 +236,7 @@
         except NoStandardGraph:
             return self.skipped_function(func)
         pycfunctionobj = self.uniquename('gfunc_' + func.__name__)
-        self.wrappers[pycfunctionobj] = func.__name__, self.getvalue(fwrapper), func.__doc__
+        self.wrappers[pycfunctionobj] = func.__name__, self.db.get(fwrapper), func.__doc__
         return pycfunctionobj
 
     def import_function(self, func):
@@ -622,7 +633,7 @@
         fwrapper = gen_wrapper(g, self.translator, newname=newname,
                                as_method=g in self.is_method)
         pycfunctionobj = self.uniquename('gfunc_' + newname)
-        self.wrappers[pycfunctionobj] = g.func.__name__, self.getvalue(fwrapper), g.func.__doc__
+        self.wrappers[pycfunctionobj] = g.func.__name__, self.db.get(fwrapper), g.func.__doc__
         return pycfunctionobj
 
     def nameof_property(self, p):

Modified: pypy/dist/pypy/translator/c/src/module.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/module.h	(original)
+++ pypy/dist/pypy/translator/c/src/module.h	Sun Jul  9 17:38:20 2006
@@ -38,6 +38,8 @@
 	} \
 	if (setup_globalfunctions(globalfunctiondefs, #modname) < 0) \
 		return;	\
+	if (setup_exportglobalobjects(cpyobjheaddefs) < 0)	\
+		return;	\
 	if (setup_initcode(frozen_initcode, FROZEN_INITCODE_SIZE) < 0) \
 		return;	\
 	if (setup_globalobjects(globalobjectdefs, cpyobjheaddefs) < 0) \
@@ -75,11 +77,9 @@
 
 #ifndef PYPY_NOT_MAIN_FILE
 
-static int setup_globalobjects(globalobjectdef_t* globtable,
-			       cpyobjheaddef_t* cpyheadtable)
+static int setup_exportglobalobjects(cpyobjheaddef_t* cpyheadtable)
 {
 	PyObject* obj;
-	globalobjectdef_t* def;
 	cpyobjheaddef_t* cpydef;
 
 	/* Store the object given by their heads into the module's dict.
@@ -93,6 +93,16 @@
 					 cpydef->name, obj) < 0)
 			return -1;
 	}
+	return 0;
+}
+
+static int setup_globalobjects(globalobjectdef_t* globtable,
+			       cpyobjheaddef_t* cpyheadtable)
+{
+	PyObject* obj;
+	globalobjectdef_t* def;
+	cpyobjheaddef_t* cpydef;
+
 	/* Patch all locations that need to contain a specific PyObject*.
 	   This must go after the previous loop, otherwise
 	   PyDict_GetItemString() might not find some of them.



More information about the Pypy-commit mailing list