Example #1
0
 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)
Example #2
0
def finish_type_2(space, pto, w_obj):
    """
    Sets up other attributes, when the interpreter type has been created.
    """
    pto.c_tp_mro = make_ref(space, space.newtuple(w_obj.mro_w))
    base = pto.c_tp_base
    if base:
        inherit_special(space, pto, base)
    for w_base in space.fixedview(from_ref(space, pto.c_tp_bases)):
        inherit_slots(space, pto, w_base)

    if not pto.c_tp_setattro:
        from pypy.module.cpyext.object import PyObject_GenericSetAttr
        pto.c_tp_setattro = llhelper(
            PyObject_GenericSetAttr.api_func.functype,
            PyObject_GenericSetAttr.api_func.get_wrapper(space))

    if not pto.c_tp_getattro:
        from pypy.module.cpyext.object import PyObject_GenericGetAttr
        pto.c_tp_getattro = llhelper(
            PyObject_GenericGetAttr.api_func.functype,
            PyObject_GenericGetAttr.api_func.get_wrapper(space))

    if w_obj.is_cpytype():
        Py_DecRef(space, pto.c_tp_dict)
        w_dict = w_obj.getdict(space)
        pto.c_tp_dict = make_ref(space, w_dict)
Example #3
0
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
Example #4
0
 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)
Example #5
0
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.layout.typedef)

    # 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.w_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.bytesobject import PyString_AsString
        pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name)
    else:
        pto.c_tp_name = rffi.str2charp(w_type.name)
    # 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))

    builder = space.fromcache(StaticObjectBuilder)
    if builder.cpyext_type_init is not None:
        builder.cpyext_type_init.append((pto, w_type))
    else:
        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
Example #6
0
 def _build_release_gil(self, gcrootmap):
     if gcrootmap is None or gcrootmap.is_shadow_stack:
         reacqgil_func = llhelper(self._REACQGIL0_FUNC,
                                  self._reacquire_gil_shadowstack)
         self.reacqgil_addr = self.cpu.cast_ptr_to_int(reacqgil_func)
     else:
         reacqgil_func = llhelper(self._REACQGIL2_FUNC,
                                  self._reacquire_gil_asmgcc)
         self.reacqgil_addr = self.cpu.cast_ptr_to_int(reacqgil_func)
Example #7
0
    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))
Example #8
0
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
Example #9
0
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 rpython.rtyper.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 rpython.rtyper.annlowlevel import llhelper
    llhelper(rffi.AroundFnPtr, before)
    llhelper(rffi.AroundFnPtr, after)
Example #10
0
def vmprof_execute_code(name, get_code_fn, result_class=None,
                        _hack_update_stack_untranslated=False):
    """Decorator to be used on the function that interprets a code object.

    'name' must be a unique name.

    'get_code_fn(*args)' is called to extract the code object from the
    arguments given to the decorated function.

    'result_class' is ignored (backward compatibility).
    """
    if _hack_update_stack_untranslated:
        from rpython.rtyper.annlowlevel import llhelper
        enter_code = llhelper(lltype.Ptr(
            lltype.FuncType([lltype.Signed], cintf.PVMPROFSTACK)),
            cintf.enter_code)
        leave_code = llhelper(lltype.Ptr(
            lltype.FuncType([cintf.PVMPROFSTACK], lltype.Void)),
            cintf.leave_code)
    else:
        enter_code = cintf.enter_code
        leave_code = cintf.leave_code

    def decorate(func):
        try:
            _get_vmprof()
        except cintf.VMProfPlatformUnsupported:
            return func

        @jit.oopspec("rvmprof.jitted(unique_id)")
        def decorated_jitted_function(unique_id, *args):
            return func(*args)

        def decorated_function(*args):
            unique_id = get_code_fn(*args)._vmprof_unique_id
            unique_id = rffi.cast(lltype.Signed, unique_id)
            # ^^^ removes the "known non-negative" hint for annotation
            if not jit.we_are_jitted():
                x = enter_code(unique_id)
                try:
                    return func(*args)
                finally:
                    leave_code(x)
            else:
                return decorated_jitted_function(unique_id, *args)

        decorated_function.__name__ = func.__name__ + '_rvmprof'
        return decorated_function

    return decorate
Example #11
0
    def setup_method(self, meth):
        visited = []

        def helper():
            trace = []
            stack = cintf.vmprof_tl_stack.getraw()
            while stack:
                trace.append((stack.c_kind, stack.c_value))
                stack = stack.c_next
            visited.append(trace)

        llfn = llhelper(lltype.Ptr(lltype.FuncType([], lltype.Void)), helper)

        class CodeObj(object):
            def __init__(self, name):
                self.name = name

        def get_code_fn(codes, code, arg, c):
            return code

        def get_name(code):
            return "foo"

        _get_vmprof().use_weaklist = False
        register_code_object_class(CodeObj, get_name)

        self.misc = visited, llfn, CodeObj, get_code_fn, get_name
Example #12
0
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) # XXX should be header=None
        @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
    elif name == 'tp_getattro':
        getattr_fn = w_type.getdictvalue(space, '__getattribute__')
        if getattr_fn is None:
            return

        @cpython_api([PyObject, PyObject], PyObject)
        @func_renamer("cpyext_tp_getattro_%s" % (typedef.name,))
        def slot_tp_getattro(space, w_self, w_name):
            return space.call_function(getattr_fn, w_self, w_name)
        api_func = slot_tp_getattro.api_func
    else:
        return

    return lambda: llhelper(api_func.functype, api_func.get_wrapper(space))
Example #13
0
 def define_custom_trace(cls):
     from rpython.rtyper.annlowlevel import llhelper
     from rpython.rtyper.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
Example #14
0
    def test_call_many_float_args(self):
        from rpython.rtyper.annlowlevel import llhelper
        from rpython.jit.codewriter.effectinfo import EffectInfo

        seen = []
        def func(*args):
            seen.append(args)
            return -42

        F = lltype.Float
        I = lltype.Signed
        FUNC = self.FuncType([F] * 7 + [I] + [F] * 7 + [I] + [F], I)
        FPTR = self.Ptr(FUNC)
        func_ptr = llhelper(FPTR, func)
        cpu = self.cpu
        calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                    EffectInfo.MOST_GENERAL)
        funcbox = self.get_funcbox(cpu, func_ptr)
        argvals = [.1 * i for i in range(15)]
        argvals.insert(7, 77)
        argvals.insert(15, 1515)
        argvals = tuple(argvals)
        argboxes = []
        for x in argvals:
            if isinstance(x, float):
                argboxes.append(InputArgFloat(x))
            else:
                argboxes.append(InputArgInt(x))
        res = self.execute_operation(rop.CALL_I,
                                     [funcbox] + argboxes,
                                     'int', descr=calldescr)
        assert res == -42
        assert seen == [argvals]
Example #15
0
    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))
Example #16
0
 def h(x, y, z):
     s = malloc(S)
     s.x = x
     s.y = y
     fptr = llhelper(F, myfuncs[z])
     assert typeOf(fptr) == F
     return fptr(s)
Example #17
0
 def entry_point(argv):
     ll_dealloc_trigger_callback = llhelper(FTYPE, dealloc_trigger)
     rawrefcount.init(ll_dealloc_trigger_callback)
     ob, p = make_p()
     if state.seen != []:
         print "OB COLLECTED REALLY TOO SOON"
         return 1
     rgc.collect()
     if state.seen != []:
         print "OB COLLECTED TOO SOON"
         return 1
     objectmodel.keepalive_until_here(p)
     p = None
     rgc.collect()
     if state.seen != [1]:
         print "OB NOT COLLECTED"
         return 1
     if rawrefcount.next_dead(PyObject) != ob:
         print "NEXT_DEAD != OB"
         return 1
     if rawrefcount.next_dead(PyObject) != lltype.nullptr(PyObjectS):
         print "NEXT_DEAD second time != NULL"
         return 1
     if rawrefcount.to_obj(W_Root, ob) is not None:
         print "to_obj(dead) is not None?"
         return 1
     rawrefcount.mark_deallocating(w_marker, ob)
     if rawrefcount.to_obj(W_Root, ob) is not w_marker:
         print "to_obj(marked-dead) is not w_marker"
         return 1
     print "OK!"
     lltype.free(ob, flavor='raw')
     return 0
Example #18
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     v_cond = builder.get_bool_var(r)
     subset = builder.subset_of_intvars(r)[:4]
     for i in range(len(subset)):
         if r.random() < 0.35:
             subset[i] = ConstInt(r.random_integer())
     #
     seen = []
     def call_me(*args):
         if len(seen) == 0:
             seen.append(args)
         else:
             assert seen[0] == args
     #
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), call_me)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [v_cond, c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Example #19
0
    def test_float_hf_call_mixed(self):
        if not self.cpu.supports_floats:
            py.test.skip("requires floats")
        cpu = self.cpu
        callargs = []

        def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9):
            callargs.append(zip(range(12), [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9]))
            return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9

        F = lltype.Float
        I = lltype.Signed
        FUNC = self.FuncType([F] * 7 + [I] + [F] + [I] + [F] * 2, 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)
        args = [boxfloat(0.1) for i in range(7)] + [BoxInt(1), boxfloat(0.2), BoxInt(2), boxfloat(0.3), boxfloat(0.4)]
        res = self.execute_operation(rop.CALL, [funcbox] + args, "float", descr=calldescr)
        for i, j in enumerate(callargs[0]):
            box = args[i]
            if box.type == "f":
                assert (i, args[i].getfloat()) == j
            else:
                assert (i, args[i].getint()) == j
        assert abs(res.getfloat() - 4.6) < 0.0001
Example #20
0
 def define_custom_trace(cls):
     from rpython.rtyper.annlowlevel import llhelper
     #
     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
Example #21
0
    def test_shadowstack_cond_call(self):
        cpu = self.cpu
        cpu.gc_ll_descr.init_nursery(100)
        cpu.setup_once()

        def check(i, frame):
            frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame)
            assert frame.jf_gcmap[0] # is not empty is good enough

        CHECK = lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Void)
        checkptr = llhelper(lltype.Ptr(CHECK), check)
        checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT,
                                     EffectInfo.MOST_GENERAL)

        loop = self.parse("""
        [i0, p0]
        p = force_token()
        cond_call(i0, ConstClass(funcptr), i0, p, descr=calldescr)
        guard_true(i0, descr=faildescr) [p0]
        """, namespace={
            'faildescr': BasicFailDescr(),
            'funcptr': checkptr,
            'calldescr': checkdescr,
        })
        token = JitCellToken()
        cpu.compile_loop(loop.inputargs, loop.operations, token)
        S = self.S
        s = lltype.malloc(S)
        cpu.execute_token(token, 1, s)
