def get_external_function_sandbox_graph(fnobj, db, force_stub=False): """Build the graph of a helper trampoline function to be used in place of real calls to the external function 'fnobj'. The trampoline marshals its input arguments, dumps them to STDOUT, and waits for an answer on STDIN. """ fnname = fnobj._name if hasattr(fnobj, 'graph'): # get the annotation of the input arguments and the result graph = fnobj.graph annotator = db.translator.annotator args_s = [annotator.binding(v) for v in graph.getargs()] s_result = annotator.binding(graph.getreturnvar()) else: # pure external function - fall back to the annotations # corresponding to the ll types FUNCTYPE = lltype.typeOf(fnobj) args_s = [lltype_to_annotation(ARG) for ARG in FUNCTYPE.ARGS] s_result = lltype_to_annotation(FUNCTYPE.RESULT) try: if force_stub: # old case - don't try to support suggested_primitive raise NotImplementedError("sandboxing for external function '%s'" % (fnname, )) dump_arguments = rmarshal.get_marshaller(tuple(args_s)) load_result = rmarshal.get_loader(s_result) except (NotImplementedError, rmarshal.CannotMarshal, rmarshal.CannotUnmarshall), e: msg = 'Not Implemented: %s' % (e, ) log.WARNING(msg) def execute(*args): not_implemented_stub(msg)
def get_external_function_sandbox_graph(fnobj, db, force_stub=False): """Build the graph of a helper trampoline function to be used in place of real calls to the external function 'fnobj'. The trampoline marshals its input arguments, dumps them to STDOUT, and waits for an answer on STDIN. """ fnname = fnobj._name if hasattr(fnobj, 'graph'): # get the annotation of the input arguments and the result graph = fnobj.graph annotator = db.translator.annotator args_s = [annotator.binding(v) for v in graph.getargs()] s_result = annotator.binding(graph.getreturnvar()) else: # pure external function - fall back to the annotations # corresponding to the ll types FUNCTYPE = lltype.typeOf(fnobj) args_s = [lltype_to_annotation(ARG) for ARG in FUNCTYPE.ARGS] s_result = lltype_to_annotation(FUNCTYPE.RESULT) try: if force_stub: # old case - don't try to support suggested_primitive raise NotImplementedError("sandboxing for external function '%s'" % (fnname,)) dump_arguments = rmarshal.get_marshaller(tuple(args_s)) load_result = rmarshal.get_loader(s_result) except (NotImplementedError, rmarshal.CannotMarshal, rmarshal.CannotUnmarshall), e: msg = 'Not Implemented: %s' % (e,) log.WARNING(msg) def execute(*args): not_implemented_stub(msg)
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res, extra=None, extrakey=None): assert (extra is None) == (extrakey is None) key = (oopspec_name, tuple(ll_args), ll_res, extrakey) try: return rtyper._builtin_func_for_spec_cache[key] except (KeyError, AttributeError): pass args_s = [lltype_to_annotation(v) for v in ll_args] if '.' not in oopspec_name: # 'newxxx' operations LIST_OR_DICT = ll_res else: LIST_OR_DICT = ll_args[0] s_result = lltype_to_annotation(ll_res) impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s), extra) if getattr(impl, 'need_result_type', False): bk = rtyper.annotator.bookkeeper args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))])) # if hasattr(rtyper, 'annotator'): # regular case mixlevelann = MixLevelHelperAnnotator(rtyper) c_func = mixlevelann.constfunc(impl, args_s, s_result) mixlevelann.finish() else: # for testing only c_func = Constant(oopspec_name, lltype.Ptr(lltype.FuncType(ll_args, ll_res))) # if not hasattr(rtyper, '_builtin_func_for_spec_cache'): rtyper._builtin_func_for_spec_cache = {} rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT) # return c_func, LIST_OR_DICT
def _setup_frame_realloc(self, translate_support_code): FUNC_TP = lltype.Ptr( lltype.FuncType([llmemory.GCREF, lltype.Signed], llmemory.GCREF)) base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): try: if not we_are_translated(): assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date frame.jf_frame_info.update_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_writebarrier(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception as e: print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO) def realloc_frame_crash(frame, size): print "frame", frame, "size", size return lltype.nullptr(llmemory.GCREF.TO) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) else: FUNC = FUNC_TP.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) mixlevelann = MixLevelHelperAnnotator(self.rtyper) graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() self.realloc_frame = heaptracker.adr2int( llmemory.cast_ptr_to_adr(fptr)) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame_crash) else: FUNC = FUNC_TP.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) mixlevelann = MixLevelHelperAnnotator(self.rtyper) graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() self.realloc_frame_crash = heaptracker.adr2int( llmemory.cast_ptr_to_adr(fptr))
def helper_func(self, FUNCPTR, func): if not self.cpu.translate_support_code: return llhelper(FUNCPTR, func) FUNC = FUNCPTR.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) graph = self.annhelper.getgraph(func, args_s, s_result) return self.annhelper.graph2delayed(graph, FUNC)
def _setup_frame_realloc(self, translate_support_code): FUNC_TP = lltype.Ptr(lltype.FuncType([llmemory.GCREF, lltype.Signed], llmemory.GCREF)) base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): try: if not we_are_translated(): assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date frame.jf_frame_info.update_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_writebarrier(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception as e: print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO) def realloc_frame_crash(frame, size): print "frame", frame, "size", size return lltype.nullptr(llmemory.GCREF.TO) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) else: FUNC = FUNC_TP.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) mixlevelann = MixLevelHelperAnnotator(self.rtyper) graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame_crash) else: FUNC = FUNC_TP.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) mixlevelann = MixLevelHelperAnnotator(self.rtyper) graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() self.realloc_frame_crash = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr))
def compute_result_annotation(self, s_F, s_callable): assert s_F.is_constant() assert s_callable.is_constant() F = s_F.const FUNC = F.TO args_s = [lltype_to_annotation(T) for T in FUNC.ARGS] key = (llhelper, s_callable.const) s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s) assert lltype_to_annotation(FUNC.RESULT).contains(s_res) return SomePtr(F)
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res, extra=None, extrakey=None): assert (extra is None) == (extrakey is None) key = (oopspec_name, tuple(ll_args), ll_res, extrakey) try: return rtyper._builtin_func_for_spec_cache[key] except (KeyError, AttributeError): pass args_s = [lltype_to_annotation(v) for v in ll_args] if '.' not in oopspec_name: # 'newxxx' operations LIST_OR_DICT = ll_res else: LIST_OR_DICT = ll_args[0] s_result = lltype_to_annotation(ll_res) impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s), extra) if getattr(impl, 'need_result_type', False): if hasattr(rtyper, 'annotator'): bk = rtyper.annotator.bookkeeper ll_restype = ll_res if impl.need_result_type != 'exact': ll_restype = ll_restype.TO desc = bk.getdesc(ll_restype) else: class TestingDesc(object): knowntype = int pyobj = None desc = TestingDesc() args_s.insert(0, annmodel.SomePBC([desc])) # if hasattr(rtyper, 'annotator'): # regular case mixlevelann = MixLevelHelperAnnotator(rtyper) c_func = mixlevelann.constfunc(impl, args_s, s_result) mixlevelann.finish() else: # for testing only c_func = Constant(oopspec_name, lltype.Ptr(lltype.FuncType(ll_args, ll_res))) # if not hasattr(rtyper, '_builtin_func_for_spec_cache'): rtyper._builtin_func_for_spec_cache = {} rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT) # return c_func, LIST_OR_DICT
def arguments_ALLOCATING(self): from rpython.annotator import model as annmodel from rpython.rtyper import llannotation return [ annmodel.SomeInteger(knowntype=r_longlong), llannotation.lltype_to_annotation(llmemory.GCREF) ]
def _compute_annotation(t, bookkeeper=None): from rpython.rtyper.lltypesystem import lltype from rpython.rtyper import extregistry if isinstance(t, SomeObject): return t elif isinstance(t, lltype.LowLevelType): return lltype_to_annotation(t) elif isinstance(t, list): assert len(t) == 1, "We do not support type joining in list" listdef = ListDef(bookkeeper, annotation(t[0]), mutated=True, resized=True) return SomeList(listdef) elif isinstance(t, tuple): return SomeTuple(tuple([annotation(i) for i in t])) elif isinstance(t, dict): assert len(t) == 1, "We do not support type joining in dict" result = SomeDict(DictDef(bookkeeper, annotation(t.keys()[0]), annotation(t.values()[0]))) return result elif type(t) is types.NoneType: return s_None elif extregistry.is_registered(t): entry = extregistry.lookup(t) entry.bookkeeper = bookkeeper return entry.compute_result_annotation() else: return annotationoftype(t, bookkeeper)
def compute_result_annotation(self, s_F, s_callable): from rpython.annotator.description import FunctionDesc assert s_F.is_constant() assert isinstance(s_callable, annmodel.SomePBC) F = s_F.const FUNC = F.TO args_s = [lltype_to_annotation(T) for T in FUNC.ARGS] for desc in s_callable.descriptions: assert isinstance(desc, FunctionDesc) assert desc.pyobj is not None if s_callable.is_constant(): assert s_callable.const is desc.pyobj key = (llhelper, desc.pyobj) s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s) assert lltype_to_annotation(FUNC.RESULT).contains(s_res) return SomePtr(F)
def _annotation(a, x): T = lltype.typeOf(x) if T == lltype.Ptr(ll_rstr.STR): t = str else: t = lltype_to_annotation(T) return a.typeannotation(t)
def _compute_annotation(t, bookkeeper=None): from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.llannotation import lltype_to_annotation if isinstance(t, SomeObject): return t elif isinstance(t, lltype.LowLevelType): return lltype_to_annotation(t) elif isinstance(t, list): assert len(t) == 1, "We do not support type joining in list" listdef = ListDef(bookkeeper, annotation(t[0]), mutated=True, resized=True) return SomeList(listdef) elif isinstance(t, tuple): return SomeTuple(tuple([annotation(i) for i in t])) elif isinstance(t, dict): assert len(t) == 1, "We do not support type joining in dict" result = SomeDict( DictDef(bookkeeper, annotation(t.keys()[0]), annotation(t.values()[0]))) return result elif type(t) is types.NoneType: return s_None elif extregistry.is_registered(t): entry = extregistry.lookup(t) entry.bookkeeper = bookkeeper return entry.compute_result_annotation() else: return annotationoftype(t, bookkeeper)
def getattr(self, s_attr): if not s_attr.is_constant(): raise annmodel.AnnotatorError( "non-constant attr name in getattr()") attrname = s_attr.const TYPE = STAT_FIELD_TYPES[attrname] return lltype_to_annotation(TYPE)
def compute_result_annotation(self, s_OB_PTR_TYPE, s_p): from rpython.annotator import model as annmodel from rpython.rtyper.llannotation import lltype_to_annotation assert (isinstance(s_p, annmodel.SomeInstance) or annmodel.s_None.contains(s_p)) assert s_OB_PTR_TYPE.is_constant() return lltype_to_annotation(s_OB_PTR_TYPE.const)
def compute_result_annotation(self, s_OB_PTR_TYPE, s_p): from rpython.annotator import model as annmodel from rpython.rtyper.llannotation import lltype_to_annotation assert isinstance(s_p, annmodel.SomeInstance) or annmodel.s_None.contains(s_p) assert s_OB_PTR_TYPE.is_constant() return lltype_to_annotation(s_OB_PTR_TYPE.const)
def gendirectcall(self, ll_function, *args_v): rtyper = self.rtyper args_s = [] newargs_v = [] for v in args_v: if v.concretetype is Void: s_value = rtyper.binding(v, default=annmodel.s_None) if not s_value.is_constant(): raise TyperError("non-constant variable of type Void") if not isinstance(s_value, annmodel.SomePBC): raise TyperError("non-PBC Void argument: %r", (s_value,)) args_s.append(s_value) else: args_s.append(lltype_to_annotation(v.concretetype)) newargs_v.append(v) self.rtyper.call_all_setups() # compute ForwardReferences now # hack for bound methods if hasattr(ll_function, 'im_func'): bk = rtyper.annotator.bookkeeper args_s.insert(0, bk.immutablevalue(ll_function.im_self)) newargs_v.insert(0, inputconst(Void, ll_function.im_self)) ll_function = ll_function.im_func graph = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s, rtyper.lowlevel_ann_policy) self.record_extra_call(graph) # build the 'direct_call' operation f = self.rtyper.getcallable(graph) c = inputconst(typeOf(f), f) fobj = self.rtyper.type_system.deref(f) return self.genop('direct_call', [c]+newargs_v, resulttype = typeOf(fobj).RESULT)
def complete_destrptr(gctransformer): translator = gctransformer.translator mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) args_s = [lltype_to_annotation(STACKLET_PTR)] s_result = annmodel.s_None destrptr = mixlevelannotator.delayedfunction(stacklet_destructor, args_s, s_result) mixlevelannotator.finish() lltype.attachRuntimeTypeInfo(STACKLET, destrptr=destrptr)
def test_ll_calling_ll(self): A = GcArray(Float) B = GcArray(Signed) def ll_make(T, n): x = malloc(T, n) return x def ll_get(T, x, i): return x[i] def llf(): a = ll_make(A, 3) b = ll_make(B, 2) a[0] = 1.0 b[1] = 3 y0 = ll_get(A, a, 1) y1 = ll_get(B, b, 1) # a2 = ll_make(A, 4) a2[0] = 2.0 return ll_get(A, a2, 1) s = self.annotate(llf, []) a = self.a assert s == annmodel.SomeFloat() seen = {} ngraphs = len(a.translator.graphs) vTs = [] for call in annotated_calls(a): if derived(call, "ll_"): func, T = [x.value for x in call.args[0:2]] if (func, T) in seen: continue seen[func, T] = True desc = a.bookkeeper.getdesc(func) g = desc.specialize([a.binding(x) for x in call.args[1:]]) args = g.getargs() rv = g.getreturnvar() if func is ll_get: vT, vp, vi = args assert a.binding(vT) == a.bookkeeper.immutablevalue(T) assert a.binding(vi).knowntype == int assert a.binding(vp).ll_ptrtype.TO == T assert a.binding(rv) == lltype_to_annotation(T.OF) elif func is ll_make: vT, vn = args assert a.binding(vT) == a.bookkeeper.immutablevalue(T) assert a.binding(vn).knowntype == int assert a.binding(rv).ll_ptrtype.TO == T else: assert False, func vTs.append(vT) assert len(seen) == 4 return a, vTs # reused by a test in test_rtyper
def getprimitiverepr(self, lltype): try: return self.primitive_to_repr[lltype] except KeyError: pass if isinstance(lltype, Primitive): repr = self.primitive_to_repr[lltype] = self.getrepr(lltype_to_annotation(lltype)) return repr raise TyperError('There is no primitive repr for %r' % (lltype,))
def rtype_simple_call(self, hop): hop2 = hop.copy() func = self.func s_func = hop.rtyper.annotator.bookkeeper.immutablevalue(func) v_ptr = hop2.args_v[0] hop2.r_s_popfirstarg() hop2.v_s_insertfirstarg(v_ptr, lltype_to_annotation(self.ll_ptrtype)) hop2.v_s_insertfirstarg(flowmodel.Constant(func), s_func) return hop2.dispatch()
def __init__(self, rtyper): self.rtyper = rtyper self.statvfs_field_indexes = {} for i, (name, TYPE) in enumerate(STATVFS_FIELDS): self.statvfs_field_indexes[name] = i self.s_tuple = annmodel.SomeTuple([lltype_to_annotation(TYPE) for name, TYPE in STATVFS_FIELDS]) self.r_tuple = rtyper.getrepr(self.s_tuple) self.lowleveltype = self.r_tuple.lowleveltype
def compute_result_annotation(self, s_RESTYPE, s_pythonfunction, *args_s): from rpython.annotator import model as annmodel from rpython.rtyper.llannotation import lltype_to_annotation assert s_RESTYPE.is_constant() assert s_pythonfunction.is_constant() s_result = s_RESTYPE.const if isinstance(s_result, lltype.LowLevelType): s_result = lltype_to_annotation(s_result) assert isinstance(s_result, annmodel.SomeObject) return s_result
def __init__(self, rtyper): self.rtyper = rtyper self.statvfs_field_indexes = {} for i, (name, TYPE) in enumerate(STATVFS_FIELDS): self.statvfs_field_indexes[name] = i self.s_tuple = annmodel.SomeTuple( [lltype_to_annotation(TYPE) for name, TYPE in STATVFS_FIELDS]) self.r_tuple = rtyper.getrepr(self.s_tuple) self.lowleveltype = self.r_tuple.lowleveltype
def annotate_helper(self, ll_helper, ll_args, ll_result, inline=False): assert not self.finished_helpers args_s = map(lltype_to_annotation, ll_args) s_result = lltype_to_annotation(ll_result) graph = self.mixlevelannotator.getgraph(ll_helper, args_s, s_result) # the produced graphs does not need to be fully transformed self.need_minimal_transform(graph) if inline: self.graphs_to_inline[graph] = True FUNCTYPE = lltype.FuncType(ll_args, ll_result) return self.mixlevelannotator.graph2delayed(graph, FUNCTYPE=FUNCTYPE)
def _get_rmarshall_support_(self): # for rlib.rmarshal # reduce and recreate stat_result objects from 10-tuples # (we ignore the extra values here for simplicity and portability) def stat_result_reduce(st): return (st[0], st[1], st[2], st[3], st[4], st[5], st[6], st.st_atime, st.st_mtime, st.st_ctime) def stat_result_recreate(tup): atime, mtime, ctime = tup[7:] result = tup[:7] result += (int(atime), int(mtime), int(ctime)) result += extra_zeroes result += (int((atime - result[7]) * 1e9), int((mtime - result[8]) * 1e9), int((ctime - result[9]) * 1e9)) return make_stat_result(result) s_reduced = annmodel.SomeTuple([lltype_to_annotation(TYPE) for name, TYPE in PORTABLE_STAT_FIELDS[:7]] + 3 * [lltype_to_annotation(lltype.Float)]) extra_zeroes = (0,) * (len(STAT_FIELDS) - len(PORTABLE_STAT_FIELDS) - 3) return s_reduced, stat_result_reduce, stat_result_recreate
def consider_call_site(self, call_op): binding = self.annotator.binding s_callable = binding(call_op.args[0]) args_s = [binding(arg) for arg in call_op.args[1:]] if isinstance(s_callable, SomeLLADTMeth): adtmeth = s_callable s_callable = self.immutablevalue(adtmeth.func) args_s = [lltype_to_annotation(adtmeth.ll_ptrtype)] + args_s if isinstance(s_callable, SomePBC): s_result = binding(call_op.result, s_ImpossibleValue) self.consider_call_site_for_pbc(s_callable, call_op.opname, args_s, s_result, call_op)
def __init__(self, rtyper): self.rtyper = rtyper self.stat_fields = ll_os_stat.STAT_FIELDS self.stat_field_indexes = {} for i, (name, TYPE) in enumerate(self.stat_fields): self.stat_field_indexes[name] = i self.s_tuple = annmodel.SomeTuple([lltype_to_annotation(TYPE) for name, TYPE in self.stat_fields]) self.r_tuple = rtyper.getrepr(self.s_tuple) self.lowleveltype = self.r_tuple.lowleveltype
def __init__(self, rtyper): self.rtyper = rtyper self.stat_fields = ll_os_stat.STAT_FIELDS self.stat_field_indexes = {} for i, (name, TYPE) in enumerate(self.stat_fields): self.stat_field_indexes[name] = i self.s_tuple = annmodel.SomeTuple( [lltype_to_annotation(TYPE) for name, TYPE in self.stat_fields]) self.r_tuple = rtyper.getrepr(self.s_tuple) self.lowleveltype = self.r_tuple.lowleveltype
def _get_rmarshall_support_(self): # for rlib.rmarshal # reduce and recreate stat_result objects from 10-tuples # (we ignore the extra values here for simplicity and portability) def stat_result_reduce(st): return (st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9]) def stat_result_recreate(tup): return make_stat_result(tup + extra_zeroes) s_reduced = annmodel.SomeTuple([lltype_to_annotation(TYPE) for name, TYPE in PORTABLE_STAT_FIELDS]) extra_zeroes = (0,) * (len(STAT_FIELDS) - len(PORTABLE_STAT_FIELDS)) return s_reduced, stat_result_reduce, stat_result_recreate
def getattr(self, s_attr): if not s_attr.is_constant(): raise annmodel.AnnotatorError("non-constant attr name in getattr()") attrname = s_attr.const if attrname in ('st_atime', 'st_mtime', 'st_ctime'): # like CPython, in RPython we can read the st_Xtime # attribute and get a floating-point result. We can also # get a full-precision bigint with get_stat_ns_as_bigint(). # The floating-point result is computed like a property # by _ll_get_st_Xtime(). TYPE = lltype.Float else: TYPE = STAT_FIELD_TYPES[attrname] return lltype_to_annotation(TYPE)
def consider_call_site(self, call_op): from rpython.rtyper.llannotation import SomeLLADTMeth, lltype_to_annotation annotation = self.annotator.annotation s_callable = annotation(call_op.args[0]) args_s = [annotation(arg) for arg in call_op.args[1:]] if isinstance(s_callable, SomeLLADTMeth): adtmeth = s_callable s_callable = self.immutablevalue(adtmeth.func) args_s = [lltype_to_annotation(adtmeth.ll_ptrtype)] + args_s if isinstance(s_callable, SomePBC): s_result = annotation(call_op.result) if s_result is None: s_result = s_ImpossibleValue args = call_op.build_args(args_s) s_callable.consider_call_site(args, s_result, call_op)
def _get_rmarshall_support_(self): # for rlib.rmarshal # reduce and recreate stat_result objects from 10-tuples # (we ignore the extra values here for simplicity and portability) def stat_result_reduce(st): return (st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9]) def stat_result_recreate(tup): return make_stat_result(tup + extra_zeroes) s_reduced = annmodel.SomeTuple([ lltype_to_annotation(TYPE) for name, TYPE in PORTABLE_STAT_FIELDS ]) extra_zeroes = (0, ) * (len(STAT_FIELDS) - len(PORTABLE_STAT_FIELDS)) return s_reduced, stat_result_reduce, stat_result_recreate
def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from rpython.rtyper import rmodel from rpython.rtyper.error import TyperError assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" r_func, nimplicitarg = s_repr.const.get_r_implfunc() nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" "annotations: %r" % (s_repr.const, s_sigs)) _, s_ret = s_sigs[0] rresult = r_func.rtyper.getrepr(s_ret) return lltype_to_annotation(rresult.lowleveltype)
def annotate_helper(self, ll_function, argtypes): """Annotate the given low-level helper function and return its graph """ args_s = [] for s in argtypes: # assume 's' is a low-level type, unless it is already an annotation if not isinstance(s, annmodel.SomeObject): s = lltype_to_annotation(s) args_s.append(s) # hack for bound methods if hasattr(ll_function, 'im_func'): bk = self.annotator.bookkeeper args_s.insert(0, bk.immutablevalue(ll_function.im_self)) ll_function = ll_function.im_func helper_graph = annotate_lowlevel_helper(self.annotator, ll_function, args_s, policy=self.lowlevel_ann_policy) return helper_graph
def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from rpython.rtyper.llannotation import lltype_to_annotation from rpython.rtyper import rmodel from rpython.rtyper.error import TyperError assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" r_func, nimplicitarg = s_repr.const.get_r_implfunc() nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" "annotations: %r" % (s_repr.const, s_sigs)) _, s_ret = s_sigs[0] rresult = r_func.rtyper.getrepr(s_ret) return lltype_to_annotation(rresult.lowleveltype)
def gendirectcall(self, ll_function, *args_v): rtyper = self.rtyper args_s = [] newargs_v = [] with rtyper.annotator.using_policy(rtyper.lowlevel_ann_policy): for v in args_v: if v.concretetype is Void: s_value = rtyper.annotation(v) if s_value is None: s_value = annmodel.s_None if not s_value.is_constant(): raise TyperError("non-constant variable of type Void") if not isinstance(s_value, (annmodel.SomePBC, annmodel.SomeNone)): raise TyperError("non-PBC Void argument: %r", (s_value, )) args_s.append(s_value) else: args_s.append(lltype_to_annotation(v.concretetype)) newargs_v.append(v) self.rtyper.call_all_setups() # compute ForwardReferences now # hack for bound methods if hasattr(ll_function, 'im_func'): bk = rtyper.annotator.bookkeeper args_s.insert(0, bk.immutablevalue(ll_function.im_self)) newargs_v.insert(0, inputconst(Void, ll_function.im_self)) ll_function = ll_function.im_func graph = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s, rtyper.lowlevel_ann_policy) self.record_extra_call(graph) # build the 'direct_call' operation f = self.rtyper.getcallable(graph) c = inputconst(typeOf(f), f) fobj = f._obj return self.genop('direct_call', [c] + newargs_v, resulttype=typeOf(fobj).RESULT)
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 getattr(self, s_attr): assert s_attr.is_constant() TYPE = STATVFS_FIELD_TYPES[s_attr.const] return lltype_to_annotation(TYPE)
def compute_result_annotation(self, RESULTTYPE, *args): from rpython.rtyper.llannotation import lltype_to_annotation assert RESULTTYPE.is_constant() return lltype_to_annotation(RESULTTYPE.const)
def getattr(self, s_attr): assert s_attr.is_constant(), "non-constant attr name in getattr()" attrname = s_attr.const TYPE = STAT_FIELD_TYPES[attrname] return lltype_to_annotation(TYPE)
def getitem((s_stat, s_int)): assert s_int.is_constant() name, TYPE = STATVFS_FIELDS[s_int.const] return lltype_to_annotation(TYPE)