def test_interior_ptrs(self): from pypy.rpython.lltypesystem.lltype import Struct, GcStruct, GcArray from pypy.rpython.lltypesystem.lltype import Array, Signed, malloc S1 = Struct("S1", ('x', Signed)) T1 = GcStruct("T1", ('s', S1)) def f1(): t = malloc(T1) t.s.x = 1 return t.s.x S2 = Struct("S2", ('x', Signed)) T2 = GcArray(S2) def f2(): t = malloc(T2, 1) t[0].x = 1 return t[0].x S3 = Struct("S3", ('x', Signed)) T3 = GcStruct("T3", ('items', Array(S3))) def f3(): t = malloc(T3, 1) t.items[0].x = 1 return t.items[0].x S4 = Struct("S4", ('x', Signed)) T4 = Struct("T4", ('s', S4)) U4 = GcArray(T4) def f4(): u = malloc(U4, 1) u[0].s.x = 1 return u[0].s.x S5 = Struct("S5", ('x', Signed)) T5 = GcStruct("T5", ('items', Array(S5))) def f5(): t = malloc(T5, 1) return len(t.items) T6 = GcStruct("T6", ('s', Array(Signed))) def f6(): t = malloc(T6, 1) t.s[0] = 1 return t.s[0] def func(): return (f1() * 100000 + f2() * 10000 + f3() * 1000 + f4() * 100 + f5() * 10 + f6()) assert func() == 111111 run = self.runner(func) res = run([]) assert res == 111111
def __init__(self, step, *args): self.RANGE = Ptr( GcStruct("range", ("start", Signed), ("stop", Signed), adtmeths={ "ll_length": ll_length, "ll_getitem_fast": ll_getitem_fast, "step": step, }, hints={'immutable': True})) self.RANGEITER = Ptr( GcStruct("range", ("next", Signed), ("stop", Signed))) AbstractRangeRepr.__init__(self, step, *args) self.ll_newrange = ll_newrange self.ll_newrangest = ll_newrangest
def __init__(self, r_list): self.r_list = r_list self.lowleveltype = Ptr( GcStruct('listiter', ('list', r_list.lowleveltype), ('index', Signed))) self.ll_listiter = ll_listiter self.ll_listnext = ll_listnext
def _setup_repr(self): if 'item_repr' not in self.__dict__: self.external_item_repr, self.item_repr = externalvsinternal( self.rtyper, self._item_repr_computer()) if isinstance(self.LIST, GcForwardReference): ITEM = self.item_repr.lowleveltype ITEMARRAY = self.get_itemarray_lowleveltype() # XXX we might think of turning length stuff into Unsigned self.LIST.become( GcStruct( "list", ("length", Signed), ("items", Ptr(ITEMARRAY)), adtmeths=ADTIList({ "ll_newlist": ll_newlist, "ll_newlist_hint": ll_newlist_hint, "ll_newemptylist": ll_newemptylist, "ll_length": ll_length, "ll_items": ll_items, ##"list_builder": self.list_builder, "ITEM": ITEM, "ll_getitem_fast": ll_getitem_fast, "ll_setitem_fast": ll_setitem_fast, "_ll_resize_ge": _ll_list_resize_ge, "_ll_resize_le": _ll_list_resize_le, "_ll_resize": _ll_list_resize, })))
def TUPLE_TYPE(field_lltypes): if len(field_lltypes) == 0: return Void # empty tuple else: fields = [('item%d' % i, TYPE) for i, TYPE in enumerate(field_lltypes)] kwds = {'hints': {'immutable': True, 'noidentity': True}} return Ptr(GcStruct('tuple%d' % len(field_lltypes), *fields, **kwds))
def ARRAY_ITER(ARRAY, INDEXARRAY, ITEM): ndim = dim_of_ARRAY(ARRAY) unroll_ndim = unrolling_iterable(range(ndim)) def ll_iter_reset(it, dataptr): it.index = 0 it.dataptr = dataptr for i in unroll_ndim: it.coordinates[i] = 0 ll_iter_reset._always_inline_ = True unroll_ndim_rev = unrolling_iterable(reversed(range(ndim))) def ll_iter_next(it): it.index += 1 for i in unroll_ndim_rev: if it.coordinates[i] < it.dims_m1[i]: it.coordinates[i] += 1 it.dataptr = direct_ptradd(it.dataptr, it.strides[i]) break it.coordinates[i] = 0 it.dataptr = direct_ptradd(it.dataptr, -it.backstrides[i]) ll_iter_next._always_inline_ = True DATA_PTR = Ptr(FixedSizeArray(ITEM, 1)) ADTIIter = ADTInterface(None, { 'll_reset': (['self', DATA_PTR], Void), 'll_next': (['self'], Void), }) ITER = Ptr( GcStruct( "array_iter", ("nd_m1", Signed), # number of dimensions - 1 ("index", NPY_INTP), ("size", NPY_INTP), ("coordinates", INDEXARRAY), ("dims_m1", INDEXARRAY), # array of dimensions - 1 ("strides", INDEXARRAY), ("backstrides", INDEXARRAY), #("factors", INDEXARRAY), #("ao", ARRAY), # not needed.. ("dataptr", DATA_PTR), # pointer to current item #("contiguous", Bool), adtmeths=ADTIIter({ 'll_next': ll_iter_next, 'll_reset': ll_iter_reset, }), )) return ITER
def __init__(self, r_list): self.r_list = r_list self.lowleveltype = Ptr( GcStruct('listiter', ('list', r_list.lowleveltype), ('index', Signed))) self.ll_listiter = ll_listiter if (isinstance(r_list, FixedSizeListRepr) and not r_list.listitem.mutated): self.ll_listnext = ll_listnext_foldable else: self.ll_listnext = ll_listnext self.ll_getnextindex = ll_getnextindex
def make_types(cls, ndim, ITEM): DATA_PTR = Ptr(FixedSizeArray(ITEM, 1)) ITEMARRAY = GcArray(ITEM, hints={'nolength': True}) INDEXARRAY = FixedSizeArray(NPY_INTP, ndim) STRUCT = GcStruct( "array", ("data", Ptr(ITEMARRAY)), # pointer to raw data buffer ("dataptr", DATA_PTR), # pointer to first element ("ndim", Signed), # number of dimensions ("shape", INDEXARRAY), # size in each dimension ("strides", INDEXARRAY), # elements to jump to get to the # next element in each dimension adtmeths=ADTIArray({ "ll_allocate": ll_allocate, }), ) ARRAY = Ptr(STRUCT) return ARRAY, INDEXARRAY
class UnicodeIteratorRepr(BaseStringIteratorRepr): lowleveltype = Ptr( GcStruct('unicodeiter', ('string', unicode_repr.lowleveltype), ('index', Signed)))
class StringIteratorRepr(BaseStringIteratorRepr): lowleveltype = Ptr( GcStruct('stringiter', ('string', string_repr.lowleveltype), ('index', Signed)))
mallocstr = new_malloc(STR) mallocunicode = new_malloc(UNICODE) def emptystrfun(): return emptystr def emptyunicodefun(): return emptyunicode STR.become( GcStruct('rpy_string', ('hash', Signed), ('chars', Array(Char, hints={'immutable': True})), adtmeths={ 'malloc': staticAdtMethod(mallocstr), 'empty': staticAdtMethod(emptystrfun) })) UNICODE.become( GcStruct('rpy_unicode', ('hash', Signed), ('chars', Array(UniChar, hints={'immutable': True})), adtmeths={ 'malloc': staticAdtMethod(mallocunicode), 'empty': staticAdtMethod(emptyunicodefun) })) SIGNED_ARRAY = GcArray(Signed) CONST_STR_CACHE = WeakValueDictionary() CONST_UNICODE_CACHE = WeakValueDictionary() class BaseLLStringRepr(Repr):
def __init__(self, r_tuple): self.r_tuple = r_tuple self.lowleveltype = Ptr( GcStruct('tuple1iter', ('tuple', r_tuple.lowleveltype))) self.ll_tupleiter = ll_tupleiter self.ll_tuplenext = ll_tuplenext
hop.exception_cannot_occur() # to ignore the ZeroDivisionError of '%' return hop.gendirectcall(cls.ll_join_strs, size, vtemp) do_stringformat = classmethod(do_stringformat) TEMP = GcArray(Ptr(STR)) # ____________________________________________________________ STR.become( GcStruct('rpy_string', ('hash', Signed), ('chars', Array(Char, hints={'immutable': True})), adtmeths={ 'malloc': staticAdtMethod(mallocstr), 'empty': staticAdtMethod(emptystrfun), 'copy_contents': staticAdtMethod(copy_string_contents), 'gethash': LLHelpers.ll_strhash })) UNICODE.become( GcStruct('rpy_unicode', ('hash', Signed), ('chars', Array(UniChar, hints={'immutable': True})), adtmeths={ 'malloc': staticAdtMethod(mallocunicode), 'empty': staticAdtMethod(emptyunicodefun), 'copy_contents': staticAdtMethod(copy_unicode_contents), 'gethash': LLHelpers.ll_strhash })) # TODO: make the public interface of the rstr module cleaner ll_strconcat = LLHelpers.ll_strconcat
# struct object_vtable* typeptr; # } # # struct X { # struct Y super; // inlined # ... // extra instance attributes # } # # there's also a nongcobject OBJECT_VTABLE = lltype.ForwardReference() CLASSTYPE = Ptr(OBJECT_VTABLE) OBJECT = GcStruct('object', ('typeptr', CLASSTYPE), hints={ 'immutable': True, 'shouldntbenull': True, 'typeptr': True }, rtti=True) OBJECTPTR = Ptr(OBJECT) OBJECT_VTABLE.become( Struct( 'object_vtable', #('parenttypeptr', CLASSTYPE), ('subclassrange_min', Signed), ('subclassrange_max', Signed), ('rtti', Ptr(RuntimeTypeInfo)), ('name', Ptr(Array(Char))), ('instantiate', Ptr(FuncType([], OBJECTPTR))), hints={'immutable': True})) # non-gc case
from pypy.rpython.rmodel import inputconst, PyObjPtr, IntegerRepr # ____________________________________________________________ # # Concrete implementation of RPython slice objects: # # - if stop is None, use only a Signed # - if stop is not None: # # struct slice { # Signed start; # Signed stop; # // step is always 1 # } SLICE = GcStruct("slice", ("start", Signed), ("stop", Signed), hints={'immutable': True}) class SliceRepr(AbstractSliceRepr): pass startstop_slice_repr = SliceRepr() startstop_slice_repr.lowleveltype = Ptr(SLICE) startonly_slice_repr = SliceRepr() startonly_slice_repr.lowleveltype = Signed minusone_slice_repr = SliceRepr() minusone_slice_repr.lowleveltype = Void # only for [:-1] # ____________________________________________________________
hi = l.start step = -l.step if hi <= lo: return 0 n = (hi - lo - 1) // step + 1 return n def ll_getitem_fast(l, index): return l.start + index * l.step RANGEST = GcStruct("range", ("start", Signed), ("stop", Signed), ("step", Signed), adtmeths={ "ll_length": ll_length, "ll_getitem_fast": ll_getitem_fast, }, hints={'immutable': True}) RANGESTITER = GcStruct("range", ("next", Signed), ("stop", Signed), ("step", Signed)) class RangeRepr(AbstractRangeRepr): RANGEST = Ptr(RANGEST) RANGESTITER = Ptr(RANGESTITER) getfield_opname = "getfield" def __init__(self, step, *args):