def test_ll_union(): PS1 = lltype.Ptr(lltype.GcStruct('s')) PS2 = lltype.Ptr(lltype.GcStruct('s')) PS3 = lltype.Ptr(lltype.GcStruct('s3')) PA1 = lltype.Ptr(lltype.GcArray()) PA2 = lltype.Ptr(lltype.GcArray()) assert union(SomePtr(PS1), SomePtr(PS1)) == SomePtr(PS1) assert union(SomePtr(PS1), SomePtr(PS2)) == SomePtr(PS2) assert union(SomePtr(PS1), SomePtr(PS2)) == SomePtr(PS1) assert union(SomePtr(PA1), SomePtr(PA1)) == SomePtr(PA1) assert union(SomePtr(PA1), SomePtr(PA2)) == SomePtr(PA2) assert union(SomePtr(PA1), SomePtr(PA2)) == SomePtr(PA1) assert union(SomePtr(PS1), SomeImpossibleValue()) == SomePtr(PS1) assert union(SomeImpossibleValue(), SomePtr(PS1)) == SomePtr(PS1) with py.test.raises(UnionError): union(SomePtr(PA1), SomePtr(PS1)) with py.test.raises(UnionError): union(SomePtr(PS1), SomePtr(PS3)) with py.test.raises(UnionError): union(SomePtr(PS1), SomeInteger()) with py.test.raises(UnionError): union(SomeInteger(), SomePtr(PS1))
def test_array_token(): A = lltype.GcArray(lltype.Char) basesize, itemsize, ofs_length = get_array_token(A, False) assert basesize >= WORD # at least the 'length', maybe some gc headers assert itemsize == 1 assert ofs_length == basesize - WORD A = lltype.GcArray(lltype.Signed) basesize, itemsize, ofs_length = get_array_token(A, False) assert basesize >= WORD # at least the 'length', maybe some gc headers assert itemsize == WORD assert ofs_length == basesize - WORD
def test_call_may_force_gcmap(self): cpu = self.cpu def f(frame, arg, x): assert not arg if self.cpu.backend_name != 'asmjs': assert frame.jf_gcmap[0] & 31 == 0 assert getmap(frame).count('1') == 3 # p1, p2, p3, but # not in registers frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) FUNC = lltype.FuncType([JITFRAMEPTR, llmemory.GCREF, lltype.Signed], llmemory.GCREF) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) A = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Signed))) a = lltype.malloc(A, 3, zero=True) loop = self.parse(""" [i0, p0] pf = force_token() p1 = getarrayitem_gc(p0, 0, descr=arraydescr) p2 = getarrayitem_gc(p0, 1, descr=arraydescr) p3 = getarrayitem_gc(p0, 2, descr=arraydescr) pdying = getarrayitem_gc(p0, 0, descr=arraydescr) px = call_may_force(ConstClass(fptr), pf, pdying, i0, descr=calldescr) guard_not_forced(descr=faildescr) [p1, p2, p3, px] finish(px, descr=finaldescr) """, namespace={ 'fptr': fptr, 'calldescr': calldescr, 'arraydescr': cpu.arraydescrof(A), 'faildescr': BasicFailDescr(1), 'finaldescr': BasicFinalDescr(2) }) token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert getmap(frame).count('1') == 4
def test_jit_force_virtual_seen(self): myjitdriver = JitDriver(greens=[], reds=['n']) A = lltype.GcArray(lltype.Signed) class XY(object): pass class ExCtx(object): pass exctx = ExCtx() escapes = [] def f(n): while n > 0: myjitdriver.can_enter_jit(n=n) myjitdriver.jit_merge_point(n=n) xy = XY() xy.n = n exctx.topframeref = vref = virtual_ref(xy) escapes.append(xy) xy.next1 = lltype.malloc(A, 0) n = exctx.topframeref().n - 1 exctx.topframeref = vref_None virtual_ref_finish(vref, xy) return 1 # res = self.meta_interp(f, [15]) assert res == 1 self.check_resops( new_with_vtable=2, # xy new_array=2) # next1 self.check_aborted_count(0)
def test_writebarrier_before_copy_manually_copy_card_bits(self): S = lltype.GcStruct('S', ('x', lltype.Char)) TP = lltype.GcArray(lltype.Ptr(S)) def fn(): l1 = lltype.malloc(TP, 65) l2 = lltype.malloc(TP, 33) for i in range(65): l1[i] = lltype.malloc(S) l = lltype.malloc(TP, 100) i = 0 while i < 65: l[i] = l1[i] i += 1 rgc.ll_arraycopy(l, l2, 0, 0, 33) x = [] # force minor collect t = (1, lltype.malloc(S)) for i in range(20): x.append(t) for i in range(33): assert l2[i] == l[i] return 0 self.interpret(fn, [])
def test_decode_builtin_call_method(): A = lltype.GcArray(lltype.Signed) def myfoobar(a, i, marker, c): assert marker == 'mymarker' return a[i] * ord(c) myfoobar.oopspec = 'spam.foobar(a, 2, c, i)' TYPE = lltype.FuncType( [lltype.Ptr(A), lltype.Signed, lltype.Void, lltype.Char], lltype.Signed) fnobj = lltype.functionptr(TYPE, 'foobar', _callable=myfoobar) vi = Variable('i') vi.concretetype = lltype.Signed vc = Variable('c') vc.concretetype = lltype.Char v_result = Variable('result') v_result.concretetype = lltype.Signed myarray = lltype.malloc(A, 10) myarray[5] = 42 op = SpaceOperation( 'direct_call', [newconst(fnobj), newconst(myarray), vi, voidconst('mymarker'), vc], v_result) oopspec, opargs = decode_builtin_call(op) assert oopspec == 'spam.foobar' assert opargs == [newconst(myarray), newconst(2), vc, vi]
def test_arrayitems(self): TP = lltype.GcArray(lltype.Signed) ofs = symbolic.get_field_token(TP, 'length', False)[0] itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 10 self.execute_operation(rop.SETARRAYITEM_GC, [res, ConstInt(2), BoxInt(38)], 'void', descr) assert resbuf[itemsofs / WORD + 2] == 38 self.execute_operation(rop.SETARRAYITEM_GC, [res, BoxInt(3), BoxInt(42)], 'void', descr) assert resbuf[itemsofs / WORD + 3] == 42 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, ConstInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res.constbox(), BoxInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation( rop.GETARRAYITEM_GC, [res.constbox(), ConstInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(3)], 'int', descr) assert r.value == 42
def test_include_write_array(): A = lltype.GcArray(lltype.Signed) effects = frozenset([("array", lltype.Ptr(A))]) effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert list(effectinfo.write_descrs_arrays) == [('arraydescr', A)]
def test_keepalive_const_arrayitems(): A1 = lltype.GcArray(lltype.Signed) a1 = lltype.malloc(A1, 10) a1[6] = 1234 def fn(): p1 = lltype.direct_arrayitems(a1) p2 = lltype.direct_ptradd(p1, 6) return p2[0] graph, t = get_graph(fn, []) assert summary(graph) == { 'direct_arrayitems': 1, 'direct_ptradd': 1, 'getarrayitem': 1 } constant_fold_graph(graph) # kill all references to 'a1' a1 = fn = None del graph.func import gc gc.collect() assert summary(graph) == {'getarrayitem': 1} check_graph(graph, [], 1234, t)
def define_can_move(cls): TP = lltype.GcArray(lltype.Float) def func(): return rgc.can_move(lltype.malloc(TP, 1)) return func
def test_unerased_pointers_in_short_preamble(self): from rpython.rlib.rerased import new_erasing_pair from rpython.rtyper.lltypesystem import lltype class A(object): def __init__(self, val): self.val = val erase_A, unerase_A = new_erasing_pair('A') erase_TP, unerase_TP = new_erasing_pair('TP') TP = lltype.GcArray(lltype.Signed) myjitdriver = JitDriver(greens=[], reds=['n', 'm', 'i', 'j', 'sa', 'p']) def f(n, m, j): i = sa = 0 p = erase_A(A(7)) while i < n: myjitdriver.jit_merge_point(n=n, m=m, i=i, j=j, sa=sa, p=p) if i < m: sa += unerase_A(p).val elif i == m: a = lltype.malloc(TP, 5) a[0] = 42 p = erase_TP(a) else: sa += unerase_TP(p)[0] sa += A(i).val assert n > 0 and m > 0 i += j return sa res = self.meta_interp(f, [20, 10, 1]) assert res == f(20, 10, 1)
def test_malloc_nursery_varsize_nonframe(self): self.cpu = self.getcpu(None) A = lltype.GcArray(lltype.Signed) arraydescr = self.cpu.arraydescrof(A) arraydescr.tid = 1515 ops = ''' [i0, i1, i2] p0 = call_malloc_nursery_varsize(0, 8, i0, descr=arraydescr) p1 = call_malloc_nursery_varsize(0, 5, i1, descr=arraydescr) guard_false(i0) [p0, p1] ''' self.interpret(ops, [1, 2, 3], namespace={'arraydescr': arraydescr}) # check the returned pointers gc_ll_descr = self.cpu.gc_ll_descr nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 2*WORD + 8*1 # check the nursery content and state assert gc_ll_descr.nursery_words[0] == 1515 assert gc_ll_descr.nursery_words[2 + 8 // WORD] == 1515 assert gc_ll_descr.addrs[0] == nurs_adr + (((4 * WORD + 8*1 + 5*2) + (WORD - 1)) & ~(WORD - 1)) # slowpath never called assert gc_ll_descr.calls == []
def test_fakeadr_eq(): S = lltype.GcStruct("S", ("x", lltype.Signed), ("y", lltype.Signed)) s = lltype.malloc(S) assert cast_ptr_to_adr(s) == cast_ptr_to_adr(s) adr1 = cast_ptr_to_adr(s) + FieldOffset(S, "x") adr2 = cast_ptr_to_adr(s) + FieldOffset(S, "y") adr3 = cast_ptr_to_adr(s) + FieldOffset(S, "y") assert adr1 != adr2 assert adr2 == adr3 A = lltype.GcArray(lltype.Char) a = lltype.malloc(A, 5) adr1 = cast_ptr_to_adr(a) + ArrayLengthOffset(A) adr2 = cast_ptr_to_adr(a) + ArrayLengthOffset(A) assert adr1 == adr2 adr1 = cast_ptr_to_adr(a) + ArrayItemsOffset(A) adr2 = cast_ptr_to_adr(a) + ArrayItemsOffset(A) assert adr1 == adr2 adr2 += ItemOffset(lltype.Char, 0) assert adr1 == adr2 adr1 += ItemOffset(lltype.Char, 2) adr2 += ItemOffset(lltype.Char, 3) assert adr1 != adr2 adr2 += ItemOffset(lltype.Char, -1) assert adr1 == adr2
def test_boehm(): gc_ll_descr = gc.GcLLDescr_boehm(None, None, None) # record = [] prev_malloc_fn_ptr = gc_ll_descr.malloc_fn_ptr def my_malloc_fn_ptr(size): p = prev_malloc_fn_ptr(size) record.append((size, p)) return p gc_ll_descr.malloc_fn_ptr = my_malloc_fn_ptr # # ---------- gc_malloc ---------- S = lltype.GcStruct('S', ('x', lltype.Signed)) sizedescr = descr.get_size_descr(gc_ll_descr, S) p = gc_ll_descr.gc_malloc(sizedescr) assert record == [(sizedescr.size, p)] del record[:] # ---------- gc_malloc_array ---------- A = lltype.GcArray(lltype.Signed) arraydescr = descr.get_array_descr(gc_ll_descr, A) p = gc_ll_descr.gc_malloc_array(10, arraydescr) assert record == [(arraydescr.basesize + 10 * arraydescr.itemsize, p)] del record[:] # ---------- gc_malloc_str ---------- p = gc_ll_descr.gc_malloc_str(10) basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, False) assert record == [(basesize + 10 * itemsize, p)] del record[:] # ---------- gc_malloc_unicode ---------- p = gc_ll_descr.gc_malloc_unicode(10) basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, False) assert record == [(basesize + 10 * itemsize, p)] del record[:]
class MovableObjectTracker(object): ptr_array_type = lltype.GcArray(llmemory.GCREF) def __init__(self, cpu, const_pointers): size = len(const_pointers) # check that there are any moving object (i.e. chaning pointers). # Otherwise there is no reason for an instance of this class. assert size > 0 # # prepare GC array to hold the pointers that may change self.ptr_array = lltype.malloc(MovableObjectTracker.ptr_array_type, size) self.ptr_array_descr = cpu.arraydescrof( MovableObjectTracker.ptr_array_type) self.ptr_array_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, self.ptr_array) # use always the same ConstPtr to access the array # (easer to read JIT trace) self.const_ptr_gcref_array = ConstPtr(self.ptr_array_gcref) # # assign each pointer an index and put the pointer into the GC array. # as pointers and addresses are not a good key to use before translation # ConstPtrs are used as the key for the dict. self._indexes = {} for index in range(size): ptr = const_pointers[index] self._indexes[ptr] = index self.ptr_array[index] = ptr.value def get_array_index(self, const_ptr): index = self._indexes[const_ptr] assert const_ptr.value == self.ptr_array[index] return index
def test_can_move(self): TP = lltype.GcArray(lltype.Float) def func(): return rgc.can_move(lltype.malloc(TP, 1)) assert self.interpret(func, []) == self.GC_CAN_MOVE
def test_rewrite_assembler_nonstandard_array(self): # a non-standard array is a bit hard to get; e.g. GcArray(Float) # is like that on Win32, but not on Linux. Build one manually... NONSTD = lltype.GcArray(lltype.Float) nonstd_descr = get_array_descr(self.gc_ll_descr, NONSTD) nonstd_descr.tid = 6464 nonstd_descr.basesize = 64 # <= hacked nonstd_descr.itemsize = 8 nonstd_descr_gcref = 123 self.check_rewrite(""" [i0, p1] p0 = new_array(i0, descr=nonstd_descr) setarrayitem_gc(p0, i0, p1) jump(i0) """, """ [i0, p1] p0 = call_malloc_gc(ConstClass(malloc_array_nonstandard), \ 64, 8, \ %(nonstd_descr.lendescr.offset)d, \ 6464, i0, \ descr=malloc_array_nonstandard_descr) cond_call_gc_wb_array(p0, i0, descr=wbdescr) setarrayitem_gc(p0, i0, p1) jump(i0) """, nonstd_descr=nonstd_descr)
def test_is_pure(): from rpython.flowspace.model import Variable, Constant assert llop.bool_not.is_pure([Variable()]) assert llop.debug_assert.is_pure([Variable()]) assert not llop.int_add_ovf.is_pure([Variable(), Variable()]) # S1 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) v_s1 = Variable() v_s1.concretetype = lltype.Ptr(S1) assert not llop.setfield.is_pure([v_s1, Constant('x'), Variable()]) assert not llop.getfield.is_pure([v_s1, Constant('y')]) # A1 = lltype.GcArray(lltype.Signed) v_a1 = Variable() v_a1.concretetype = lltype.Ptr(A1) assert not llop.setarrayitem.is_pure([v_a1, Variable(), Variable()]) assert not llop.getarrayitem.is_pure([v_a1, Variable()]) assert llop.getarraysize.is_pure([v_a1]) # S2 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed), hints={'immutable': True}) v_s2 = Variable() v_s2.concretetype = lltype.Ptr(S2) assert not llop.setfield.is_pure([v_s2, Constant('x'), Variable()]) assert llop.getfield.is_pure([v_s2, Constant('y')]) # A2 = lltype.GcArray(lltype.Signed, hints={'immutable': True}) v_a2 = Variable() v_a2.concretetype = lltype.Ptr(A2) assert not llop.setarrayitem.is_pure([v_a2, Variable(), Variable()]) assert llop.getarrayitem.is_pure([v_a2, Variable()]) assert llop.getarraysize.is_pure([v_a2]) # for kind in [ rclass.IR_MUTABLE, rclass.IR_IMMUTABLE, rclass.IR_IMMUTABLE_ARRAY, rclass.IR_QUASIIMMUTABLE, rclass.IR_QUASIIMMUTABLE_ARRAY ]: accessor = rclass.FieldListAccessor() S3 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed), hints={'immutable_fields': accessor}) accessor.initialize(S3, {'x': kind}) v_s3 = Variable() v_s3.concretetype = lltype.Ptr(S3) assert not llop.setfield.is_pure([v_s3, Constant('x'), Variable()]) assert not llop.setfield.is_pure([v_s3, Constant('y'), Variable()]) assert llop.getfield.is_pure([v_s3, Constant('x')]) is kind assert not llop.getfield.is_pure([v_s3, Constant('y')])
def test_interior_ptr_with_index(self): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcArray(S) def f(x): t = lltype.malloc(T, 1) t[0].x = x return t[0].x graph = self.check(f, [int], [42], 42)
def test_write_barrier_support_setarrayitem(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) ARRAYPTR = lltype.Ptr(lltype.GcArray(PTR_TYPE2)) write_barrier_check(SpaceOperation( "setarrayitem", [varoftype(ARRAYPTR), varoftype(lltype.Signed), varoftype(PTR_TYPE2)], varoftype(lltype.Void)))
def test_malloc_varsize_no_cleanup(self): x = lltype.Signed VAR1 = lltype.GcArray(x) p = self.malloc(VAR1, 5) import pytest with pytest.raises(lltype.UninitializedMemoryAccess): assert isinstance(p[0], lltype._uninitialized) x1 = p[0]
def xxx_test_malloc_array_of_ptr_arr(self): ARR_OF_PTR_ARR = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Ptr(S)))) arr_of_ptr_arr = self.malloc(ARR_OF_PTR_ARR, 10) self.stackroots.append(arr_of_ptr_arr) for i in range(10): assert arr_of_ptr_arr[i] == lltype.nullptr(lltype.GcArray(lltype.Ptr(S))) for i in range(10): self.writearray(arr_of_ptr_arr, i, self.malloc(lltype.GcArray(lltype.Ptr(S)), i)) #self.stackroots.append(arr_of_ptr_arr[i]) #debug_print(arr_of_ptr_arr[i]) for elem in arr_of_ptr_arr[i]: #self.stackroots.append(elem) assert elem == lltype.nullptr(S) elem = self.malloc(S) assert elem.prev == lltype.nullptr(S) assert elem.next == lltype.nullptr(S)
def test_gc_malloc_array(self): A = lltype.GcArray(lltype.Signed) arraydescr = descr.get_array_descr(self.gc_ll_descr, A) p = self.gc_ll_descr.gc_malloc_array(10, arraydescr) assert self.llop1.record == [ ("varsize", arraydescr.tid, 10, repr(arraydescr.basesize), repr(arraydescr.itemsize), repr(arraydescr.lendescr.offset), p) ]
def test_trace_array_of_structs(self): R = lltype.GcStruct('R', ('i', lltype.Signed)) S1 = lltype.GcArray(('p1', lltype.Ptr(R))) S2 = lltype.GcArray(('p1', lltype.Ptr(R)), ('p2', lltype.Ptr(R))) S3 = lltype.GcArray(('p1', lltype.Ptr(R)), ('p2', lltype.Ptr(R)), ('p3', lltype.Ptr(R))) def func(): s1 = lltype.malloc(S1, 2) s1[0].p1 = lltype.malloc(R) s1[1].p1 = lltype.malloc(R) s2 = lltype.malloc(S2, 2) s2[0].p1 = lltype.malloc(R) s2[0].p2 = lltype.malloc(R) s2[1].p1 = lltype.malloc(R) s2[1].p2 = lltype.malloc(R) s3 = lltype.malloc(S3, 2) s3[0].p1 = lltype.malloc(R) s3[0].p2 = lltype.malloc(R) s3[0].p3 = lltype.malloc(R) s3[1].p1 = lltype.malloc(R) s3[1].p2 = lltype.malloc(R) s3[1].p3 = lltype.malloc(R) s1[0].p1.i = 100 s1[1].p1.i = 101 s2[0].p1.i = 102 s2[0].p2.i = 103 s2[1].p1.i = 104 s2[1].p2.i = 105 s3[0].p1.i = 106 s3[0].p2.i = 107 s3[0].p3.i = 108 s3[1].p1.i = 109 s3[1].p2.i = 110 s3[1].p3.i = 111 rgc.collect() return ((s1[0].p1.i == 100) + (s1[1].p1.i == 101) + (s2[0].p1.i == 102) + (s2[0].p2.i == 103) + (s2[1].p1.i == 104) + (s2[1].p2.i == 105) + (s3[0].p1.i == 106) + (s3[0].p2.i == 107) + (s3[0].p3.i == 108) + (s3[1].p1.i == 109) + (s3[1].p2.i == 110) + (s3[1].p3.i == 111)) res = self.interpret(func, []) assert res == 12
def test_list_from_fixedptr(self, space, api): A = lltype.GcArray(lltype.Float) ptr = lltype.malloc(A, 3) assert isinstance(ptr, lltype._ptr) ptr[0] = 10. ptr[1] = 5. ptr[2] = 3. l = list(ptr) assert l == [10., 5., 3.]
def test_write_barrier_support_setinteriorfield(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) ARRAYPTR2 = lltype.Ptr(lltype.GcArray(('a', lltype.Signed), ('b', PTR_TYPE2))) write_barrier_check(SpaceOperation( "setinteriorfield", [varoftype(ARRAYPTR2), varoftype(lltype.Signed), Constant('b', lltype.Void), varoftype(PTR_TYPE2)], varoftype(lltype.Void)))
def test_ll_arrayclear(): TYPE = lltype.GcArray(lltype.Signed) a1 = lltype.malloc(TYPE, 10) for i in range(10): a1[i] = 100 + i rgc.ll_arrayclear(a1) assert len(a1) == 10 for i in range(10): assert a1[i] == 0
def test_interior_ptr_with_index_and_field(self): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.Struct("T", ('s', S)) U = lltype.GcArray(T) def f(x): u = lltype.malloc(U, 1) u[0].s.x = x return u[0].s.x graph = self.check(f, [int], [42], 42)
def test_generic_gcarray_of_ptr(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed)) A1 = lltype.GcArray(lltype.Ptr(S1)) A2 = lltype.GcArray(lltype.Ptr(A1)) a2 = lltype.malloc(A2, 3) a2[1] = lltype.malloc(A1, 4) a2[1][2] = lltype.malloc(S1) a2[1][2].x = -33 adr = cast_ptr_to_adr(a2) assert (adr + gcarrayofptr_lengthoffset).signed[0] == 3 adr += gcarrayofptr_itemsoffset adr += gcarrayofptr_singleitemoffset adr = adr.address[0] # => a2[1] assert (adr + gcarrayofptr_lengthoffset).signed[0] == 4 adr += gcarrayofptr_itemsoffset + 2 * gcarrayofptr_singleitemoffset adr = adr.address[0] # => s2[1][2] assert (adr + FieldOffset(S1, 'x')).signed[0] == -33
def test_getvar_const_ptr(self): x = ''' [] call_n(ConstPtr(func_ptr)) ''' TP = lltype.GcArray(lltype.Signed) NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) loop = self.parse(x, None, {'func_ptr': NULL}) assert loop.operations[0].getarg(0).value == NULL