Example #1
0
def prep_string(s):
    """Takes a Pixie string and returns a VoidP to that string. The string should be freed via dispose!, otherwise
    memory leaks could result."""
    affirm(isinstance(s, String), u"Can only prep strings with prep-string")
    utf8 = unicode_to_utf8(rt.name(s))
    raw = rffi.str2charp(utf8)
    return VoidP(rffi.cast(rffi.VOIDP, raw))
Example #2
0
def unpack(ptr, offset, tp):
    """(unpack ptr offset tp)
       Reads a value of type tp from offset of ptr."""
    affirm(isinstance(ptr, VoidP) or isinstance(ptr, Buffer) or isinstance(ptr, CStruct), u"Type is not unpackable")
    affirm(isinstance(tp, CType), u"Packing type must be a CType")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    return tp.ffi_get_value(ptr)
Example #3
0
def ffi_prep_callback(tp, f):
    """(ffi-prep-callback callback-tp fn)
       Prepares a Pixie function for use as a c callback. callback-tp is a ffi callback type,
       fn is a pixie function (can be a closure, native fn or any object that implements -invoke.
       Returns a function pointer that can be passed to c and invoked as a callback."""
    affirm(isinstance(tp, CFunctionType),
           u"First argument to ffi-prep-callback must be a CFunctionType")
    raw_closure = rffi.cast(rffi.VOIDP, clibffi.closureHeap.alloc())

    if not we_are_translated():
        unique_id = id_generator.get_next()
    else:
        unique_id = rffi.cast(lltype.Signed, raw_closure)

    res = clibffi.c_ffi_prep_closure(
        rffi.cast(clibffi.FFI_CLOSUREP, raw_closure),
        tp.get_cd().cif, invoke_callback, rffi.cast(rffi.VOIDP, unique_id))

    if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
        registered_callbacks[unique_id] = None
        runtime_error(u"libffi failed to build this callback")

    cb = CCallback(tp, raw_closure, unique_id, f)
    registered_callbacks[unique_id] = cb

    return cb
Example #4
0
File: ffi.py Project: kidaa/pixie
def unpack(ptr, offset, tp):
    """(unpack ptr offset tp)
       Reads a value of type tp from offset of ptr."""
    affirm(isinstance(ptr, VoidP) or isinstance(ptr, Buffer) or isinstance(ptr, CStruct), u"Type is not unpackable")
    affirm(isinstance(tp, CType), u"Packing type must be a CType")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    return tp.ffi_get_value(ptr)
Example #5
0
File: ffi.py Project: kidaa/pixie
def prep_string(s):
    """Takes a Pixie string and returns a VoidP to that string. The string should be freed via dispose!, otherwise
    memory leaks could result."""
    affirm(isinstance(s, String), u"Can only prep strings with prep-string")
    utf8 = unicode_to_utf8(rt.name(s))
    raw = rffi.str2charp(utf8)
    return VoidP(rffi.cast(rffi.VOIDP, raw))
Example #6
0
File: ffi.py Project: kidaa/pixie
def ffi_prep_callback(tp, f):
    """(ffi-prep-callback callback-tp fn)
       Prepares a Pixie function for use as a c callback. callback-tp is a ffi callback type,
       fn is a pixie function (can be a closure, native fn or any object that implements -invoke.
       Returns a function pointer that can be passed to c and invoked as a callback."""
    affirm(isinstance(tp, CFunctionType), u"First argument to ffi-prep-callback must be a CFunctionType")
    raw_closure = rffi.cast(rffi.VOIDP, clibffi.closureHeap.alloc())

    if not we_are_translated():
        unique_id = id_generator.get_next()
    else:
        unique_id = rffi.cast(lltype.Signed, raw_closure)

    res = clibffi.c_ffi_prep_closure(rffi.cast(clibffi.FFI_CLOSUREP, raw_closure), tp.get_cd().cif,
                             invoke_callback,
                             rffi.cast(rffi.VOIDP, unique_id))


    if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
        registered_callbacks[unique_id] = None
        runtime_error(u"libffi failed to build this callback")

    cb = CCallback(tp, raw_closure, unique_id, f)
    registered_callbacks[unique_id] = cb

    return cb