Example #22
0
    def test_shadowstack_collecting_call_float(self):
        cpu = self.cpu

        def float_return(i, f):
            # mark frame for write barrier
            frame = rffi.cast(lltype.Ptr(JITFRAME), i)
            frame.hdr |= 1
            return 1.2 + f

        FUNC = lltype.FuncType([lltype.Signed, lltype.Float], lltype.Float)
        fptr = llhelper(lltype.Ptr(FUNC), float_return)
        calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                    EffectInfo.MOST_GENERAL)
        loop = self.parse("""
        [f0]
        i = force_token()
        f1 = call(ConstClass(fptr), i, f0, descr=calldescr)
        finish(f1, descr=finaldescr)
        """, namespace={'fptr': fptr, 'calldescr': calldescr,
                        'finaldescr': BasicFinalDescr(1)})
        token = JitCellToken()
        cpu.gc_ll_descr.init_nursery(20)
        cpu.setup_once()
        cpu.compile_loop(loop.inputargs, loop.operations, token)
        arg = longlong.getfloatstorage(2.3)
        frame = cpu.execute_token(token, arg)
        ofs = cpu.get_baseofs_of_frame_field()
        f = cpu.read_float_at_mem(frame, ofs)
        f = longlong.getrealfloat(f)
        assert f == 2.3 + 1.2
Example #23
0
    def test_call_function(self):
        functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
        call_addr = rffi.cast(lltype.Signed, llhelper(functype, func))
        a = PPCBuilder()

        # NOW EXPLICITLY:
        #
        # - Load the address of the function to call into a register x
        # - Move the content of this register x into CTR
        # - Set the LR manually (or with bctrl)
        # - Do jump

        a.li(3, 50)
        if IS_PPC_32:
            a.load_imm(r10, call_addr)
        elif IS_BIG_ENDIAN:
            # load the 3-words descriptor
            a.load_from_addr(r10, call_addr)
            a.load_from_addr(r2, call_addr + WORD)
            a.load_from_addr(r11, call_addr + 2 * WORD)
        else:
            # no descriptor on little-endian, but the ABI says r12 must
            # contain the function pointer
            a.load_imm(r10, call_addr)
            a.mr(12, 10)
        a.mtctr(10)
        a.bctr()
        a.blr()

        f = a.get_assembler_function()
        assert f() == 65
Example #24
0
    def test_call_argument_spilling(self):
        # bug when we have a value in r0, that is overwritten by an argument
        # and needed after the call, so that the register gets spilled after it
        # was overwritten with the argument to the call
        def func(a):
            return a + 16

        I = lltype.Signed
        FUNC = self.FuncType([I], I)
        FPTR = self.Ptr(FUNC)
        func_ptr = llhelper(FPTR, func)
        calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL)
        funcbox = self.get_funcbox(self.cpu, func_ptr)

        args = ", ".join(["i%d" % i for i in range(11)])
        ops = """
        [%s]
        i99 = call(ConstClass(func_ptr), 22, descr=calldescr)
        guard_true(i0) [%s, i99]
        finish()""" % (
            args,
            args,
        )
        loop = parse(ops, namespace=locals())
        looptoken = JitCellToken()
        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
        args = [x for x in range(11)]
        deadframe = self.cpu.execute_token(looptoken, *args)
        for x in range(11):
            assert self.cpu.get_int_value(deadframe, x) == x
        assert self.cpu.get_int_value(deadframe, 11) == 38
Example #25
0
def getInterpreterProxy():
    if not IProxy.vm_initialized:
        vm_proxy = lltype.malloc(VirtualMachine, flavor='raw')
        for func_name, signature, func in proxy_functions:
            setattr(vm_proxy, func_name, llhelper(signature, func))
        IProxy.vm_proxy = vm_proxy
        IProxy.vm_initialized = True
    return IProxy.vm_proxy
Example #26
0
 def test_call_python_func(self):
     functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
     call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
     self.a.gen_func_prolog()
     self.a.mc.MOV_ri(r.r0.value, 123)
     self.a.mc.BL(call_addr)
     self.a.gen_func_epilog()
     assert run_asm(self.a) == 133
Example #27
0
 def helper_func(self, FUNCPTR, func):
     if not self.cpu.translate_support_code:
         return llhelper(FUNCPTR, func)
     FUNC = FUNCPTR.TO
     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):
        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_f(ConstClass(func_ptr), %s, descr=calldescr)\n' % arguments
            ops += 'i99 = same_as_i(0)\n'
            ops += 'guard_true(i99) [f99, %s]\n' % arguments
            ops += 'finish()\n'

            loop = parse(ops, namespace=locals())
            looptoken = JitCellToken()
            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
            argvals, expected_result = self._prepare_args(args, floats, ints)

            deadframe = self.cpu.execute_token(looptoken, *argvals)
            x = longlong.getrealfloat(cpu.get_float_value(deadframe, 0))
            assert abs(x - expected_result) < 0.0001
