def chooser(x): s = lltype.malloc(STRUCT, flavor="raw") if x: s.bar = llhelper(FTPTR, a_f.make_func()) else: s.bar = llhelper(FTPTR, a_g.make_func()) return f(s)
def test_call_stubs(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] RES = lltype.Char descr1 = get_call_descr(c0, ARGS, RES) def f(a, b): return 'c' call_stub = descr1.call_stub fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) res = call_stub(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None) assert res == ord('c') ARRAY = lltype.GcArray(lltype.Signed) ARGS = [lltype.Float, lltype.Ptr(ARRAY)] RES = lltype.Float def f(a, b): return float(b[0]) + a fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) descr2 = get_call_descr(c0, ARGS, RES) a = lltype.malloc(ARRAY, 3) opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) a[0] = 1 res = descr2.call_stub(rffi.cast(lltype.Signed, fnptr), [], [opaquea], [longlong.getfloatstorage(3.5)]) assert longlong.getrealfloat(res) == 4.5
def get_on_leave_jitted_int(self, save_exception): if save_exception: f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_save_exc) else: f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_noexc) return rffi.cast(lltype.Signed, f)
def h(x, y, z): s = ootype.new(S) s.x = x s.y = y fsm = llhelper(F, f) gsm = llhelper(G, g) assert typeOf(fsm) == F return fsm(s, z)+fsm(s, z*2)+gsm(s)
def setup_buffer_buffer_procs(space, pto): c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True) lltype.render_immortal(c_buf) c_buf.c_bf_getsegcount = llhelper(str_segcount.api_func.functype, str_segcount.api_func.get_wrapper(space)) c_buf.c_bf_getreadbuffer = llhelper(buf_getreadbuffer.api_func.functype, buf_getreadbuffer.api_func.get_wrapper(space)) pto.c_tp_as_buffer = c_buf
def h(x, y, z): s = malloc(S) s.x = x s.y = y fptr = llhelper(F, f) gptr = llhelper(G, g) assert typeOf(fptr) == F return fptr(s, z)+fptr(s, z*2)+gptr(s)
def h(x, y, z): s = malloc(S) s.x = x s.y = y fptr = llhelper(F, f) gptr = llhelper(G, g) assert typeOf(fptr) == F return fptr(s, z) + fptr(s, z * 2) + gptr(s)
def h(x, y, z): s = ootype.new(S) s.x = x s.y = y fsm = llhelper(F, f) gsm = llhelper(G, g) assert typeOf(fsm) == F return fsm(s, z) + fsm(s, z * 2) + gsm(s)
def get_on_leave_jitted_int(self, save_exception, default_to_memoryerror=False): if default_to_memoryerror: f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_memoryerr) elif save_exception: f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_save_exc) else: f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_noexc) return rffi.cast(lltype.Signed, f)
def wrapper(*args): # XXX the next line is a workaround for the annotation bug # shown in rpython.test.test_llann:test_pbctype. Remove it # when the test is fixed... assert isinstance(lltype.Signed, lltype.Number) real_args = () to_free = () for i, TARGET in unrolling_arg_tps: arg = args[i] freeme = None if TARGET == CCHARP: if arg is None: arg = lltype.nullptr(CCHARP.TO) # None => (char*)NULL freeme = arg elif isinstance(arg, str): arg = str2charp(arg) # XXX leaks if a str2charp() fails with MemoryError # and was not the first in this function freeme = arg elif _isfunctype(TARGET) and not _isllptr(arg): # XXX pass additional arguments if invoke_around_handlers: arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg, aroundstate)) else: arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg)) else: SOURCE = lltype.typeOf(arg) if SOURCE != TARGET: if TARGET is lltype.Float: arg = float(arg) elif ((isinstance(SOURCE, lltype.Number) or SOURCE is lltype.Bool) and (isinstance(TARGET, lltype.Number) or TARGET is lltype.Bool)): arg = cast(TARGET, arg) real_args = real_args + (arg,) to_free = to_free + (freeme,) if invoke_around_handlers: before = aroundstate.before after = aroundstate.after if before: before() # NB. it is essential that no exception checking occurs after # the call to before(), because we don't have the GIL any more! res = funcptr(*real_args) if invoke_around_handlers: if after: after() for i, TARGET in unrolling_arg_tps: if to_free[i]: lltype.free(to_free[i], flavor='raw') if rarithmetic.r_int is not r_int: if result is INT: return cast(lltype.Signed, res) elif result is UINT: return cast(lltype.Unsigned, res) return res
def type_attach(space, py_obj, w_type): """ Fills a newly allocated PyTypeObject from an existing type. """ from pypy.module.cpyext.object import PyObject_Del assert isinstance(w_type, W_TypeObject) pto = rffi.cast(PyTypeObjectPtr, py_obj) typedescr = get_typedescr(w_type.instancetypedef) # dealloc pto.c_tp_dealloc = typedescr.get_dealloc(space) # buffer protocol if space.is_w(w_type, space.w_str): setup_string_buffer_procs(space, pto) if space.is_w(w_type, space.gettypefor(Buffer)): setup_buffer_buffer_procs(space, pto) pto.c_tp_free = llhelper(PyObject_Del.api_func.functype, PyObject_Del.api_func.get_wrapper(space)) pto.c_tp_alloc = llhelper(PyType_GenericAlloc.api_func.functype, PyType_GenericAlloc.api_func.get_wrapper(space)) if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE: w_typename = space.getattr(w_type, space.wrap('__name__')) heaptype = rffi.cast(PyHeapTypeObject, pto) heaptype.c_ht_name = make_ref(space, w_typename) from pypy.module.cpyext.stringobject import PyString_AsString pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name) else: pto.c_tp_name = rffi.str2charp(w_type.getname(space)) pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out pto.c_tp_itemsize = 0 # uninitialized fields: # c_tp_print, c_tp_getattr, c_tp_setattr # XXX implement # c_tp_compare and the following fields (see http://docs.python.org/c-api/typeobj.html ) w_base = best_base(space, w_type.bases_w) pto.c_tp_base = rffi.cast(PyTypeObjectPtr, make_ref(space, w_base)) finish_type_1(space, pto) finish_type_2(space, pto, w_type) pto.c_tp_basicsize = rffi.sizeof(typedescr.basestruct) if pto.c_tp_base: if pto.c_tp_base.c_tp_basicsize > pto.c_tp_basicsize: pto.c_tp_basicsize = pto.c_tp_base.c_tp_basicsize # will be filled later on with the correct value # may not be 0 if space.is_w(w_type, space.w_object): pto.c_tp_new = rffi.cast(newfunc, 1) update_all_slots(space, w_type, pto) pto.c_tp_flags |= Py_TPFLAGS_READY return pto
def get_dealloc(self, space): if tp_dealloc: return llhelper( tp_dealloc.api_func.functype, tp_dealloc.api_func.get_wrapper(space)) else: from pypy.module.cpyext.typeobject import subtype_dealloc return llhelper( subtype_dealloc.api_func.functype, subtype_dealloc.api_func.get_wrapper(space))
def setup_string_buffer_procs(space, pto): c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True) c_buf.c_bf_getsegcount = llhelper(str_segcount.api_func.functype, str_segcount.api_func.get_wrapper(space)) c_buf.c_bf_getreadbuffer = llhelper(str_getreadbuffer.api_func.functype, str_getreadbuffer.api_func.get_wrapper(space)) c_buf.c_bf_getcharbuffer = llhelper(str_getcharbuffer.api_func.functype, str_getcharbuffer.api_func.get_wrapper(space)) pto.c_tp_as_buffer = c_buf pto.c_tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER
def setup_string_buffer_procs(space, pto): c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True) lltype.render_immortal(c_buf) c_buf.c_bf_getsegcount = llhelper(str_segcount.api_func.functype, str_segcount.api_func.get_wrapper(space)) c_buf.c_bf_getreadbuffer = llhelper(str_getreadbuffer.api_func.functype, str_getreadbuffer.api_func.get_wrapper(space)) c_buf.c_bf_getcharbuffer = llhelper(str_getcharbuffer.api_func.functype, str_getcharbuffer.api_func.get_wrapper(space)) pto.c_tp_as_buffer = c_buf pto.c_tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER
def invoke_around_extcall(before, after): """Call before() before any external function call, and after() after. At the moment only one pair before()/after() can be registered at a time. """ # NOTE: the hooks are cleared during translation! To be effective # in a compiled program they must be set at run-time. from pypy.rpython.lltypesystem import rffi rffi.aroundstate.before = before rffi.aroundstate.after = after # the 'aroundstate' contains regular function and not ll pointers to them, # but let's call llhelper() anyway to force their annotation from pypy.rpython.annlowlevel import llhelper llhelper(rffi.AroundFnPtr, before) llhelper(rffi.AroundFnPtr, after)
def wrapper(*args): # XXX the next line is a workaround for the annotation bug # shown in rpython.test.test_llann:test_pbctype. Remove it # when the test is fixed... assert isinstance(lltype.Signed, lltype.Number) real_args = () to_free = () for i, TARGET in unrolling_arg_tps: arg = args[i] freeme = None if TARGET == CCHARP: if arg is None: arg = lltype.nullptr(CCHARP.TO) # None => (char*)NULL freeme = arg elif isinstance(arg, str): arg = str2charp(arg) # XXX leaks if a str2charp() fails with MemoryError # and was not the first in this function freeme = arg elif _isfunctype(TARGET) and not _isllptr(arg): # XXX pass additional arguments if invoke_around_handlers: arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg, aroundstate)) else: arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg)) else: SOURCE = lltype.typeOf(arg) if SOURCE != TARGET: if TARGET is lltype.Float: arg = float(arg) elif ((isinstance(SOURCE, lltype.Number) or SOURCE is lltype.Bool) and (isinstance(TARGET, lltype.Number) or TARGET is lltype.Bool)): arg = cast(TARGET, arg) real_args = real_args + (arg,) to_free = to_free + (freeme,) res = call_external_function(*real_args) for i, TARGET in unrolling_arg_tps: if to_free[i]: lltype.free(to_free[i], flavor='raw') if rarithmetic.r_int is not r_int: if result is INT: return cast(lltype.Signed, res) elif result is UINT: return cast(lltype.Unsigned, res) return res
def get_tp_function(space, typedef): @cpython_api([], lltype.Signed, error=-1, external=False) def slot_tp_function(space): return typedef.value api_func = slot_tp_function.api_func return lambda: llhelper(api_func.functype, api_func.get_wrapper(space))
def make_finalizer_funcptr_for_type(self, TYPE): from pypy.rpython.memory.gctransform.support import get_rtti, type_contains_pyobjs rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, "destructor_funcptr"): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] destrgraph = destrptr._obj.graph else: return None, False assert not type_contains_pyobjs(TYPE), "not implemented" t = self.llinterp.typer.annotator.translator light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) def ll_finalizer(addr, dummy): assert dummy == llmemory.NULL try: v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) self.llinterp.eval_graph(destrgraph, [v], recursive=True) except llinterp.LLException: raise RuntimeError("a finalizer raised an exception, shouldn't happen") return llmemory.NULL return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light
class FakeJitDriverSD: portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner) portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr) portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, None) portal_finishtoken = compile.DoneWithThisFrameDescrInt() num_red_args = 2 result_type = INT
def define_custom_trace(cls): from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import llmemory # S = lltype.GcStruct('S', ('x', llmemory.Address), rtti=True) T = lltype.GcStruct('T', ('z', lltype.Signed)) offset_of_x = llmemory.offsetof(S, 'x') def customtrace(obj, prev): if not prev: return obj + offset_of_x else: return llmemory.NULL CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) lltype.attachRuntimeTypeInfo(S, customtraceptr=customtraceptr) # def setup(): s1 = lltype.malloc(S) tx = lltype.malloc(T) tx.z = 4243 s1.x = llmemory.cast_ptr_to_adr(tx) return s1 def f(): s1 = setup() llop.gc__collect(lltype.Void) return llmemory.cast_adr_to_ptr(s1.x, lltype.Ptr(T)).z return f
def define_custom_trace(cls): from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import llmemory # S = lltype.GcStruct('S', ('x', llmemory.Address), rtti=True) offset_of_x = llmemory.offsetof(S, 'x') def customtrace(obj, prev): if not prev: return obj + offset_of_x else: return llmemory.NULL CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) lltype.attachRuntimeTypeInfo(S, customtraceptr=customtraceptr) # def setup(): s = lltype.nullptr(S) for i in range(10000): t = lltype.malloc(S) t.x = llmemory.cast_ptr_to_adr(s) s = t return s def measure_length(s): res = 0 while s: res += 1 s = llmemory.cast_adr_to_ptr(s.x, lltype.Ptr(S)) return res def f(n): s1 = setup() llop.gc__collect(lltype.Void) return measure_length(s1) return f
class FakeWarmRunnerDesc: rtyper = None green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) confirm_enter_jit_ptr = None get_jitcell_at_ptr = None
def get_shadowstackref(gctransformer): if hasattr(gctransformer, '_SHADOWSTACKREF'): return gctransformer._SHADOWSTACKREF SHADOWSTACKREFPTR = lltype.Ptr(lltype.GcForwardReference()) SHADOWSTACKREF = lltype.GcStruct('ShadowStackRef', ('base', llmemory.Address), ('top', llmemory.Address), ('context', llmemory.Address), #('fullstack', lltype.Bool), rtti=True) SHADOWSTACKREFPTR.TO.become(SHADOWSTACKREF) gc = gctransformer.gcdata.gc root_iterator = get_root_iterator(gctransformer) def customtrace(obj, prev): obj = llmemory.cast_adr_to_ptr(obj, SHADOWSTACKREFPTR) if not prev: root_iterator.setcontext(obj.context) prev = obj.top return root_iterator.nextleft(gc, obj.base, prev) CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], llmemory.Address) customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace) lltype.attachRuntimeTypeInfo(SHADOWSTACKREF, customtraceptr=customtraceptr) gctransformer._SHADOWSTACKREF = SHADOWSTACKREF return SHADOWSTACKREF
def test_qsort(self): CMPFUNC = lltype.FuncType([rffi.VOIDP, rffi.VOIDP], rffi.INT) qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(CMPFUNC)], lltype.Void) lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10] A = lltype.Array(lltype.Signed, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') for i in range(10): a[i] = lst[i] SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) def my_compar(p1, p2): p1 = rffi.cast(SIGNEDPTR, p1) p2 = rffi.cast(SIGNEDPTR, p2) print 'my_compar:', p1[0], p2[0] return rffi.cast(rffi.INT, cmp(p1[0], p2[0])) qsort(rffi.cast(rffi.VOIDP, a), rffi.cast(rffi.SIZE_T, 10), rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)), llhelper(lltype.Ptr(CMPFUNC), my_compar)) for i in range(10): print a[i], print lst.sort() for i in range(10): assert a[i] == lst[i] lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
class FakeWarmRunnerDesc: rtyper = None green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = None get_printable_location_ptr = None confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) get_jitcell_at_ptr = None
def test_qsort(self): CMPFUNC = lltype.FuncType([rffi.VOIDP, rffi.VOIDP], rffi.INT) qsort = rffi.llexternal( 'qsort', [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(CMPFUNC)], lltype.Void) lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10] A = lltype.Array(lltype.Signed, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') for i in range(10): a[i] = lst[i] SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) def my_compar(p1, p2): p1 = rffi.cast(SIGNEDPTR, p1) p2 = rffi.cast(SIGNEDPTR, p2) print 'my_compar:', p1[0], p2[0] return rffi.cast(rffi.INT, cmp(p1[0], p2[0])) qsort(rffi.cast(rffi.VOIDP, a), rffi.cast(rffi.SIZE_T, 10), rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)), llhelper(lltype.Ptr(CMPFUNC), my_compar)) for i in range(10): print a[i], print lst.sort() for i in range(10): assert a[i] == lst[i] lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def build_slot_tp_function(space, typedef, name): w_type = space.gettypeobject(typedef) if name == 'tp_setattro': setattr_fn = w_type.getdictvalue(space, '__setattr__') delattr_fn = w_type.getdictvalue(space, '__delattr__') if setattr_fn is None: return @cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1, external=True) # XXX should not be exported @func_renamer("cpyext_tp_setattro_%s" % (typedef.name, )) def slot_tp_setattro(space, w_self, w_name, w_value): if w_value is not None: space.call_function(setattr_fn, w_self, w_name, w_value) else: space.call_function(delattr_fn, w_self, w_name) return 0 api_func = slot_tp_setattro.api_func else: return return lambda: llhelper(api_func.functype, api_func.get_wrapper(space))
def sort_gcmap(gcmapstart, gcmapend): count = (gcmapend - gcmapstart) // arrayitemsize qsort( gcmapstart, rffi.cast(rffi.SIZE_T, count), rffi.cast(rffi.SIZE_T, arrayitemsize), llhelper(QSORT_CALLBACK_PTR, _compare_gcmap_entries), )
def _new_callback(): # Here, we just closed the stack. Get the stack anchor, store # it in the gcrootfinder.suspstack.anchor, and create a new # stacklet with stacklet_new(). If this call fails, then we # are just returning NULL. _stack_just_closed() return _c.new(gcrootfinder.thrd, llhelper(_c.run_fn, _new_runfn), llmemory.NULL)
def helper_func(self, FUNCPTR, func): if not self.cpu.translate_support_code: return llhelper(FUNCPTR, func) FUNC = get_functype(FUNCPTR) args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = annmodel.lltype_to_annotation(FUNC.RESULT) graph = self.annhelper.getgraph(func, args_s, s_result) return self.annhelper.graph2delayed(graph, FUNC)
def test_call_aligned_with_spilled_values(self): from pypy.rlib.libffi import types cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') def func(*args): return float(sum(args)) F = lltype.Float I = lltype.Signed floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 13, -42, 1111, 95, 1] for case in range(256): local_floats = list(floats) local_ints = list(ints) args = [] spills = [] funcargs = [] float_count = 0 int_count = 0 for i in range(8): if case & (1 << i): args.append('f%d' % float_count) spills.append('force_spill(f%d)' % float_count) float_count += 1 funcargs.append(F) else: args.append('i%d' % int_count) spills.append('force_spill(i%d)' % int_count) int_count += 1 funcargs.append(I) arguments = ', '.join(args) spill_ops = '\n'.join(spills) FUNC = self.FuncType(funcargs, F) FPTR = self.Ptr(FUNC) func_ptr = llhelper(FPTR, func) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) ops = '[%s]\n' % arguments ops += '%s\n' % spill_ops ops += 'f99 = call(ConstClass(func_ptr), %s, descr=calldescr)\n' % arguments ops += 'finish(f99, %s)\n' % arguments loop = parse(ops, namespace=locals()) looptoken = JitCellToken() done_number = self.cpu.get_fail_descr_number( loop.operations[-1].getdescr()) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) res = self.cpu.execute_token(looptoken, *argvals) x = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert abs(x - expected_result) < 0.0001
def test_call_aligned_with_spilled_values(self): from pypy.rlib.libffi import types cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') def func(*args): return float(sum(args)) F = lltype.Float I = lltype.Signed floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 13, -42, 1111, 95, 1] for case in range(256): local_floats = list(floats) local_ints = list(ints) args = [] spills = [] funcargs = [] float_count = 0 int_count = 0 for i in range(8): if case & (1<<i): args.append('f%d' % float_count) spills.append('force_spill(f%d)' % float_count) float_count += 1 funcargs.append(F) else: args.append('i%d' % int_count) spills.append('force_spill(i%d)' % int_count) int_count += 1 funcargs.append(I) arguments = ', '.join(args) spill_ops = '\n'.join(spills) FUNC = self.FuncType(funcargs, F) FPTR = self.Ptr(FUNC) func_ptr = llhelper(FPTR, func) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) ops = '[%s]\n' % arguments ops += '%s\n' % spill_ops ops += 'f99 = call(ConstClass(func_ptr), %s, descr=calldescr)\n' % arguments ops += 'finish(f99, %s)\n' % arguments loop = parse(ops, namespace=locals()) looptoken = JitCellToken() done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) res = self.cpu.execute_token(looptoken, *argvals) x = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert abs(x - expected_result) < 0.0001
class FakeJitDriverSD: jitdriver = None _green_args_spec = [lltype.Signed, lltype.Float] _get_printable_location_ptr = None _confirm_enter_jit_ptr = None _can_never_inline_ptr = llhelper(CAN_NEVER_INLINE, can_never_inline) _get_jitcell_at_ptr = None _should_unroll_one_iteration_ptr = None red_args_types = []
def test_recursive_llhelper(): from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import lltype from pypy.rlib.objectmodel import specialize from pypy.rlib.nonconst import NonConstant FT = lltype.ForwardReference() FTPTR = lltype.Ptr(FT) STRUCT = lltype.Struct("foo", ("bar", FTPTR)) FT.become(lltype.FuncType([lltype.Ptr(STRUCT)], lltype.Signed)) class A: def __init__(self, func, name): self.func = func self.name = name def _freeze_(self): return True @specialize.memo() def make_func(self): f = getattr(self, "_f", None) if f is not None: return f f = lambda *args: self.func(*args) f.c_name = self.name f.relax_sig_check = True f.__name__ = "WRAP%s" % (self.name, ) self._f = f return f def get_llhelper(self): return llhelper(FTPTR, self.make_func()) def f(s): if s.bar == t.bar: lltype.free(s, flavor="raw") return 1 lltype.free(s, flavor="raw") return 0 def g(x): return 42 def chooser(x): s = lltype.malloc(STRUCT, flavor="raw") if x: s.bar = llhelper(FTPTR, a_f.make_func()) else: s.bar = llhelper(FTPTR, a_g.make_func()) return f(s) a_f = A(f, "f") a_g = A(g, "g") t = lltype.malloc(STRUCT, flavor="raw", immortal=True) t.bar = llhelper(FTPTR, a_f.make_func()) fn = compile(chooser, [bool]) assert fn(True)
def parse(vm): (xml_o, nodes_mod),_ = vm.decode_args("SM") assert isinstance(xml_o, Con_String) with lltype.scoped_alloc(xmlSAXHandler, zero=True) as h: h.c_initialized = rffi.r_uint(XML_SAX2_MAGIC) h.c_characters = llhelper(charactersSAXFuncP, _characters) h.c_startElementNs = llhelper(startElementNsSAX2FuncP, _start_element) h.c_endElementNs = llhelper(endElementNsSAX2FuncP, _end_element) docs_eo = Con_List(vm, []) _storage_hack.push(_Store(vm, [docs_eo], nodes_mod)) r = xmlSAXUserParseMemory(h, lltype.nullptr(rffi.VOIDP.TO), xml_o.v, len(xml_o.v)) if r < 0 or len(_storage_hack.peek().elems_stack) != 1: raise Exception("XXX") _storage_hack.pop() doc_o = vm.get_slot_apply(nodes_mod.get_defn(vm, "Doc"), "new", [docs_eo]) return doc_o
def test_call_with_singlefloats(self): cpu = self.cpu if not cpu.supports_floats or not cpu.supports_singlefloats: py.test.skip('requires floats and singlefloats') import random from pypy.rlib.libffi import types from pypy.rlib.rarithmetic import r_singlefloat def func(*args): res = 0.0 for i, x in enumerate(args): res += (i + 1.1) * float(x) return res F = lltype.Float S = lltype.SingleFloat I = lltype.Signed floats = [random.random() - 0.5 for i in range(8)] singlefloats = [r_singlefloat(random.random() - 0.5) for i in range(8)] ints = [random.randrange(-99, 99) for i in range(8)] for repeat in range(100): args = [] argvalues = [] argslist = [] local_floats = list(floats) local_singlefloats = list(singlefloats) local_ints = list(ints) for i in range(8): case = random.randrange(0, 3) if case == 0: args.append(F) arg = local_floats.pop() argslist.append(boxfloat(arg)) elif case == 1: args.append(S) arg = local_singlefloats.pop() argslist.append(BoxInt(longlong.singlefloat2int(arg))) else: args.append(I) arg = local_ints.pop() argslist.append(BoxInt(arg)) argvalues.append(arg) FUNC = self.FuncType(args, F) FPTR = self.Ptr(FUNC) func_ptr = llhelper(FPTR, func) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) res = self.execute_operation(rop.CALL, [funcbox] + argslist, 'float', descr=calldescr) expected = func(*argvalues) assert abs(res.getfloat() - expected) < 0.0001
def subtype_dealloc(space, obj): pto = obj.c_ob_type base = pto this_func_ptr = llhelper(subtype_dealloc.api_func.functype, subtype_dealloc.api_func.get_wrapper(space)) while base.c_tp_dealloc == this_func_ptr: base = base.c_tp_base assert base dealloc = base.c_tp_dealloc # XXX call tp_del if necessary generic_cpy_call(space, dealloc, obj)
def new(self, thrd, callback, arg): self.thrd = thrd._thrd self.runfn = callback self.arg = arg # make a fresh new clean SUSPSTACK newsuspstack = lltype.malloc(SUSPSTACK) newsuspstack.handle = _c.null_handle self.suspstack = newsuspstack # Invoke '_new_callback' by closing the stack h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _new_callback), alternateanchor) return self.get_result_suspstack(h)
def test_call_stubs_1(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] RES = lltype.Char descr1 = get_call_descr(c0, ARGS, RES) def f(a, b): return 'c' call_stub = descr1.call_stub fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) res = call_stub(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None) assert res == ord('c')
def f42(): length = len(glob.lst) c_qsort = glob.c_qsort raw = alloc1() fn = llhelper(CALLBACK, rffi._make_wrapper_for(CALLBACK, callback)) argchain = ArgChain() argchain = argchain.arg(rffi.cast(lltype.Signed, raw)) argchain = argchain.arg(rffi.cast(rffi.SIZE_T, 2)) argchain = argchain.arg(rffi.cast(rffi.SIZE_T, 8)) argchain = argchain.arg(rffi.cast(lltype.Signed, fn)) c_qsort.call(argchain, lltype.Void) free1(raw) check(len(glob.lst) > length) del glob.lst[:]
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT) self.put(builder, args, descr) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=BasicFailDescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def test_call_stubs_1(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] RES = lltype.Char descr1 = get_call_descr(c0, ARGS, RES) def f(a, b): return 'c' fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) res = descr1.call_stub_i(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None) assert res == ord('c')
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=BasicFailDescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def test_funcptr1(self): def dummy(n): return n + 1 FUNCTYPE = lltype.FuncType([lltype.Signed], lltype.Signed) cdummy = lltype2ctypes(llhelper(lltype.Ptr(FUNCTYPE), dummy)) assert isinstance(cdummy, ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_long)) res = cdummy(41) assert res == 42 lldummy = ctypes2lltype(lltype.Ptr(FUNCTYPE), cdummy) assert lltype.typeOf(lldummy) == lltype.Ptr(FUNCTYPE) res = lldummy(41) assert res == 42 assert not ALLOCATED # detects memory leaks in the test
def test_funcptr1(self): def dummy(n): return n+1 FUNCTYPE = lltype.FuncType([lltype.Signed], lltype.Signed) cdummy = lltype2ctypes(llhelper(lltype.Ptr(FUNCTYPE), dummy)) assert isinstance(cdummy, ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_long)) res = cdummy(41) assert res == 42 lldummy = ctypes2lltype(lltype.Ptr(FUNCTYPE), cdummy) assert lltype.typeOf(lldummy) == lltype.Ptr(FUNCTYPE) res = lldummy(41) assert res == 42 assert not ALLOCATED # detects memory leaks in the test