def test_dont_include_read_and_write_field(): S = lltype.GcStruct("S", ("a", lltype.Signed)) effects = frozenset([("readstruct", lltype.Ptr(S), "a"), ("struct", lltype.Ptr(S), "a")]) effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) assert not effectinfo.readonly_descrs_fields assert list(effectinfo.write_descrs_fields) == [("fielddescr", S, "a")] assert not effectinfo.write_descrs_arrays
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_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_include_write_field(): S = lltype.GcStruct("S", ("a", lltype.Signed)) effects = frozenset([("struct", lltype.Ptr(S), "a")]) effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) assert list(effectinfo.write_descrs_fields) == [('fielddescr', S, "a")] assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_arrays
def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE, extraeffect=None): """Return the calldescr that describes all calls done by 'op'. This returns a calldescr that we can put in the corresponding call operation in the calling jitcode. It gets an effectinfo describing the effect of the call: which field types it may change, whether it can force virtualizables, whether it can raise, etc. """ NON_VOID_ARGS = [x.concretetype for x in op.args[1:] if x.concretetype is not lltype.Void] RESULT = op.result.concretetype # check the number and type of arguments FUNC = get_functype(op.args[0].concretetype) ARGS = FUNC.ARGS assert NON_VOID_ARGS == [T for T in ARGS if T is not lltype.Void] assert RESULT == FUNC.RESULT # ok # get the 'pure' and 'loopinvariant' flags from the function object pure = False loopinvariant = False if op.opname == "direct_call": func = getattr(get_funcobj(op.args[0].value), '_callable', None) pure = getattr(func, "_pure_function_", False) loopinvariant = getattr(func, "_jit_loop_invariant_", False) if loopinvariant: assert not NON_VOID_ARGS, ("arguments not supported for " "loop-invariant function!") # build the extraeffect can_invalidate = self.quasiimmut_analyzer.analyze(op) if extraeffect is None: if self.virtualizable_analyzer.analyze(op): extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE elif loopinvariant: extraeffect = EffectInfo.EF_LOOPINVARIANT elif pure: # XXX check what to do about exceptions (also MemoryError?) extraeffect = EffectInfo.EF_PURE elif self._canraise(op): extraeffect = EffectInfo.EF_CAN_RAISE else: extraeffect = EffectInfo.EF_CANNOT_RAISE # effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op), self.cpu, extraeffect, oopspecindex, can_invalidate) # if oopspecindex != EffectInfo.OS_NONE: assert effectinfo is not None if pure or loopinvariant: assert effectinfo is not None assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE # XXX this should also say assert not can_invalidate, but # it can't because our analyzer is not good enough for now # (and getexecutioncontext() can't really invalidate) # return self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT, effectinfo)
def test_filter_out_instance_with_void(): effects = frozenset([("struct", ootype.Instance("x", ootype.ROOT, {"a": ootype.Void}), "a")]) effectinfo = effectinfo_from_writeanalyze(effects, None) assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays
def test_filter_out_ooarray_of_void(): effects = frozenset([("array", ootype.Array(ootype.Void))]) effectinfo = effectinfo_from_writeanalyze(effects, None) assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays
def test_filter_out_struct_with_void(): effects = frozenset([("struct", lltype.Ptr(lltype.GcStruct("x", ("a", lltype.Void))), "a")]) effectinfo = effectinfo_from_writeanalyze(effects, None) assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays
def test_filter_out_typeptr(): effects = frozenset([("struct", lltype.Ptr(OBJECT), "typeptr")]) effectinfo = effectinfo_from_writeanalyze(effects, None) assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays
def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE, extraeffect=None): """Return the calldescr that describes all calls done by 'op'. This returns a calldescr that we can put in the corresponding call operation in the calling jitcode. It gets an effectinfo describing the effect of the call: which field types it may change, whether it can force virtualizables, whether it can raise, etc. """ NON_VOID_ARGS = [x.concretetype for x in op.args[1:] if x.concretetype is not lltype.Void] RESULT = op.result.concretetype # check the number and type of arguments FUNC = get_functype(op.args[0].concretetype) ARGS = FUNC.ARGS assert NON_VOID_ARGS == [T for T in ARGS if T is not lltype.Void] assert RESULT == FUNC.RESULT # ok # get the 'elidable' and 'loopinvariant' flags from the function object elidable = False loopinvariant = False if op.opname == "direct_call": funcobj = get_funcobj(op.args[0].value) assert getattr(funcobj, 'calling_conv', 'c') == 'c', ( "%r: getcalldescr() with a non-default call ABI" % (op,)) func = getattr(funcobj, '_callable', None) elidable = getattr(func, "_elidable_function_", False) loopinvariant = getattr(func, "_jit_loop_invariant_", False) if loopinvariant: assert not NON_VOID_ARGS, ("arguments not supported for " "loop-invariant function!") # build the extraeffect random_effects = self.randomeffects_analyzer.analyze(op) if random_effects: extraeffect = EffectInfo.EF_RANDOM_EFFECTS # random_effects implies can_invalidate can_invalidate = random_effects or self.quasiimmut_analyzer.analyze(op) if extraeffect is None: if self.virtualizable_analyzer.analyze(op): extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE elif loopinvariant: extraeffect = EffectInfo.EF_LOOPINVARIANT elif elidable: if self._canraise(op): extraeffect = EffectInfo.EF_ELIDABLE_CAN_RAISE else: extraeffect = EffectInfo.EF_ELIDABLE_CANNOT_RAISE elif self._canraise(op): extraeffect = EffectInfo.EF_CAN_RAISE else: extraeffect = EffectInfo.EF_CANNOT_RAISE # effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op), self.cpu, extraeffect, oopspecindex, can_invalidate) # assert effectinfo is not None if elidable or loopinvariant: assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE # XXX this should also say assert not can_invalidate, but # it can't because our analyzer is not good enough for now # (and getexecutioncontext() can't really invalidate) # return self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT, effectinfo)