Example #29
0
    def test_call_release_gil(self):
        py.test.skip(
            "xxx fix this test: the code is now assuming that "
            "'before' is just rgil.release_gil(), and 'after' is "
            "only needed if 'rpy_fastgil' was not changed."
        )
        # note that we can't test floats here because when untranslated
        # people actually wreck xmm registers
        cpu = self.cpu
        l = []
        copied_stack = [None]

        def before():
            # put nonsense on the top of shadowstack
            frame = rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.gcrootmap.stack[0])
            assert getmap(frame).count("1") == 7  #
            copied_stack[0] = cpu.gc_ll_descr.gcrootmap.stack[0]
            cpu.gc_ll_descr.gcrootmap.stack[0] = -42
            l.append("before")

        def after():
            cpu.gc_ll_descr.gcrootmap.stack[0] = copied_stack[0]
            l.append("after")

        invoke_around_extcall(before, after)

        def f(frame, x):
            # all the gc pointers are alive p1 -> p7 (but not p0)
            assert x == 1
            return 2

        FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed)
        fptr = llhelper(lltype.Ptr(FUNC), f)
        calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL)
        loop = self.parse(
            """
        [i0, p1, p2, p3, p4, p5, p6, p7]
        p0 = force_token()
        i1 = call_release_gil(ConstClass(fptr), p0, i0, descr=calldescr)
        guard_not_forced(descr=faildescr) [p1, p2, p3, p4, p5, p6, p7]
        finish(i1, descr=finaldescr)
        """,
            namespace={
                "fptr": fptr,
                "calldescr": calldescr,
                "faildescr": BasicFailDescr(),
                "finaldescr": BasicFinalDescr(),
            },
        )
        token = JitCellToken()
        cpu.gc_ll_descr.init_nursery(100)
        cpu.setup_once()
        cpu.compile_loop(loop.inputargs, loop.operations, token)
        args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)]
        frame = cpu.execute_token(token, 1, *args)
        frame = rffi.cast(JITFRAMEPTR, frame)
        assert frame.jf_frame[0] == 2
        assert l == ["before", "after"]
    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 rpython.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(20)]
        singlefloats = [r_singlefloat(random.random() - 0.5) for i in range(20)]
        ints = [random.randrange(-99, 99) for i in range(20)]
        for repeat in range(100):
            args = []
            argvalues = []
            argslist = []
            local_floats = list(floats)
            local_singlefloats = list(singlefloats)
            local_ints = list(ints)
            for i in range(random.randrange(4, 20)):
                case = random.randrange(0, 6)
                if case & 1: boxme = InputArgInt
                else:        boxme = ConstInt
                if case < 2:
                    args.append(F)
                    arg = arg1 = local_floats.pop()
                    if case & 1: boxme = boxfloat
                    else:        boxme = constfloat
                elif case < 4:
                    args.append(S)
                    arg = local_singlefloats.pop()
                    arg1 = longlong.singlefloat2int(arg)
                else:
                    args.append(I)
                    arg = arg1 = local_ints.pop()
                argslist.append(boxme(arg1))
                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_F,
                                         [funcbox] + argslist,
                                         'float', descr=calldescr)
            expected = func(*argvalues)
            res = longlong.getrealfloat(res)
            assert abs(res - expected) < 0.0001
Example #31
0
    def make_finalizer_funcptr_for_type(self, TYPE):
        from rpython.memory.gctransform.support import get_rtti
        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

        t = self.llinterp.typer.annotator.translator
        light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph)
        def ll_finalizer(addr):
            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 llhelper(gctypelayout.GCData.FINALIZER, ll_finalizer), light
Example #32
0
 def new(self, thrd, callback, arg):
     self.newthrd = thrd._thrd
     self.runfn = callback
     self.arg = arg
     # make a fresh new clean SUSPSTACK
     rgc.register_custom_trace_hook(SUSPSTACK, lambda_customtrace)
     newsuspstack = lltype.malloc(SUSPSTACK)
     newsuspstack.handle = _c.null_handle
     self.suspstack = newsuspstack
     # Invoke '_new_callback' by closing the stack
     #
     callback_pieces = llop.gc_detach_callback_pieces(llmemory.Address)
     newsuspstack.callback_pieces = callback_pieces
     #
     h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _new_callback),
                             alternateanchor)
     h = rffi.cast(_c.handle, h)
     #
     llop.gc_reattach_callback_pieces(lltype.Void, callback_pieces)
     return self.get_result_suspstack(h)
Example #33
0
 def produce_into(self, builder, 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)
     while True:
         _, vtableptr = builder.get_random_structure_type_and_vtable(r)
         if vtableptr != exc:
             break
     other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [other_box],
                       descr=builder.getfaildescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Example #34
0
    def test_call_aligned_with_args_on_the_stack(self):
        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):
            result = 0.0
            args = []
            argslist = []
            local_floats = list(floats)
            local_ints = list(ints)
            for i in range(8):
                if case & (1 << i):
                    args.append(F)
                    arg = local_floats.pop()
                    result += arg
                    argslist.append(boxfloat(arg))
                else:
                    args.append(I)
                    arg = local_ints.pop()
                    result += arg
                    argslist.append(InputArgInt(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_F, [funcbox] + argslist,
                                         'float',
                                         descr=calldescr)
            res = longlong.getrealfloat(res)
            assert abs(res - result) < 0.0001
Example #35
0
def finish_type_2(space, pto, w_obj):
    """
    Sets up other attributes, when the interpreter type has been created.
    """
    pto.c_tp_mro = make_ref(space, space.newtuple(w_obj.mro_w))
    base = pto.c_tp_base
    if base:
        inherit_special(space, pto, base)
    for w_base in space.fixedview(from_ref(space, pto.c_tp_bases)):
        inherit_slots(space, pto, w_base)

    if not pto.c_tp_setattro:
        from pypy.module.cpyext.object import PyObject_GenericSetAttr
        pto.c_tp_setattro = llhelper(
            PyObject_GenericSetAttr.api_func.functype,
            PyObject_GenericSetAttr.api_func.get_wrapper(space))

    if w_obj.is_cpytype():
        Py_DecRef(space, pto.c_tp_dict)
        w_dict = w_obj.getdict(space)
        pto.c_tp_dict = make_ref(space, w_dict)
 def produce_into(self, builder, r):
     subset, f = self.non_raising_func_code(builder, r)
     if len(subset) == 0:
         RES = lltype.Void
     else:
         RES = lltype.Signed
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     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)
     _, vtableptr = builder.get_random_structure_type_and_vtable(r)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(),
                       descr=builder.getfaildescr())
     op.setfailargs(builder.subset_of_intvars(r))
     op._exc_box = None
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Example #37
0
 def switch(self, suspstack):
     # Immediately before the switch, 'suspstack' describes the suspended
     # state of the *target* of the switch.  Then it is theoretically
     # freed.  In fact what occurs is that we reuse the same 'suspstack'
     # object in the target, just after the switch, to store the
     # description of where we came from.  Then that "other" 'suspstack'
     # object is returned.
     self.suspstack = suspstack
     #
     callback_pieces = llop.gc_detach_callback_pieces(llmemory.Address)
     old_callback_pieces = suspstack.callback_pieces
     suspstack.callback_pieces = callback_pieces
     #
     h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _switch_callback),
                             alternateanchor)
     h = rffi.cast(_c.handle, h)
     #
     llop.gc_reattach_callback_pieces(lltype.Void, callback_pieces)
     if not h:
         self.suspstack.callback_pieces = old_callback_pieces
     #
     return self.get_result_suspstack(h)
