def getentrypointptr(self): entrypoints = [] bk = self.translator.annotator.bookkeeper for f, _ in self.functions: graph = bk.getdesc(f).getuniquegraph() entrypoints.append(getfunctionptr(graph)) return entrypoints
def handle_residual_call(self, op, newgraph, newnodes): fspecptr = getfunctionptr(newgraph) newargs = [Constant(fspecptr, concretetype=lltype.typeOf(fspecptr))] newargs += self.expand_nodes(newnodes) newresult = self.make_rt_result(op.result) newop = SpaceOperation('direct_call', newargs, newresult) return [newop]
def prepare_database(db): FUNCPTR = lltype.Ptr(lltype.FuncType([revdb._CMDPTR, lltype.Ptr(rstr.STR)], lltype.Void)) ALLOCFUNCPTR = lltype.Ptr(lltype.FuncType([rffi.LONGLONG, llmemory.GCREF], lltype.Void)) bk = db.translator.annotator.bookkeeper cmds = getattr(db.translator, 'revdb_commands', {}) numcmds = [(num, func) for (num, func) in cmds.items() if isinstance(num, int)] S = lltype.Struct('RPY_REVDB_COMMANDS', ('names', lltype.FixedSizeArray(rffi.INT, len(numcmds) + 1)), ('funcs', lltype.FixedSizeArray(FUNCPTR, len(numcmds))), ('alloc', ALLOCFUNCPTR)) s = lltype.malloc(S, flavor='raw', immortal=True, zero=True) i = 0 for name, func in cmds.items(): fnptr = lltype.getfunctionptr(bk.getdesc(func).getuniquegraph()) if isinstance(name, int): assert name != 0 s.names[i] = rffi.cast(rffi.INT, name) s.funcs[i] = fnptr i += 1 elif name == "ALLOCATING": s.alloc = fnptr else: raise AssertionError("bad tag in register_debug_command(): %r" % (name,)) exports.EXPORTS_obj2name[s._as_obj()] = 'rpy_revdb_commands' db.get(s) db.stack_bottom_funcnames = []
def dispatcher(self, shape, index, argtypes, resulttype): key = shape, index, tuple(argtypes), resulttype if key in self._dispatch_cache: return self._dispatch_cache[key] graph = self.make_dispatcher(shape, index, argtypes, resulttype) self.rtyper.annotator.translator.graphs.append(graph) ll_ret = getfunctionptr(graph) c_ret = self._dispatch_cache[key] = inputconst(typeOf(ll_ret), ll_ret) return c_ret
def build_database(self): translator = self.translator gcpolicyclass = self.get_gcpolicyclass() if self.config.translation.gcrootfinder == "asmgcc": if not self.standalone: raise NotImplementedError("--gcrootfinder=asmgcc requires standalone") exctransformer = translator.getexceptiontransformer() db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicyclass=gcpolicyclass, gchooks=self.gchooks, exctransformer=exctransformer, thread_enabled=self.config.translation.thread, sandbox=self.config.translation.sandbox, split_gc_address_space= self.config.translation.split_gc_address_space, reverse_debugger= self.config.translation.reverse_debugger) self.db = db # give the gc a chance to register interest in the start-up functions it # need (we call this for its side-effects of db.get()) list(db.gcpolicy.gc_startup_code()) # build entrypoint and eventually other things to expose pf = self.getentrypointptr() if isinstance(pf, list): for one_pf in pf: db.get(one_pf) self.c_entrypoint_name = None else: pfname = db.get(pf) for func, _ in self.secondary_entrypoints: bk = translator.annotator.bookkeeper db.get(getfunctionptr(bk.getdesc(func).getuniquegraph())) self.c_entrypoint_name = pfname if self.config.translation.reverse_debugger: from rpython.translator.revdb import gencsupp gencsupp.prepare_database(db) for obj in exports.EXPORTS_obj2name.keys(): db.getcontainernode(obj) exports.clear() for ll_func in db.translator._call_at_startup: db.get(ll_func) db.complete() self.collect_compilation_info(db) return db
def test_malloc(): S = GcStruct('testing', ('x', Signed), ('y', Signed)) def ll_f(x): p = malloc(S) p.x = x p.y = x+1 return p.x * p.y t, graph = makegraph(ll_f, [int]) db = LowLevelDatabase(t, exctransformer=t.getexceptiontransformer()) db.get(getfunctionptr(graph)) db.complete() dump_on_stdout(db)
def get_jitcode_calldescr(self, graph): """Return the calldescr that describes calls to the 'graph'. This returns a calldescr that is appropriate to attach to the jitcode corresponding to 'graph'. It has no extra effectinfo, because it is not needed there; it is only used by the blackhole interp to really do the call corresponding to 'inline_call' ops. """ fnptr = getfunctionptr(graph) FUNC = lltype.typeOf(fnptr).TO fnaddr = llmemory.cast_ptr_to_adr(fnptr) NON_VOID_ARGS = [ARG for ARG in FUNC.ARGS if ARG is not lltype.Void] calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), FUNC.RESULT, EffectInfo.MOST_GENERAL) return (fnaddr, calldescr)
def getentrypointptr(self): # XXX check that the entrypoint has the correct # signature: list-of-strings -> int if not self.make_entrypoint_wrapper: bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) if self._entrypoint_wrapper is not None: return self._entrypoint_wrapper # from rpython.annotator import model as annmodel from rpython.rtyper.lltypesystem import rffi from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator from rpython.rtyper.llannotation import lltype_to_annotation entrypoint = self.entrypoint # def entrypoint_wrapper(argc, argv): """This is a wrapper that takes "Signed argc" and "char **argv" like the C main function, and puts them inside an RPython list of strings before invoking the real entrypoint() function. """ list = [""] * argc i = 0 while i < argc: list[i] = rffi.charp2str(argv[i]) i += 1 return entrypoint(list) # mix = MixLevelHelperAnnotator(self.translator.rtyper) args_s = [annmodel.SomeInteger(), lltype_to_annotation(rffi.CCHARPP)] s_result = annmodel.SomeInteger() graph = mix.getgraph(entrypoint_wrapper, args_s, s_result) mix.finish() res = getfunctionptr(graph) self._entrypoint_wrapper = res return res
def test_malloc(): S = GcStruct('testing', ('x', Signed), ('y', Signed)) def ll_f(x): p = malloc(S) p.x = x p.y = x + 1 return p.x * p.y t, graph = makegraph(ll_f, [int]) db = LowLevelDatabase(t, exctransformer=t.getexceptiontransformer()) db.get(getfunctionptr(graph)) db.complete() dump_on_stdout(db)
def getcallable(self, graph): def getconcretetype(v): return self.bindingrepr(v).lowleveltype if self.annotator.translator.config.translation.sandbox: try: name = graph.func._sandbox_external_name except AttributeError: pass else: args_s = [v.annotation for v in graph.getargs()] s_result = graph.getreturnvar().annotation sandboxed = make_sandbox_trampoline(name, args_s, s_result) return self.getannmixlevel().delayedfunction( sandboxed, args_s, s_result) return getfunctionptr(graph, getconcretetype)
def build_database(self): translator = self.translator gcpolicyclass = self.get_gcpolicyclass() if self.config.translation.gcrootfinder == "asmgcc": if not self.standalone: raise NotImplementedError("--gcrootfinder=asmgcc requires standalone") exctransformer = translator.getexceptiontransformer() db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicyclass=gcpolicyclass, exctransformer=exctransformer, thread_enabled=self.config.translation.thread, sandbox=self.config.translation.sandbox) self.db = db # give the gc a chance to register interest in the start-up functions it # need (we call this for its side-effects of db.get()) list(db.gcpolicy.gc_startup_code()) # build entrypoint and eventually other things to expose pf = self.getentrypointptr() if isinstance(pf, list): for one_pf in pf: db.get(one_pf) self.c_entrypoint_name = None else: pfname = db.get(pf) for func, _ in self.secondary_entrypoints: bk = translator.annotator.bookkeeper db.get(getfunctionptr(bk.getdesc(func).getuniquegraph())) self.c_entrypoint_name = pfname for obj in exports.EXPORTS_obj2name.keys(): db.getcontainernode(obj) exports.clear() db.complete() self.collect_compilation_info(db) return db
def test_multiple_malloc(): S1 = GcStruct('testing1', ('x', Signed), ('y', Signed)) S = GcStruct('testing', ('ptr1', Ptr(S1)), ('ptr2', Ptr(S1)), ('z', Signed)) def ll_f(x): ptr1 = malloc(S1) ptr1.x = x ptr2 = malloc(S1) ptr2.x = x+1 s = malloc(S) s.ptr1 = ptr1 s.ptr2 = ptr2 return s.ptr1.x * s.ptr2.x t, graph = makegraph(ll_f, [int]) db = LowLevelDatabase(t, exctransformer=t.getexceptiontransformer()) db.get(getfunctionptr(graph)) db.complete() dump_on_stdout(db)
def test_multiple_malloc(): S1 = GcStruct('testing1', ('x', Signed), ('y', Signed)) S = GcStruct('testing', ('ptr1', Ptr(S1)), ('ptr2', Ptr(S1)), ('z', Signed)) def ll_f(x): ptr1 = malloc(S1) ptr1.x = x ptr2 = malloc(S1) ptr2.x = x + 1 s = malloc(S) s.ptr1 = ptr1 s.ptr2 = ptr2 return s.ptr1.x * s.ptr2.x t, graph = makegraph(ll_f, [int]) db = LowLevelDatabase(t, exctransformer=t.getexceptiontransformer()) db.get(getfunctionptr(graph)) db.complete() dump_on_stdout(db)
def getcallable(self, graph): def getconcretetype(v): return self.bindingrepr(v).lowleveltype return getfunctionptr(graph, getconcretetype)
def getentrypointptr(self): # XXX check that the entrypoint has the correct # signature: list-of-strings -> int bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph())