[pypy-svn] r16188 - in pypy/dist/pypy: module/thread/rpython module/thread/rpython/test rpython rpython/module

arigo at codespeak.net arigo at codespeak.net
Mon Aug 22 12:23:53 CEST 2005


Author: arigo
Date: Mon Aug 22 12:23:49 2005
New Revision: 16188

Modified:
   pypy/dist/pypy/module/thread/rpython/exttable.py
   pypy/dist/pypy/module/thread/rpython/ll_thread.py
   pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py
   pypy/dist/pypy/rpython/annlowlevel.py
   pypy/dist/pypy/rpython/exceptiondata.py
   pypy/dist/pypy/rpython/extfunctable.py
   pypy/dist/pypy/rpython/lltype.py
   pypy/dist/pypy/rpython/module/support.py
   pypy/dist/pypy/rpython/rexternalobj.py
   pypy/dist/pypy/rpython/rspecialcase.py
Log:
Reorganized the low-level representation of "external types" to take advantage
of the memory management that GcStruct provides.  Now an object like a
thread.lock is implemented as a GcStruct with a single field "obj" that is an
inlined Opaque object.

* updated lltype.py to allow Opaque objects to be inlined in structures.

* allow thread.rpython.exttable to register a new standard exception,
  thread.error, raised by the release() method of locks.

* thread.rpython.ll_thread: each function is divided in two functions, one
  that does the mallocing of the GcStruct for locks, or that reads the "obj"
  field of the GcStruct, and another that is the suggested_primitive, 
  operating on the opaque object.



Modified: pypy/dist/pypy/module/thread/rpython/exttable.py
==============================================================================
--- pypy/dist/pypy/module/thread/rpython/exttable.py	(original)
+++ pypy/dist/pypy/module/thread/rpython/exttable.py	Mon Aug 22 12:23:49 2005
@@ -3,18 +3,18 @@
 """
 
 import thread
-from pypy.rpython.extfunctable import declare, declaretype
+from pypy.rpython.extfunctable import declare, declaretype, standardexceptions
 
 module = 'pypy.module.thread.rpython.ll_thread'
 
 # ____________________________________________________________
 # The external type thread.LockType
 
-declaretype(thread.LockType,
-            "ThreadLock",
-            acquire = (bool,       '%s/acquire_lock' % module),
-            release = (type(None), '%s/release_lock' % module),
-            )
+locktypeinfo = declaretype(thread.LockType,
+                           "ThreadLock",
+                           acquire = (bool,       '%s/acquire_lock' % module),
+                           release = (type(None), '%s/release_lock' % module),
+                           )
 
 # ____________________________________________________________
 # Built-in functions needed in the rtyper
@@ -22,3 +22,9 @@
 declare(thread.start_new_thread, int,            '%s/start_new_thread' % module)
 declare(thread.get_ident,        int,            '%s/get_ident'        % module)
 declare(thread.allocate_lock,   thread.LockType, '%s/allocate_lock'    % module)
+
+# ____________________________________________________________
+# thread.error can be raised by the above
+
+# XXX a bit hackish
+standardexceptions[thread.error] = True

Modified: pypy/dist/pypy/module/thread/rpython/ll_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/rpython/ll_thread.py	(original)
+++ pypy/dist/pypy/module/thread/rpython/ll_thread.py	Mon Aug 22 12:23:49 2005
@@ -4,7 +4,12 @@
 """
 
 import thread
-from pypy.rpython.module.support import from_rexternalobj, to_rexternalobj
+from pypy.rpython.lltype import malloc
+from pypy.rpython.module.support import init_opaque_object, from_opaque_object
+from pypy.module.thread.rpython.exttable import locktypeinfo
+
+LOCKCONTAINERTYPE = locktypeinfo.get_lltype()
+
 
 def ll_thread_start_new_thread(funcptr, argtuple):
     # wrapper around ll_thread_start, to extract the single argument
@@ -21,17 +26,27 @@
 ll_thread_get_ident.suggested_primitive = True
 
 
-def ll_thread_allocate_lock():
-    lock = thread.allocate_lock()
-    return to_rexternalobj(lock)
-ll_thread_allocate_lock.suggested_primitive = True
+def newlock(opaqueptr):
+    init_opaque_object(opaqueptr, thread.allocate_lock())
+newlock.suggested_primitive = True
 
-def ll_thread_acquire_lock(lockptr, waitflag):
-    lock = from_rexternalobj(lockptr)
+def acquirelock(opaqueptr, waitflag):
+    lock = from_opaque_object(opaqueptr)
     return lock.acquire(waitflag)
-ll_thread_acquire_lock.suggested_primitive = True
+acquirelock.suggested_primitive = True
 
-def ll_thread_release_lock(lockptr):
-    lock = from_rexternalobj(lockptr)
+def releaselock(opaqueptr):
+    lock = from_opaque_object(opaqueptr)
     lock.release()