Example #38
0
    def test_one(self):
        py.test.skip("needs thread-locals in the JIT, which is only available "
                     "after translation")
        visited = []

        def helper():
            stack = cintf.vmprof_tl_stack.getraw()
            if stack:
                # not during tracing
                visited.append(stack.c_value)
            else:
                visited.append(0)

        llfn = llhelper(lltype.Ptr(lltype.FuncType([], lltype.Void)), helper)

        driver = jit.JitDriver(greens=[], reds='auto')

        def f(n):
            i = 0
            while i < n:
                driver.jit_merge_point()
                i += 1
                llfn()

        class Hooks(jit.JitHookInterface):
            def after_compile(self, debug_info):
                self.raw_start = debug_info.asminfo.rawstart

        hooks = Hooks()

        null = lltype.nullptr(cintf.VMPROFSTACK)
        cintf.vmprof_tl_stack.setraw(null)  # make it empty
        self.meta_interp(f, [10], policy=JitPolicy(hooks))
        v = set(visited)
        assert 0 in v
        v.remove(0)
        assert len(v) == 1
        assert 0 <= list(v)[0] - hooks.raw_start <= 10 * 1024
        assert cintf.vmprof_tl_stack.getraw() == null
Example #39
0
    def test_float_hf_call_int(self):
        cpu = self.cpu
        callargs = []
        def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9):
            callargs.append(zip(range(10),
                        [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9]))
            return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9

        I = lltype.Signed
        FUNC = self.FuncType([I] * 10, I)
        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)
        args = ([BoxInt(1) for i in range(10)])
        res = self.execute_operation(rop.CALL,
                                     [funcbox] + args,
                                     'int', descr=calldescr)
        for i,j in enumerate(callargs[0]):
            assert (i, 1) == j
        assert res.getint() == 10
Example #40
0
    def test_float_hf_call_mixed(self):
        if not self.cpu.supports_floats:
            py.test.skip("requires floats")
        cpu = self.cpu
        callargs = []

        def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9):
            callargs.append(
                zip(range(12),
                    [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9]))
            return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 +
                                                            i1) + f7 + f8 + f9

        F = lltype.Float
        I = lltype.Signed
        FUNC = self.FuncType([F] * 7 + [I] + [F] + [I] + [F] * 2, 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)
        args = (
            [boxfloat(.1) for i in range(7)] +
            [boxint(1),
             boxfloat(.2),
             boxint(2),
             boxfloat(.3),
             boxfloat(.4)])
        res = self.execute_operation(rop.CALL_F, [funcbox] + args,
                                     'float',
                                     descr=calldescr)
        for i, j in enumerate(callargs[0]):
            box = args[i]
            if box.type == 'f':
                assert (i, args[i].getfloat()) == j
            else:
                assert (i, args[i].getint()) == j
        assert abs(res.getfloat() - 4.6) < 0.0001
Example #41
0
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))
Example #42
0
 def test_float_hf_call_float(self):
     if not self.cpu.supports_floats:
         py.test.skip("requires floats")
     cpu = self.cpu
     callargs = []
     def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9):
         callargs.append(zip(range(10),
                     [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9]))
         return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9
     F = lltype.Float
     FUNC = self.FuncType([F] * 10, 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)
     args = ([boxfloat(.1) for i in range(10)])
     res = self.execute_operation(rop.CALL,
                                  [funcbox] + args,
                                  'float', descr=calldescr)
     for i,j in enumerate(callargs[0]):
         assert (i, 0.1) == j
     assert abs(res.getfloat() - 1) < 0.0001
Example #43
0
def test_call_stubs_single_float():
    from rpython.rlib.longlong2float import uint2singlefloat, singlefloat2uint
    from rpython.rlib.rarithmetic import r_singlefloat, intmask
    #
    c0 = GcCache(False)
    ARGS = [lltype.SingleFloat, lltype.SingleFloat, lltype.SingleFloat]
    RES = lltype.SingleFloat

    def f(a, b, c):
        a = float(a)
        b = float(b)
        c = float(c)
        x = a - (b / c)
        return r_singlefloat(x)

    fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f)
    descr2 = get_call_descr(c0, ARGS, RES)
    a = intmask(singlefloat2uint(r_singlefloat(-10.0)))
    b = intmask(singlefloat2uint(r_singlefloat(3.0)))
    c = intmask(singlefloat2uint(r_singlefloat(2.0)))
    res = descr2.call_stub_i(rffi.cast(lltype.Signed, fnptr),
                             [a, b, c], [], [])
    assert float(uint2singlefloat(rffi.r_uint(res))) == -11.5
