[pypy-svn] r22616 - in pypy/dist/pypy: annotation rpython rpython/l3interp rpython/l3interp/test translator/c/src

ac at codespeak.net ac at codespeak.net
Tue Jan 24 18:40:58 CET 2006


Author: ac
Date: Tue Jan 24 18:40:57 2006
New Revision: 22616

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/rpython/l3interp/convertgraph.py
   pypy/dist/pypy/rpython/l3interp/l3interp.py
   pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/translator/c/src/mem.h
Log:
(arre,mwh)
Refactor l3interp.convertgraph.convert_block to mostly be methods on a 
BlockConverter class.
A test and a very naive implementation depending very very much on
the Boehm GC for the l3 operation 'malloc'.


Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Tue Jan 24 18:40:57 2006
@@ -511,6 +511,11 @@
 
 BUILTIN_ANALYZERS[llmemory.offsetof] = offsetof
 
+from pypy.rpython.l3interp import l3interp
+def l3malloc(size):
+    return SomeAddress()
+
+BUILTIN_ANALYZERS[l3interp.malloc] = l3malloc
 
 #_________________________________
 # external functions

Modified: pypy/dist/pypy/rpython/l3interp/convertgraph.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/convertgraph.py	(original)
+++ pypy/dist/pypy/rpython/l3interp/convertgraph.py	Tue Jan 24 18:40:57 2006
@@ -49,30 +49,36 @@
             raise Exception("don't know how to acess %s value"%T)
     else:
         return 'ptr'
-
 def convert_block(block, memo):
     if block in memo:
         return memo[block]
+    converter = BlockConverter(block, memo)
+    return converter.convert()
+
+class BlockConverter:
 
-    stacksizes = {'int': 0,
-                  'dbl': 0,
-                  'ptr': 0}
-    constants = {'int': [],
-                 'dbl': [],
-                 'ptr': [],
-                 'offset':[]}
-    var2stack = {}
+    def __init__(self, block, memo):
+        self.block = block
+        self.memo = memo
+        self.stacksizes = {'int': 0,
+                           'dbl': 0,
+                           'ptr': 0}
+        self.constants = {'int': [],
+                          'dbl': [],
+                          'ptr': [],
+                          'offset':[]}
+        self.var2stack = {}
 
-    def push(v):
+    def push(self, v):
         kind = getkind(v.concretetype)
-        position = stacksizes[kind]
-        stacksizes[kind] += 1
-        var2stack[v] = position
+        position = self.stacksizes[kind]
+        self.stacksizes[kind] += 1
+        self.var2stack[v] = position
 
-    def get(v):
+    def get(self, v):
         kind = getkind(v.concretetype)
         if isinstance(v, flowmodel.Constant):
-            clist = constants[kind]
+            clist = self.constants[kind]
             if kind == 'ptr':
                 value = fakeaddress(v.value)
             else:
@@ -84,11 +90,11 @@
                 clist.append(value)
             return res
         else:
-            position = var2stack[v]
-            return position - stacksizes[kind]    # < 0
+            position = self.var2stack[v]
+            return position - self.stacksizes[kind]    # < 0
 
-    def getoffset(offset):
-        clist = constants['offset']
+    def getoffset(self, offset):
+        clist = self.constants['offset']
         try:
             res = clist.index(offset)
         except ValueError:
@@ -96,118 +102,142 @@
             clist.append(offset)
         return res
 