-ll_thread_release_lock.suggested_primitive = True
+releaselock.suggested_primitive = True
+
+def ll_thread_allocate_lock():
+    lockcontainer = malloc(LOCKCONTAINERTYPE)
+    newlock(lockcontainer.obj)
+    return lockcontainer
+
+def ll_thread_acquire_lock(lockcontainer, waitflag):
+    return acquirelock(lockcontainer.obj, waitflag)
+
+def ll_thread_release_lock(lockcontainer):
+    releaselock(lockcontainer.obj)

Modified: pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py	(original)
+++ pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py	Mon Aug 22 12:23:49 2005
@@ -23,3 +23,15 @@
         return ok1 and not ok2 and ok3
     res = interpret(fn, [])
     assert res is True
+
+def test_thread_error():
+    def fn():
+        l = thread.allocate_lock()
+        try:
+            l.release()
+        except thread.error:
+            return True
+        else:
+            return False
+    res = interpret(fn, [])
+    assert res is True

Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Mon Aug 22 12:23:49 2005
@@ -56,17 +56,18 @@
                     key.append(s_obj.__class__)
         return tuple(key), bookkeeper.build_args('simple_call', new_args_s)
 
-    def override__to_rexternalobj(pol, s_obj):
-        assert isinstance(s_obj, annmodel.SomeExternalObject)
-        exttypeinfo = extfunctable.typetable[s_obj.knowntype]
-        OPAQUE = exttypeinfo.get_opaque_lltype()
-        return annmodel.SomePtr(lltype.Ptr(OPAQUE))
+    def override__init_opaque_object(pol, s_opaqueptr, s_value):
+        assert isinstance(s_opaqueptr, annmodel.SomePtr)
+        assert isinstance(s_opaqueptr.ll_ptrtype.TO, lltype.OpaqueType)
+        assert isinstance(s_value, annmodel.SomeExternalObject)
+        exttypeinfo = extfunctable.typetable[s_value.knowntype]
+        assert s_opaqueptr.ll_ptrtype.TO._exttypeinfo == exttypeinfo
+        return annmodel.SomeExternalObject(exttypeinfo.typ)
 
-    def override__from_rexternalobj(pol, s_objptr):
-        assert isinstance(s_objptr, annmodel.SomePtr)
-        OPAQUE = s_objptr.ll_ptrtype.TO
-        assert isinstance(OPAQUE, lltype.OpaqueType)
-        exttypeinfo = OPAQUE.exttypeinfo
+    def override__from_opaque_object(pol, s_opaqueptr):
+        assert isinstance(s_opaqueptr, annmodel.SomePtr)
+        assert isinstance(s_opaqueptr.ll_ptrtype.TO, lltype.OpaqueType)
+        exttypeinfo = s_opaqueptr.ll_ptrtype.TO._exttypeinfo
         return annmodel.SomeExternalObject(exttypeinfo.typ)
 
 

Modified: pypy/dist/pypy/rpython/exceptiondata.py
==============================================================================
--- pypy/dist/pypy/rpython/exceptiondata.py	(original)
+++ pypy/dist/pypy/rpython/exceptiondata.py	Mon Aug 22 12:23:49 2005
@@ -3,15 +3,12 @@
 from pypy.rpython.annlowlevel import annotate_lowlevel_helper
 from pypy.rpython.lltype import Array, malloc, Ptr, PyObject, pyobjectptr
 from pypy.rpython.lltype import FuncType, functionptr, Signed
+from pypy.rpython.extfunctable import standardexceptions
 
 
 class ExceptionData:
     """Public information for the code generators to help with exceptions."""
 
-    # the exceptions that can be implicitely raised by some operations
-    standardexceptions = [TypeError, OverflowError, ValueError,
-                          ZeroDivisionError, MemoryError, IOError]
-
     def __init__(self, rtyper):
         self.make_standard_exceptions(rtyper)
         # (NB. rclass identifies 'Exception' and 'object')
@@ -35,7 +32,7 @@
 
     def make_standard_exceptions(self, rtyper):
         bk = rtyper.annotator.bookkeeper
-        for cls in self.standardexceptions:
+        for cls in standardexceptions:
             classdef = bk.getclassdef(cls)
             rclass.getclassrepr(rtyper, classdef).setup()
 
@@ -72,7 +69,14 @@
             if (clsdef and clsdef.cls is not Exception
                 and issubclass(clsdef.cls, Exception)):
                 cls = clsdef.cls
-                if cls.__module__ == 'exceptions' and not clsdef.attrs:
+                if cls in standardexceptions:
+                    is_standard = True
+                    assert not clsdef.attrs, (
+                        "%r should not have grown atributes" % (cls,))
+                else:
+                    is_standard = (cls.__module__ == 'exceptions'
+                                   and not clsdef.attrs)
+                if is_standard:
                     r_inst = rclass.getinstancerepr(rtyper, clsdef)
                     r_inst.setup()
                     example = malloc(r_inst.lowleveltype.TO, immortal=True)

Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py	(original)
+++ pypy/dist/pypy/rpython/extfunctable.py	Mon Aug 22 12:23:49 2005
@@ -31,7 +31,7 @@
     def __init__(self, typ, tag, methods):
         self.typ = typ
         self.tag = tag
