def test_convert_subarray(self): A = lltype.GcArray(lltype.Signed) a = lltype.malloc(A, 20) inside = lltype.direct_ptradd(lltype.direct_arrayitems(a), 3) lltype2ctypes(inside) start = rffi.cast(lltype.Signed, lltype.direct_arrayitems(a)) inside_int = rffi.cast(lltype.Signed, inside) assert inside_int == start+rffi.sizeof(lltype.Signed)*3
def test_convert_subarray(self): A = lltype.GcArray(lltype.Signed) a = lltype.malloc(A, 20) inside = lltype.direct_ptradd(lltype.direct_arrayitems(a), 3) lltype2ctypes(inside) start = rffi.cast(lltype.Signed, lltype.direct_arrayitems(a)) inside_int = rffi.cast(lltype.Signed, inside) assert inside_int == start + rffi.sizeof(lltype.Signed) * 3
def walk_roots(self, collect_stack_root, collect_static_in_prebuilt_nongc, collect_static_in_prebuilt_gc): gc = self.tester.gc layoutbuilder = self.tester.layoutbuilder if collect_static_in_prebuilt_gc: for addrofaddr in layoutbuilder.addresses_of_static_ptrs: if addrofaddr.address[0]: collect_static_in_prebuilt_gc(gc, addrofaddr) if collect_static_in_prebuilt_nongc: for addrofaddr in layoutbuilder.addresses_of_static_ptrs_in_nongc: if addrofaddr.address[0]: collect_static_in_prebuilt_nongc(gc, addrofaddr) if collect_stack_root: stackroots = self.tester.stackroots a = lltype.malloc(ADDR_ARRAY, len(stackroots), flavor='raw') for i in range(len(a)): a[i] = llmemory.cast_ptr_to_adr(stackroots[i]) a_base = lltype.direct_arrayitems(a) for i in range(len(a)): ai = lltype.direct_ptradd(a_base, i) collect_stack_root(gc, llmemory.cast_ptr_to_adr(ai)) for i in range(len(a)): PTRTYPE = lltype.typeOf(stackroots[i]) stackroots[i] = llmemory.cast_adr_to_ptr(a[i], PTRTYPE) lltype.free(a, flavor='raw')
def ll_build_from_size(ARRAY, size, _malloc): array = ARRAY.ll_allocate(1) array.shape[0] = size array.strides[0] = 1 array.data = _malloc(ARRAY.data.TO, size) array.dataptr = direct_arrayitems(array.data) return array
def get_address_of_gcref(self, gcref): assert lltype.typeOf(gcref) == llmemory.GCREF # first look in the hashtable, using an inexact hash (fails after # the object moves) addr = llmemory.cast_ptr_to_adr(gcref) hash = llmemory.cast_adr_to_int(addr) hash -= hash >> self.HASHTABLE_BITS hash &= self.HASHTABLE_SIZE - 1 addr_ref = self.hashtable[hash] # the following test is safe anyway, because the addresses found # in the hashtable are always the addresses of nonmovable stuff # ('addr_ref' is an address inside self.list, not directly the # address of a real moving GC object -- that's 'addr_ref.address[0]'.) if addr_ref.address[0] == addr: return addr_ref # if it fails, add an entry to the list if self.nextindex == len(self.list): # reallocate first, increasing a bit the size every time self.oldlists.append(self.list) self.list = self.alloc_gcref_list(len(self.list) // 4 * 5) self.nextindex = 0 # add it index = self.nextindex self.list[index] = gcref addr_ref = lltype.direct_ptradd(lltype.direct_arrayitems(self.list), index) addr_ref = llmemory.cast_ptr_to_adr(addr_ref) self.nextindex = index + 1 # record it in the hashtable self.hashtable[hash] = addr_ref return addr_ref
def get_addr_for_num(self, i): chunk_no, ofs = self._no_of(i) chunk = self.chunks[chunk_no] rffi.cast(lltype.Signed, chunk) return rffi.cast( lltype.Signed, lltype.direct_ptradd(lltype.direct_arrayitems(chunk), ofs))
def ref(self, arrayptr): assert array_type_match(lltype.typeOf(arrayptr).TO, self.TYPE) if isinstance(self.TYPE.OF, lltype.ContainerType): # XXX this doesn't support empty arrays o = arrayptr._obj.getitem(0) return o._as_ptr() else: return lltype.direct_arrayitems(arrayptr)
def ll_build_from_scalar(ARRAY, value): array = ARRAY.ll_allocate(1) array.shape[0] = 1 array.strides[0] = 1 array.data = malloc(ARRAY.data.TO, 1) array.dataptr = direct_arrayitems(array.data) array.data[0] = value return array
def ll_chararrayvalue(box): from pypy.rpython.rctypes import rchar_p p = box.c_data length = rchar_p.ll_strnlen(lltype.direct_arrayitems(p), len(p)) newstr = lltype.malloc(string_repr.lowleveltype.TO, length) newstr.hash = 0 for i in range(length): newstr.chars[i] = p[i] return newstr
def writeall_not_sandboxed(fd, buf, length): while length > 0: size = rffi.cast(rffi.SIZE_T, length) count = rffi.cast(lltype.Signed, ll_write_not_sandboxed(fd, buf, size)) if count <= 0: raise IOError length -= count buf = lltype.direct_ptradd(lltype.direct_arrayitems(buf), count) buf = rffi.cast(rffi.CCHARP, buf)
def ll_build_alias_to_list(ARRAY, lst): # This should only be used for temporary calculations size = lst.ll_length() array = ARRAY.ll_allocate(1) array.shape[0] = size array.strides[0] = 1 # Well.. this doesn't work (because array.data has nolength ?) array.data = lst.ll_items() array.dataptr = direct_arrayitems(array.data) return array
def ll_build_from_shape(ARRAY, shape): array = ll_allocate(ARRAY, ndim) itemsize = 1 for i in unrolling_dims: attr = 'item%d'%i size = getattr(shape, attr) array.shape[i] = size array.strides[i] = itemsize itemsize *= size array.data = malloc(ARRAY.data.TO, itemsize, zero=zero) array.dataptr = direct_arrayitems(array.data) return array
def ll_build_from_list(ARRAY, lst): size = lst.ll_length() array = ARRAY.ll_allocate(1) array.shape[0] = size array.strides[0] = 1 array.data = malloc(ARRAY.data.TO, size) i = 0 while i < size: array.data[i] = lst.ll_getitem_fast(i) i += 1 array.dataptr = direct_arrayitems(array.data) return array
def ll_build_from_shape(ARRAY, shape): array = ll_allocate(ARRAY, ndim) itemsize = 1 for i in unrolling_dims: attr = 'item%d' % i size = getattr(shape, attr) array.shape[i] = size array.strides[i] = itemsize itemsize *= size array.data = malloc(ARRAY.data.TO, itemsize, zero=zero) array.dataptr = direct_arrayitems(array.data) return array
def pop(self): while self.static_current != gcdata.static_root_end: result = self.static_current self.static_current += sizeofaddr if result.address[0].address[0] != llmemory.NULL: return result.address[0] i = self.static_roots_index if i > 0: i -= 1 self.static_roots_index = i p = lltype.direct_arrayitems(gcdata.static_roots) p = lltype.direct_ptradd(p, i) return llmemory.cast_ptr_to_adr(p) return llmemory.NULL
def ll_build_like(ARRAY, array0): ndim = array0.ndim array = ARRAY.ll_allocate(ndim) sz = ll_mul_list(array0.shape, array0.ndim) array.data = malloc(ARRAY.data.TO, sz) array.dataptr = direct_arrayitems(array.data) itemsize = 1 i = ndim - 1 while i >= 0: size = array0.shape[i] array.shape[i] = size array.strides[i] = itemsize itemsize *= size i -= 1 return array
def make_struct_ffitype_e(size, aligment, field_types): """Compute the type of a structure. Returns a FFI_STRUCT_P out of which the 'ffistruct' member is a regular FFI_TYPE. """ tpe = lltype.malloc(FFI_STRUCT_P.TO, len(field_types) + 1, flavor="raw") tpe.ffistruct.c_type = rffi.cast(rffi.USHORT, FFI_TYPE_STRUCT) tpe.ffistruct.c_size = rffi.cast(rffi.SIZE_T, size) tpe.ffistruct.c_alignment = rffi.cast(rffi.USHORT, aligment) tpe.ffistruct.c_elements = rffi.cast(FFI_TYPE_PP, lltype.direct_arrayitems(tpe.members)) n = 0 while n < len(field_types): tpe.members[n] = field_types[n] n += 1 tpe.members[n] = lltype.nullptr(FFI_TYPE_P.TO) return tpe
def ll_get_view(ARRAY, ao, tpl): array = ARRAY.ll_allocate(ndim) dataptr = direct_arrayitems(ao.data) src_i = 0 tgt_i = 0 for src_i, r_key in unroll_r_tuple: if isinstance(r_key, IntegerRepr): dataptr = direct_ptradd( dataptr, getattr(tpl, 'item%d' % src_i) * ao.strides[src_i]) elif r_key == rslice.startonly_slice_repr: start = getattr(tpl, 'item%d' % src_i) size = ao.shape[src_i] if start > size: start = size size -= start dataptr = direct_ptradd(dataptr, start * ao.strides[src_i]) array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 elif r_key == rslice.startstop_slice_repr: start = getattr(tpl, 'item%d' % src_i).start stop = getattr(tpl, 'item%d' % src_i).stop size = ao.shape[src_i] if start > size: start = size dataptr = direct_ptradd(dataptr, start * ao.strides[src_i]) if stop < size: size = stop size -= start if size < 0: size = 0 array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 else: assert 0 src_i += 1 # consume the rest of ndim as if we found more slices while tgt_i < ndim: array.shape[tgt_i] = ao.shape[src_i] array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 src_i += 1 ll_assert(tgt_i == ndim, "tgt_i == ndim") array.dataptr = dataptr array.data = ao.data # keep a ref return array
def make_struct_ffitype_e(size, aligment, field_types): """Compute the type of a structure. Returns a FFI_STRUCT_P out of which the 'ffistruct' member is a regular FFI_TYPE. """ tpe = lltype.malloc(FFI_STRUCT_P.TO, len(field_types)+1, flavor='raw') tpe.ffistruct.c_type = rffi.cast(rffi.USHORT, FFI_TYPE_STRUCT) tpe.ffistruct.c_size = rffi.cast(rffi.SIZE_T, size) tpe.ffistruct.c_alignment = rffi.cast(rffi.USHORT, aligment) tpe.ffistruct.c_elements = rffi.cast(FFI_TYPE_PP, lltype.direct_arrayitems(tpe.members)) n = 0 while n < len(field_types): tpe.members[n] = field_types[n] n += 1 tpe.members[n] = lltype.nullptr(FFI_TYPE_P.TO) return tpe
def ll_get_view(ARRAY, ao, tpl): array = ARRAY.ll_allocate(ndim) dataptr = direct_arrayitems(ao.data) src_i = 0 tgt_i = 0 for src_i, r_key in unroll_r_tuple: if isinstance(r_key, IntegerRepr): dataptr = direct_ptradd(dataptr, getattr(tpl, 'item%d'%src_i)*ao.strides[src_i]) elif r_key == rslice.startonly_slice_repr: start = getattr(tpl, 'item%d'%src_i) size = ao.shape[src_i] if start > size: start = size size -= start dataptr = direct_ptradd(dataptr, start*ao.strides[src_i]) array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 elif r_key == rslice.startstop_slice_repr: start = getattr(tpl, 'item%d'%src_i).start stop = getattr(tpl, 'item%d'%src_i).stop size = ao.shape[src_i] if start > size: start = size dataptr = direct_ptradd(dataptr, start*ao.strides[src_i]) if stop < size: size = stop size -= start if size < 0: size = 0 array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 else: assert 0 src_i += 1 # consume the rest of ndim as if we found more slices while tgt_i < ndim: array.shape[tgt_i] = ao.shape[src_i] array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 src_i += 1 ll_assert(tgt_i == ndim, "tgt_i == ndim") array.dataptr = dataptr array.data = ao.data # keep a ref return array
def initialize(self): if we_are_translated(): n = 2000 else: n = 10 # tests only self.list = self.alloc_gcref_list(n) self.nextindex = 0 self.oldlists = [] # A pseudo dictionary: it is fixed size, and it may contain # random nonsense after a collection moved the objects. It is only # used to avoid too many duplications in the GCREF_LISTs. self.hashtable = lltype.malloc(self.HASHTABLE, self.HASHTABLE_SIZE + 1, flavor='raw') dummy = lltype.direct_ptradd(lltype.direct_arrayitems(self.hashtable), self.HASHTABLE_SIZE) dummy = llmemory.cast_ptr_to_adr(dummy) for i in range(self.HASHTABLE_SIZE + 1): self.hashtable[i] = dummy
def initialize(self): if we_are_translated(): n = 2000 else: n = 10 # tests only self.list = self.alloc_gcref_list(n) self.nextindex = 0 self.oldlists = [] # A pseudo dictionary: it is fixed size, and it may contain # random nonsense after a collection moved the objects. It is only # used to avoid too many duplications in the GCREF_LISTs. self.hashtable = lltype.malloc(self.HASHTABLE, self.HASHTABLE_SIZE+1, flavor='raw') dummy = lltype.direct_ptradd(lltype.direct_arrayitems(self.hashtable), self.HASHTABLE_SIZE) dummy = llmemory.cast_ptr_to_adr(dummy) for i in range(self.HASHTABLE_SIZE+1): self.hashtable[i] = dummy
def ll_build_like2(ARRAY, array0, array1): # Build with shape from the largest of array0 or array1. # Note we cannot take the union of array0 and array1. ndim = max(array0.ndim, array1.ndim) array = ARRAY.ll_allocate(ndim) sz0 = ll_mul_list(array0.shape, array0.ndim) sz1 = ll_mul_list(array1.shape, array1.ndim) sz = max(sz0, sz1) array.data = malloc(ARRAY.data.TO, sz) array.dataptr = direct_arrayitems(array.data) itemsize = 1 i = ndim - 1 while i >= 0: if sz0>sz1: size = array0.shape[i] else: size = array1.shape[i] array.shape[i] = size array.strides[i] = itemsize itemsize *= size i -= 1 return array
def ll_build_like2(ARRAY, array0, array1): # Build with shape from the largest of array0 or array1. # Note we cannot take the union of array0 and array1. ndim = max(array0.ndim, array1.ndim) array = ARRAY.ll_allocate(ndim) sz0 = ll_mul_list(array0.shape, array0.ndim) sz1 = ll_mul_list(array1.shape, array1.ndim) sz = max(sz0, sz1) array.data = malloc(ARRAY.data.TO, sz) array.dataptr = direct_arrayitems(array.data) itemsize = 1 i = ndim - 1 while i >= 0: if sz0 > sz1: size = array0.shape[i] else: size = array1.shape[i] array.shape[i] = size array.strides[i] = itemsize itemsize *= size i -= 1 return array
def get_addr_for_num(self, i): return rffi.cast( lltype.Signed, lltype.direct_ptradd(lltype.direct_arrayitems(self.ar), i))
def op_direct_arrayitems(obj): checkptr(obj) return lltype.direct_arrayitems(obj)
def build_pytypeobject(r_inst): rtyper = r_inst.rtyper cache = rtyper.classdef_to_pytypeobject try: return cache[r_inst.classdef] except KeyError: for parentdef in r_inst.classdef.getmro(): cpytype = parentdef._cpy_exported_type_ if cpytype is not None: break else: # for classes that cannot be exported at all return lltype.nullptr(lltype.PyObject) from pypy.rpython.lltypesystem.rclass import CPYOBJECTPTR from pypy.rpython.rtyper import LowLevelOpList typetype = lltype.pyobjectptr(type) # XXX default tp_new should go away # make the graph of tp_new manually v1 = Variable('tp'); v1.concretetype = lltype.Ptr(PY_TYPE_OBJECT) v2 = Variable('args'); v2.concretetype = PyObjPtr v3 = Variable('kwds'); v3.concretetype = PyObjPtr block = Block([v1, v2, v3]) llops = LowLevelOpList(None) v4 = r_inst.new_instance(llops, v_cpytype = v1) v5 = llops.genop('cast_pointer', [v4], resulttype = PyObjPtr) block.operations = list(llops) tp_new_graph = FunctionGraph('ll_tp_new', block) block.closeblock(Link([v5], tp_new_graph.returnblock)) tp_new_graph.getreturnvar().concretetype = v5.concretetype # build the PyTypeObject structure pytypeobj = lltype.malloc(PY_TYPE_OBJECT, flavor='cpy', extra_args=(typetype,)) name = cpytype.name T = lltype.FixedSizeArray(lltype.Char, len(name)+1) p = lltype.malloc(T, immortal=True) for i in range(len(name)): p[i] = name[i] p[len(name)] = '\x00' pytypeobj.c_tp_name = lltype.direct_arrayitems(p) pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO) if cpytype.subclassable and False: # XXX deallocation of subclass object segfaults! pytypeobj.c_tp_flags = CDefinedIntSymbolic('''(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_BASETYPE)''') else: pytypeobj.c_tp_flags = CDefinedIntSymbolic('''(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES)''') pytypeobj.c_tp_new = rtyper.type_system.getcallable(tp_new_graph) pytypeobj.c_tp_dealloc = rtyper.annotate_helper_fn(ll_tp_dealloc, [PyObjPtr]) pytypeobj.c_tp_as_number = lltype.malloc(PyNumberMethods, immortal=True) pytypeobj.c_tp_as_sequence = lltype.malloc(PySequenceMethods, immortal=True) pytypeobj.c_tp_as_mapping = lltype.malloc(PyMappingMethods, immortal=True) result = lltype.cast_pointer(PyObjPtr, pytypeobj) # the llsetup function that will store the 'objects' into the # type's tp_dict Py_TPFLAGS_HEAPTYPE = CDefinedIntSymbolic('Py_TPFLAGS_HEAPTYPE') if cpytype.objects: objects = [(lltype.pyobjectptr(name), value) for name, value in cpytype.objects.items() if name != '__new__'] if '__new__' in cpytype.objects: new = cpytype.objects['__new__']._obj.value objects.append((lltype.pyobjectptr('__new__'), lltype.pyobjectptr(staticmethod(new)))) def ll_type_setup(p): tp = lltype.cast_pointer(lltype.Ptr(PY_TYPE_OBJECT), p) old_flags = tp.c_tp_flags tp.c_tp_flags |= Py_TPFLAGS_HEAPTYPE for name, value in objects: llop.setattr(PyObjPtr, tp, name, value) tp.c_tp_flags = old_flags result._obj.setup_fnptr = rtyper.annotate_helper_fn(ll_type_setup, [PyObjPtr]) cache[r_inst.classdef] = result return result
def get_addr_for_num(self, i): chunk_no, ofs = self._no_of(i) chunk = self.chunks[chunk_no] rffi.cast(lltype.Signed, chunk) return rffi.cast(lltype.Signed, lltype.direct_ptradd(lltype.direct_arrayitems(chunk), ofs))
def get_addr_for_num(self, i): return rffi.cast(lltype.Signed, lltype.direct_ptradd( lltype.direct_arrayitems(self.ar), i))
def str2subarray(string): llstring = string_repr.convert_const(string) keepalive.append(llstring) return lltype.direct_arrayitems(llstring.chars)
def fn(): p1 = lltype.direct_arrayitems(a1) p2 = lltype.direct_ptradd(p1, 6) return p2[0]
def direct_arrayitems(s_p): assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p cast_p = lltype.direct_arrayitems(s_p.ll_ptrtype._example()) return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
def ll_string2addr(s): if s: ptr = lltype.direct_arrayitems(s.chars) return llmemory.cast_ptr_to_adr(ptr) else: return llmemory.NULL
def ref(self, arrayptr): assert lltype.typeOf(arrayptr).TO == self.TYPE if isinstance(self.TYPE.OF, lltype.ContainerType): return arrayptr[0] else: return lltype.direct_arrayitems(arrayptr)