Example #44
0
 def entry_point(argv):
     ll_dealloc_trigger_callback = llhelper(FTYPE, dealloc_trigger)
     rawrefcount.init(ll_dealloc_trigger_callback)
     ob, p = make_p()
     if state.seen != []:
         print "OB COLLECTED REALLY TOO SOON"
         return 1
     rgc.collect()
     if state.seen != []:
         print "OB COLLECTED TOO SOON"
         return 1
     objectmodel.keepalive_until_here(p)
     p = None
     rgc.collect()
     if state.seen != [1]:
         print "OB NOT COLLECTED"
         return 1
     if rawrefcount.next_dead(PyObject) != ob:
         print "NEXT_DEAD != OB"
         return 1
     if ob.c_ob_refcnt != 1:
         print "next_dead().ob_refcnt != 1"
         return 1
     if rawrefcount.next_dead(PyObject) != lltype.nullptr(PyObjectS):
         print "NEXT_DEAD second time != NULL"
         return 1
     if rawrefcount.to_obj(W_Root, ob) is not None:
         print "to_obj(dead) is not None?"
         return 1
     rawrefcount.mark_deallocating(w_marker, ob)
     if rawrefcount.to_obj(W_Root, ob) is not w_marker:
         print "to_obj(marked-dead) is not w_marker"
         return 1
     print "OK!"
     lltype.free(ob, flavor='raw')
     return 0
Example #45
0
 class FakeJitDriverSD:
     index_of_virtualizable = -1
     _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
     assembler_helper_adr = llmemory.cast_ptr_to_adr(
         _assembler_helper_ptr)
Example #46
0
 def fn16(n):
     a = A()
     a.n = n
     h = llhelper(F, h1)
     h2 = lloperation.llop.same_as(F, h)
     return h2(a.n)
Example #47
0
 def wrapper(*args):
     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 TARGET == CWCHARP:
             if arg is None:
                 arg = lltype.nullptr(CWCHARP.TO)   # None => (wchar_t*)NULL
                 freeme = arg
             elif isinstance(arg, unicode):
                 arg = unicode2wcharp(arg)
                 # XXX leaks if a unicode2wcharp() fails with MemoryError
                 # and was not the first in this function
                 freeme = arg
         elif TARGET is VOIDP:
             if arg is None:
                 arg = lltype.nullptr(VOIDP.TO)
             elif isinstance(arg, str):
                 arg = str2charp(arg)
                 freeme = arg
             elif isinstance(arg, unicode):
                 arg = unicode2wcharp(arg)
                 freeme = arg
         elif _isfunctype(TARGET) and not _isllptr(arg):
             # XXX pass additional arguments
             use_gil = invoke_around_handlers
             arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg,
                                                      callbackholder,
                                                      use_gil))
         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
Example #48
0
File: gc.py Project: weijiwei/pypy
 def get_malloc_fn(self, funcname):
     func = getattr(self, funcname)
     FUNC = getattr(self, funcname + '_FUNCPTR')
     return llhelper(FUNC, func)
Example #49
0
File: llmodel.py Project: Mu-L/pypy
 def insert_stack_check():
     endaddr = rstack._stack_get_end_adr()
     lengthaddr = rstack._stack_get_length_adr()
     f = llhelper(STACK_CHECK_SLOWPATH, rstack.stack_check_slowpath)
     slowpathaddr = rffi.cast(lltype.Signed, f)
     return endaddr, lengthaddr, slowpathaddr
Example #50
0
    os.close(fd)
    return ''.join(blocks)


def read_code():
    from pypy.module.marshal.interp_marshal import dumps

    filename = 'pypyjit_demo.py'
    source = readfile(filename)
    ec = space.getexecutioncontext()
    code = ec.compiler.compile(source, filename, 'exec', 0)
    return llstr(space.str_w(dumps(space, code, space.wrap(2))))


FPTR = lltype.Ptr(lltype.FuncType([], lltype.Ptr(STR)))
read_code_ptr = llhelper(FPTR, read_code)


def entry_point():
    space.startup()
    from pypy.module.marshal.interp_marshal import loads
    code = loads(space, space.wrap(hlstr(read_code_ptr())))
    assert isinstance(code, PyCode)
    code.exec_code(space, w_dict, w_dict)


def test_run_translation():
    from pypy.tool.ann_override import PyPyAnnotatorPolicy
    from rpython.rtyper.test.test_llinterp import get_interpreter

    # first annotate and rtype
Example #51
0
 def helper_func(self, FUNCPTR, func):
     from rpython.rtyper.annlowlevel import llhelper
     return llhelper(FUNCPTR, func)
Example #52
0
 def get_write_barrier_from_array_failing_case(self, FPTRTYPE):
     if self._have_wb_from_array:
         return llhelper(FPTRTYPE,
                         self._write_barrier_from_array_failing_case)
     else:
         return lltype.nullptr(FPTRTYPE.TO)
Example #53
0
    p[0] = rffi.cast(rffi.ULONGLONG, 123321)
    return rffi.cast(rffi.INT, 1)


FETCH_CB_P = rffi.CCallback([rffi.ULONGLONGP], rffi.INT)

ctx_globals = lltype.malloc(rffi.CArray(parse_c_type.GLOBAL_S),
                            len(global_names),
                            flavor='raw',
                            zero=True,
                            track_allocation=False)
