cffi / demo / pyobj.py

Armin Rigo 8c4195c 
Armin Rigo ea467ca 
Armin Rigo 8c4195c 


Armin Rigo ea467ca 
Armin Rigo 8c4195c 
Armin Rigo 225281d 


Armin Rigo 8c4195c 

Armin Rigo 225281d 


Armin Rigo 8c4195c 
Armin Rigo 225281d 


Armin Rigo 8c4195c 
Armin Rigo 225281d 



Armin Rigo 8c4195c 

Armin Rigo ea467ca 


Armin Rigo 8c4195c 


Armin Rigo 225281d 

Armin Rigo 8c4195c 
Armin Rigo 225281d 
Armin Rigo 8c4195c 
Armin Rigo ea467ca 

Armin Rigo 225281d 

Armin Rigo ea467ca 

Armin Rigo 225281d 
Armin Rigo ea467ca 

Armin Rigo 8c4195c 

Armin Rigo 225281d 

Armin Rigo 8c4195c 
Armin Rigo 225281d 
Armin Rigo 8dadf84 
Armin Rigo 225281d 




Armin Rigo 8c4195c 
Armin Rigo 225281d 



Armin Rigo ea467ca 
Armin Rigo 225281d 



Armin Rigo ea467ca 
Armin Rigo 225281d 


Armin Rigo ea467ca 
Armin Rigo 225281d 


Armin Rigo ea467ca 
Armin Rigo 225281d 



Armin Rigo 8c4195c 
Armin Rigo 225281d 
















Armin Rigo 8c4195c 
Armin Rigo ea467ca 
Armin Rigo 225281d 












Armin Rigo ea467ca 
Armin Rigo 225281d 
Armin Rigo 8c4195c 
Armin Rigo 225281d 




Armin Rigo ea467ca 
Armin Rigo 225281d 
referents = []     # list "object descriptor -> python object"
freelist = None

def store(x):
    "Store the object 'x' and returns a new object descriptor for it."
    global freelist
    p = freelist
    if p is None:
        p = len(referents)
        referents.append(x)
    else:
        freelist = referents[p]
        referents[p] = x
    return p

def discard(p):
    """Discard (i.e. close) the object descriptor 'p'.
    Return the original object that was attached to 'p'."""
    global freelist
    x = referents[p]
    referents[p] = freelist
    freelist = p
    return x

class Ref(object):
    """For use in 'with Ref(x) as ob': open an object descriptor
    and returns it in 'ob', and close it automatically when the
    'with' statement finishes."""
    def __init__(self, x):
        self.x = x
    def __enter__(self):
        self.p = p = store(self.x)
        return p
    def __exit__(self, *args):
        discard(self.p)

def count_pyobj_alive():
    result = len(referents)
    p = freelist
    while p is not None:
        assert result > 0
        result -= 1
        p = referents[p]
    return result

# ------------------------------------------------------------

if __name__ == '__main__':
    import api

    ffi = api.PythonFFI()

    ffi.cdef("""
        typedef int pyobj_t;
        int sum_integers(pyobj_t p_list);
        pyobj_t sum_objects(pyobj_t p_list, pyobj_t p_initial);
    """)

    @ffi.pyexport("int(pyobj_t)")
    def length(p_list):
        list = referents[p_list]
        return len(list)

    @ffi.pyexport("int(pyobj_t, int)")
    def getitem(p_list, index):
        list = referents[p_list]
        return list[index]

    @ffi.pyexport("pyobj_t(pyobj_t)")
    def pyobj_dup(p):
        return store(referents[p])

    @ffi.pyexport("void(pyobj_t)")
    def pyobj_close(p):
        discard(p)

    @ffi.pyexport("pyobj_t(pyobj_t, int)")
    def pyobj_getitem(p_list, index):
        list = referents[p_list]
        return store(list[index])

    @ffi.pyexport("pyobj_t(pyobj_t, pyobj_t)")
    def pyobj_add(p1, p2):
        return store(referents[p1] + referents[p2])

    lib = ffi.verify("""
        typedef int pyobj_t;    /* an "object descriptor" number */

        int sum_integers(pyobj_t p_list) {
            /* this a demo function written in C, using the API
               defined above: length() and getitem(). */
            int i, result = 0;
            int count = length(p_list);
            for (i=0; i<count; i++) {
                int n = getitem(p_list, i);
                result += n;
            }
            return result;
        }

        pyobj_t sum_objects(pyobj_t p_list, pyobj_t p_initial) {
            /* same as above, but keeps all additions as Python objects */
            int i;
            int count = length(p_list);
            pyobj_t p1 = pyobj_dup(p_initial);
            for (i=0; i<count; i++) {
                pyobj_t p2 = pyobj_getitem(p_list, i);
                pyobj_t p3 = pyobj_add(p1, p2);
                pyobj_close(p2);
                pyobj_close(p1);
                p1 = p3;
            }
            return p1;
        }
    """)

    with Ref([10, 20, 30, 40]) as p_list:
        print lib.sum_integers(p_list)
        with Ref(5) as p_initial:
            result = discard(lib.sum_objects(p_list, p_initial))
            print result

    assert count_pyobj_alive() == 0
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.