Example #7
0
    def ffi_set_value(self, ptr, val):
        affirm(isinstance(val, CCallback), u"Can only encode CCallbacks as function pointers")


        casted = rffi.cast(rffi.VOIDPP, ptr)
        casted[0] = val.get_raw_closure()

        return None
Example #8
0
File: ffi.py Project: kidaa/pixie
def pack(ptr, offset, tp, val):
    """(pack! ptr offset tp val)
       Writes val at offset of ptr with the format tp"""
    affirm(isinstance(ptr, VoidP) or isinstance(ptr, Buffer) or isinstance(ptr, CStruct), u"Type is not unpackable")
    affirm(isinstance(tp, CType), u"Packing type must be a CType")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    tp.ffi_set_value(ptr, val)
    return nil
Example #9
0
File: ffi.py Project: kgann/pixie
    def ffi_set_value(self, ptr, val):
        affirm(isinstance(val, CCallback),
               u"Can only encode CCallbacks as function pointers")

        casted = rffi.cast(rffi.VOIDPP, ptr)
        casted[0] = val.get_raw_closure()

        return None
Example #10
0
def pack(ptr, offset, tp, val):
    """(pack! ptr offset tp val)
       Writes val at offset of ptr with the format tp"""
    affirm(isinstance(ptr, VoidP) or isinstance(ptr, Buffer) or isinstance(ptr, CStruct), u"Type is not unpackable")
    affirm(isinstance(tp, CType), u"Packing type must be a CType")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    tp.ffi_set_value(ptr, val)
    return nil
Example #11
0
 def ffi_set_value(self, ptr, val):
     pnt = rffi.cast(rffi.VOIDPP, ptr)
     if isinstance(val, Buffer):
         pnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         pnt[0] = val.raw_data()
     else:
         print val
         affirm(False, u"Cannot encode this type")
Example #12
0
File: ffi.py Project: Xsan-21/pixie
 def ffi_set_value(self, ptr, val):
     pnt = rffi.cast(rffi.VOIDPP, ptr)
     if isinstance(val, Buffer):
         pnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         pnt[0] = val.raw_data()
     else:
         print val
         affirm(False, u"Cannot encode this type")
Example #13
0
File: ffi.py Project: kidaa/pixie
    def ffi_set_value(self, ptr, val):
        if isinstance(val, CCallback):
            casted = rffi.cast(rffi.VOIDPP, ptr)
            casted[0] = val.get_raw_closure()
        elif val is nil:
            casted = rffi.cast(rffi.VOIDPP, ptr)
            casted[0] = rffi.cast(rffi.VOIDP, 0)
        else:
            frm_name = rt.name(rt.str(val.type()))
            to_name = rt.name(rt.str(self))
            affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)

        return None
Example #14
0
    def ffi_set_value(self, ptr, val):
        if isinstance(val, CCallback):
            casted = rffi.cast(rffi.VOIDPP, ptr)
            casted[0] = val.get_raw_closure()
        elif val is nil:
            casted = rffi.cast(rffi.VOIDPP, ptr)
            casted[0] = rffi.cast(rffi.VOIDP, 0)
        else:
            frm_name = rt.name(rt.str(val.type()))
            to_name = rt.name(rt.str(self))
            affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)

        return None
Example #15
0
def c_struct(name, size, spec):
    d = {}
    for x in range(rt.count(spec)):
        row = rt.nth(spec, rt.wrap(x))
        nm = rt.nth(row, rt.wrap(0))
        tp = rt.nth(row, rt.wrap(1))
        offset = rt.nth(row, rt.wrap(2))

        affirm(isinstance(nm, Keyword), u"c-struct field names must be keywords")
        if not isinstance(tp, CType):
            runtime_error(u"c-struct field types must be c types, got: " + rt.name(rt.str(tp)))

        d[nm] = (tp, offset.int_val())

    return CStructType(rt.name(name), size.int_val(), d)
