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 dispatcher(self, shape, index, argtypes, resulttype): key = shape, index, tuple(argtypes), resulttype if key in self._dispatch_cache: return self._dispatch_cache[key] from rpython.translator.unsimplify import varoftype from rpython.flowspace.model import FunctionGraph, Link, Block, SpaceOperation inputargs = [varoftype(t) for t in [Char] + argtypes] startblock = Block(inputargs) startblock.exitswitch = inputargs[0] graph = FunctionGraph("dispatcher", startblock, varoftype(resulttype)) row_of_graphs = self.callfamily.calltables[shape][index] links = [] descs = list(self.s_pbc.descriptions) if self.s_pbc.can_be_None: descs.insert(0, None) for desc in descs: if desc is None: continue args_v = [varoftype(t) for t in argtypes] b = Block(args_v) llfn = self.rtyper.getcallable(row_of_graphs[desc]) v_fn = inputconst(typeOf(llfn), llfn) v_result = varoftype(resulttype) b.operations.append( SpaceOperation("direct_call", [v_fn] + args_v, v_result)) b.closeblock(Link([v_result], graph.returnblock)) i = self.descriptions.index(desc) links.append(Link(inputargs[1:], b, chr(i))) links[-1].llexitcase = chr(i) startblock.closeblock(*links) self.rtyper.annotator.translator.graphs.append(graph) ll_ret = getfunctionptr(graph) #FTYPE = FuncType c_ret = self._dispatch_cache[key] = inputconst(typeOf(ll_ret), ll_ret) return c_ret
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 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 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 assert self.rtyper.type_system.name == "lltypesystem" 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 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") db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicyclass=gcpolicyclass, 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 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") db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicyclass=gcpolicyclass, 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 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())