Beispiel #1
0
def test_func_simple():
    # -------------------- flowgraph building --------------------
    #     def f(x):
    #         return x+1
    x = Variable("x")
    x.concretetype = Signed
    result = Variable("result")
    result.concretetype = Signed
    one = Constant(1)
    one.concretetype = Signed
    op = SpaceOperation("int_add", [x, one], result)
    block = Block([x])
    graph = FunctionGraph("f", block)
    block.operations.append(op)
    block.closeblock(Link([result], graph.returnblock))
    graph.getreturnvar().concretetype = Signed
    # --------------------         end        --------------------

    F = FuncType([Signed], Signed)
    f = functionptr(F, "f", graph=graph)
    db = LowLevelDatabase()
    db.get(f)
    db.complete()
    dump_on_stdout(db)

    S = GcStruct('testing', ('fptr', Ptr(F)))
    s = malloc(S)
    s.fptr = f
    db = LowLevelDatabase()
    db.get(s)
    db.complete()
    dump_on_stdout(db)
Beispiel #2
0
def test_func_simple():
    # -------------------- flowgraph building --------------------
    #     def f(x):
    #         return x+1
    x = Variable("x")
    x.concretetype = Signed
    result = Variable("result")
    result.concretetype = Signed
    one = Constant(1)
    one.concretetype = Signed
    op = SpaceOperation("int_add", [x, one], result)
    block = Block([x])
    graph = FunctionGraph("f", block)
    block.operations.append(op)
    block.closeblock(Link([result], graph.returnblock))
    graph.getreturnvar().concretetype = Signed
    # --------------------         end        --------------------
    
    F = FuncType([Signed], Signed)
    f = functionptr(F, "f", graph=graph)
    db = LowLevelDatabase()
    db.get(f)
    db.complete()
    dump_on_stdout(db)

    S = GcStruct('testing', ('fptr', Ptr(F)))
    s = malloc(S)
    s.fptr = f
    db = LowLevelDatabase()
    db.get(s)
    db.complete()
    dump_on_stdout(db)
Beispiel #3
0
def create_instantiate_function(annotator, classdef):
    # build the graph of a function that looks like
    # 
    # def my_instantiate():
    #     return instantiate(cls)
    #
    if hasattr(classdef, 'my_instantiate_graph'):
        return
    v = Variable()
    block = Block([])
    block.operations.append(SpaceOperation('instantiate1', [], v))
    name = valid_identifier('instantiate_'+classdef.name)
    graph = FunctionGraph(name, block)
    block.closeblock(Link([v], graph.returnblock))
    annotator.setbinding(v, annmodel.SomeInstance(classdef))
    annotator.annotated[block] = graph
    # force the result to be converted to a generic OBJECTPTR
    generalizedresult = annmodel.SomeInstance(classdef=None)
    annotator.setbinding(graph.getreturnvar(), generalizedresult)
    classdef.my_instantiate_graph = graph
    annotator.translator.graphs.append(graph)
Beispiel #4
0
def create_instantiate_function(annotator, classdef):
    # build the graph of a function that looks like
    # 
    # def my_instantiate():
    #     return instantiate(cls)
    #
    if hasattr(classdef, 'my_instantiate_graph'):
        return
    v = Variable()
    block = Block([])
    block.operations.append(SpaceOperation('instantiate1', [], v))
    name = valid_identifier('instantiate_'+classdef.name)
    graph = FunctionGraph(name, block)
    block.closeblock(Link([v], graph.returnblock))
    annotator.setbinding(v, annmodel.SomeInstance(classdef))
    annotator.annotated[block] = graph
    # force the result to be converted to a generic OBJECTPTR
    generalizedresult = annmodel.SomeInstance(classdef=None)
    annotator.setbinding(graph.getreturnvar(), generalizedresult)
    classdef.my_instantiate_graph = graph
    annotator.translator.graphs.append(graph)