c_glob_names = [rffi.str2charp(_n.encode('ascii')) for _n in global_names]
_helpers_keepalive = []
for _i, _fn in enumerate(
    [fetch_constant_five, fetch_constant_neg, fetch_constant_zero]):
    llf = llhelper(FETCH_CB_P, _fn)
    _helpers_keepalive.append(llf)
    ctx_globals[_i].c_name = c_glob_names[_i]
    ctx_globals[_i].c_address = rffi.cast(rffi.VOIDP, llf)
    type_op = (cffi_opcode.OP_CONSTANT_INT if _i != 1 else cffi_opcode.OP_ENUM)
    ctx_globals[_i].c_type_op = rffi.cast(rffi.VOIDP, type_op)
ctx.c_globals = ctx_globals
rffi.setintfield(ctx, 'c_num_globals', len(global_names))


def parse(input):
    OUTPUT_SIZE = 100
    out = lltype.malloc(rffi.VOIDPP.TO,
                        OUTPUT_SIZE,
                        flavor='raw',
                        track_allocation=False)
Example #54
0
    def test_shadowstack_call(self):
        cpu = self.cpu
        cpu.gc_ll_descr.init_nursery(100)
        cpu.setup_once()
        S = self.S
        frames = []

        def check(i):
            assert cpu.gc_ll_descr.gcrootmap.curtop() == i
            frame = rffi.cast(JITFRAMEPTR, i)
            assert len(frame.jf_frame) == self.cpu.JITFRAME_FIXED_SIZE + 4
            # we "collect"
            frames.append(frame)
            new_frame = JITFRAME.allocate(frame.jf_frame_info)
            gcmap = unpack_gcmap(frame)
            if self.cpu.backend_name.startswith('ppc64'):
                assert gcmap == [30, 31, 32]
            elif self.cpu.backend_name.startswith('zarch'):
                # 10 gpr, 14 fpr -> 25 is the first slot
                assert gcmap == [26, 27, 28]
            elif self.cpu.IS_64_BIT:
                assert gcmap == [28, 29, 30]
            elif self.cpu.backend_name.startswith('arm'):
                assert gcmap == [44, 45, 46]
            else:
                assert gcmap == [22, 23, 24]
            for item, s in zip(gcmap, new_items):
                new_frame.jf_frame[item] = rffi.cast(lltype.Signed, s)
            assert cpu.gc_ll_descr.gcrootmap.curtop() == rffi.cast(lltype.Signed, frame)
            cpu.gc_ll_descr.gcrootmap.settop(rffi.cast(lltype.Signed, new_frame))
            print '"Collecting" moved the frame from %d to %d' % (
                i, cpu.gc_ll_descr.gcrootmap.curtop())
            frames.append(new_frame)

        def check2(i):
            assert cpu.gc_ll_descr.gcrootmap.curtop() == i
            frame = rffi.cast(JITFRAMEPTR, i)
            assert frame == frames[1]
            assert frame != frames[0]

        CHECK = lltype.FuncType([lltype.Signed], lltype.Void)
        checkptr = llhelper(lltype.Ptr(CHECK), check)
        check2ptr = llhelper(lltype.Ptr(CHECK), check2)
        checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT,
                                          EffectInfo.MOST_GENERAL)

        loop = self.parse("""
        [p0, p1, p2]
        pf = force_token() # this is the frame
        call_n(ConstClass(check_adr), pf, descr=checkdescr) # this can collect
        p3 = getfield_gc_r(p0, descr=fielddescr)
        pf2 = force_token()
        call_n(ConstClass(check2_adr), pf2, descr=checkdescr)
        guard_nonnull(p3, descr=faildescr) [p0, p1, p2, p3]
        p4 = getfield_gc_r(p0, descr=fielddescr)
        finish(p4, descr=finaldescr)
        """, namespace={'finaldescr': BasicFinalDescr(),
                        'faildescr': BasicFailDescr(),
                        'check_adr': checkptr, 'check2_adr': check2ptr,
                        'checkdescr': checkdescr,
                        'fielddescr': cpu.fielddescrof(S, 'x')})
        token = JitCellToken()
        cpu.compile_loop(loop.inputargs, loop.operations, token)
        p0 = lltype.malloc(S, zero=True)
        p1 = lltype.malloc(S)
        p2 = lltype.malloc(S)
        new_items = [lltype.malloc(S), lltype.malloc(S), lltype.malloc(S)]
        new_items[0].x = new_items[2]
        frame = cpu.execute_token(token, p0, p1, p2)
        frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame)
        gcmap = unpack_gcmap(lltype.cast_opaque_ptr(JITFRAMEPTR, frame))
        assert len(gcmap) == 1
        assert gcmap[0] < self.cpu.JITFRAME_FIXED_SIZE
        item = rffi.cast(lltype.Ptr(S), frame.jf_frame[gcmap[0]])
        assert item == new_items[2]
Example #55
0
 def get_llhelper(self):
     return llhelper(FTPTR, self.make_func())