Example #16
0
def c_struct(name, size, spec):
    """(c-struct name size spec)
       Creates a CStruct named name, of size size, with the given spec. Spec is a vector
       of vectors. Each row of the format [field-name type offset]"""
    d = {}
    for x in range(rt.count(spec)):
        row = rt.nth(spec, rt.wrap(x))
        nm = rt.nth(row, rt.wrap(0))
        tp = rt.nth(row, rt.wrap(1))
        offset = rt.nth(row, rt.wrap(2))

        affirm(isinstance(nm, Keyword), u"c-struct field names must be keywords")
        #if not isinstance(tp, CType):
        #    runtime_error(u"c-struct field types must be c types, got: " + rt.name(rt.str(tp)))

        d[nm] = (tp, offset.int_val())

    tp = CStructType(rt.name(name), size.int_val(), d)
    proto._dispose_BANG_.extend(tp, _dispose_cstruct)
    return tp
Example #17
0
File: ffi.py Project: kidaa/pixie
 def ffi_set_value(self, ptr, val):
     pnt = rffi.cast(rffi.VOIDPP, ptr)
     if isinstance(val, String):
         pnt = rffi.cast(rffi.CCHARPP, ptr)
         utf8 = unicode_to_utf8(rt.name(val))
         raw = rffi.str2charp(utf8)
         pnt[0] = raw
         return CCharPToken(raw)
     elif isinstance(val, Buffer):
         pnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         pnt[0] = val.raw_data()
     elif val is nil:
         pnt[0] = rffi.cast(rffi.VOIDP, 0)
     elif isinstance(val, CStruct):
         pnt[0] = rffi.cast(rffi.VOIDP, val.raw_data())
     else:
         frm_name = rt.name(rt.str(val.type()))
         to_name = rt.name(rt.str(self))
         affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)
Example #18
0
File: ffi.py Project: kidaa/pixie
def c_struct(name, size, spec):
    """(c-struct name size spec)
       Creates a CStruct named name, of size size, with the given spec. Spec is a vector
       of vectors. Each row of the format [field-name type offset]"""
    d = {}
    for x in range(rt.count(spec)):
        row = rt.nth(spec, rt.wrap(x))
        nm = rt.nth(row, rt.wrap(0))
        tp = rt.nth(row, rt.wrap(1))
        offset = rt.nth(row, rt.wrap(2))

        affirm(isinstance(nm, Keyword), u"c-struct field names must be keywords")
        #if not isinstance(tp, CType):
        #    runtime_error(u"c-struct field types must be c types, got: " + rt.name(rt.str(tp)))

        d[nm] = (tp, offset.int_val())

    tp = CStructType(rt.name(name), size.int_val(), d)
    proto._dispose_BANG_.extend(tp, _dispose_cstruct)
    return tp
Example #19
0
 def ffi_set_value(self, ptr, val):
     pnt = rffi.cast(rffi.VOIDPP, ptr)
     if isinstance(val, String):
         pnt = rffi.cast(rffi.CCHARPP, ptr)
         utf8 = unicode_to_utf8(rt.name(val))
         raw = rffi.str2charp(utf8)
         pnt[0] = raw
         return CCharPToken(raw)
     elif isinstance(val, Buffer):
         pnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         pnt[0] = val.raw_data()
     elif val is nil:
         pnt[0] = rffi.cast(rffi.VOIDP, 0)
     elif isinstance(val, CStruct):
         pnt[0] = rffi.cast(rffi.VOIDP, val.raw_data())
     else:
         frm_name = rt.name(rt.str(val.type()))
         to_name = rt.name(rt.str(self))
         affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)