-    for v in block.inputargs:
-        if v.concretetype is not lltype.Void:
-            push(v)
-
-    insns = []
-    l3block = model.Block(insns)
-    memo[block] = l3block
-
-    if block.operations == ():
-        if len(block.inputargs) == 1:  # return block
-            if block.inputargs[0].concretetype is lltype.Void:
-                l3block.insns.append(Op.void_return)
-            else:
-                kind = getkind(block.inputargs[0].concretetype)
-                l3block.insns.append(model.very_low_level_opcode[
-                    {'int': 'int_return',
-                     'dbl': 'float_return',
-                     'ptr': 'adr_return'}[kind]])
-                l3block.insns.append(-1)
-        else:
-            raise NotImplementedError("except block")
-        return l3block
-
-    for spaceop in block.operations:
-        if spaceop.opname == 'getfield':
-            opname = spaceop.opname + '_' + \
-                     getaccesskind(spaceop.result.concretetype)
-            insns.append(model.very_low_level_opcode[opname])
-            v0, v1 = spaceop.args
-            insns.append(get(v0))
-
-            offset = FieldOffset(v0.concretetype, v1.value)
-            insns.append(getoffset(offset))
-        elif spaceop.opname == 'setfield':
-            v0, v1, v2 = spaceop.args
-            opname = spaceop.opname + '_' + \
-                     getaccesskind(v2.concretetype)
-            insns.append(model.very_low_level_opcode[opname])
-            insns.append(get(v0))
-
-            offset = FieldOffset(v0.concretetype, v1.value)
-            insns.append(getoffset(offset))
-            insns.append(get(v2))
-        elif spaceop.opname == 'getarrayitem':
-            opname = spaceop.opname + '_' + \
-                     getaccesskind(spaceop.result.concretetype)
-            insns.append(model.very_low_level_opcode[opname])
-            v0, v1 = spaceop.args
-            insns.append(get(v0))
-            insns.append(get(v1))
-
-            offset = ArrayItemsOffset(v0.concretetype)
-            insns.append(getoffset(offset))
-
-            offset = ItemOffset(spaceop.result.concretetype)
-            insns.append(getoffset(offset))
-        elif spaceop.opname == 'setarrayitem':
-            array, index, value = spaceop.args
-            opname = spaceop.opname + '_' + \
-                     getaccesskind(value.concretetype)
-            insns.append(model.very_low_level_opcode[opname])
-            insns.append(get(array))
-            insns.append(get(index))
-
-            offset = ArrayItemsOffset(array.concretetype)
-            insns.append(getoffset(offset))
-
-            offset = ItemOffset(value.concretetype)
-            insns.append(getoffset(offset))
-            insns.append(get(value))
-        else:
-            insns.append(model.very_low_level_opcode[spaceop.opname])
-            for v in spaceop.args:
-                insns.append(get(v))
-        if spaceop.result.concretetype is not lltype.Void:
-            push(spaceop.result)
-
-    def convert_link(link):
+    def convert_link(self, link):
         targetregs = {'int': [],
                       'dbl': [],
                       'ptr': []}
         for v in link.args:
             if v.concretetype is not lltype.Void:
                 kind = getkind(v.concretetype)