Beispiel #5
0
 def build_callback_graph(self, graph, metadesccls=False):
     args_v = [copyvar(None, v) for v in graph.getargs()]
     v_res = copyvar(None, graph.getreturnvar())
     rtyper = self.bookkeeper.annotator.base_translator.rtyper  # fish
     fnptr = rtyper.getcallable(graph)
     v_ptr = Constant(fnptr, lltype.typeOf(fnptr))
     newstartblock = Block(args_v)
     if metadesccls:
         v_metadesccls = Constant(metadesccls, lltype.Void)
         args_v = [v_metadesccls] + args_v
         opname = 'ts_metacall'
         suffix = 'ts_metacall'
     else:
         opname = 'direct_call'
         suffix = 'ts_stub'
     newstartblock.operations.append(
         SpaceOperation(opname, [v_ptr] + args_v, v_res))
     newgraph = FunctionGraph('%s_%s' % (graph.name, suffix), newstartblock)
     newgraph.getreturnvar().concretetype = v_res.concretetype
     newstartblock.closeblock(Link([v_res], newgraph.returnblock))
     return newgraph
Beispiel #6
0
def new_wrapper(func, translator, newname=None):
    # The basic idea is to produce a flow graph from scratch, using the
    # help of the rtyper for the conversion of the arguments after they
    # have been decoded.
    
    bk = translator.annotator.bookkeeper
    graph = bk.getdesc(func).getuniquegraph()

    f = getfunctionptr(graph)
    FUNCTYPE = typeOf(f).TO

    newops = LowLevelOpList(translator.rtyper)

    varguments = []
    for var in graph.startblock.inputargs:
        v = Variable(var)
        v.concretetype = PyObjPtr
        varguments.append(v)

    wrapper_inputargs = varguments[:]
    # use the rtyper to produce the conversions
    inputargs = f._obj.graph.getargs()
    for i in range(len(varguments)):
        if FUNCTYPE.ARGS[i] != PyObjPtr:
            rtyper = translator.rtyper
            r_arg = rtyper.bindingrepr(inputargs[i])
            # give the rtyper a chance to know which function we are wrapping
            rtyper.set_wrapper_context(func)
            varguments[i] = newops.convertvar(varguments[i],
                                              r_from = pyobj_repr,
                                              r_to = r_arg)
            rtyper.set_wrapper_context(None)

    vlist = [inputconst(typeOf(f), f)] + varguments
    vresult = newops.genop('direct_call', vlist, resulttype=FUNCTYPE.RESULT)

    if FUNCTYPE.RESULT != PyObjPtr:
        # convert "result" back to a PyObject
        rtyper = translator.rtyper
        assert rtyper is not None, (
            "needs the rtyper to perform function result conversions")
        r_result = rtyper.bindingrepr(f._obj.graph.getreturnvar())
        vresult = newops.convertvar(vresult,
                                    r_from = r_result,
                                    r_to = pyobj_repr)

    # "return result"
    block = Block(wrapper_inputargs)
    wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
    translator.update_call_graph(wgraph, graph, object())
    translator.graphs.append(wgraph)
    block.operations[:] = newops
    block.closeblock(Link([vresult], wgraph.returnblock))
    wgraph.getreturnvar().concretetype = PyObjPtr
    checkgraph(wgraph)

    # the above convertvar()s may have created and annotated new helpers
    # that need to be specialized now
    translator.rtyper.specialize_more_blocks()

    return functionptr(FuncType([PyObjPtr] * len(wrapper_inputargs),
                                PyObjPtr),
                       wgraph.name,
                       graph = wgraph,
                       exception_policy = "CPython")
Beispiel #7
0
def build_pytypeobject(r_inst):
    rtyper = r_inst.rtyper
    cache = rtyper.classdef_to_pytypeobject
    try:
        return cache[r_inst.classdef]
    except KeyError:
        for parentdef in r_inst.classdef.getmro():
            cpytype = parentdef._cpy_exported_type_
            if cpytype is not None:
                break
        else:
            # for classes that cannot be exported at all
            return lltype.nullptr(lltype.PyObject)

        from pypy.rpython.lltypesystem.rclass import CPYOBJECTPTR
        from pypy.rpython.rtyper import LowLevelOpList
        typetype = lltype.pyobjectptr(type)

        # XXX default tp_new should go away
        # make the graph of tp_new manually    
        v1 = Variable('tp');   v1.concretetype = lltype.Ptr(PY_TYPE_OBJECT)
        v2 = Variable('args'); v2.concretetype = PyObjPtr
        v3 = Variable('kwds'); v3.concretetype = PyObjPtr
        block = Block([v1, v2, v3])
        llops = LowLevelOpList(None)
        v4 = r_inst.new_instance(llops, v_cpytype = v1)
        v5 = llops.genop('cast_pointer', [v4], resulttype = PyObjPtr)
        block.operations = list(llops)
        tp_new_graph = FunctionGraph('ll_tp_new', block)
        block.closeblock(Link([v5], tp_new_graph.returnblock))
        tp_new_graph.getreturnvar().concretetype = v5.concretetype

        # build the PyTypeObject structure
        pytypeobj = lltype.malloc(PY_TYPE_OBJECT, flavor='cpy',
                                  extra_args=(typetype,))
        name = cpytype.name
        T = lltype.FixedSizeArray(lltype.Char, len(name)+1)
        p = lltype.malloc(T, immortal=True)
        for i in range(len(name)):
            p[i] = name[i]
        p[len(name)] = '\x00'
        pytypeobj.c_tp_name = lltype.direct_arrayitems(p)
        pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO)
        if cpytype.subclassable and False: # XXX deallocation of subclass object segfaults!
            pytypeobj.c_tp_flags = CDefinedIntSymbolic('''(Py_TPFLAGS_DEFAULT |
                Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_BASETYPE)''')
        else:
            pytypeobj.c_tp_flags = CDefinedIntSymbolic('''(Py_TPFLAGS_DEFAULT |
                Py_TPFLAGS_CHECKTYPES)''')
        pytypeobj.c_tp_new = rtyper.type_system.getcallable(tp_new_graph)
        pytypeobj.c_tp_dealloc = rtyper.annotate_helper_fn(ll_tp_dealloc,
                                                           [PyObjPtr])
        pytypeobj.c_tp_as_number = lltype.malloc(PyNumberMethods, immortal=True)
        pytypeobj.c_tp_as_sequence = lltype.malloc(PySequenceMethods, immortal=True)
        pytypeobj.c_tp_as_mapping = lltype.malloc(PyMappingMethods, immortal=True)
        result =  lltype.cast_pointer(PyObjPtr, pytypeobj)

        # the llsetup function that will store the 'objects' into the
        # type's tp_dict
        Py_TPFLAGS_HEAPTYPE = CDefinedIntSymbolic('Py_TPFLAGS_HEAPTYPE')
        if cpytype.objects:
            objects = [(lltype.pyobjectptr(name), value)
                       for name, value in cpytype.objects.items() if name != '__new__']
            if '__new__' in cpytype.objects:
                new = cpytype.objects['__new__']._obj.value
                objects.append((lltype.pyobjectptr('__new__'),
                                lltype.pyobjectptr(staticmethod(new))))

            def ll_type_setup(p):
                tp = lltype.cast_pointer(lltype.Ptr(PY_TYPE_OBJECT), p)
                old_flags = tp.c_tp_flags
                tp.c_tp_flags |= Py_TPFLAGS_HEAPTYPE
                for name, value in objects:
                    llop.setattr(PyObjPtr, tp, name, value)
                tp.c_tp_flags = old_flags
            result._obj.setup_fnptr = rtyper.annotate_helper_fn(ll_type_setup,
                                                                [PyObjPtr])

        cache[r_inst.classdef] = result
        return result