def test_reprkeys_dont_clash(): stup1 = annmodel.SomeTuple((annmodel.SomeFloat(), annmodel.SomeInteger())) stup2 = annmodel.SomeTuple((annmodel.SomeString(), annmodel.SomeInteger())) rtyper = RPythonTyper(annrpython.RPythonAnnotator(None)) key1 = rtyper.makekey(stup1) key2 = rtyper.makekey(stup2) assert key1 != key2
def test_slice_reprkeys(): one = annmodel.SomeInteger(nonneg=True) one.const = 1 three = annmodel.SomeInteger(nonneg=True) three.const = 3 minusone = annmodel.SomeInteger() minusone.const = -1 none = annmodel.s_None startonly = annmodel.SomeSlice(one, none, none) startonly2 = annmodel.SomeSlice(one, none, one) startonly3 = annmodel.SomeSlice(three, none, one) startstop = annmodel.SomeSlice(one, one, none) startstop2 = annmodel.SomeSlice(one, one, one) startstop3 = annmodel.SomeSlice(one, three, none) minusone_slice = annmodel.SomeSlice(none, minusone, none) minusone_slice2 = annmodel.SomeSlice(none, minusone, one) assert startonly.rtyper_makekey() == startonly2.rtyper_makekey( ) == startonly3.rtyper_makekey() assert startstop.rtyper_makekey() == startstop2.rtyper_makekey( ) == startstop3.rtyper_makekey() assert minusone_slice.rtyper_makekey() == minusone_slice2.rtyper_makekey() assert startonly.rtyper_makekey() != startstop.rtyper_makekey() assert startonly.rtyper_makekey() != minusone_slice.rtyper_makekey() assert minusone_slice.rtyper_makekey() != startstop.rtyper_makekey()
def test_pseudohighlevelcallable(): t = TranslationContext() t.buildannotator() rtyper = t.buildrtyper() rtyper.specialize() a = MixLevelHelperAnnotator(rtyper) class A: value = 5 def double(self): return self.value * 2 def fn1(a): a2 = A() a2.value = a.double() return a2 s_A, r_A = a.s_r_instanceof(A) fn1ptr = a.delayedfunction(fn1, [s_A], s_A) pseudo = PseudoHighLevelCallable(fn1ptr, [s_A], s_A) def fn2(n): a = A() a.value = n a2 = pseudo(a) return a2.value graph = a.getgraph(fn2, [annmodel.SomeInteger()], annmodel.SomeInteger()) a.finish() llinterp = LLInterpreter(rtyper) res = llinterp.eval_graph(graph, [21]) assert res == 42
def test_cast_primitive(self): def llf(u): return cast_primitive(Signed, u) s = self.annotate(llf, [annmodel.SomeInteger(unsigned=True)]) assert s.knowntype == int def llf(s): return cast_primitive(Unsigned, s) s = self.annotate(llf, [annmodel.SomeInteger()]) assert s.unsigned == True
class CTestFuncEntry(ExtFuncEntry): _about_ = c name = 'ccc' signature_args = [annmodel.SomeInteger()] * 2 signature_result = annmodel.SomeInteger() def lltypeimpl(y, x): return y + x lltypeimpl = staticmethod(lltypeimpl)
def test_some_generic_function_call(self): def h(x): return int(x) def c(x): return int(x) + 1 def default(x): return int(x) + 3 def g(a, x): if x == -1: a = None if x > 0: if x == 1: a = h else: a = c x = x + 0.01 return a(x) def f(x): return g(default, x) g._annenforceargs_ = policy.Sig( annmodel.SomeGenericCallable(args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()), float) assert interpret(f, [1.]) == 1 assert interpret(f, [10.]) == 11 assert interpret(f, [-3.]) == 0
def test_funny_links(): from pypy.objspace.flow.model import Block, FunctionGraph, \ SpaceOperation, Variable, Constant, Link for i in range(2): v_i = Variable("i") v_case = Variable("case") block = Block([v_i]) g = FunctionGraph("is_one", block) block.operations.append( SpaceOperation("eq", [v_i, Constant(1)], v_case)) block.exitswitch = v_case tlink = Link([Constant(1)], g.returnblock, True) flink = Link([Constant(0)], g.returnblock, False) links = [tlink, flink] if i: links.reverse() block.closeblock(*links) t = TranslationContext() a = t.buildannotator() a.build_graph_types(g, [annmodel.SomeInteger()]) rtyper = t.buildrtyper() rtyper.specialize() interp = LLInterpreter(rtyper) assert interp.eval_graph(g, [1]) == 1 assert interp.eval_graph(g, [0]) == 0
def test_secondary_backendopt(self): # checks an issue with a newly added graph that calls an # already-exception-transformed graph. This can occur e.g. # from a late-seen destructor added by the GC transformer # which ends up calling existing code. def common(n): if n > 5: raise ValueError def main(n): common(n) def later(n): try: common(n) return 0 except ValueError: return 1 t = TranslationContext() t.buildannotator().build_types(main, [int]) t.buildrtyper(type_system='lltype').specialize() exctransformer = t.getexceptiontransformer() exctransformer.create_exception_handling(graphof(t, common)) from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator annhelper = MixLevelHelperAnnotator(t.rtyper) later_graph = annhelper.getgraph(later, [annmodel.SomeInteger()], annmodel.SomeInteger()) annhelper.finish() annhelper.backend_optimize() # ^^^ as the inliner can't handle exception-transformed graphs, # this should *not* inline common() into later(). if conftest.option.view: later_graph.show() common_graph = graphof(t, common) found = False for block in later_graph.iterblocks(): for op in block.operations: if (op.opname == 'direct_call' and op.args[0].value._obj.graph is common_graph): found = True assert found, "cannot find the call (buggily inlined?)" from pypy.rpython.llinterp import LLInterpreter llinterp = LLInterpreter(t.rtyper) res = llinterp.eval_graph(later_graph, [10]) assert res == 1
class CC(BasicExternal): _methods = { 'some_method': MethodDesc([ annmodel.SomeGenericCallable(args=[annmodel.SomeInteger()], result=annmodel.SomeFloat()) ], int) }
def test_stress(self): from pypy.annotation.dictdef import DictKey, DictValue from pypy.annotation import model as annmodel dictrepr = rdict.DictRepr(None, rint.signed_repr, rint.signed_repr, DictKey(None, annmodel.SomeInteger()), DictValue(None, annmodel.SomeInteger())) dictrepr.setup() l_dict = rdict.ll_newdict(dictrepr.DICT) referencetable = [None] * 400 referencelength = 0 value = 0 def complete_check(): for n, refvalue in zip(range(len(referencetable)), referencetable): try: gotvalue = rdict.ll_dict_getitem(l_dict, n) except KeyError: assert refvalue is None else: assert gotvalue == refvalue for x in not_really_random(): n = int(x*100.0) # 0 <= x < 400 op = repr(x)[-1] if op <= '2' and referencetable[n] is not None: rdict.ll_dict_delitem(l_dict, n) referencetable[n] = None referencelength -= 1 elif op <= '6': rdict.ll_dict_setitem(l_dict, n, value) if referencetable[n] is None: referencelength += 1 referencetable[n] = value value += 1 else: try: gotvalue = rdict.ll_dict_getitem(l_dict, n) except KeyError: assert referencetable[n] is None else: assert gotvalue == referencetable[n] if 1.38 <= x <= 1.39: complete_check() print 'current dict length:', referencelength assert l_dict.num_items == referencelength complete_check()
def make_raise_OSError(self, rtyper): # ll_raise_OSError(errno) def ll_raise_OSError(errno): raise OSError(errno, None) helper_fn = rtyper.annotate_helper_fn(ll_raise_OSError, [annmodel.SomeInteger()]) return helper_fn
def compute_result_annotation(self, s_driver, s_name, s_value): from pypy.annotation import model as annmodel assert s_name.is_constant() if not self.bookkeeper.immutablevalue(DEFAULT).contains(s_value): if s_name.const == 'enable_opts': assert annmodel.SomeString(can_be_None=True).contains(s_value) else: assert annmodel.SomeInteger().contains(s_value) return annmodel.s_None
def test_oopspec(self): lst1 = [123, 456] # non-mutated list def f(i): lst2 = [i] lst2.append(42) # mutated list return lst1[i] + lst2[i] from pypy.annotation import model as annmodel _, _, graph = self.gengraph(f, [annmodel.SomeInteger(nonneg=True)]) block = graph.startblock lst1_getitem_op = block.operations[-3] # XXX graph fishing lst2_getitem_op = block.operations[-2] func1 = lst1_getitem_op.args[0].value._obj._callable func2 = lst2_getitem_op.args[0].value._obj._callable assert func1.oopspec == 'list.getitem_foldable(l, index)' assert not hasattr(func2, 'oopspec')
class I386PortalTestMixin(object): RGenOp = RI386GenOp def postprocess_timeshifting(self): annhelper = self.hrtyper.annhelper convert_result = getattr(self.main, 'convert_result', str) annotator = self.rtyper.annotator args_s = [annmodel.lltype_to_annotation(v.concretetype) for v in self.maingraph.getargs()] retvar = self.maingraph.getreturnvar() s_result = annmodel.lltype_to_annotation(retvar.concretetype) main_fnptr = self.rtyper.type_system.getcallable(self.maingraph) main = PseudoHighLevelCallable(main_fnptr, args_s, s_result) if hasattr(self.main, 'convert_arguments'): decoders = self.main.convert_arguments assert len(decoders) == len(args_s) else: decoders = [int] * len(args_s) decoders = unrolling_iterable(decoders) def ll_main(argv): args = () i = 1 for decoder in decoders: args += (decoder(argv[i]),) i = i + 1 try: res = main(*args) except Exception, e: os.write(1, 'EXCEPTION: %s\n' % (e,)) return 0 os.write(1, convert_result(res) + '\n') return 0 annhelper.getgraph(ll_main, [s_list_of_strings], annmodel.SomeInteger()) annhelper.finish() t = self.rtyper.annotator.translator t.config.translation.gc = 'boehm' self.cbuilder = CStandaloneBuilder(t, ll_main, config=t.config) self.cbuilder.generate_source() self.cbuilder.compile()
def specialize_call(self, hop): rtyper = hop.rtyper bk = rtyper.annotator.bookkeeper r_result = rtyper.getrepr(hop.s_result) hop.exception_is_here() args_r = [rtyper.getrepr(s_arg) for s_arg in hop.args_s] _callable = hop.args_s[0].const funcptr = lltype.functionptr(CALLBACK.TO, _callable.func_name, _callable=_callable) func_s = bk.immutablevalue(funcptr) s_args = [func_s, hop.args_s[1]] obj = rtyper.getannmixlevel().delayedfunction( ll_start_new_thread, s_args, annmodel.SomeInteger()) bootstrap = rtyper.getannmixlevel().delayedfunction( _callable, [hop.args_s[1]], annmodel.s_None) vlist = [hop.inputconst(typeOf(obj), obj), hop.inputconst(typeOf(bootstrap), bootstrap), #hop.inputarg(args_r[0], 0), hop.inputarg(args_r[1], 1)] return hop.genop('direct_call', vlist, r_result)
def test_mix_after_recursion(self): def prefn(n): if n: return 2 * prefn(n - 1) else: return 1 t = TranslationContext() a = t.buildannotator() a.build_types(prefn, [int]) typer = t.buildrtyper() typer.specialize() #t.view() def f(): return 1 from pypy.rpython import annlowlevel annhelper = annlowlevel.MixLevelHelperAnnotator(typer) graph = annhelper.getgraph(f, [], annmodel.SomeInteger()) annhelper.finish()
class Entry(ExtRegistryEntry): _about_ = dummy s_result_annotation = annmodel.SomeInteger()
class Entry(ExtRegistryEntry): _about_ = dummy_func s_result_annotation = annmodel.SomeInteger() def specialize_call(self, hop): return hop.inputconst(lltype.Signed, 42)
return True elif t == TYPE_FALSE: return False else: raise ValueError("expected a bool") add_loader(annmodel.s_Bool, load_bool) def dump_int(buf, x): buf.append(TYPE_INT) w_long(buf, x) add_dumper(annmodel.SomeInteger(), dump_int) def load_int_nonneg(loader): x = load_int(loader) if x < 0: raise ValueError("expected a non-negative int") return x add_loader(annmodel.SomeInteger(nonneg=True), load_int_nonneg) def load_int(loader): if readchr(loader) != TYPE_INT: raise ValueError("expected an int")
def compute_result_annotation(self, s_obj): assert SomeErased().contains(s_obj) return annmodel.SomeInteger()
def compute_annotation(self): assert self.type is RealClass assert self.instance is None return annmodel.SomeInteger()
def compute_result_annotation(self, str_s, base_s): assert isinstance(str_s, annmodel.SomeOOInstance)\ and str_s.ootype is ootype.String assert isinstance(base_s, annmodel.SomeInteger) return annmodel.SomeInteger()
def compute_result_annotation(self, s_instance): return annmodel.SomeInteger()
def compute_annotation(self): from pypy.annotation import model as annmodel return annmodel.SomeInteger(knowntype=r_ulonglong)
def compute_result_annotation(self, *args_s, **kwds_s): from pypy.annotation import model as annmodel return annmodel.SomeInteger(knowntype=int_type)
def compute_result_annotation(self): return annmodel.SomeInteger()
def compute_annotation(self): assert self.instance is dummy_type return annmodel.SomeInteger()
def annotation(self): from pypy.annotation import model return model.SomeInteger()
class I386TimeshiftingTestMixin(object): RGenOp = RI386GenOp SEPLINE = 'running residual graph...\n' def annotate_interface_functions(self): annhelper = self.hrtyper.annhelper RGenOp = self.RGenOp SEPLINE = self.SEPLINE ml_generate_code = self.ml_generate_code argcolors = list(self.argcolors) if hasattr(self.ll_function, 'convert_arguments'): decoders = self.ll_function.convert_arguments assert len(decoders) == len(argcolors) else: decoders = [int] * len(argcolors) argcolors_decoders = zip(argcolors, decoders) argcolors_decoders = unrolling_iterable(argcolors_decoders) convert_result = getattr(self.ll_function, 'convert_result', str) def ll_main(argv): i = 1 mainargs = () residualargs = () if len(argv) == 2 and argv[1] == '--help': os.write(1, 'usage: ' + argv[0]) for color, decoder in argcolors_decoders: os.write(1, ' ') if color == 'green': os.write(1, decoder.__name__) else: os.write(1, "-const|-var "+decoder.__name__) os.write(1, '\n') return 0 for color, decoder in argcolors_decoders: try: if color == 'green': llvalue = decoder(argv[i]) mainargs += (llvalue,) i = i + 1 else: if argv[i] == '-const': is_const = True elif argv[i] == '-var': is_const = False else: raise ValueError() i += 1 llvalue = decoder(argv[i]) mainargs += (is_const, llvalue) residualargs += (llvalue,) i += 1 except (ValueError, IndexError): j = 1 while j < len(argv): arg = argv[j] if j == i: os.write(1, '--> ') else: os.write(1, ' ') os.write(1, arg+'\n') j += 1 if j == i: os.write(1, '-->\n') return 1 rgenop = RGenOp() generated = ml_generate_code(rgenop, *mainargs) os.write(1, SEPLINE) bench = Benchmark() while 1: try: res = generated(*residualargs) except Exception, e: os.write(1, 'EXCEPTION: %s\n' % (e,)) return 0 if bench.stop(): break os.write(1, convert_result(res) + '\n') rgenop.check_no_open_mc() keepalive_until_here(rgenop) # to keep the code blocks alive return 0 annhelper.getgraph(ll_main, [s_list_of_strings], annmodel.SomeInteger()) annhelper.finish() t = self.rtyper.annotator.translator t.config.translation.gc = 'boehm' cbuilder = CStandaloneBuilder(t, ll_main, config=t.config) cbuilder.generate_source() cbuilder.compile() self.main_cbuilder= cbuilder
def compute_result_annotation(self, s_obj): config = self.bookkeeper.annotator.translator.config assert config.translation.taggedpointers, "need to enable tagged pointers to use erase_int" assert annmodel.SomeInteger().contains(s_obj) return SomeErased()