Example #56
0
class CustomBaseTestRegalloc(BaseTestRegalloc):
    cpu = CPU(None, None)
    cpu.setup_once()

    def raising_func(i):
        if i:
            raise LLException(zero_division_error, zero_division_value)

    FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    raising_fptr = llhelper(FPTR, raising_func)

    def f(a):
        return 23

    FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
    f_fptr = llhelper(FPTR, f)
    f_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
                                  EffectInfo.MOST_GENERAL)

    zero_division_tp, zero_division_value = get_zero_division_error(cpu)
    zd_addr = cpu.cast_int_to_adr(zero_division_tp)
    zero_division_error = llmemory.cast_adr_to_ptr(
        zd_addr, lltype.Ptr(rclass.OBJECT_VTABLE))
    raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
                                        EffectInfo.MOST_GENERAL)

    targettoken = TargetToken()
    targettoken2 = TargetToken()
    fdescr1 = BasicFailDescr(1)
    fdescr2 = BasicFailDescr(2)
    fdescr3 = BasicFailDescr(3)

    def setup_method(self, meth):
        self.targettoken._ll_loop_code = 0
        self.targettoken2._ll_loop_code = 0

    def f1(x):
        return x + 1

    def f2(x, y):
        return x * y

    def f10(*args):
        assert len(args) == 10
        return sum(args)

    F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
    F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 2, lltype.Signed))
    F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 10, lltype.Signed))
    f1ptr = llhelper(F1PTR, f1)
    f2ptr = llhelper(F2PTR, f2)
    f10ptr = llhelper(F10PTR, f10)

    f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)
    f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)
    f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS,
                                    F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL)
    typesystem = 'lltype'
    namespace = locals().copy()
Example #57
0
 def entry_point(argv):
     x = llhelper(FUNC_TP, f)
     s = lltype.malloc(S)
     s.f = x
     glob.s = s  # escape
     return 0
class BaseTestRegalloc(object):
    cpu = CPU(None, None)
    cpu.setup_once()

    def raising_func(i):
        if i:
            raise LLException(zero_division_error, zero_division_value)

    FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    raising_fptr = llhelper(FPTR, raising_func)
    zero_division_tp, zero_division_value = get_zero_division_error(cpu)
    zd_addr = cpu.cast_int_to_adr(zero_division_tp)
    zero_division_error = llmemory.cast_adr_to_ptr(
        zd_addr, lltype.Ptr(rclass.OBJECT_VTABLE))
    raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
                                        EffectInfo.MOST_GENERAL)

    targettoken = TargetToken()
    targettoken2 = TargetToken()
    fdescr1 = BasicFailDescr(1)
    fdescr2 = BasicFailDescr(2)
    fdescr3 = BasicFailDescr(3)

    def setup_method(self, meth):
        self.targettoken._ll_loop_code = 0
        self.targettoken2._ll_loop_code = 0

    def f1(x):
        return x + 1

    def f2(x, y):
        return x * y

    def f10(*args):
        assert len(args) == 10
        return sum(args)

    F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
    F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 2, lltype.Signed))
    F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 10, lltype.Signed))
    f1ptr = llhelper(F1PTR, f1)
    f2ptr = llhelper(F2PTR, f2)
    f10ptr = llhelper(F10PTR, f10)

    f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)
    f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)
    f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS,
                                    F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL)

    namespace = locals().copy()

    def parse(self, s, boxkinds=None, namespace=None):
        return parse(s,
                     self.cpu,
                     namespace or self.namespace,
                     boxkinds=boxkinds)

    def interpret(self, ops, args, run=True, namespace=None):
        loop = self.parse(ops, namespace=namespace)
        self.loop = loop
        looptoken = JitCellToken()
        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
        arguments = []
        for arg in args:
            if isinstance(arg, int):
                arguments.append(arg)
            elif isinstance(arg, float):
                arg = longlong.getfloatstorage(arg)
                arguments.append(arg)
            else:
                assert isinstance(lltype.typeOf(arg), lltype.Ptr)
                llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg)
                arguments.append(llgcref)
        loop._jitcelltoken = looptoken
        if run:
            self.deadframe = self.cpu.execute_token(looptoken, *arguments)
        return loop

    def prepare_loop(self, ops):
        loop = self.parse(ops)
        regalloc = self.cpu.build_regalloc()
        regalloc.prepare_loop(loop.inputargs, loop.operations,
                              loop.original_jitcell_token, [])
        return regalloc

    def getint(self, index):
        return self.cpu.get_int_value(self.deadframe, index)

    def getfloat(self, index):
        return self.cpu.get_float_value(self.deadframe, index)

    def getints(self, end):
        return [
            self.cpu.get_int_value(self.deadframe, index)
            for index in range(0, end)
        ]

    def getfloats(self, end):
        return [
            longlong.getrealfloat(
                self.cpu.get_float_value(self.deadframe, index))
            for index in range(0, end)
        ]

    def getptr(self, index, T):
        gcref = self.cpu.get_ref_value(self.deadframe, index)
        return lltype.cast_opaque_ptr(T, gcref)

    def attach_bridge(self, ops, loop, guard_op_index, **kwds):
        guard_op = loop.operations[guard_op_index]
        assert guard_op.is_guard()
        bridge = self.parse(ops, **kwds)
        assert ([box.type for box in bridge.inputargs
                 ] == [box.type for box in guard_op.getfailargs()])
        faildescr = guard_op.getdescr()
        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
                                loop._jitcelltoken)
        return bridge

    def run(self, loop, *arguments):
        self.deadframe = self.cpu.execute_token(loop._jitcelltoken, *arguments)
        return self.cpu.get_latest_descr(self.deadframe)
Example #59
0
 def get_write_barrier_failing_case(self, FPTRTYPE):
     return llhelper(FPTRTYPE, self._write_barrier_failing_case)
Example #60
0
File: llmodel.py Project: Mu-L/pypy
    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 info lives on assembler stack, so we need to enable
                    # writing
                    enter_assembler_writing()
                    frame.jf_frame_info.update_frame_depth(base_ofs, size)
                    leave_assembler_writing()
                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 = ptr2int(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 = ptr2int(fptr)