-                targetregs[kind].append(get(v))
-        return model.Link(convert_block(link.target, memo),
+                targetregs[kind].append(self.get(v))
+        return model.Link(convert_block(link.target, self.memo),
                           targetregs['int'] or None,
                           targetregs['dbl'] or None,
                           targetregs['ptr'] or None)
 
-    if block.exitswitch is None:
-        insns.append(Op.jump)
-        link, = block.exits
-        l3block.exit0 = convert_link(link)
-
-    elif block.exitswitch != flowmodel.Constant(flowmodel.last_exception):
-        link0, link1 = block.exits
-        if link0.exitcase:
-            link0, link1 = link1, link0
-        assert not link0.exitcase
-        assert link1.exitcase
-        insns.append(Op.jump_cond)
-        insns.append(get(block.exitswitch))
-        l3block.exit0 = convert_link(link0)
-        l3block.exit1 = convert_link(link1)
+    def convert(self, memo=None):
+        block = self.block
+        for v in block.inputargs:
+            if v.concretetype is not lltype.Void:
+                self.push(v)
+
+        self.insns = []
+        l3block = model.Block(self.insns)
+        self.memo[block] = l3block
+
+        if block.operations == ():
+            if len(block.inputargs) == 1:  # return block
+                if block.inputargs[0].concretetype is lltype.Void:
+                    l3block.insns.append(Op.void_return)
+                else:
+                    kind = getkind(block.inputargs[0].concretetype)
+                    l3block.insns.append(model.very_low_level_opcode[
+                        {'int': 'int_return',
+                         'dbl': 'float_return',
+                         'ptr': 'adr_return'}[kind]])
+                    l3block.insns.append(-1)
+            else:
+                raise NotImplementedError("except block")
+            return l3block
 
-    else:
-        raise NotImplementedError("exceptions")
+        for spaceop in block.operations:
+            getattr(self, 'convert_'+spaceop.opname,
+                    self.default_convert)(spaceop)
+            
+        if block.exitswitch is None:
+            self.insns.append(Op.jump)
+            link, = block.exits
+            l3block.exit0 = self.convert_link(link)
+
+        elif block.exitswitch != flowmodel.Constant(flowmodel.last_exception):
+            link0, link1 = block.exits
+            if link0.exitcase:
+                link0, link1 = link1, link0
+            assert not link0.exitcase
+            assert link1.exitcase
+            self.insns.append(Op.jump_cond)
+            self.insns.append(self.get(block.exitswitch))
+            l3block.exit0 = self.convert_link(link0)
+            l3block.exit1 = self.convert_link(link1)
+
+        else:
+            raise NotImplementedError("exceptions")
+
+        if self.constants['int']: l3block.constants_int = self.constants['int']
+        if self.constants['dbl']: l3block.constants_dbl = self.constants['dbl']
+        if self.constants['ptr']: l3block.constants_ptr = self.constants['ptr']
+        if self.constants['offset']:
+            l3block.constants_offset = self.constants['offset']
+
+        return l3block
+
+    def default_convert(self, spaceop):
+        self.insns.append(model.very_low_level_opcode[spaceop.opname])
+        for v in spaceop.args:
+            self.insns.append(self.get(v))
+        if spaceop.result.concretetype is not lltype.Void:
+            self.push(spaceop.result)
 
-    if constants['int']: l3block.constants_int = constants['int']
-    if constants['dbl']: l3block.constants_dbl = constants['dbl']
-    if constants['ptr']: l3block.constants_ptr = constants['ptr']
-    if constants['offset']: l3block.constants_offset = constants['offset']
+    def convert_getfield(self, spaceop):
+        opname = spaceop.opname + '_' + \
+                 getaccesskind(spaceop.result.concretetype)
+        self.insns.append(model.very_low_level_opcode[opname])
+        v0, v1 = spaceop.args
+        self.insns.append(self.get(v0))
+
+        offset = FieldOffset(v0.concretetype, v1.value)
+        self.insns.append(self.getoffset(offset))
+        self.push(spaceop.result)
+
+    def convert_setfield(self, spaceop):
+        v0, v1, v2 = spaceop.args
+        opname = spaceop.opname + '_' + \
+                 getaccesskind(v2.concretetype)
+        self.insns.append(model.very_low_level_opcode[opname])
+        self.insns.append(self.get(v0))
+
+        offset = FieldOffset(v0.concretetype, v1.value)
+        self.insns.append(self.getoffset(offset))
+        self.insns.append(self.get(v2))
+
+    def convert_getarrayitem(self, spaceop):
+        opname = spaceop.opname + '_' + \
+                 getaccesskind(spaceop.result.concretetype)
+        self.insns.append(model.very_low_level_opcode[opname])
+        v0, v1 = spaceop.args
+        self.insns.append(self.get(v0))
+        self.insns.append(self.get(v1))
+        
+        offset = ArrayItemsOffset(v0.concretetype)
+        self.insns.append(self.getoffset(offset))
+        
+        offset = ItemOffset(spaceop.result.concretetype)
+        self.insns.append(self.getoffset(offset))
+        self.push(spaceop.result)
+
+    def convert_setarrayitem(self, spaceop):
+        array, index, value = spaceop.args
+        opname = spaceop.opname + '_' + \
+                 getaccesskind(value.concretetype)
+        self.insns.append(model.very_low_level_opcode[opname])
+        self.insns.append(self.get(array))
+        self.insns.append(self.get(index))
+        
+        offset = ArrayItemsOffset(array.concretetype)
+        self.insns.append(self.getoffset(offset))
+        
+        offset = ItemOffset(value.concretetype)
+        self.insns.append(self.getoffset(offset))
+        self.insns.append(self.get(value))
+        
+    def convert_malloc(self, spaceop):
+        type, = spaceop.args
+        self.insns.append(Op.malloc)
+        self.insns.append(self.getoffset(ItemOffset(type.value)))
+        self.push(spaceop.result)
+        
+    def convert_malloc_varsize(self, spaceop):
+        TYPE, nitems = spaceop.args
+        
+        raise NotImplementedError
 
-    return l3block

Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/l3interp.py	(original)
+++ pypy/dist/pypy/rpython/l3interp/l3interp.py	Tue Jan 24 18:40:57 2006
@@ -252,8 +252,16 @@
         frame = L3Frame(graph, self.stack_int, self.stack_dbl, self.stack_ptr)
         frame.execute()
 
+    def op_malloc(self):
+        size = self.getoffset()
+        self.stack_ptr.append(malloc(size))
+        
     # ____________________________________________________________
 
+# XXX should this live here?
+def malloc(size):
+    return fakeaddress(lltype.malloc(size.TYPE))
+
 class L3Return(Exception):
     pass
 

Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py	(original)
+++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py	Tue Jan 24 18:40:57 2006
@@ -4,6 +4,7 @@
 from pypy.translator.c.test.test_genc import compile
 from pypy.translator.translator import TranslationContext
 from pypy.annotation import policy
+from pypy.rpython.lltypesystem import lltype 
 
 def setup_module(mod):
     mod._cleanups = []
@@ -240,7 +241,6 @@
 
 
 def test_getitem():
-    from pypy.rpython.lltypesystem import lltype 
 
     A = lltype.GcArray(lltype.Signed)
     a = lltype.malloc(A, 3)
@@ -267,7 +267,6 @@
         assert fn(arg) == f(arg)
 
 def test_setitem():
-    from pypy.rpython.lltypesystem import lltype 
 
     A = lltype.GcArray(lltype.Signed)
     a = lltype.malloc(A, 3)
@@ -297,7 +296,6 @@
     assert entry_point(1, 0) == 65
 
 def test_getsetitem_complex():
-    from pypy.rpython.lltypesystem import lltype 
 
     A = lltype.GcArray(lltype.Signed)
     AA = lltype.GcArray(lltype.Ptr(A))
@@ -334,3 +332,25 @@
 
     for x,y,value in (0,0,0), (0,0,11), (0,0,0), (2,1,0), (2,1,26), (2,1,0):
         assert fn(x, y, value) == f(x, y, value)
+
+
+def test_malloc():
+    S = lltype.GcStruct("S", ('x',lltype.Signed))
+
+    def f(n):
+        s = lltype.malloc(S)
+        s.x = n
+        return s.x
+    
+    l3graph = l3ify(f, [int])
+    def entry_point(x):
+        value = l3interp.l3interpret(l3graph, [x], [], [])
+        assert isinstance(value, l3interp.L3Integer)
+        return value.intval
+
+    assert entry_point(5) == f(5)
+
+    fn = translate(entry_point, [int])
+
+    assert fn(9) == f(9)
+

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Tue Jan 24 18:40:57 2006
@@ -389,6 +389,18 @@
 
 BUILTIN_TYPER[llmemory.offsetof] = rtype_offsetof
 
+# XXX this next little bit is a monstrous hack.  the Real Thing awaits
+# some kind of proper GC integration
+from pypy.rpython.l3interp import l3interp
+from pypy.rpython.raddress import offset_repr
+
+def rtype_l3malloc(hop):
+    v_list = hop.inputargs(offset_repr)
+    return hop.genop("call_boehm_gc_alloc", v_list,
+                     resulttype=llmemory.Address)
+
+BUILTIN_TYPER[l3interp.malloc] = rtype_l3malloc
+
 # _________________________________________________________________
 # non-gc objects
 

Modified: pypy/dist/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/mem.h	(original)
+++ pypy/dist/pypy/translator/c/src/mem.h	Tue Jan 24 18:40:57 2006
@@ -75,6 +75,13 @@
 		memset((void*) r, 0, size);                                  \
   }
 
+/* as we said in rbuiltin.py: 
+# XXX this next little bit is a monstrous hack.  the Real Thing awaits
+# some kind of proper GC integration
+if GC integration has happened and this junk is still here, please delete it :)
+*/
+#define OP_CALL_BOEHM_GC_ALLOC(size, r, err) OP_BOEHM_ZERO_MALLOC(size, r, 0, 0, err)
+
 #undef PUSH_ALIVE
 #define PUSH_ALIVE(obj)
 



More information about the Pypy-commit mailing list