Skip to content

Instantly share code, notes, and snippets.

@nilium
Created November 30, 2009 07:43
Show Gist options
  • Select an option

  • Save nilium/245313 to your computer and use it in GitHub Desktop.

Select an option

Save nilium/245313 to your computer and use it in GitHub Desktop.
libffi ooc bindings WIP
use libffi
import libffi
import structs/Array
main: func {
closure := FFIClosure new()
cif := FFICIF new()
types: Array<FFIType*> = Array<FFIType*> new(2)
types[0] = FFIType SINT&
types[1] = FFIType POINTER&
cif prepare(FFIABI DEFAULT, 2, FFIType SINT&, types)
closure prepare(cif,
func(cif: FFICIF, ret: Pointer, args: Pointer*, data: Pointer) {
"Inside closure wrapper" println()
"Argument 1: %d\n" format((args[0] as Int*)@) print()
"Argument 2: %s\n" format((args[1] as String*)@) print()
},
null)
f := closure as Func
f(-1234, "woop")
}
use libffi
import os/mmap
import structs/Array
FFIType: cover from ffi_type {
size: extern SizeT
alignment: extern UShort
type: extern UShort
VOID: static extern(ffi_type_void) const This
UINT8: static extern(ffi_type_uint8) const This
SINT8: static extern(ffi_type_sint8) const This
UINT16: static extern(ffi_type_uint16) const This
SINT16: static extern(ffi_type_sint16) const This
UINT32: static extern(ffi_type_uint32) const This
SINT32: static extern(ffi_type_sint32) const This
UINT64: static extern(ffi_type_uint64) const This
SINT64: static extern(ffi_type_sint64) const This
FLOAT: static extern(ffi_type_float) const This
DOUBLE: static extern(ffi_type_double) const This
LONGDOUBLE: static extern(ffi_type_longdouble) const This
POINTER: static extern(ffi_type_pointer) const This
UCHAR: static extern(ffi_type_uchar) const This
SCHAR: static extern(ffi_type_schar) const This
USHORT: static extern(ffi_type_ushort) const This
SSHORT: static extern(ffi_type_sshort) const This
UINT: static extern(ffi_type_uint) const This
SINT: static extern(ffi_type_sint) const This
ULONG: static extern(ffi_type_ulong) const This
SLONG: static extern(ffi_type_slong) const This
}
FFIABI: cover from ffi_abi {
FIRST_ABI: static extern(FFI_FIRST_ABI) const This
DEFAULT: static extern(FFI_DEFAULT_ABI) const This
SYSV: static extern(FFI_SYSV) const This
//version(windows) {
STDCALL: static extern(FFI_STDCALL) const This
//}
//version(!windows && (i386 || x86_64)) {
UNIX64: static extern(FFI_UNIX64) const This
//}
LAST_ABI: static extern(FFI_LAST_ABI) const This
}
FFICIF_Struct: cover from ffi_cif
FFICIF: cover from ffi_cif* {
new: static func -> This {
return gc_malloc(sizeof(FFICIF_Struct)) as This
}
ffi_prep_cif: static extern(ffi_prep_cif) func(cif: FFICIF_Struct*, abi: FFIABI, nargs: UInt, rtype: FFIType*, atypes: FFIType**) -> FFIStatus
prepare: func(abi: FFIABI, nargs: UInt, rtype: FFIType*, atypes: Array<FFIType*>) -> FFIStatus {
return ffi_prep_cif(this, abi, nargs, rtype, atypes data)
}
// call: extern(ffi_call) func(fn: Func, rvalue: Pointer, avalue: Pointer*)
}
FFIClosure_Struct: cover from ffi_closure
FFIClosure: class {
closure: FFIClosure_Struct*
init: func {
value := MAP_PRIVATE
version(apple||solaris) { value |= MAP_ANON }
version(linux) { value |= MAP_ANONYMOUS }
closure = mmap(null, sizeof(FFIClosure_Struct), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0) as FFIClosure_Struct*
if ( closure as Pointer == MAP_FAILED ) {
Exception new(This, "mmap failed") throw()
}
}
/* cif: FFICIF, Func(CIF, result: Pointer, args: Pointer*, userdata: Pointer) */
/* please do not call this yourself. */
ffi_prep_closure: static extern(ffi_prep_closure) func(FFIClosure_Struct*, FFICIF, Func(FFICIF, Pointer, Pointer*, Pointer), Pointer) -> FFIStatus
prepare: func(cif: FFICIF, fn: Func(FFICIF, Pointer, Pointer*, Pointer), user_data: Pointer) -> FFIStatus {
status := ffi_prep_closure(closure, cif, fn, user_data)
if ( mprotect(closure, sizeof(FFIClosure_Struct), PROT_READ|PROT_EXEC) == -1 ) {
Exception new(This, "mprotect failed to set page as PROT_READ and PROT_EXEC") throw()
}
return status
}
destroy: func {
munmap(closure, sizeof(FFIClosure_Struct))
}
}
operator as (ffic: FFIClosure) -> Func { ffic closure as Func }
FFIStatus: cover from ffi_status {
OK: static extern(FFI_OK) const This
BAD_TYPEDEF: static extern(FFI_OK) const This
BAD_ABI: static extern(FFI_OK) const This
}
Name: libffi
Description: Foreign Function Interface
Includes: ffi/ffi.h
Libs: -lffi
SourcePath: .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment