def gen_guard(self, builder, r): if r.random() < 0.5: return GuardClassOperation.gen_guard(self, builder, r) else: v = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) op = ResOperation(rop.SAME_AS, [ConstPtr(v.value)], v) builder.loop.operations.append(op) v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable2 = S2._hints['vtable']._as_ptr() c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), builder.cpu) op = ResOperation(self.opnum, [v, c_vtable2], None) return op, False
def test_unicode(self): ofs = symbolic.get_field_token(rstr.UNICODE, 'chars', False)[0] u = rstr.mallocunicode(13) for i in range(13): u.chars[i] = unichr(ord(u'a') + i) b = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, u)) r = self.execute_operation(rop.UNICODEGETITEM, [b, ConstInt(2)], 'int') assert r.value == ord(u'a') + 2 self.execute_operation(rop.UNICODESETITEM, [b, ConstInt(2), ConstInt(ord(u'z'))], 'void') assert u.chars[2] == u'z' assert u.chars[3] == u'd'
def test_simple_read_tagged_ints(): b1, b2, b3 = [BoxInt(), BoxPtr(), BoxInt()] storage = Storage() storage.rd_consts = [] numb = Numbering(None, [tag(0, TAGBOX), tag(1, TAGBOX), tag(2, TAGBOX)]) numb = Numbering(numb, [tag(2, TAGINT), tag(3, TAGINT)]) numb = Numbering( numb, [tag(0, TAGBOX), tag(1, TAGINT), tag(0, TAGBOX), tag(1, TAGBOX)]) storage.rd_numb = numb storage.rd_virtuals = None b1s, b2s, b3s = [BoxInt(), BoxPtr(), BoxInt()] assert b1s != b3s reader = ResumeDataReader(storage, [b1s, b2s, b3s], MyMetaInterp()) lst = reader.consume_boxes() assert lst == [b1s, ConstInt(1), b1s, b2s] lst = reader.consume_boxes() assert lst == [ConstInt(2), ConstInt(3)] lst = reader.consume_boxes() assert lst == [b1s, b2s, b3s]
def test_NotVirtualStateInfo_generalization(self): def isgeneral(value1, value2): info1 = NotVirtualStateInfo(value1) info1.position = 0 info2 = NotVirtualStateInfo(value2) info2.position = 0 return info1.generalization_of(info2, {}, {}) assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7))) assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt())) ptr = OptValue(BoxPtr()) nonnull = OptValue(BoxPtr()) nonnull.make_nonnull(0) knownclass = OptValue(BoxPtr()) knownclass.make_constant_class(ConstPtr(self.someptr1), 0) const = OptValue(BoxPtr) const.make_constant_class(ConstPtr(self.someptr1), 0) const.make_constant(ConstPtr(self.someptr1)) inorder = [ptr, nonnull, knownclass, const] for i in range(len(inorder)): for j in range(i, len(inorder)): assert isgeneral(inorder[i], inorder[j]) if i != j: assert not isgeneral(inorder[j], inorder[i]) value1 = OptValue(BoxInt()) value2 = OptValue(BoxInt()) value2.intbound.make_lt(IntBound(10, 10)) assert isgeneral(value1, value2) assert not isgeneral(value2, value1) assert isgeneral(OptValue(ConstInt(7)), OptValue(ConstInt(7))) S = lltype.GcStruct('S') foo = lltype.malloc(S) fooref = lltype.cast_opaque_ptr(llmemory.GCREF, foo) assert isgeneral(OptValue(ConstPtr(fooref)), OptValue(ConstPtr(fooref)))
def test_virtual_adder_pending_fields(): b2s, b4s = [BoxPtr(), BoxPtr()] storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} v2 = OptValue(b2s) v4 = OptValue(b4s) modifier.register_box(b2s) modifier.register_box(b4s) values = {b4s: v4, b2s: v2} liveboxes = [] modifier._number_virtuals(liveboxes, values, 0) assert liveboxes == [b2s, b4s] or liveboxes == [b4s, b2s] modifier._add_pending_fields([(LLtypeMixin.nextdescr, b2s, b4s)]) storage.rd_consts = memo.consts[:] storage.rd_numb = None # resume demo55.next = lltype.nullptr(LLtypeMixin.NODE) b2t = BoxPtr(demo55o) b4t = BoxPtr(demo66o) newboxes = _resume_remap(liveboxes, [b2s, b4s], b2t, b4t) metainterp = MyMetaInterp() reader = ResumeDataReader(storage, newboxes, metainterp) assert reader.virtuals is None trace = metainterp.trace b2set = (rop.SETFIELD_GC, [b2t, b4t], None, LLtypeMixin.nextdescr) expected = [b2set] for x, y in zip(expected, trace): assert x == y assert len(expected) == len(trace) assert demo55.next == demo66
def test_nullity_with_guard(self): allops = [rop.OONONNULL, rop.OOISNULL, rop.INT_IS_TRUE] guards = [rop.GUARD_TRUE, rop.GUARD_FALSE] p = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcStruct('x'))) nullptr = lltype.nullptr(llmemory.GCREF.TO) f = BoxInt() for op in allops: for guard in guards: if op == rop.INT_IS_TRUE: bp = BoxInt(1) n = BoxInt(0) else: bp = BoxPtr(p) n = BoxPtr(nullptr) for b in (bp, n): i1 = BoxInt(1) ops = [ ResOperation(rop.SAME_AS, [ConstInt(1)], i1), ResOperation(op, [b], f), ResOperation(guard, [f], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], None, descr=BasicFailDescr()), ] ops[-2].fail_args = [i1] looptoken = LoopToken() self.cpu.compile_loop([b], ops, looptoken) if op == rop.INT_IS_TRUE: self.cpu.set_future_value_int(0, b.value) else: self.cpu.set_future_value_ref(0, b.value) r = self.cpu.execute_token(looptoken) result = self.cpu.get_latest_value_int(0) if guard == rop.GUARD_FALSE: assert result == execute(self.cpu, op, None, b).value else: assert result != execute(self.cpu, op, None, b).value
def test_known_class(self): value1 = OptValue(self.nodebox) classbox = self.cpu.ts.cls_of_box(self.nodebox) value1.make_constant_class(classbox, -1) info1 = NotVirtualStateInfo(value1) info2 = NotVirtualStateInfo(OptValue(self.nodebox)) expected = """ [p0] guard_nonnull(p0) [] guard_class(p0, ConstClass(node_vtable)) [] """ self.guards(info1, info2, self.nodebox, expected) py.test.raises(InvalidLoop, self.guards, info1, info2, BoxPtr(), expected)
def test_virtual_adder_make_varray(): b2s, b4s = [BoxPtr(), BoxInt(4)] c1s = ConstInt(111) storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} class FakeOptimizer(object): class cpu: pass def new_const_item(self, descr): return None v2 = VArrayValue(FakeOptimizer(), LLtypeMixin.arraydescr, 2, b2s) v2._items = [b4s, c1s] modifier.register_virtual_fields(b2s, [b4s, c1s]) liveboxes = [] values = {b2s: v2} modifier._number_virtuals(liveboxes, values, 0) dump_storage(storage, liveboxes) storage.rd_consts = memo.consts[:] storage.rd_numb = None # resume b1t, b3t, b4t = [BoxInt(11), BoxInt(33), BoxInt(44)] newboxes = _resume_remap(liveboxes, [#b2s -- virtual b4s], b4t) # resume metainterp = MyMetaInterp() reader = ResumeDataReader(storage, newboxes, metainterp) assert len(reader.virtuals) == 1 b2t = reader._decode_box(tag(0, TAGVIRTUAL)) trace = metainterp.trace expected = [ (rop.NEW_ARRAY, [ConstInt(2)], b2t, LLtypeMixin.arraydescr), (rop.SETARRAYITEM_GC, [b2t,ConstInt(0), b4t],None, LLtypeMixin.arraydescr), (rop.SETARRAYITEM_GC, [b2t,ConstInt(1), c1s], None, LLtypeMixin.arraydescr), ] for x, y in zip(expected, trace): assert x == y # ptr = b2t.value._obj.container._as_ptr() assert lltype.typeOf(ptr) == lltype.Ptr(lltype.GcArray(lltype.Signed)) assert len(ptr) == 2 assert ptr[0] == 44 assert ptr[1] == 111
def test_simple_read(): b1, b2, b3 = [BoxInt(), BoxPtr(), BoxInt()] c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] storage = Storage() storage.rd_consts = [c1, c2, c3] numb = Numbering(None, [tag(0, TAGBOX), tag(1, TAGBOX), tag(2, TAGBOX)]) numb = Numbering(numb, [tag(1, TAGCONST), tag(2, TAGCONST)]) numb = Numbering(numb, [tag(0, TAGBOX), tag(0, TAGCONST), NULLREF, tag(0, TAGBOX), tag(1, TAGBOX)]) storage.rd_numb = numb b1s, b2s, b3s = [BoxInt(), BoxPtr(), BoxInt()] assert b1s != b3s reader = ResumeDataReader(storage, [b1s, b2s, b3s], MyMetaInterp()) lst = reader.consume_boxes() assert lst == [b1s, ConstInt(1), LLtypeMixin.cpu.ts.CONST_NULL, b1s, b2s] lst = reader.consume_boxes() assert lst == [ConstInt(2), ConstInt(3)] lst = reader.consume_boxes() assert lst == [b1s, b2s, b3s]
def test_rebuild_from_resumedata_with_virtualizable(): b1, b2, b3, b4 = [BoxInt(), BoxPtr(), BoxInt(), BoxPtr()] c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] storage = Storage() fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] capture_resumedata(fs, [b4], [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) liveboxes = modifier.finish({}) metainterp = MyMetaInterp() b1t, b2t, b3t, b4t = [BoxInt(), BoxPtr(), BoxInt(), BoxPtr()] newboxes = _resume_remap(liveboxes, [b1, b2, b3, b4], b1t, b2t, b3t, b4t) result = rebuild_from_resumedata(metainterp, newboxes, storage, True) assert result == ([b4t], []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] assert metainterp.framestack == fs2
def do_call(self, args, calldescr): assert isinstance(calldescr, CallDescr) num_args = len(calldescr.args_indices) assert num_args == len(args) - 1 loop = self._get_loop_for_call(num_args, calldescr) history.set_future_values(self, args) self.execute_operations(loop) # Note: if an exception is set, the rest of the code does a bit of # nonsense but nothing wrong (the return value should be ignored) if calldescr.res_index < 0: return None elif calldescr.res_index == self.SIZE_GCPTR: return BoxPtr(self.get_latest_value_ref(0)) else: return BoxInt(self.get_latest_value_int(0))
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=BasicFailDescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def test_write_failure_recovery_description(): assembler = Assembler386(FakeCPU()) mc = FakeMC() failargs = [BoxInt(), BoxPtr(), BoxFloat()] * 3 failargs.insert(6, None) failargs.insert(7, None) locs = [ X86FrameManager.frame_pos(0, INT), X86FrameManager.frame_pos(1, REF), X86FrameManager.frame_pos(10, FLOAT), X86FrameManager.frame_pos(100, INT), X86FrameManager.frame_pos(101, REF), X86FrameManager.frame_pos(110, FLOAT), None, None, ebx, esi, xmm2 ] assert len(failargs) == len(locs) assembler.write_failure_recovery_description(mc, failargs, locs) base = 8 + 8 * IS_X86_64 nums = [ Assembler386.DESCR_INT + 4 * (base + 0), Assembler386.DESCR_REF + 4 * (base + 1), Assembler386.DESCR_FLOAT + 4 * (base + 10), Assembler386.DESCR_INT + 4 * (base + 100), Assembler386.DESCR_REF + 4 * (base + 101), Assembler386.DESCR_FLOAT + 4 * (base + 110), Assembler386.CODE_HOLE, Assembler386.CODE_HOLE, Assembler386.DESCR_INT + 4 * ebx.value, Assembler386.DESCR_REF + 4 * esi.value, Assembler386.DESCR_FLOAT + 4 * xmm2.value ] double_byte_nums = [] for num in nums[3:6]: double_byte_nums.append((num & 0x7F) | 0x80) double_byte_nums.append(num >> 7) assert mc.content == (nums[:3] + double_byte_nums + nums[6:] + [assembler.CODE_STOP]) # also test rebuild_faillocs_from_descr(), which should not # reproduce the holes at all bytecode = lltype.malloc(rffi.UCHARP.TO, len(mc.content), flavor='raw', immortal=True) for i in range(len(mc.content)): assert 0 <= mc.content[i] <= 255 bytecode[i] = rffi.cast(rffi.UCHAR, mc.content[i]) bytecode_addr = rffi.cast(lltype.Signed, bytecode) newlocs = assembler.rebuild_faillocs_from_descr(bytecode_addr) assert ([loc.assembler() for loc in newlocs ] == [loc.assembler() for loc in locs if loc is not None])
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT) self.put(builder, args, descr) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) assert builder.cpu.get_exception() builder.cpu.clear_exception() op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=builder.make_fail_descr()) op.fail_args = fail_subset builder.loop.operations.append(op)
def test_virtual_adder_make_varray(): b2s, b4s = [BoxPtr(), BoxInt(4)] c1s = ConstInt(111) storage = Storage() memo = ResumeDataLoopMemo(LLtypeMixin.cpu) modifier = ResumeDataVirtualAdder(storage, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.virtuals = [] modifier.vfieldboxes = [] modifier.make_varray(b2s, LLtypeMixin.arraydescr, [b4s, c1s]) # new fields liveboxes = [] modifier._number_virtuals(liveboxes) storage.rd_consts = memo.consts[:] storage.rd_numb = None # resume b1t, b3t, b4t = [BoxInt(11), BoxInt(33), BoxInt(44)] newboxes = _resume_remap( liveboxes, [ #b2s -- virtual b4s ], b4t) # resume metainterp = MyMetaInterp() reader = ResumeDataReader(storage, newboxes, metainterp) assert len(reader.virtuals) == 1 b2t = reader._decode_box(tag(0, TAGVIRTUAL)) trace = metainterp.trace expected = [ (rop.NEW_ARRAY, [ConstInt(2)], b2t, LLtypeMixin.arraydescr), (rop.SETARRAYITEM_GC, [b2t, ConstInt(0), b4t], None, LLtypeMixin.arraydescr), (rop.SETARRAYITEM_GC, [b2t, ConstInt(1), c1s], None, LLtypeMixin.arraydescr), ] for x, y in zip(expected, trace): assert x == y # ptr = b2t.value._obj.container._as_ptr() assert lltype.typeOf(ptr) == lltype.Ptr(lltype.GcArray(lltype.Signed)) assert len(ptr) == 2 assert ptr[0] == 44 assert ptr[1] == 111
def _do_getfield(self, struct, fielddescr): assert isinstance(fielddescr, FieldDescr) size_index = fielddescr.size_index if size_index == self.SIZE_GCPTR: p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) res = p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] return BoxPtr(res) elif size_index == self.SIZE_INT: p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) res = p[fielddescr.offset / rffi.sizeof(lltype.Signed)] elif size_index == self.SIZE_CHAR: p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct) res = ord(p[fielddescr.offset / rffi.sizeof(lltype.Char)]) elif size_index == self.SIZE_UNICHAR: p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct) res = ord(p[fielddescr.offset / rffi.sizeof(lltype.UniChar)]) else: raise BadSizeError return BoxInt(res)
def do_call(self, args, calldescr): assert isinstance(calldescr, BaseCallDescr) assert len(args) == 1 + len(calldescr.arg_classes) if not we_are_translated(): assert (list( calldescr.arg_classes) == [arg.type for arg in args[1:]]) loop_token = calldescr.get_token_for_call(self) set_future_values(self, args) self.execute_token(loop_token) # Note: if an exception is set, the rest of the code does a bit of # nonsense but nothing wrong (the return value should be ignored) if calldescr.returns_a_pointer(): return BoxPtr(self.get_latest_value_ref(0)) elif calldescr.returns_a_float(): return BoxFloat(self.get_latest_value_float(0)) elif calldescr.get_result_size(self.translate_support_code) > 0: return BoxInt(self.get_latest_value_int(0)) else: return None
def test_register_virtual_fields(): b1, b2 = BoxInt(), BoxInt() vbox = BoxPtr() modifier = ResumeDataVirtualAdder(None, None) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} modifier.register_virtual_fields(vbox, [b1, b2]) assert modifier.liveboxes == {vbox: UNASSIGNEDVIRTUAL, b1: UNASSIGNED, b2: UNASSIGNED} assert modifier.vfieldboxes == {vbox: [b1, b2]} modifier = ResumeDataVirtualAdder(None, None) modifier.liveboxes_from_env = {vbox: tag(0, TAGVIRTUAL)} modifier.liveboxes = {} modifier.vfieldboxes = {} modifier.register_virtual_fields(vbox, [b1, b2, vbox]) assert modifier.liveboxes == {b1: UNASSIGNED, b2: UNASSIGNED, vbox: tag(0, TAGVIRTUAL)} assert modifier.vfieldboxes == {vbox: [b1, b2, vbox]}
def produce_into(self, builder, r): subset, f = self.non_raising_func_code(builder, r) if len(subset) == 0: RES = lltype.Void else: RES = lltype.Signed TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT) self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=BasicFailDescr()) op.fail_args = builder.subset_of_intvars(r) op._exc_box = None builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def produce_into(self, builder, r): subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) while True: _, vtableptr = builder.get_random_structure_type_and_vtable(r) if vtableptr != exc: break other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr(), descr=BasicFailDescr()) op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def do_getarrayitem_gc(self, args, arraydescr): array = args[0].getref_base() index = args[1].getint() assert isinstance(arraydescr, ArrayDescr) itemsize_index = arraydescr.itemsize_index if itemsize_index == self.SIZE_GCPTR: p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) res = p[index] return BoxPtr(res) elif itemsize_index == self.SIZE_INT: p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) res = p[index] elif itemsize_index == self.SIZE_CHAR: p = rffi.cast(lltype.Ptr(self.gcarray_char), array) res = ord(p[index]) elif itemsize_index == self.SIZE_UNICHAR: p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array) res = ord(p[index]) else: raise BadSizeError return BoxInt(res)
def test_execute_nonspec(): cpu = FakeCPU() descr = FakeDescr() # cases with a descr # arity == -1 argboxes = [BoxInt(321), ConstInt(123)] box = execute_nonspec(cpu, FakeMetaInterp(), rop.CALL, argboxes, FakeCallDescr()) assert box.getfloat() == 42.5 # arity == 0 box = execute_nonspec(cpu, None, rop.NEW, [], descr) assert box.value.fakeargs == ('new', descr) # arity == 1 box1 = BoxPtr() box = execute_nonspec(cpu, None, rop.ARRAYLEN_GC, [box1], descr) assert box.value == 55 # arity == 2 box2 = boxfloat(222.2) fielddescr = FakeFieldDescr() execute_nonspec(cpu, None, rop.SETFIELD_GC, [box1, box2], fielddescr) assert cpu.fakesetfield == (box1.value, box2.value, fielddescr) # arity == 3 box3 = BoxInt(33) arraydescr = FakeArrayDescr() execute_nonspec(cpu, None, rop.SETARRAYITEM_GC, [box1, box3, box2], arraydescr) assert cpu.fakesetarrayitem == (box1.value, box3.value, box2.value, arraydescr) # cases without descr # arity == 1 box = execute_nonspec(cpu, None, rop.INT_INVERT, [box3]) assert box.value == ~33 # arity == 2 box = execute_nonspec(cpu, None, rop.INT_LSHIFT, [box3, BoxInt(3)]) assert box.value == 33 << 3 # arity == 3 execute_nonspec(cpu, None, rop.STRSETITEM, [box1, BoxInt(3), box3]) assert cpu.fakestrsetitem == (box1.value, 3, box3.value)
def _base_do_getfield(self, gcref, fielddescr): ofs, size, ptr, float = self.unpack_fielddescr(fielddescr) # --- start of GC unsafe code (no GC operation!) --- field = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) # if ptr: pval = rffi.cast(rffi.CArrayPtr(lltype.Signed), field)[0] pval = self._cast_int_to_gcref(pval) # --- end of GC unsafe code --- return BoxPtr(pval) # if float: fval = rffi.cast(rffi.CArrayPtr(lltype.Float), field)[0] # --- end of GC unsafe code --- return BoxFloat(fval) # for TYPE, itemsize in unroll_basic_sizes: if size == itemsize: val = rffi.cast(rffi.CArrayPtr(TYPE), field)[0] # --- end of GC unsafe code --- val = rffi.cast(lltype.Signed, val) return BoxInt(val) else: raise NotImplementedError("size = %d" % size)
def test_wrap(): def _is(box1, box2): return (box1.__class__ == box2.__class__ and box1.value == box2.value) p = lltype.malloc(lltype.GcStruct('S')) po = lltype.cast_opaque_ptr(llmemory.GCREF, p) assert _is(wrap(None, 42), BoxInt(42)) assert _is(wrap(None, 42.5), boxfloat(42.5)) assert _is(wrap(None, p), BoxPtr(po)) assert _is(wrap(None, 42, in_const_box=True), ConstInt(42)) assert _is(wrap(None, 42.5, in_const_box=True), constfloat(42.5)) assert _is(wrap(None, p, in_const_box=True), ConstPtr(po)) if longlong.supports_longlong: import sys from pypy.rlib.rarithmetic import r_longlong, r_ulonglong value = r_longlong(-sys.maxint * 17) assert _is(wrap(None, value), BoxFloat(value)) assert _is(wrap(None, value, in_const_box=True), ConstFloat(value)) value_unsigned = r_ulonglong(-sys.maxint * 17) assert _is(wrap(None, value_unsigned), BoxFloat(value)) sfval = r_singlefloat(42.5) ival = longlong.singlefloat2int(sfval) assert _is(wrap(None, sfval), BoxInt(ival)) assert _is(wrap(None, sfval, in_const_box=True), ConstInt(ival))
def do(cpu, _, *argboxes): newargs = () for argtype in argtypes: if argtype == 'cpu': value = cpu elif argtype == 'd': value = argboxes[-1] assert isinstance(value, AbstractDescr) argboxes = argboxes[:-1] else: argbox = argboxes[0] argboxes = argboxes[1:] if argtype == 'i': value = argbox.getint() elif argtype == 'r': value = argbox.getref_base() elif argtype == 'f': value = argbox.getfloatstorage() newargs = newargs + (value, ) assert not argboxes # result = func(*newargs) # if resulttype == 'i': return BoxInt(result) if resulttype == 'r': return BoxPtr(result) if resulttype == 'f': return BoxFloat(result) return None
def _get_loop_for_call(self, argnum, calldescr): loop = calldescr._generated_mp if loop is None: args = [BoxInt() for i in range(argnum + 1)] if calldescr.res_index < 0: result = None elif calldescr.res_index == self.SIZE_GCPTR: result = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) else: result = BoxInt(0) result_list = [] if result is not None: result_list.append(result) operations = [ ResOperation(rop.CALL, args, result, calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None), ResOperation(rop.FAIL, result_list, None)] operations[1].suboperations = [ResOperation(rop.FAIL, [], None)] loop = history.TreeLoop('call') loop.inputargs = args loop.operations = operations self.compile_operations(loop) calldescr._generated_mp = loop return loop
class LLtypeMixin(object): type_system = 'lltype' def get_class_of_box(self, box): return box.getref(rclass.OBJECTPTR).typeptr node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable.name = rclass.alloc_array_name('node') node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable) node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable2.name = rclass.alloc_array_name('node2') node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2) cpu = runner.LLtypeCPU(None) NODE = lltype.GcForwardReference() NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT), ('value', lltype.Signed), ('floatval', lltype.Float), ('next', lltype.Ptr(NODE)))) NODE2 = lltype.GcStruct('NODE2', ('parent', NODE), ('other', lltype.Ptr(NODE))) node = lltype.malloc(NODE) node.parent.typeptr = node_vtable nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) myptr = nodebox.value myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE)) nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) valuedescr = cpu.fielddescrof(NODE, 'value') floatdescr = cpu.fielddescrof(NODE, 'floatval') nextdescr = cpu.fielddescrof(NODE, 'next') otherdescr = cpu.fielddescrof(NODE2, 'other') NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT), ('ref', lltype.Ptr(OBJECT))) nodeobj = lltype.malloc(NODEOBJ) nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj) refdescr = cpu.fielddescrof(NODEOBJ, 'ref') arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed)) floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float)) # a GcStruct not inheriting from OBJECT S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE))) ssize = cpu.sizeof(S) adescr = cpu.fielddescrof(S, 'a') bdescr = cpu.fielddescrof(S, 'b') sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))) arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S))) T = lltype.GcStruct('TUPLE', ('c', lltype.Signed), ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE))))) tsize = cpu.sizeof(T) cdescr = cpu.fielddescrof(T, 'c') ddescr = cpu.fielddescrof(T, 'd') arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE))) U = lltype.GcStruct('U', ('parent', OBJECT), ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE))))) u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable) usize = cpu.sizeof(U) onedescr = cpu.fielddescrof(U, 'one') FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [])) writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [adescr], [])) writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [adescr], [arraydescr])) readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([adescr], [], [])) mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([nextdescr], [], [], forces_virtual_or_virtualizable=True)) class LoopToken(AbstractDescr): pass asmdescr = LoopToken() # it can be whatever, it's not a descr though from pypy.jit.metainterp.virtualref import VirtualRefInfo class FakeWarmRunnerDesc: pass FakeWarmRunnerDesc.cpu = cpu vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc) virtualtokendescr = vrefinfo.descr_virtual_token virtualrefindexdescr = vrefinfo.descr_virtualref_index virtualforceddescr = vrefinfo.descr_forced jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) cpu.class_sizes = { cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U), cpu.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof( vrefinfo.JIT_VIRTUAL_REF), } namespace = locals()
class LLtypeMixin(object): type_system = 'lltype' def get_class_of_box(self, box): return box.getref(rclass.OBJECTPTR).typeptr node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable.name = rclass.alloc_array_name('node') node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable) node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable2.name = rclass.alloc_array_name('node2') node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2) cpu = runner.LLtypeCPU(None) NODE = lltype.GcForwardReference() NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT), ('value', lltype.Signed), ('floatval', lltype.Float), ('next', lltype.Ptr(NODE)))) NODE2 = lltype.GcStruct('NODE2', ('parent', NODE), ('other', lltype.Ptr(NODE))) node = lltype.malloc(NODE) node.parent.typeptr = node_vtable node2 = lltype.malloc(NODE2) node2.parent.parent.typeptr = node_vtable2 nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) myptr = nodebox.value myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE)) nullptr = lltype.nullptr(llmemory.GCREF.TO) nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node2)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) valuedescr = cpu.fielddescrof(NODE, 'value') floatdescr = cpu.fielddescrof(NODE, 'floatval') nextdescr = cpu.fielddescrof(NODE, 'next') otherdescr = cpu.fielddescrof(NODE2, 'other') accessor = FieldListAccessor() accessor.initialize(None, {'inst_field': IR_QUASIIMMUTABLE}) QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed), ('mutate_field', rclass.OBJECTPTR), hints={'immutable_fields': accessor}) quasisize = cpu.sizeof(QUASI) quasi = lltype.malloc(QUASI, immortal=True) quasi.inst_field = -4247 quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field') quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi)) quasiimmutdescr = QuasiImmutDescr(cpu, quasibox, quasifielddescr, cpu.fielddescrof(QUASI, 'mutate_field')) NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT), ('ref', lltype.Ptr(OBJECT))) nodeobj = lltype.malloc(NODEOBJ) nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj) refdescr = cpu.fielddescrof(NODEOBJ, 'ref') INTOBJ_NOIMMUT = lltype.GcStruct('INTOBJ_NOIMMUT', ('parent', OBJECT), ('intval', lltype.Signed)) INTOBJ_IMMUT = lltype.GcStruct('INTOBJ_IMMUT', ('parent', OBJECT), ('intval', lltype.Signed), hints={'immutable': True}) intobj_noimmut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) intobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) noimmut_intval = cpu.fielddescrof(INTOBJ_NOIMMUT, 'intval') immut_intval = cpu.fielddescrof(INTOBJ_IMMUT, 'intval') PTROBJ_IMMUT = lltype.GcStruct('PTROBJ_IMMUT', ('parent', OBJECT), ('ptrval', lltype.Ptr(OBJECT)), hints={'immutable': True}) ptrobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) immut_ptrval = cpu.fielddescrof(PTROBJ_IMMUT, 'ptrval') arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed)) floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float)) # a GcStruct not inheriting from OBJECT S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE))) ssize = cpu.sizeof(S) adescr = cpu.fielddescrof(S, 'a') bdescr = cpu.fielddescrof(S, 'b') sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))) arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S))) T = lltype.GcStruct('TUPLE', ('c', lltype.Signed), ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE))))) tsize = cpu.sizeof(T) cdescr = cpu.fielddescrof(T, 'c') ddescr = cpu.fielddescrof(T, 'd') arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE))) U = lltype.GcStruct('U', ('parent', OBJECT), ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE))))) u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable) usize = cpu.sizeof(U) onedescr = cpu.fielddescrof(U, 'one') FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [], [])) writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [adescr], [])) writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [adescr], [arraydescr])) readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([adescr], [], [], [])) mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([nextdescr], [], [], [], EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE, can_invalidate=True)) arraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [arraydescr], [], [arraydescr], EffectInfo.EF_CANNOT_RAISE, oopspecindex=EffectInfo.OS_ARRAYCOPY)) # array of structs (complex data) complexarray = lltype.GcArray( lltype.Struct("complex", ("real", lltype.Float), ("imag", lltype.Float), ) ) complexarraydescr = cpu.arraydescrof(complexarray) complexrealdescr = cpu.interiorfielddescrof(complexarray, "real") compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag") for _name, _os in [ ('strconcatdescr', 'OS_STR_CONCAT'), ('strslicedescr', 'OS_STR_SLICE'), ('strequaldescr', 'OS_STR_EQUAL'), ('streq_slice_checknull_descr', 'OS_STREQ_SLICE_CHECKNULL'), ('streq_slice_nonnull_descr', 'OS_STREQ_SLICE_NONNULL'), ('streq_slice_char_descr', 'OS_STREQ_SLICE_CHAR'), ('streq_nonnull_descr', 'OS_STREQ_NONNULL'), ('streq_nonnull_char_descr', 'OS_STREQ_NONNULL_CHAR'), ('streq_checknull_char_descr', 'OS_STREQ_CHECKNULL_CHAR'), ('streq_lengthok_descr', 'OS_STREQ_LENGTHOK'), ]: _oopspecindex = getattr(EffectInfo, _os) locals()[_name] = \ cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [], [], EffectInfo.EF_CANNOT_RAISE, oopspecindex=_oopspecindex)) # _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI')) locals()[_name.replace('str', 'unicode')] = \ cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [], [], EffectInfo.EF_CANNOT_RAISE, oopspecindex=_oopspecindex)) s2u_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [], [], [], oopspecindex=EffectInfo.OS_STR2UNICODE)) # class LoopToken(AbstractDescr): pass asmdescr = LoopToken() # it can be whatever, it's not a descr though from pypy.jit.metainterp.virtualref import VirtualRefInfo class FakeWarmRunnerDesc: pass FakeWarmRunnerDesc.cpu = cpu vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc) virtualtokendescr = vrefinfo.descr_virtual_token virtualforceddescr = vrefinfo.descr_forced jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) register_known_gctype(cpu, node_vtable, NODE) register_known_gctype(cpu, node_vtable2, NODE2) register_known_gctype(cpu, u_vtable, U) register_known_gctype(cpu, jit_virtual_ref_vtable,vrefinfo.JIT_VIRTUAL_REF) register_known_gctype(cpu, intobj_noimmut_vtable, INTOBJ_NOIMMUT) register_known_gctype(cpu, intobj_immut_vtable, INTOBJ_IMMUT) register_known_gctype(cpu, ptrobj_immut_vtable, PTROBJ_IMMUT) namespace = locals()
def do_newunicode(self, countbox): num_elem = countbox.getint() res = self.gc_ll_descr.gc_malloc_unicode(num_elem) return BoxPtr(res)
def do_new_array(self, countbox, arraydescr): num_elem = countbox.getint() res = self.gc_ll_descr.gc_malloc_array(arraydescr, num_elem) return BoxPtr(res)