-        self.TYPE = None
+        self._TYPE = None
         self.methods = methods     # {'name': ExtFuncInfo()}
 
     def get_annotation(self, methodname):
@@ -46,13 +46,14 @@
             if extfuncinfo.func is not None:
                 yield (extfuncinfo.func, extfuncinfo)
 
-    def get_opaque_lltype(self):
-        if self.TYPE is None:
+    def get_lltype(self):
+        if self._TYPE is None:
             from pypy.rpython import lltype
             OPAQUE = lltype.OpaqueType(self.tag)
-            OPAQUE.exttypeinfo = self
-            self.TYPE = OPAQUE
-        return self.TYPE
+            OPAQUE._exttypeinfo = self
+            STRUCT = lltype.GcStruct(self.tag, ('obj', OPAQUE))
+            self._TYPE = STRUCT
+        return self._TYPE
 
 
 class ImportMe:
@@ -185,3 +186,14 @@
 declare(rarithmetic.parts_to_float, float, 'll_strtod/parts_to_float')
 # float->string helper
 declare(rarithmetic.formatd, str, 'll_strtod/formatd')
+
+# ___________________________________________________________
+# the exceptions that can be implicitely raised by some operations
+standardexceptions = {
+    TypeError        : True,
+    OverflowError    : True,
+    ValueError       : True,
+    ZeroDivisionError: True,
+    MemoryError      : True,
+    IOError          : True,
+    }

Modified: pypy/dist/pypy/rpython/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltype.py	Mon Aug 22 12:23:49 2005
@@ -275,6 +275,15 @@
     def __str__(self):
         return "%s (opaque)" % self.tag
 
+    def _inline_is_varsize(self, last):
+        return False    # OpaqueType can be inlined
+
+    def _container_example(self):
+        return _opaque(self)
+
+    def _defl(self, parent=None, parentindex=None):
+        return self._container_example()
+
 RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo")
 
 class PyObjectType(ContainerType):

Modified: pypy/dist/pypy/rpython/module/support.py
==============================================================================
--- pypy/dist/pypy/rpython/module/support.py	(original)
+++ pypy/dist/pypy/rpython/module/support.py	Mon Aug 22 12:23:49 2005
@@ -20,12 +20,12 @@
         dstchars[i] = srcchars[i]
         i += 1
 
-def to_rexternalobj(obj):
-    exttypeinfo = extfunctable.typetable[type(obj)]
-    OPAQUE = exttypeinfo.get_opaque_lltype()
-    return lltype.opaqueptr(OPAQUE, name=None, externalobj=obj)
-to_rexternalobj._annspecialcase_ = "override:to_rexternalobj"
+def init_opaque_object(opaqueptr, value):
+    "NOT_RPYTHON"
+    opaqueptr._obj.externalobj = value
+init_opaque_object._annspecialcase_ = "override:init_opaque_object"
 
-def from_rexternalobj(objptr):
-    return objptr._obj.externalobj
-from_rexternalobj._annspecialcase_ = "override:from_rexternalobj"
+def from_opaque_object(opaqueptr):
+    "NOT_RPYTHON"
+    return opaqueptr._obj.externalobj
+from_opaque_object._annspecialcase_ = "override:from_opaque_object"

Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py	(original)
+++ pypy/dist/pypy/rpython/rexternalobj.py	Mon Aug 22 12:23:49 2005
@@ -18,8 +18,8 @@
 
     def __init__(self, knowntype):
         self.exttypeinfo = typetable[knowntype]
-        OPAQUE = self.exttypeinfo.get_opaque_lltype()
-        self.lowleveltype = lltype.Ptr(OPAQUE)
+        TYPE = self.exttypeinfo.get_lltype()
+        self.lowleveltype = lltype.Ptr(TYPE)
         # The set of methods supported depends on 'knowntype', so we
         # cannot have rtype_method_xxx() methods directly on the
         # ExternalObjRepr class.  But we can store them in 'self' now.

Modified: pypy/dist/pypy/rpython/rspecialcase.py
==============================================================================
--- pypy/dist/pypy/rpython/rspecialcase.py	(original)
+++ pypy/dist/pypy/rpython/rspecialcase.py	Mon Aug 22 12:23:49 2005
@@ -33,5 +33,10 @@
     v, = hop.inputargs(hop.args_r[0])
     return v
 
-rtype_override_to_rexternalobj   = rtype_identity_function
-rtype_override_from_rexternalobj = rtype_identity_function
+def rtype_override_init_opaque_object(hop, clsdef):
+    return hop.genop('init_opaque_object_should_never_be_seen_by_the_backend',
+                     [], resulttype=hop.r_result)
+
+def rtype_override_from_opaque_object(hop, clsdef):
+    return hop.genop('from_opaque_object_should_never_be_seen_by_the_backend',
+                     [], resulttype=hop.r_result)



More information about the Pypy-commit mailing list