Created
November 30, 2009 07:43
-
-
Save nilium/245313 to your computer and use it in GitHub Desktop.
libffi ooc bindings WIP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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") | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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