[pypy-svn] r22590 - in pypy/dist/pypy: annotation rpython rpython/l3interp rpython/l3interp/test rpython/lltypesystem rpython/lltypesystem/test rpython/memory translator/c
ac at codespeak.net
ac at codespeak.net
Tue Jan 24 14:22:58 CET 2006
Author: ac
Date: Tue Jan 24 14:22:57 2006
New Revision: 22590
Added:
pypy/dist/pypy/rpython/lltypesystem/test/ (props changed)
pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py (contents, props changed)
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/rpython/l3interp/convertgraph.py
pypy/dist/pypy/rpython/l3interp/l3interp.py
pypy/dist/pypy/rpython/l3interp/model.py
pypy/dist/pypy/rpython/l3interp/test/test_convert.py
pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py
pypy/dist/pypy/rpython/lltypesystem/llmemory.py
pypy/dist/pypy/rpython/memory/lladdress.py
pypy/dist/pypy/rpython/memory/lltypelayout.py
pypy/dist/pypy/rpython/raddress.py
pypy/dist/pypy/translator/c/primitive.py
Log:
(mwh, arre)
Implemented getarrayitem and in the process refactored
Offsets.
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Tue Jan 24 14:22:57 2006
@@ -737,6 +737,10 @@
def add((s_off1, s_off2)):
return SomeOffset()
+class __extend__(pairtype(SomeOffset, SomeInteger)):
+ def mul((s_off1, s_off2)):
+ return SomeOffset()
+
class __extend__(pairtype(SomeAddress, SomeOffset)):
def add((s_addr, s_off)):
return SomeAddress()
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 14:22:57 2006
@@ -3,7 +3,8 @@
from pypy.rpython.l3interp.model import Op
from pypy.objspace.flow import model as flowmodel
from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.lltypesystem.llmemory import OffsetOf, fakeaddress
+from pypy.rpython.lltypesystem.llmemory import FieldOffset, \
+ ItemOffset, ArrayItemsOffset, fakeaddress
class LL2L3Converter(object):
@@ -86,6 +87,15 @@
position = var2stack[v]
return position - stacksizes[kind] # < 0
+ def getoffset(offset):
+ clist = constants['offset']
+ try:
+ res = clist.index(offset)
+ except ValueError:
+ res = len(clist)
+ clist.append(offset)
+ return res
+
for v in block.inputargs:
if v.concretetype is not lltype.Void:
push(v)
@@ -117,14 +127,8 @@
v0, v1 = spaceop.args
insns.append(get(v0))
- offset = OffsetOf(v0.concretetype, v1.value)
- clist = constants['offset']
- try:
- res = clist.index(offset)
- except ValueError:
- res = len(clist)
- clist.append(offset)
- insns.append(res)
+ offset = FieldOffset(v0.concretetype, v1.value)
+ insns.append(getoffset(offset))
elif spaceop.opname == 'setfield':
v0, v1, v2 = spaceop.args
opname = spaceop.opname + '_' + \
@@ -132,15 +136,22 @@
insns.append(model.very_low_level_opcode[opname])
insns.append(get(v0))
- offset = OffsetOf(v0.concretetype, v1.value)
- clist = constants['offset']
- try:
- res = clist.index(offset)
- except ValueError:
- res = len(clist)
- clist.append(offset)
- insns.append(res)
+ 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))
else:
insns.append(model.very_low_level_opcode[spaceop.opname])
for v in spaceop.args:
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 14:22:57 2006
@@ -2,7 +2,7 @@
from pypy.rpython.memory import lladdress
from pypy.rpython.rarithmetic import r_uint
from pypy.interpreter.miscutils import InitializedClass
-from pypy.rpython.lltypesystem.llmemory import fakeaddress, OffsetOf
+from pypy.rpython.lltypesystem.llmemory import fakeaddress, AddressOffset
from pypy.rpython.lltypesystem import lltype
class L3Exception(Exception):
@@ -46,7 +46,7 @@
return L3Nothing()
raise AssertionError("stacks corrupted")
-constant_offset = OffsetOf(lltype.Void)
+constant_offset = AddressOffset()
constant_fakeaddress = fakeaddress(None)
class L3Frame(object):
@@ -203,6 +203,14 @@
o = self.getoffset()
v = self.getint()
(p + o).signed[0] = v
+
+ def op_getarrayitem_int(self):
+ a = self.getptr()
+ i = self.getint()
+ items_offset = self.getoffset()
+ s = self.getoffset()
+ v = (a + items_offset + s * i).signed[0]
+ self.stack_int.append(v)
def op_flavored_malloc(self):
self.stack_ptr.append(constant_fakeaddress)
Modified: pypy/dist/pypy/rpython/l3interp/model.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/model.py (original)
+++ pypy/dist/pypy/rpython/l3interp/model.py Tue Jan 24 14:22:57 2006
@@ -37,7 +37,8 @@
'float_ne', 'float_neg', 'float_sub', 'float_truediv',
#array operations:
- 'getarrayitem', 'getarraysize', 'getarraysubstruct', 'setarrayitem',
+ 'getarrayitem_int', 'getarrayitem_ptr',
+ 'getarraysize', 'getarraysubstruct', 'setarrayitem',
#struct operations:
'getfield_int', 'getfield_char', 'getfield_dbl', 'getfield_ptr',
Modified: pypy/dist/pypy/rpython/l3interp/test/test_convert.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/test/test_convert.py (original)
+++ pypy/dist/pypy/rpython/l3interp/test/test_convert.py Tue Jan 24 14:22:57 2006
@@ -76,6 +76,29 @@
assert isinstance(result, l3interp.L3Integer)
assert result.intval == 2
+
+def test_convert_getitem():
+ from pypy.rpython.lltypesystem import lltype
+
+ A = lltype.GcArray(lltype.Signed)
+ a = lltype.malloc(A, 3)
+ a[0] = 1
+ a[1] = 2
+ a[2] = 3
+
+
+ def f(n):
+ return a[n]
+
+ l3graph = l3ify(f, [int])
+ result = l3interp.l3interpret(l3graph, [0], [], [])
+ assert isinstance(result, l3interp.L3Integer)
+ assert result.intval == 1
+
+ result = l3interp.l3interpret(l3graph, [1], [], [])
+ assert isinstance(result, l3interp.L3Integer)
+ assert result.intval == 2
+
def dont_test_call():
def f():
return 2
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 14:22:57 2006
@@ -238,3 +238,31 @@
for y in 0, 1:
assert fn(x, y) == f(x, y)
+
+def test_getitem():
+ from pypy.rpython.lltypesystem import lltype
+
+ A = lltype.GcArray(lltype.Signed)
+ a = lltype.malloc(A, 3)
+ a[0] = 1
+ a[1] = 2
+ a[2] = 3
+
+
+ def f(n):
+ return a[n]
+
+ l3graph = l3ify(f, [int])
+ def entry_point(x):
+ value = l3interp.l3interpret(l3graph, [x], [], [])
+ assert isinstance(value, l3interp.L3Integer)
+ return value.intval
+
+ for arg in 0,1,2:
+ assert entry_point(arg) == f(arg)
+
+ fn = translate(entry_point, [int])
+
+ for arg in 0,1,2:
+ assert fn(arg) == f(arg)
+
Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Tue Jan 24 14:22:57 2006
@@ -7,11 +7,7 @@
from pypy.rpython.objectmodel import Symbolic
from pypy.rpython.lltypesystem import lltype
-class OffsetOf(Symbolic):
-
- def __init__(self, TYPE, *fldnames):
- self.TYPE = TYPE
- self.fldnames = fldnames
+class AddressOffset(Symbolic):
def annotation(self):
from pypy.annotation import model
@@ -20,72 +16,140 @@
def lltype(self):
return lltype.Signed
+ def __add__(self, other):
+ return CompositeOffset(self, other)
+
+
+class ItemOffset(AddressOffset):
+
+ def __init__(self, TYPE, repeat=1):
+ self.TYPE = TYPE
+ self.repeat = repeat
+
def __repr__(self):
- return "<OffsetOf %r %r>" % (self.TYPE, self.fldnames)
+ return "<ItemOffset %r %r>" % (self.TYPE, self.repeat)
- def __add__(self, other):
- if not isinstance(other, OffsetOf):
+ def __mul__(self, other):
+ if not isinstance(other, int):
return NotImplemented
- t = self.TYPE
- for f in self.fldnames:
- t = t._flds[f]
- assert t == other.TYPE
- return OffsetOf(self.TYPE, *(self.fldnames + other.fldnames))
+ return ItemOffset(self.TYPE, self.repeat * other)
+
+ def get(self, ob):
+ return ob[self.repeat]
+
+ def set(self, ob, value):
+ ob[self.repeat] = value
+
+
+class FieldOffset(AddressOffset):
+
+ def __init__(self, TYPE, fldname):
+ self.TYPE = TYPE
+ self.fldname = fldname
+
+ def __repr__(self):
+ return "<FieldOffset %r %r>" % (self.TYPE, self.fldname)
+
+ def get(self, ob):
+ return getattr(ob, self.fldname)
+
+ def set(self, ob, value):
+ setattr(ob, self.fldname, value)
+
+
+class CompositeOffset(AddressOffset):
+
+ def __init__(self, first, second):
+ self.first = first
+ self.second = second
+
+ def __repr__(self):
+ return '< %r + %r >'%(self.first, self.second)
+
+ def get(self, ob):
+ return self.second.get(self.first.get(ob))
+
+ def set(self, ob, value):
+ return self.second.set(self.first.get(ob), value)
+
+
+class ArrayItemsOffset(AddressOffset):
+
+ def __init__(self, TYPE):
+ self.TYPE = TYPE
+
+ def __repr__(self):
+ return '< ArrayItemsOffset >'
+
+ def get(self, ob):
+ return ob
+
+ def set(self, ob, value):
+ raise Exception("can't assign to an array's items")
+
def sizeof(TYPE, n=None):
pass
def offsetof(TYPE, fldname):
assert fldname in TYPE._flds
- return OffsetOf(TYPE, fldname)
+ return FieldOffset(TYPE, fldname)
-def itemoffsetof(TYPE, n=None):
- pass
+# -------------------------------------------------------------
class fakeaddress(object):
def __init__(self, ob, offset=None):
self.ob = ob
- if offset is None:
- self.offset = OffsetOf(lltype.typeOf(self.ob))
- else:
- self.offset = offset
+ self.offset = offset
def __add__(self, other):
- if not isinstance(other, OffsetOf):
- return NotImplemented
- return fakeaddress(self.ob, self.offset + other)
-
+ if isinstance(other, AddressOffset):
+ if self.offset is None:
+ offset = other
+ else:
+ offset = self.offset + other
+ return fakeaddress(self.ob, offset)
+ return NotImplemented
+
+ def get(self):
+ if self.offset is None:
+ return self.ob
+ else:
+ return self.offset.get(self.ob)
+
+ def set(self, value):
+ if self.offset is None:
+ raise Exception("can't assign to whole object")
+ else:
+ self.offset.set(self.ob, value)
+
+# XXX the indexing in code like
+# addr.signed[0] = v
+# is just silly. remove it.
+
class _fakeaccessor(object):
def __init__(self, addr):
self.addr = addr
def __getitem__(self, index):
assert index == 0
- ob = self.addr.ob
- for n in self.addr.offset.fldnames:
- ob = getattr(ob, n)
- return self.vet(ob)
+ return self.convert(self.addr.get())
def __setitem__(self, index, value):
assert index == 0
- ob = self.addr.ob
- for n in self.addr.offset.fldnames[:-1]:
- ob = getattr(ob, n)
- fld = self.addr.offset.fldnames[-1]
- assert lltype.typeOf(value) == self.TYPE
- assert lltype.typeOf(ob).TO._flds[fld] == self.TYPE
- setattr(ob, fld, value)
+ self.addr.set(value)
+
class _signed_fakeaccessor(_fakeaccessor):
TYPE = lltype.Signed
- def vet(self, value):
+ def convert(self, value):
assert lltype.typeOf(value) == self.TYPE
return value
class _address_fakeaccessor(_fakeaccessor):
TYPE = None
- def vet(self, value):
+ def convert(self, value):
# XXX is this the right check for "Ptr-ness" ?
assert isinstance(value, lltype._ptr)
return fakeaddress(value)
Added: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py Tue Jan 24 14:22:57 2006
@@ -0,0 +1,35 @@
+from pypy.rpython.lltypesystem.llmemory import *
+
+def test_simple():
+ class C:
+ def __init__(self, x):
+ self.x = x
+ c = C(1)
+ a = fakeaddress(c)
+ assert a.get() is c
+ b = a + FieldOffset('dummy', 'x')
+ assert b.get() == 1
+ b.set(2)
+ assert c.x == 2
+
+def test_composite():
+ class C:
+ def __init__(self, x):
+ self.x = x
+ c = C(C(3))
+ a = fakeaddress(c)
+ assert a.get() is c
+ b = a + FieldOffset('dummy', 'x') + FieldOffset('dummy', 'x')
+ assert b.get() == 3
+ b.set(2)
+ assert c.x.x == 2
+
+def test_array():
+ x = [2, 3, 5, 7, 11]
+ a = fakeaddress(x)
+ # is there a way to ensure that we add the ArrayItemsOffset ?
+ b = a + ArrayItemsOffset('dummy') + ItemOffset('dummy')*3
+ assert b.get() == x[3]
+ b.set(14)
+ assert x[3] == 14
+
Modified: pypy/dist/pypy/rpython/memory/lladdress.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lladdress.py (original)
+++ pypy/dist/pypy/rpython/memory/lladdress.py Tue Jan 24 14:22:57 2006
@@ -28,7 +28,7 @@
if isinstance(offset, int):
return address(self.intaddress + offset)
else:
- assert isinstance(offset, llmemory.OffsetOf)
+ assert isinstance(offset, llmemory.AddressOffset)
return address(self.intaddress + convert_offset_to_int(offset))
def __sub__(self, other):
@@ -50,7 +50,7 @@
def _store(self, fmt, *values):
# XXX annoyance: suddenly an OffsetOf changes into a Signed?!
from pypy.rpython.memory.lltypelayout import convert_offset_to_int
- if len(values) == 1 and isinstance(values[0], llmemory.OffsetOf):
+ if len(values) == 1 and isinstance(values[0], llmemory.AddressOffset):
values = [convert_offset_to_int(values[0])]
simulator.setstruct(fmt, self.intaddress, *values)
@@ -81,7 +81,7 @@
def convert_to(self, offset):
from pypy.rpython.memory.lltypelayout import convert_offset_to_int
# XXX same annoyance as in _store
- if isinstance(offset, llmemory.OffsetOf):
+ if isinstance(offset, llmemory.AddressOffset):
return convert_offset_to_int(offset)
return int(offset)
Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypelayout.py (original)
+++ pypy/dist/pypy/rpython/memory/lltypelayout.py Tue Jan 24 14:22:57 2006
@@ -88,13 +88,21 @@
return fixedsize + i * varsize
def convert_offset_to_int(offset):
- TYPE = offset.TYPE
- res = 0
- for fld in offset.fldnames:
- layout = get_layout(TYPE)
- res += layout[fld]
- TYPE = getattr(TYPE, fld)
- return res
+ if isinstance(offset, llmemory.FieldOffset):
+ layout = get_layout(offset.TYPE)
+ return layout[offset.fldname]
+ elif isinstance(offset, llmemory.CompositeOffset):
+ return convert_offset_to_int(offset.first) + \
+ convert_offset_to_int(offset.second)
+ elif type(offset) == llmemory.AddressOffset:
+ return 0
+ elif isinstance(offset, llmemory.ItemOffset):
+ return sizeof(offset.TYPE) * offset.repeat
+ elif isinstance(offset, llmemory.ArrayItemsOffset):
+ return get_fixed_size(lltype.Signed)
+ else:
+ raise Exception("unknown offset type %r"%offset)
+
# _____________________________________________________________________________
# the following functions are used to find contained pointers
Modified: pypy/dist/pypy/rpython/raddress.py
==============================================================================
--- pypy/dist/pypy/rpython/raddress.py (original)
+++ pypy/dist/pypy/rpython/raddress.py Tue Jan 24 14:22:57 2006
@@ -129,6 +129,11 @@
v_offset1, v_offset2 = hop.inputargs(offset_repr, offset_repr)
return hop.genop('int_add', [v_offset1, v_offset2], resulttype=lltype.Signed)
+class __extend__(pairtype(OffsetRepr, IntegerRepr)):
+ def rtype_mul((r_offset, r_int), hop):
+ v_offset, v_int = hop.inputargs(r_offset, r_int)
+ return hop.genop('int_mul', [v_offset, v_int], resulttype=lltype.Signed)
+
class __extend__(pairtype(AddressRepr, OffsetRepr)):
def rtype_add((r_offset1, r_offset2), hop):
v_offset1, v_offset2 = hop.inputargs(Address, offset_repr)
Modified: pypy/dist/pypy/translator/c/primitive.py
==============================================================================
--- pypy/dist/pypy/translator/c/primitive.py (original)
+++ pypy/dist/pypy/translator/c/primitive.py Tue Jan 24 14:22:57 2006
@@ -1,6 +1,7 @@
import sys
from pypy.rpython.lltypesystem.lltype import *
-from pypy.rpython.lltypesystem.llmemory import Address, OffsetOf, fakeaddress
+from pypy.rpython.lltypesystem.llmemory import Address, fakeaddress, \
+ AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset
from pypy.rpython.memory.lladdress import NULL
# ____________________________________________________________
@@ -9,15 +10,21 @@
def name_signed(value, db):
if isinstance(value, Symbolic):
- assert isinstance(value, OffsetOf)
- assert len(value.fldnames) <= 1
- if len(value.fldnames) == 0:
- return '0 /*offsetof*/'
- else:
+ if isinstance(value, FieldOffset):
structnode = db.gettypedefnode(value.TYPE.TO)
- return 'offsetof(struct %s, %s)'%(
- structnode.name,
- structnode.c_struct_field_name(value.fldnames[0]))
+ return 'offsetof(%s, %s)'%(
+ db.gettype(value.TYPE.TO).replace('@', ''),
+ structnode.c_struct_field_name(value.fldname))
+ elif isinstance(value, ItemOffset):
+ return '(sizeof(%s) * %s)'%(
+ db.gettype(value.TYPE).replace('@', ''), value.repeat)
+ elif isinstance(value, ArrayItemsOffset):
+ return 'offsetof(%s, items)'%(
+ db.gettype(value.TYPE.TO).replace('@', ''))
+ elif type(value) == AddressOffset:
+ return '0'
+ else:
+ raise Exception("unimplemented symbolic %r"%value)
if value == -sys.maxint-1: # blame C
return '(-%dL-1L)' % sys.maxint
else:
More information about the Pypy-commit
mailing list