[pypy-svn] r23921 - in pypy/dist/pypy/rpython/rctypes: . test

goden at codespeak.net goden at codespeak.net
Thu Mar 2 18:37:03 CET 2006


Author: goden
Date: Thu Mar  2 18:36:54 2006
New Revision: 23921

Modified:
   pypy/dist/pypy/rpython/rctypes/rprimitive.py
   pypy/dist/pypy/rpython/rctypes/test/test_rprimitive.py
Log:
(arigo, goden) - can now set the ".value" attribute of CTypes primitive types.  Refactored the PrimitiveRepr to move duplicate llops to helper functions.



Modified: pypy/dist/pypy/rpython/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rprimitive.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rprimitive.py	Thu Mar  2 18:36:54 2006
@@ -3,7 +3,7 @@
 from ctypes import c_double, c_char_p
 from pypy.annotation import model as annmodel
 from pypy.rpython import extregistry
-from pypy.rpython.rmodel import Repr
+from pypy.rpython.rmodel import Repr, inputconst
 from pypy.rpython.lltypesystem import lltype
 from pypy.annotation.pairtype import pairtype
 from pypy.rpython.rmodel import IntegerRepr
@@ -25,44 +25,70 @@
 ]
 
 class PrimitiveRepr(Repr):
-    def __init__(self, rtyper, type, ll_type):
+    def __init__(self, rtyper, ctype, ll_type):
+        self.ctype = ctype
         self.ll_type = ll_type
         self.lowleveltype = lltype.Ptr(
-            lltype.GcStruct( "CtypesBox_%s" % (type.__name__,),
-                ( "c_data", lltype.Struct('C_Data_%s' % (type.__name__,),
+            lltype.GcStruct( "CtypesBox_%s" % (ctype.__name__,),
+                ( "c_data", lltype.Struct('C_Data_%s' % (ctype.__name__,),
                     ('value', ll_type) )
                 )
             )
         )
 
+        self.const_cache = {} # store generated const values+original value
+
+    def get_c_data(self, llops, v_primitive):
+        inputargs = [v_primitive, inputconst(lltype.Void, "c_data")]
+        return llops.genop('getsubstruct', inputargs,
+                    lltype.Ptr(self.lowleveltype.TO.c_data) )
+
+    def setfield(self, llops, v_primitive, v_value):
+        v_c_data = self.get_c_data(llops, v_primitive)
+        cname = inputconst(lltype.Void, 'value')
+        llops.genop('setfield', [v_c_data, cname, v_value])
+
+    def getfield(self, llops, v_primitive):
+        v_c_data = self.get_c_data(llops, v_primitive)
+
+        cname = inputconst(lltype.Void, 'value')
+        return llops.genop('getfield', [v_c_data, cname],
+                resulttype=self.ll_type)
+
+    def convert_const(self, ctype_value):
+        assert isinstance(ctype_value, self.ctype)
+        key = id(ctype_value)
+        try:
+            return self.const_cache[key][0]
+        except KeyError:
+            p = lltype.malloc(self.lowleveltype.TO)
+            
+            self.const_cache[key] = p, ctype_value
+            p.c_data.value = ctype_value.value
+            return p
+        
     def rtype_getattr(self, hop):
         s_attr = hop.args_s[1]
         assert s_attr.is_constant()
         assert s_attr.const == 'value'
         v_primitive = hop.inputarg(self, 0)
-        cname = hop.inputconst(lltype.Void, 'value')
-        inputargs = [v_primitive, hop.inputconst(lltype.Void, "c_data")]
-        v_c_data = hop.genop('getsubstruct',
-                    inputargs,
-                    lltype.Ptr(self.lowleveltype.TO.c_data) )
-
-        return hop.genop('getfield', [v_c_data, cname],
-                resulttype=self.ll_type)
+        return self.getfield(hop.llops, v_primitive)
 
+    def rtype_setattr(self, hop):
+        s_attr = hop.args_s[1]
+        assert s_attr.is_constant()
+        assert s_attr.const == 'value'
+        v_primitive, v_attr, v_value = hop.inputargs(self, lltype.Void,
+                                                        self.ll_type)
+        self.setfield(hop.llops, v_primitive, v_value)
 
 def primitive_specialize_call(hop):
     r_primitive = hop.r_result
     c1 = hop.inputconst(lltype.Void, r_primitive.lowleveltype.TO) 
     v_result = hop.genop("malloc", [c1], resulttype=r_primitive.lowleveltype)
-    inputargs = [v_result, hop.inputconst(lltype.Void, "c_data")]
-    v_c_data = hop.genop('getsubstruct',
-                inputargs,
-                lltype.Ptr(r_primitive.lowleveltype.TO.c_data) )
-    cname = hop.inputconst(lltype.Void, 'value')
     if len(hop.args_s):
         v_value, = hop.inputargs(r_primitive.ll_type)
-
-        hop.genop('setfield', [v_c_data, cname, v_value])
+        r_primitive.setfield(hop.llops, v_result, v_value)
     return v_result
 
 def do_register(the_type, ll_type):

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rprimitive.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rprimitive.py	Thu Mar  2 18:36:54 2006
@@ -35,7 +35,7 @@
         if conftest.option.view:
             t.view()
 
-    def test_annotate_c_int_2(self):
+    def test_annotate_prebuilt_c_int(self):
         res = c_int(42)
 
         def func():
@@ -50,6 +50,22 @@
         if conftest.option.view:
             t.view()
 
+    def test_annotate_set_c_int_value(self):
+        def func():
+            res = c_int(42)
+            res.value = 52
+
+            return res.value
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(func, [])
+
+        assert s.knowntype == int
+
+        if conftest.option.view:
+            t.view()
+
 class Test_specialization:
     def test_specialize_c_int(self):
         def create_c_int():
@@ -71,9 +87,43 @@
         res = interpret(create_c_int, [])
         assert res == 42
 
+    def test_specialize_c_int_set_value(self):
+        def set_c_int_value():
+            ci = c_int(42)
+            ci.value = 52
+            return ci.value
+
+        res = interpret(set_c_int_value, [])
+        assert res == 52
+
+    def test_specialize_access_prebuilt_c_int_value(self):
+        ci = c_int(42)
+        def access_cint():
+            return ci.value
+
+        res = interpret(access_cint, [])
+        assert res == 42
+
 class Test_compilation:
     def test_compile_c_int(self):
         def create_c_int():
             return c_int(42).value
         fn = compile(create_c_int, [])
         assert fn() == 42
+
+    def test_compile_prebuilt_c_int(self):
+        ci = c_int(42)
+        def access_cint():
+            return ci.value
+
+        fn = compile(access_cint, [])
+        assert fn() == 42
+
+    def test_compile_set_prebuilt_c_int_value(self):
+        ci = c_int(42)
+        def access_cint():
+            ci.value = 52
+            return ci.value
+
+        fn = compile(access_cint, [])
+        assert fn() == 52



More information about the Pypy-commit mailing list