[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