def test_runtime_type_info(): S = GcStruct('s', ('x', Signed)) attachRuntimeTypeInfo(S) def ll_example(p): return (runtime_type_info(p), runtime_type_info(p) == getRuntimeTypeInfo(S)) assert ll_example(malloc(S)) == (getRuntimeTypeInfo(S), True) s, t = ll_rtype(ll_example, [annmodel.SomePtr(Ptr(S))]) assert s == annmodel.SomeTuple([annmodel.SomePtr(Ptr(RuntimeTypeInfo)), annmodel.SomeBool()])
def test_subclassof(): I = Instance("test", ROOT, {'a': Signed}) I1 = Instance("test1", I) def oof(): i = new(I) i1 = new(I1) return subclassof(classof(i1), classof(i)) a = RPythonAnnotator() s = a.build_types(oof, []) #a.translator.view() assert s == annmodel.SomeBool()
newcell = annmodel.SomeObject() if cell.knowntype == type: newcell.knowntype = type if cell.is_constant(): newcell.const = cell.const cell = newcell cell.is_type_of = renamed_is_type_of if hasattr(cell, 'knowntypedata'): renamed_knowntypedata = {} for (value, v), s in cell.knowntypedata.items(): new_vs = renaming.get(v, []) for new_v in new_vs: renamed_knowntypedata[value, new_v] = s assert isinstance(cell, annmodel.SomeBool) newcell = annmodel.SomeBool() if cell.is_constant(): newcell.const = cell.const cell = newcell cell.knowntypedata = renamed_knowntypedata cells.append(cell) if ignore_link: continue if in_except_block: last_exception_object.is_type_of = last_exc_value_vars self.links_followed[link] = True self.addpendingblock(graph, link.target, cells)
def compute_result_annotation(self, s_p): from pypy.annotation import model as annmodel return annmodel.SomeBool()
def compute_result_annotation(self, s_arg): from pypy.annotation import model r = model.SomeBool() r.const = s_arg.is_constant() return r
def __init__(self, translator): from pypy.rpython.memory.gc.base import choose_gc_from_config super(FrameworkGCTransformer, self).__init__(translator, inline=True) if hasattr(self, 'GC_PARAMS'): # for tests: the GC choice can be specified as class attributes from pypy.rpython.memory.gc.marksweep import MarkSweepGC GCClass = getattr(self, 'GCClass', MarkSweepGC) GC_PARAMS = self.GC_PARAMS else: # for regular translation: pick the GC from the config GCClass, GC_PARAMS = choose_gc_from_config(translator.config) self.layoutbuilder = TransformerLayoutBuilder(self) self.get_type_id = self.layoutbuilder.get_type_id # set up dummy a table, to be overwritten with the real one in finish() type_info_table = lltype._ptr( lltype.Ptr(gctypelayout.GCData.TYPE_INFO_TABLE), "delayed!type_info_table", solid=True) gcdata = gctypelayout.GCData(type_info_table) # initialize the following two fields with a random non-NULL address, # to make the annotator happy. The fields are patched in finish() # to point to a real array. foo = lltype.malloc(lltype.FixedSizeArray(llmemory.Address, 1), immortal=True, zero=True) a_random_address = llmemory.cast_ptr_to_adr(foo) gcdata.static_root_start = a_random_address # patched in finish() gcdata.static_root_nongcend = a_random_address # patched in finish() gcdata.static_root_end = a_random_address # patched in finish() self.gcdata = gcdata self.malloc_fnptr_cache = {} gcdata.gc = GCClass(**GC_PARAMS) root_walker = self.build_root_walker() gcdata.set_query_functions(gcdata.gc) gcdata.gc.set_root_walker(root_walker) self.num_pushs = 0 self.write_barrier_calls = 0 def frameworkgc_setup(): # run-time initialization code root_walker.setup_root_walker() gcdata.gc.setup() bk = self.translator.annotator.bookkeeper # the point of this little dance is to not annotate # self.gcdata.static_root_xyz as constants. XXX is it still needed?? data_classdef = bk.getuniqueclassdef(gctypelayout.GCData) data_classdef.generalize_attr( 'static_root_start', annmodel.SomeAddress()) data_classdef.generalize_attr( 'static_root_nongcend', annmodel.SomeAddress()) data_classdef.generalize_attr( 'static_root_end', annmodel.SomeAddress()) annhelper = annlowlevel.MixLevelHelperAnnotator(self.translator.rtyper) def getfn(ll_function, args_s, s_result, inline=False, minimal_transform=True): graph = annhelper.getgraph(ll_function, args_s, s_result) if minimal_transform: self.need_minimal_transform(graph) if inline: self.graphs_to_inline[graph] = True return annhelper.graph2const(graph) self.frameworkgc_setup_ptr = getfn(frameworkgc_setup, [], annmodel.s_None) if root_walker.need_root_stack: self.incr_stack_ptr = getfn(root_walker.incr_stack, [annmodel.SomeInteger()], annmodel.SomeAddress(), inline = True) self.decr_stack_ptr = getfn(root_walker.decr_stack, [annmodel.SomeInteger()], annmodel.SomeAddress(), inline = True) else: self.incr_stack_ptr = None self.decr_stack_ptr = None self.weakref_deref_ptr = self.inittime_helper( ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address) classdef = bk.getuniqueclassdef(GCClass) s_gc = annmodel.SomeInstance(classdef) s_gcref = annmodel.SomePtr(llmemory.GCREF) malloc_fixedsize_clear_meth = GCClass.malloc_fixedsize_clear.im_func self.malloc_fixedsize_clear_ptr = getfn( malloc_fixedsize_clear_meth, [s_gc, annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), annmodel.SomeBool(), annmodel.SomeBool(), annmodel.SomeBool()], s_gcref, inline = False) if hasattr(GCClass, 'malloc_fixedsize'): malloc_fixedsize_meth = GCClass.malloc_fixedsize.im_func self.malloc_fixedsize_ptr = getfn( malloc_fixedsize_meth, [s_gc, annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), annmodel.SomeBool(), annmodel.SomeBool(), annmodel.SomeBool()], s_gcref, inline = False) else: malloc_fixedsize_meth = None self.malloc_fixedsize_ptr = self.malloc_fixedsize_clear_ptr ## self.malloc_varsize_ptr = getfn( ## GCClass.malloc_varsize.im_func, ## [s_gc] + [annmodel.SomeInteger(nonneg=True) for i in range(5)] ## + [annmodel.SomeBool(), annmodel.SomeBool()], s_gcref) self.malloc_varsize_clear_ptr = getfn( GCClass.malloc_varsize_clear.im_func, [s_gc] + [annmodel.SomeInteger(nonneg=True) for i in range(5)] + [annmodel.SomeBool(), annmodel.SomeBool()], s_gcref) self.collect_ptr = getfn(GCClass.collect.im_func, [s_gc], annmodel.s_None) self.can_move_ptr = getfn(GCClass.can_move.im_func, [s_gc, annmodel.SomeAddress()], annmodel.SomeBool()) # in some GCs we can inline the common case of # malloc_fixedsize(typeid, size, True, False, False) if getattr(GCClass, 'inline_simple_malloc', False): # make a copy of this function so that it gets annotated # independently and the constants are folded inside if malloc_fixedsize_meth is None: malloc_fast_meth = malloc_fixedsize_clear_meth self.malloc_fast_is_clearing = True else: malloc_fast_meth = malloc_fixedsize_meth self.malloc_fast_is_clearing = False malloc_fast = func_with_new_name( malloc_fast_meth, "malloc_fast") s_False = annmodel.SomeBool(); s_False.const = False s_True = annmodel.SomeBool(); s_True .const = True self.malloc_fast_ptr = getfn( malloc_fast, [s_gc, annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), s_True, s_False, s_False], s_gcref, inline = True) else: self.malloc_fast_ptr = None # in some GCs we can also inline the common case of # malloc_varsize(typeid, length, (3 constant sizes), True, False) if getattr(GCClass, 'inline_simple_malloc_varsize', False): # make a copy of this function so that it gets annotated # independently and the constants are folded inside malloc_varsize_clear_fast = func_with_new_name( GCClass.malloc_varsize_clear.im_func, "malloc_varsize_clear_fast") s_False = annmodel.SomeBool(); s_False.const = False s_True = annmodel.SomeBool(); s_True .const = True self.malloc_varsize_clear_fast_ptr = getfn( malloc_varsize_clear_fast, [s_gc, annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True), s_True, s_False], s_gcref, inline = True) else: self.malloc_varsize_clear_fast_ptr = None if getattr(GCClass, 'malloc_varsize_nonmovable', False): malloc_nonmovable = func_with_new_name( GCClass.malloc_varsize_nonmovable.im_func, "malloc_varsize_nonmovable") self.malloc_varsize_nonmovable_ptr = getfn( malloc_nonmovable, [s_gc, annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True)], s_gcref) else: self.malloc_varsize_nonmovable_ptr = None if getattr(GCClass, 'malloc_varsize_resizable', False): malloc_resizable = func_with_new_name( GCClass.malloc_varsize_resizable.im_func, "malloc_varsize_resizable") self.malloc_varsize_resizable_ptr = getfn( malloc_resizable, [s_gc, annmodel.SomeInteger(nonneg=True), annmodel.SomeInteger(nonneg=True)], s_gcref) else: self.malloc_varsize_resizable_ptr = None if getattr(GCClass, 'realloc', False): self.realloc_ptr = getfn( GCClass.realloc.im_func, [s_gc, s_gcref] + [annmodel.SomeInteger(nonneg=True)] * 4 + [annmodel.SomeBool()], s_gcref) if GCClass.moving_gc: self.id_ptr = getfn(GCClass.id.im_func, [s_gc, s_gcref], annmodel.SomeInteger(), inline = False, minimal_transform = False) else: self.id_ptr = None self.set_max_heap_size_ptr = getfn(GCClass.set_max_heap_size.im_func, [s_gc, annmodel.SomeInteger(nonneg=True)], annmodel.s_None) if GCClass.needs_write_barrier: self.write_barrier_ptr = getfn(GCClass.write_barrier.im_func, [s_gc, annmodel.SomeAddress(), annmodel.SomeAddress()], annmodel.s_None, inline=True) else: self.write_barrier_ptr = None self.statistics_ptr = getfn(GCClass.statistics.im_func, [s_gc, annmodel.SomeInteger()], annmodel.SomeInteger()) # experimental gc_x_* operations s_x_pool = annmodel.SomePtr(marksweep.X_POOL_PTR) s_x_clone = annmodel.SomePtr(marksweep.X_CLONE_PTR) # the x_*() methods use some regular mallocs that must be # transformed in the normal way self.x_swap_pool_ptr = getfn(GCClass.x_swap_pool.im_func, [s_gc, s_x_pool], s_x_pool, minimal_transform = False) self.x_clone_ptr = getfn(GCClass.x_clone.im_func, [s_gc, s_x_clone], annmodel.s_None, minimal_transform = False) # thread support if translator.config.translation.thread: if not hasattr(root_walker, "need_thread_support"): raise Exception("%s does not support threads" % ( root_walker.__class__.__name__,)) root_walker.need_thread_support() self.thread_prepare_ptr = getfn(root_walker.thread_prepare, [], annmodel.s_None) self.thread_run_ptr = getfn(root_walker.thread_run, [], annmodel.s_None, inline=True) self.thread_die_ptr = getfn(root_walker.thread_die, [], annmodel.s_None) annhelper.finish() # at this point, annotate all mix-level helpers annhelper.backend_optimize() self.collect_analyzer = CollectAnalyzer(self.translator) self.collect_analyzer.analyze_all() s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass) r_gc = self.translator.rtyper.getrepr(s_gc) self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc) self.malloc_zero_filled = GCClass.malloc_zero_filled HDR = self._gc_HDR = self.gcdata.gc.gcheaderbuilder.HDR self._gc_fields = fields = [] for fldname in HDR._names: FLDTYPE = getattr(HDR, fldname) fields.append(('_' + fldname, FLDTYPE))
@register_helper(annmodel.s_None) def resop_setresult(llop, llbox): _cast_to_resop(llop).result = _cast_to_box(llbox) @register_helper(annmodel.SomeInteger()) def box_getint(llbox): return _cast_to_box(llbox).getint() @register_helper(annmodel.SomePtr(llmemory.GCREF)) def box_clone(llbox): return _cast_to_gcref(_cast_to_box(llbox).clonebox()) @register_helper(annmodel.SomePtr(llmemory.GCREF)) def box_constbox(llbox): return _cast_to_gcref(_cast_to_box(llbox).constbox()) @register_helper(annmodel.SomePtr(llmemory.GCREF)) def box_nonconstbox(llbox): return _cast_to_gcref(_cast_to_box(llbox).nonconstbox()) @register_helper(annmodel.SomeBool()) def box_isconst(llbox): from pypy.jit.metainterp.history import Const return isinstance(_cast_to_box(llbox), Const)
setannotation(gengetsubstruct, s_ConstOrVar) setannotation(gengetarraysubstruct, s_ConstOrVar) setannotation(gensetfield, None) setannotation(gengetfield, s_ConstOrVar) setannotation(gensetarrayitem, None) setannotation(gengetarrayitem, s_ConstOrVar) setannotation(gengetarraysize, s_ConstOrVar) setannotation(end, None) setannotation(genconst, s_ConstOrVar) setannotation(genzeroconst, s_ConstOrVar) setannotation(cast, s_ConstOrVar) setannotation(revealconst, lambda s_T, s_gv: annmodel.lltype_to_annotation(s_T.const)) from pypy.rpython.lltypesystem.rstr import STR setannotation(revealconstrepr, annmodel.SomePtr(lltype.Ptr(STR))) setannotation(isconst, annmodel.SomeBool()) setannotation(closeblock1, s_Link) setannotation(closeblock2, s_LinkPair) setannotation(closeblockswitch, None) setannotation(add_case, s_Link) setannotation(add_default, s_Link) setannotation(closelink, None) setannotation(closereturnlink, None) setannotation(closelinktofreshblock, s_Block) setannotation(isptrtype, annmodel.SomeBool()) # XXX(for now) void constant constructors setannotation(constFieldName, s_ConstOrVar, specialize_as_constant=True) setannotation(constTYPE, s_ConstOrVar, specialize_as_constant=True) #setannotation(placeholder, s_ConstOrVar, specialize_as_constant=True)
def compute_result_annotation(self, s_value): from pypy.annotation import model as annmodel s = annmodel.SomeBool() if s_value.is_constant(): s.const = True return s