def test_unknown_operation(): op = SpaceOperation("foobar", [], varoftype(lltype.Void)) tr = Transformer() try: tr.rewrite_operation(op) except Exception, e: assert "foobar" in str(e)
def indirect_residual_call_test(argtypes, restype, expectedkind): # an indirect call that is residual in all cases is very similar to # a residual direct call op = get_direct_call_op(argtypes, restype) op.opname = "indirect_call" op.args[0] = varoftype(op.args[0].concretetype) op.args.append(Constant(["somegraph1", "somegraph2"], lltype.Void)) tr = Transformer(FakeCPU(), FakeResidualIndirectCallControl()) tr.graph = "someinitialgraph" oplist = tr.rewrite_operation(op) op0, op1 = oplist reskind = getkind(restype)[0] assert op0.opname == "residual_call_%s_%s" % (expectedkind, reskind) assert op0.result == op.result assert op0.args[0] == op.args[0] assert op0.args[-1] == "calldescr" assert len(op0.args) == 1 + len(expectedkind) + 1 for sublist, kind1 in zip(op0.args[1:-1], expectedkind): assert sublist.kind.startswith(kind1) assert list(sublist) == [v for v in op.args[1:] if getkind(v.concretetype) == sublist.kind] for v in op.args[1:]: kind = getkind(v.concretetype) assert kind == "void" or kind[0] in expectedkind assert op1.opname == "-live-" assert op1.args == []
def do_check(self, opname, oopspecindex, ARGS, RESULT): vlist = [varoftype(ARG) for ARG in ARGS] v_result = varoftype(RESULT) op = SpaceOperation(opname, vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) if isinstance(op1, list): [op1] = op1 # def is_llf(TYPE): return (TYPE == lltype.SignedLongLong or TYPE == lltype.UnsignedLongLong or TYPE == lltype.Float) if is_llf(RESULT): assert op1.opname == 'residual_call_irf_f' else: assert op1.opname == 'residual_call_irf_i' gotindex = getattr(EffectInfo, 'OS_' + op1.args[0].value.upper().lstrip('U')) assert gotindex == oopspecindex assert list(op1.args[1]) == [v for v in vlist if not is_llf(v.concretetype)] assert list(op1.args[2]) == [] assert list(op1.args[3]) == [v for v in vlist if is_llf(v.concretetype)] assert op1.args[4] == 'calldescr-%d' % oopspecindex assert op1.result == v_result
def test_is_true(self): for opname, T in [('llong_is_true', lltype.SignedLongLong), ('ullong_is_true', lltype.UnsignedLongLong)]: v = varoftype(T) v_result = varoftype(lltype.Bool) op = SpaceOperation(opname, [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == opname.split('_')[0]+'_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert v_x.concretetype is T assert oplist[1].opname == 'residual_call_irf_i' assert oplist[1].args[0].value == 'llong_ne' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v, v_x] assert oplist[1].args[4] == 'calldescr-76' assert oplist[1].result == v_result
def do_check(self, opname, oopspecindex, ARGS, RESULT): vlist = [varoftype(ARG) for ARG in ARGS] v_result = varoftype(RESULT) op = SpaceOperation(opname, vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) if isinstance(op1, list): [op1] = op1 # def is_llf(TYPE): return (TYPE == lltype.SignedLongLong or TYPE == lltype.UnsignedLongLong or TYPE == lltype.Float) if is_llf(RESULT): assert op1.opname == 'residual_call_irf_f' else: assert op1.opname == 'residual_call_irf_i' gotindex = getattr(EffectInfo, 'OS_' + op1.args[0].value.upper().lstrip('U')) assert gotindex == oopspecindex assert list( op1.args[1]) == [v for v in vlist if not is_llf(v.concretetype)] assert list(op1.args[2]) == [] assert list( op1.args[3]) == [v for v in vlist if is_llf(v.concretetype)] assert op1.args[4] == 'calldescr-%d' % oopspecindex assert op1.result == v_result
def test_is_true(self): for opname, T in [('llong_is_true', lltype.SignedLongLong), ('ullong_is_true', lltype.UnsignedLongLong)]: v = varoftype(T) v_result = varoftype(lltype.Bool) op = SpaceOperation(opname, [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == opname.split( '_')[0] + '_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert v_x.concretetype is T assert oplist[1].opname == 'residual_call_irf_i' assert oplist[1].args[0].value == 'llong_ne' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v, v_x] assert oplist[1].args[4] == 'calldescr-76' assert oplist[1].result == v_result
def test_double_promote_nonstr(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = SpaceOperation("hint", [v1, Constant({"promote": True}, lltype.Void)], v2) op2 = SpaceOperation("hint", [v1, Constant({"promote_string": True, "promote": True}, lltype.Void)], v2) lst1 = tr.rewrite_operation(op1) lst2 = tr.rewrite_operation(op2) assert lst1 == lst2
def test_int_abs(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) op = SpaceOperation("int_abs", [v1], v2) tr = Transformer(FakeCPU(), FakeRegularCallControl()) tr.graph = "somemaingraph" oplist = tr.rewrite_operation(op) assert oplist[0].opname == "inline_call_ir_i" assert oplist[0].args[0] == "somejitcode"
def test_raw_free(): S = rffi.CArray(lltype.Char) flags = Constant({"flavor": "raw", "track_allocation": True}, lltype.Void) op = SpaceOperation("free", [varoftype(lltype.Ptr(S)), flags], varoftype(lltype.Void)) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op0 = tr.rewrite_operation(op) assert op0.opname == "residual_call_ir_v" assert op0.args[0].value == "raw_free" assert op0.args[-1] == "calldescr-%d" % effectinfo.EffectInfo.OS_RAW_FREE
def test_raw_free_no_track_allocation(): S = rffi.CArray(lltype.Signed) flags = Constant({"flavor": "raw", "track_allocation": False}, lltype.Void) op = SpaceOperation("free", [varoftype(lltype.Ptr(S)), flags], varoftype(lltype.Void)) tr = Transformer(FakeCPU(), FakeResidualCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == "residual_call_ir_v" assert op0.args[0].value == "raw_free_no_track_allocation" assert op1.opname == "-live-"
def test_raw_malloc_fixedsize(): S = lltype.Struct("dummy", ("x", lltype.Signed)) v = varoftype(lltype.Ptr(S)) flags = Constant({"flavor": "raw", "zero": True}, lltype.Void) op = SpaceOperation("malloc", [Constant(S, lltype.Void), flags], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == "residual_call_r_i" assert op0.args[0].value == "raw_malloc_fixedsize_zero" # pseudo-fn as a str assert op1.opname == "-live-" assert op1.args == []
def test_str_promote(): PSTR = lltype.Ptr(rstr.STR) v1 = varoftype(PSTR) v2 = varoftype(PSTR) op = SpaceOperation("hint", [v1, Constant({"promote_string": True}, lltype.Void)], v2) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op0, op1, _ = tr.rewrite_operation(op) assert op1.opname == "str_guard_value" assert op1.args[0] == v1 assert op1.args[2] == "calldescr" assert op1.result == v2 assert op0.opname == "-live-"
def test_raw_malloc_zero(): S = rffi.CArray(lltype.Signed) v1 = varoftype(lltype.Signed) v = varoftype(lltype.Ptr(S)) flags = Constant({"flavor": "raw", "zero": True}, lltype.Void) op = SpaceOperation("malloc_varsize", [Constant(S, lltype.Void), flags, v1], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == "residual_call_ir_i" assert op0.args[0].value == "raw_malloc_varsize_zero" # pseudo-fn as a str assert op1.opname == "-live-" assert op1.args == []
def test_cast_opaque_ptr(): S = lltype.GcStruct("S", ("x", lltype.Signed)) v1 = varoftype(lltype.Ptr(S)) v2 = varoftype(lltype.Ptr(rclass.OBJECT)) op = SpaceOperation("cast_opaque_ptr", [v1], v2) tr = Transformer() [op1, op2] = tr.rewrite_operation(op) assert op1.opname == "mark_opaque_ptr" assert op1.args == [v1] assert op1.result is None assert op2 is None
def test_constants(self): for TYPE in [lltype.SignedLongLong, lltype.UnsignedLongLong]: v_x = varoftype(TYPE) vlist = [v_x, const(rffi.cast(TYPE, 7))] v_result = varoftype(TYPE) op = SpaceOperation('llong_add', vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) # assert op1.opname == 'residual_call_irf_f' assert list(op1.args[1]) == [] assert list(op1.args[2]) == [] assert list(op1.args[3]) == vlist assert op1.result == v_result
def test_constants(self): for TYPE in [lltype.SignedLongLong, lltype.UnsignedLongLong]: v_x = varoftype(TYPE) vlist = [v_x, const(rffi.cast(TYPE, 7))] v_result = varoftype(TYPE) op = SpaceOperation('llong_add', vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) # assert op1.opname == 'residual_call_irf_f' assert list(op1.args[1]) == [] assert list(op1.args[2]) == [] assert list(op1.args[3]) == vlist assert op1.result == v_result
def test_raw_malloc(): S = rffi.CArray(lltype.Char) v1 = varoftype(lltype.Signed) v = varoftype(lltype.Ptr(S)) flags = Constant({"flavor": "raw"}, lltype.Void) op = SpaceOperation("malloc_varsize", [Constant(S, lltype.Void), flags, v1], v) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == "residual_call_ir_i" assert op0.args[0].value == "raw_malloc_varsize" # pseudo-function as a str assert op0.args[-1] == "calldescr-%d" % effectinfo.EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR assert op1.opname == "-live-" assert op1.args == []
def test_str2unicode(): # test that the oopspec is present and correctly transformed PSTR = lltype.Ptr(rstr.STR) PUNICODE = lltype.Ptr(rstr.UNICODE) FUNC = lltype.FuncType([PSTR], PUNICODE) func = lltype.functionptr(FUNC, "ll_str2unicode", _callable=rstr.LLHelpers.ll_str2unicode) v1 = varoftype(PSTR) v2 = varoftype(PUNICODE) op = SpaceOperation("direct_call", [const(func), v1], v2) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1.opname == "residual_call_r_r" assert op1.args[0].value == func assert op1.args[1] == ListOfKind("ref", [v1]) assert op1.args[2] == "calldescr-%d" % effectinfo.EffectInfo.OS_STR2UNICODE assert op1.result == v2
def test_malloc_new_with_destructor(): vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) S = lltype.GcStruct("S", ("parent", rclass.OBJECT), rtti=True) DESTRUCTOR = lltype.FuncType([lltype.Ptr(S)], lltype.Void) destructor = lltype.functionptr(DESTRUCTOR, "destructor") lltype.attachRuntimeTypeInfo(S, destrptr=destructor) heaptracker.set_testing_vtable_for_gcstruct(S, vtable, "S") v = varoftype(lltype.Ptr(S)) op = SpaceOperation("malloc", [Constant(S, lltype.Void), Constant({"flavor": "gc"}, lltype.Void)], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) oplist = tr.rewrite_operation(op) op0, op1 = oplist assert op0.opname == "residual_call_r_r" assert op0.args[0].value == "alloc_with_del" # pseudo-function as a str assert list(op0.args[1]) == [] assert op1.opname == "-live-" assert op1.args == []
def test_math_sqrt(): # test that the oopspec is present and correctly transformed FLOAT = lltype.Float FUNC = lltype.FuncType([FLOAT], FLOAT) func = lltype.functionptr(FUNC, "ll_math", _callable=ll_math.sqrt_nonneg) v1 = varoftype(FLOAT) v2 = varoftype(FLOAT) op = SpaceOperation("direct_call", [const(func), v1], v2) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1.opname == "residual_call_irf_f" assert op1.args[0].value == func assert op1.args[1] == ListOfKind("int", []) assert op1.args[2] == ListOfKind("ref", []) assert op1.args[3] == ListOfKind("float", [v1]) assert op1.args[4] == "calldescr-%d" % effectinfo.EffectInfo.OS_MATH_SQRT assert op1.result == v2
def test_unicode_slice(): # test that the oopspec is present and correctly transformed PUNICODE = lltype.Ptr(rstr.UNICODE) INT = lltype.Signed FUNC = lltype.FuncType([PUNICODE, INT, INT], PUNICODE) func = lltype.functionptr(FUNC, "_ll_stringslice", _callable=rstr.LLHelpers._ll_stringslice) v1 = varoftype(PUNICODE) v2 = varoftype(INT) v3 = varoftype(INT) v4 = varoftype(PUNICODE) op = SpaceOperation("direct_call", [const(func), v1, v2, v3], v4) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1.opname == "residual_call_ir_r" assert op1.args[0].value == func assert op1.args[1] == ListOfKind("int", [v2, v3]) assert op1.args[2] == ListOfKind("ref", [v1]) assert op1.args[3] == "calldescr-%d" % effectinfo.EffectInfo.OS_UNI_SLICE assert op1.result == v4
def residual_call_test(argtypes, restype, expectedkind): op = get_direct_call_op(argtypes, restype) tr = Transformer(FakeCPU(), FakeResidualCallControl()) oplist = tr.rewrite_operation(op) op0, op1 = oplist reskind = getkind(restype)[0] assert op0.opname == "residual_call_%s_%s" % (expectedkind, reskind) assert op0.result == op.result assert op0.args[0] == op.args[0] assert op0.args[-1] == "calldescr" assert len(op0.args) == 1 + len(expectedkind) + 1 for sublist, kind1 in zip(op0.args[1:-1], expectedkind): assert sublist.kind.startswith(kind1) assert list(sublist) == [v for v in op.args[1:] if getkind(v.concretetype) == sublist.kind] for v in op.args[1:]: kind = getkind(v.concretetype) assert kind == "void" or kind[0] in expectedkind assert op1.opname == "-live-" assert op1.args == []
def direct_call_test(argtypes, restype, expectedkind): op = get_direct_call_op(argtypes, restype) tr = Transformer(FakeCPU(), FakeRegularCallControl()) tr.graph = "someinitialgraph" oplist = tr.rewrite_operation(op) op0, op1 = oplist reskind = getkind(restype)[0] assert op0.opname == "inline_call_%s_%s" % (expectedkind, reskind) assert op0.result == op.result assert op0.args[0] == "somejitcode" assert len(op0.args) == 1 + len(expectedkind) for sublist, kind1 in zip(op0.args[1:], expectedkind): assert sublist.kind.startswith(kind1) assert list(sublist) == [v for v in op.args[1:] if getkind(v.concretetype) == sublist.kind] for v in op.args[1:]: kind = getkind(v.concretetype) assert kind == "void" or kind[0] in expectedkind assert op1.opname == "-live-" assert op1.args == []
def test_quasi_immutable_setfield(): from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE accessor = FieldListAccessor() accessor.initialize(None, {"inst_x": IR_QUASIIMMUTABLE}) v1 = varoftype(lltype.Signed) STRUCT = lltype.GcStruct( "struct", ("inst_x", lltype.Signed), ("mutate_x", rclass.OBJECTPTR), hints={"immutable_fields": accessor} ) for v_x in [const(lltype.malloc(STRUCT)), varoftype(lltype.Ptr(STRUCT))]: op = SpaceOperation( "jit_force_quasi_immutable", [v_x, Constant("mutate_x", lltype.Void)], varoftype(lltype.Void) ) tr = Transformer(FakeCPU(), FakeRegularCallControl()) tr.graph = "currentgraph" op0, op1 = tr.rewrite_operation(op) assert op0.opname == "-live-" assert op1.opname == "jit_force_quasi_immutable" assert op1.args[0] == v_x assert op1.args[1] == ("fielddescr", STRUCT, "mutate_x")
def test_unicode_eq_checknull_char(): # test that the oopspec is present and correctly transformed PUNICODE = lltype.Ptr(rstr.UNICODE) FUNC = lltype.FuncType([PUNICODE, PUNICODE], lltype.Bool) func = lltype.functionptr(FUNC, "ll_streq", _callable=rstr.LLHelpers.ll_streq) v1 = varoftype(PUNICODE) v2 = varoftype(PUNICODE) v3 = varoftype(lltype.Bool) op = SpaceOperation("direct_call", [const(func), v1, v2], v3) cc = FakeBuiltinCallControl() tr = Transformer(FakeCPU(), cc) op1 = tr.rewrite_operation(op) assert op1.opname == "residual_call_r_i" assert op1.args[0].value == func assert op1.args[1] == ListOfKind("ref", [v1, v2]) assert op1.args[2] == "calldescr-%d" % effectinfo.EffectInfo.OS_UNI_EQUAL assert op1.result == v3 # test that the OS_UNIEQ_* functions are registered cic = cc.callinfocollection assert cic.has_oopspec(effectinfo.EffectInfo.OS_UNIEQ_SLICE_NONNULL) assert cic.has_oopspec(effectinfo.EffectInfo.OS_UNIEQ_CHECKNULL_CHAR)
def test_list_ll_arraycopy(): from rpython.rlib.rgc import ll_arraycopy LIST = lltype.GcArray(lltype.Signed) PLIST = lltype.Ptr(LIST) INT = lltype.Signed FUNC = lltype.FuncType([PLIST] * 2 + [INT] * 3, lltype.Void) func = lltype.functionptr(FUNC, "ll_arraycopy", _callable=ll_arraycopy) v1 = varoftype(PLIST) v2 = varoftype(PLIST) v3 = varoftype(INT) v4 = varoftype(INT) v5 = varoftype(INT) v6 = varoftype(lltype.Void) op = SpaceOperation("direct_call", [const(func), v1, v2, v3, v4, v5], v6) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1.opname == "residual_call_ir_v" assert op1.args[0].value == func assert op1.args[1] == ListOfKind("int", [v3, v4, v5]) assert op1.args[2] == ListOfKind("ref", [v1, v2]) assert op1.args[3] == "calldescr-%d" % effectinfo.EffectInfo.OS_ARRAYCOPY
def test_jit_merge_point_1(): class FakeJitDriverSD: index = 42 class jitdriver: active = True greens = ["green1", "green2", "voidgreen3"] reds = ["red1", "red2", "voidred3"] numreds = 3 jd = FakeJitDriverSD() v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) vvoid1 = varoftype(lltype.Void) v3 = varoftype(lltype.Signed) v4 = varoftype(lltype.Signed) vvoid2 = varoftype(lltype.Void) v5 = varoftype(lltype.Void) op = SpaceOperation( "jit_marker", [Constant("jit_merge_point", lltype.Void), Constant(jd.jitdriver, lltype.Void), v1, v2, vvoid1, v3, v4, vvoid2], v5, ) tr = Transformer() tr.portal_jd = jd oplist = tr.rewrite_operation(op) assert len(oplist) == 7 assert oplist[0].opname == "-live-" assert oplist[1].opname == "int_guard_value" assert oplist[1].args == [v1] assert oplist[2].opname == "-live-" assert oplist[3].opname == "int_guard_value" assert oplist[3].args == [v2] assert oplist[4].opname == "-live-" assert oplist[5].opname == "jit_merge_point" assert oplist[5].args[0].value == 42 assert list(oplist[5].args[1]) == [v1, v2] assert list(oplist[5].args[4]) == [v3, v4] assert oplist[6].opname == "-live-"
def test_casts(self): self.do_check('cast_int_to_longlong', EffectInfo.OS_LLONG_FROM_INT, [lltype.Signed], lltype.SignedLongLong) self.do_check('cast_uint_to_longlong', EffectInfo.OS_LLONG_FROM_UINT, [lltype.Unsigned], lltype.SignedLongLong) self.do_check('truncate_longlong_to_int', EffectInfo.OS_LLONG_TO_INT, [lltype.SignedLongLong], lltype.Signed) self.do_check('cast_float_to_longlong', EffectInfo.OS_LLONG_FROM_FLOAT, [lltype.Float], lltype.SignedLongLong) self.do_check('cast_float_to_ulonglong', EffectInfo.OS_LLONG_FROM_FLOAT, [lltype.Float], lltype.UnsignedLongLong) self.do_check('cast_longlong_to_float', EffectInfo.OS_LLONG_TO_FLOAT, [lltype.SignedLongLong], lltype.Float) self.do_check('cast_ulonglong_to_float', EffectInfo.OS_LLONG_U_TO_FLOAT, [lltype.UnsignedLongLong], lltype.Float) for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: for T2 in [lltype.Signed, lltype.Unsigned]: self.do_check('cast_primitive', EffectInfo.OS_LLONG_TO_INT, [T1], T2) self.do_check('force_cast', EffectInfo.OS_LLONG_TO_INT, [T1], T2) if T2 == lltype.Signed: expected = EffectInfo.OS_LLONG_FROM_INT else: expected = EffectInfo.OS_LLONG_FROM_UINT self.do_check('cast_primitive', expected, [T2], T1) self.do_check('force_cast', expected, [T2], T1) # for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: for T2 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: vlist = [varoftype(T1)] v_result = varoftype(T2) op = SpaceOperation('force_cast', vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1 is None
def indirect_regular_call_test(argtypes, restype, expectedkind): # a regular indirect call is preceded by a guard_value on the # function address, so that pyjitpl can know which jitcode to follow from rpython.jit.codewriter.flatten import IndirectCallTargets op = get_direct_call_op(argtypes, restype) op.opname = "indirect_call" op.args[0] = varoftype(op.args[0].concretetype) op.args.append(Constant(["somegraph1", "somegraph2"], lltype.Void)) tr = Transformer(FakeCPU(), FakeRegularIndirectCallControl()) tr.graph = "someinitialgraph" oplist = tr.rewrite_operation(op) op0gv, op1gv, op0, op1 = oplist assert op0gv.opname == "-live-" assert op0gv.args == [] assert op1gv.opname == "int_guard_value" assert op1gv.args == [op.args[0]] assert op1gv.result is None # reskind = getkind(restype)[0] assert op0.opname == "residual_call_%s_%s" % (expectedkind, reskind) assert op0.result == op.result assert op0.args[0] == op.args[0] assert isinstance(op0.args[1], IndirectCallTargets) assert op0.args[1].lst == ["somejitcode1", "somejitcode2"] assert op0.args[-1] == "calldescr" assert len(op0.args) == 2 + len(expectedkind) + 1 for sublist, kind1 in zip(op0.args[2:-1], expectedkind): assert sublist.kind.startswith(kind1) assert list(sublist) == [v for v in op.args[1:] if getkind(v.concretetype) == sublist.kind] for v in op.args[1:]: kind = getkind(v.concretetype) assert kind == "void" or kind[0] in expectedkind # Note: we still expect a -live- here, even though canraise() returns # False, because this 'residual_call' will likely call further jitcodes # which can do e.g. guard_class or other stuff requiring anyway a -live-. assert op1.opname == "-live-" assert op1.args == []
def test_unicode_concat(): # test that the oopspec is present and correctly transformed PSTR = lltype.Ptr(rstr.UNICODE) FUNC = lltype.FuncType([PSTR, PSTR], PSTR) func = lltype.functionptr(FUNC, "ll_strconcat", _callable=rstr.LLHelpers.ll_strconcat) v1 = varoftype(PSTR) v2 = varoftype(PSTR) v3 = varoftype(PSTR) op = SpaceOperation("direct_call", [const(func), v1, v2], v3) cc = FakeBuiltinCallControl() tr = Transformer(FakeCPU(), cc) op1 = tr.rewrite_operation(op) assert op1.opname == "residual_call_r_r" assert op1.args[0].value == func assert op1.args[1] == ListOfKind("ref", [v1, v2]) assert op1.args[2] == "calldescr-%d" % effectinfo.EffectInfo.OS_UNI_CONCAT assert op1.result == v3 # # check the callinfo_for_oopspec got = cc.callinfocollection.seen[0] assert got[0] == effectinfo.EffectInfo.OS_UNI_CONCAT assert got[1] == op1.args[2] # the calldescr assert heaptracker.int2adr(got[2]) == llmemory.cast_ptr_to_adr(func)
def test_llong_neg(self): T = lltype.SignedLongLong v = varoftype(T) v_result = varoftype(T) op = SpaceOperation('llong_neg', [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == 'llong_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert oplist[1].opname == 'residual_call_irf_f' assert oplist[1].args[0].value == 'llong_sub' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v_x, v] assert oplist[1].args[4] == 'calldescr-71' assert oplist[1].result == v_result
def test_llong_neg(self): T = lltype.SignedLongLong v = varoftype(T) v_result = varoftype(T) op = SpaceOperation('llong_neg', [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == 'llong_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert oplist[1].opname == 'residual_call_irf_f' assert oplist[1].args[0].value == 'llong_sub' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v_x, v] assert oplist[1].args[4] == 'calldescr-71' assert oplist[1].result == v_result
def test_casts(self): self.do_check('cast_int_to_longlong', EffectInfo.OS_LLONG_FROM_INT, [lltype.Signed], lltype.SignedLongLong) self.do_check('cast_uint_to_longlong', EffectInfo.OS_LLONG_FROM_UINT, [lltype.Unsigned], lltype.SignedLongLong) self.do_check('truncate_longlong_to_int', EffectInfo.OS_LLONG_TO_INT, [lltype.SignedLongLong], lltype.Signed) self.do_check('cast_float_to_longlong', EffectInfo.OS_LLONG_FROM_FLOAT, [lltype.Float], lltype.SignedLongLong) self.do_check('cast_float_to_ulonglong', EffectInfo.OS_LLONG_FROM_FLOAT, [lltype.Float], lltype.UnsignedLongLong) self.do_check('cast_longlong_to_float', EffectInfo.OS_LLONG_TO_FLOAT, [lltype.SignedLongLong], lltype.Float) self.do_check('cast_ulonglong_to_float', EffectInfo.OS_LLONG_U_TO_FLOAT, [lltype.UnsignedLongLong], lltype.Float) for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: for T2 in [lltype.Signed, lltype.Unsigned]: self.do_check('cast_primitive', EffectInfo.OS_LLONG_TO_INT, [T1], T2) self.do_check('force_cast', EffectInfo.OS_LLONG_TO_INT, [T1], T2) if T2 == lltype.Signed: expected = EffectInfo.OS_LLONG_FROM_INT else: expected = EffectInfo.OS_LLONG_FROM_UINT self.do_check('cast_primitive', expected, [T2], T1) self.do_check('force_cast', expected, [T2], T1) # for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: for T2 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: vlist = [varoftype(T1)] v_result = varoftype(T2) op = SpaceOperation('force_cast', vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1 is None
def test_quasi_immutable(): from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE accessor = FieldListAccessor() accessor.initialize(None, {"inst_x": IR_QUASIIMMUTABLE}) v2 = varoftype(lltype.Signed) STRUCT = lltype.GcStruct( "struct", ("inst_x", lltype.Signed), ("mutate_x", rclass.OBJECTPTR), hints={"immutable_fields": accessor} ) for v_x in [const(lltype.malloc(STRUCT)), varoftype(lltype.Ptr(STRUCT))]: op = SpaceOperation("getfield", [v_x, Constant("inst_x", lltype.Void)], v2) tr = Transformer(FakeCPU()) [_, op1, op2] = tr.rewrite_operation(op) assert op1.opname == "record_quasiimmut_field" assert len(op1.args) == 3 assert op1.args[0] == v_x assert op1.args[1] == ("fielddescr", STRUCT, "inst_x") assert op1.args[2] == ("fielddescr", STRUCT, "mutate_x") assert op1.result is None assert op2.opname == "getfield_gc_i" assert len(op2.args) == 2 assert op2.args[0] == v_x assert op2.args[1] == ("fielddescr", STRUCT, "inst_x") assert op2.result is op.result
def test_cast_ptr_to_adr(): t = Transformer(FakeCPU(), None) v = varoftype(lltype.Ptr(lltype.Array())) v2 = varoftype(llmemory.Address) op1 = t.rewrite_operation(SpaceOperation("cast_ptr_to_adr", [v], v2)) assert op1 is None