Example #20
0
def _ffi_fn(lib, nm, args, ret_type):
    affirm(isinstance(lib, ExternalLib), u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(args)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(args, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    f = FFIFn(lib, rt.name(nm), new_args, ret_type)
    return f
Example #21
0
File: ffi.py Project: kgann/pixie
 def ffi_set_value(self, ptr, val):
     if isinstance(val, String):
         pnt = rffi.cast(rffi.CCHARPP, ptr)
         utf8 = unicode_to_utf8(rt.name(val))
         raw = rffi.str2charp(utf8)
         pnt[0] = raw
         return CCharPToken(raw)
     elif isinstance(val, Buffer):
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = val.raw_data()
     elif val is nil:
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = rffi.cast(rffi.VOIDP, 0)
     elif isinstance(val, CStruct):
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = rffi.cast(rffi.VOIDP, val.raw_data())
     else:
         print val
         affirm(False, u"Cannot encode this type")
Example #22
0
def _ffi_fn(lib, nm, args, ret_type):
    affirm(isinstance(lib, ExternalLib),
           u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(args)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(args, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    f = FFIFn(lib, rt.name(nm), new_args, ret_type)
    return f
Example #23
0
File: ffi.py Project: kidaa/pixie
def pack(ptr, offset):
    affirm(isinstance(ptr, VoidP) or isinstance(ptr, Buffer) or isinstance(ptr, CStruct), u"Type is not unpackable")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    return VoidP(ptr)
Example #24
0
File: ffi.py Project: kidaa/pixie
def _ffi_voidp(lib, nm):
    affirm(isinstance(lib, ExternalLib), u"First argument to ffi-voidp should be an external library")
    name = rt.name(nm)
    return VoidP(lib.get_fn_ptr(name))
Example #25
0
File: ffi.py Project: kidaa/pixie
def _ffi_fn__args(args):
    affirm(len(args) >= 4, u"ffi-fn requires at least 4 arguments")
    lib, nm, arg_types, ret_type = args[:4]

    affirm(isinstance(lib, ExternalLib), u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(arg_types)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(arg_types, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    kwargs = args[4:]
    affirm(len(kwargs) & 0x1 == 0, u"ffi-fn requires even number of options")

    is_variadic = False
    for i in range(0, len(kwargs)/2, 2):
        key = kwargs[i]
        val = kwargs[i+1]
        
        affirm(isinstance(key, Keyword), u"ffi-fn options should be keyword/bool pairs")
        affirm(val is true or val is false, u"ffi-fn options should be keyword/bool pairs")

        k = rt.name(key)
        if k == u"variadic?":
            is_variadic = True if val is true else False
        else:
            affirm(False, u"unknown ffi-fn option: :" + k)

    tp = CFunctionType(new_args, ret_type, is_variadic)
    nm = rt.name(nm)
    f = FFIFn(nm, lib.get_fn_ptr(nm), tp)
    return f
Example #26
0
def prep_ffi_call__args(args):
    fn = args[0]
    affirm(isinstance(fn, CFunctionType), u"First arg must be a FFI function")
Example #27
0
def _ffi_fn__args(args):
    affirm(len(args) >= 4, u"ffi-fn requires at least 4 arguments")
    lib, nm, arg_types, ret_type = args[:4]

    affirm(isinstance(lib, ExternalLib),
           u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(arg_types)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(arg_types, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    kwargs = args[4:]
    affirm(len(kwargs) & 0x1 == 0, u"ffi-fn requires even number of options")

    is_variadic = False
    for i in range(0, len(kwargs) / 2, 2):
        key = kwargs[i]
        val = kwargs[i + 1]

        affirm(isinstance(key, Keyword),
               u"ffi-fn options should be keyword/bool pairs")
        affirm(val is true or val is false,
               u"ffi-fn options should be keyword/bool pairs")

        k = rt.name(key)
        if k == u"variadic?":
            is_variadic = True if val is true else False
        else:
            affirm(False, u"unknown ffi-fn option: :" + k)

    tp = CFunctionType(new_args, ret_type, is_variadic)
    nm = rt.name(nm)
    f = FFIFn(nm, lib.get_fn_ptr(nm), tp)
    return f
Example #28
0
def _ffi_voidp(lib, nm):
    affirm(isinstance(lib, ExternalLib),
           u"First argument to ffi-voidp should be an external library")
    name = rt.name(nm)
    return VoidP(lib.get_fn_ptr(name))
Example #29
0
File: ffi.py Project: kidaa/pixie
def prep_ffi_call__args(args):
    fn = args[0]
    affirm(isinstance(fn, CFunctionType), u"First arg must be a FFI function")
Example #30
0
def pack(ptr, offset):
    affirm(
        isinstance(ptr, VoidP) or isinstance(ptr, Buffer)
        or isinstance(ptr, CStruct), u"Type is not unpackable")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    return VoidP(ptr)