File: typesystem.py

package info (click to toggle)
pypy 2.4.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 86,992 kB
  • ctags: 170,715
  • sloc: python: 1,030,417; ansic: 43,437; cpp: 5,241; asm: 5,169; sh: 458; makefile: 408; xml: 231; lisp: 45
file content (78 lines) | stat: -rw-r--r-- 3,017 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

"""typesystem.py -- Typesystem-specific operations for RTyper."""

from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.error import TyperError


class LowLevelTypeSystem(object):
    name = "lltypesystem"

    def deref(self, obj):
        assert isinstance(lltype.typeOf(obj), lltype.Ptr)
        return obj._obj

    def check_null(self, repr, hop):
        # None is a nullptr, which is false; everything else is true.
        vlist = hop.inputargs(repr)
        return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool)

    def null_callable(self, T):
        return lltype.nullptr(T.TO)

    def getexternalcallable(self, ll_args, ll_result, name, **kwds):
        FT = lltype.FuncType(ll_args, ll_result)
        return lltype.functionptr(FT, name, **kwds)

    def generic_is(self, robj1, robj2, hop):
        roriginal1 = robj1
        roriginal2 = robj2
        if robj1.lowleveltype is lltype.Void:
            robj1 = robj2
        elif robj2.lowleveltype is lltype.Void:
            robj2 = robj1
        if (not isinstance(robj1.lowleveltype, lltype.Ptr) or
            not isinstance(robj2.lowleveltype, lltype.Ptr)):
            raise TyperError('is of instances of the non-pointers: %r, %r' % (
                roriginal1, roriginal2))
        if robj1.lowleveltype != robj2.lowleveltype:
            raise TyperError('is of instances of different pointer types: %r, %r' % (
                roriginal1, roriginal2))

        v_list = hop.inputargs(robj1, robj2)
        return hop.genop('ptr_eq', v_list, resulttype=lltype.Bool)


def _getconcretetype(v):
    return v.concretetype


def getfunctionptr(graph, getconcretetype=None):
    """Return callable given a Python function."""
    if getconcretetype is None:
        getconcretetype = _getconcretetype
    llinputs = [getconcretetype(v) for v in graph.getargs()]
    lloutput = getconcretetype(graph.getreturnvar())

    FT = lltype.FuncType(llinputs, lloutput)
    name = graph.name
    if hasattr(graph, 'func') and callable(graph.func):
        # the Python function object can have _llfnobjattrs_, specifying
        # attributes that are forced upon the functionptr().  The idea
        # for not passing these extra attributes as arguments to
        # getcallable() itself is that multiple calls to getcallable()
        # for the same graph should return equal functionptr() objects.
        if hasattr(graph.func, '_llfnobjattrs_'):
            fnobjattrs = graph.func._llfnobjattrs_.copy()
            # can specify a '_name', but use graph.name by default
            name = fnobjattrs.pop('_name', name)
        else:
            fnobjattrs = {}
        # _callable is normally graph.func, but can be overridden:
        # see fakeimpl in extfunc.py
        _callable = fnobjattrs.pop('_callable', graph.func)
        return lltype.functionptr(FT, name, graph = graph,
                                  _callable = _callable, **fnobjattrs)
    else:
        return lltype.functionptr(FT, name, graph = graph)