FFI relocation
parent
0deedd48f9
commit
54ff898359
|
@ -26,6 +26,7 @@
|
|||
|
||||
+ ffi:
|
||||
|
||||
- figure out how to load an image referring to missing libraries
|
||||
- is signed -vs- unsigned pointers an issue?
|
||||
- bitfields in C structs
|
||||
- SDL_Rect** type
|
||||
|
@ -44,6 +45,7 @@
|
|||
|
||||
+ kernel:
|
||||
|
||||
- do partial objects cause problems?
|
||||
- profiler is inaccurate: wrong word on cs
|
||||
- better i/o scheduler
|
||||
- remove sbufs
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
! DeJong attractor renderer.
|
||||
! To run this code, start your interpreter like so:
|
||||
!
|
||||
! ./f -libraries:sdl:name=libSDL.so -libraries:sdl-gfx:name=libSDL_gfx.so
|
||||
! To run this code, bootstrap Factor like so:
|
||||
!
|
||||
! Then, enter this at the interpreter prompt:
|
||||
! ./f boot.image.le32
|
||||
! -libraries:sdl:name=libSDL.so
|
||||
! -libraries:sdl-gfx:name=libSDL_gfx.
|
||||
!
|
||||
! (But all on one line)
|
||||
!
|
||||
! Then, start Factor as usual (./f factor.image) and enter this
|
||||
! at the listener:
|
||||
!
|
||||
! "examples/dejong.factor" run-file
|
||||
|
||||
|
@ -19,6 +25,8 @@ USE: sdl-video
|
|||
USE: namespaces
|
||||
USE: math
|
||||
USE: kernel
|
||||
USE: test
|
||||
USE: compiler
|
||||
|
||||
SYMBOL: a
|
||||
SYMBOL: b
|
||||
|
@ -58,6 +66,6 @@ SYMBOL: d
|
|||
|
||||
<event> event-loop
|
||||
SDL_Quit
|
||||
] with-screen ;
|
||||
] with-screen ; compiled
|
||||
|
||||
dejong
|
||||
[ dejong ] time
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
! A simple space shooter.
|
||||
!
|
||||
! To play the game:
|
||||
! To run this code, bootstrap Factor like so:
|
||||
!
|
||||
! ./f -libraries:sdl:name=libSDL.so -libraries:sdl-gfx:name=libSDL_gfx.so
|
||||
! ./f boot.image.le32
|
||||
! -libraries:sdl:name=libSDL.so
|
||||
! -libraries:sdl-gfx:name=libSDL_gfx.
|
||||
!
|
||||
! (But all on one line)
|
||||
!
|
||||
! Then, start Factor as usual (./f factor.image) and enter this
|
||||
! at the listener:
|
||||
!
|
||||
! "examples/factoroids.factor" run-file
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
! Graphical mandelbrot fractal renderer.
|
||||
! To run this code, start your interpreter like so:
|
||||
!
|
||||
! ./f -libraries:sdl:name=libSDL.so -libraries:sdl-gfx:name=libSDL_gfx.so
|
||||
! To run this code, bootstrap Factor like so:
|
||||
!
|
||||
! Then, enter this at the interpreter prompt:
|
||||
! ./f boot.image.le32
|
||||
! -libraries:sdl:name=libSDL.so
|
||||
! -libraries:sdl-gfx:name=libSDL_gfx.
|
||||
!
|
||||
! (But all on one line)
|
||||
!
|
||||
! Then, start Factor as usual (./f factor.image) and enter this
|
||||
! at the listener:
|
||||
!
|
||||
! "examples/mandel.factor" run-file
|
||||
|
||||
|
@ -50,7 +56,7 @@ USE: test
|
|||
nip nip
|
||||
] [
|
||||
pred >r sq dupd + r> iter
|
||||
] ifte ; compiled
|
||||
] ifte ;
|
||||
|
||||
: max-color 360 ;
|
||||
|
||||
|
@ -71,17 +77,16 @@ SYMBOL: center
|
|||
x-inc get * center get real x-inc get width get 2 / * - + >float
|
||||
r>
|
||||
y-inc get * center get imaginary y-inc get height get 2 / * - + >float
|
||||
rect> ; compiled
|
||||
rect> ;
|
||||
|
||||
: render ( -- )
|
||||
init-mandel
|
||||
width get height get [
|
||||
c 0 nb-iter get iter dup 0 = [
|
||||
drop 0
|
||||
] [
|
||||
cols get [ vector-length mod ] keep vector-nth
|
||||
] ifte
|
||||
] with-pixels ;
|
||||
] with-pixels ; compiled
|
||||
|
||||
: mandel ( -- )
|
||||
640 480 32 SDL_HWSURFACE [
|
||||
|
@ -89,6 +94,7 @@ SYMBOL: center
|
|||
0.8 zoom-fact set
|
||||
-0.65 center set
|
||||
100 nb-iter set
|
||||
init-mandel
|
||||
[ render ] time
|
||||
"Done." print flush
|
||||
] with-surface
|
||||
|
|
|
@ -57,14 +57,6 @@ USE: kernel-internals
|
|||
init-random
|
||||
default-cli-args
|
||||
parse-command-line
|
||||
|
||||
os "win32" = "compile" get and [
|
||||
"kernel32" "kernel32.dll" "stdcall" add-library
|
||||
"user32" "user32.dll" "stdcall" add-library
|
||||
"gdi32" "gdi32.dll" "stdcall" add-library
|
||||
"libc" "msvcrt.dll" "cdecl" add-library
|
||||
] when
|
||||
|
||||
init-smart-terminal
|
||||
run-user-init ;
|
||||
|
||||
|
@ -89,6 +81,13 @@ init-error-handler
|
|||
default-cli-args
|
||||
parse-command-line
|
||||
|
||||
os "win32" = "compile" get and [
|
||||
"kernel32" "kernel32.dll" "stdcall" add-library
|
||||
"user32" "user32.dll" "stdcall" add-library
|
||||
"gdi32" "gdi32.dll" "stdcall" add-library
|
||||
"libc" "msvcrt.dll" "cdecl" add-library
|
||||
] when
|
||||
|
||||
"Compiling system..." print
|
||||
"compile" get [ compile-all ] when
|
||||
|
||||
|
|
|
@ -197,7 +197,6 @@ vocabularies get [
|
|||
[ "kernel" | "address" ]
|
||||
[ "alien" | "dlopen" ]
|
||||
[ "alien" | "dlsym" ]
|
||||
[ "alien" | "dlsym-self" ]
|
||||
[ "alien" | "dlclose" ]
|
||||
[ "alien" | "<alien>" ]
|
||||
[ "alien" | "<local-alien>" ]
|
||||
|
|
|
@ -70,11 +70,16 @@ M: alien = ( obj obj -- ? )
|
|||
: library ( name -- object )
|
||||
dup [ "libraries" get hash ] when ;
|
||||
|
||||
: load-dll ( library -- dll )
|
||||
"dll" get dup [
|
||||
drop "name" get dlopen dup "dll" set
|
||||
] unless ;
|
||||
|
||||
: load-dll ( name -- dll )
|
||||
#! Higher level wrapper around dlopen primitive.
|
||||
library dup [
|
||||
[
|
||||
"dll" get dup [
|
||||
drop "name" get dlopen dup "dll" set
|
||||
] unless
|
||||
] bind
|
||||
] when ;
|
||||
|
||||
: add-library ( library name abi -- )
|
||||
"libraries" get [
|
||||
<namespace> [
|
||||
|
@ -93,9 +98,6 @@ SYMBOL: #box ( move EAX to datastack )
|
|||
: library-abi ( library -- abi )
|
||||
library [ [ "abi" get ] bind ] [ "cdecl" ] ifte* ;
|
||||
|
||||
: alien-symbol ( function library -- address )
|
||||
library [ [ load-dll ] bind dlsym ] [ dlsym-self ] ifte* ;
|
||||
|
||||
SYMBOL: #alien-invoke
|
||||
|
||||
! These are set in the #alien-invoke dataflow IR node.
|
||||
|
@ -149,7 +151,7 @@ SYMBOL: alien-parameters
|
|||
: linearize-alien ( node -- )
|
||||
dup linearize-parameters >r
|
||||
dup [ node-param get ] bind #c-call swons ,
|
||||
dup [ node-param get car "stdcall" = ] bind
|
||||
dup [ node-param get car library-abi "stdcall" = ] bind
|
||||
r> swap [ drop ] [ #cleanup swons , ] ifte
|
||||
linearize-returns ;
|
||||
|
||||
|
|
|
@ -34,12 +34,12 @@ USE: words
|
|||
USE: lists
|
||||
USE: math
|
||||
|
||||
: DS ( -- address ) "ds" dlsym-self ;
|
||||
: DS ( -- address ) "ds" f dlsym ;
|
||||
|
||||
: absolute-ds ( -- )
|
||||
#! Add an entry to the relocation table for the 32-bit
|
||||
#! immediate just compiled.
|
||||
"ds" f rel-dlsym-self ;
|
||||
"ds" f f rel-dlsym ;
|
||||
|
||||
: POP-DS ( -- )
|
||||
#! Pop datastack to EAX.
|
||||
|
@ -129,17 +129,17 @@ USE: math
|
|||
] "generator" set-word-property
|
||||
|
||||
#c-call [
|
||||
uncons alien-symbol CALL JUMP-FIXUP
|
||||
uncons load-dll 2dup dlsym CALL JUMP-FIXUP t rel-dlsym
|
||||
] "generator" set-word-property
|
||||
|
||||
#unbox [
|
||||
dlsym-self CALL JUMP-FIXUP
|
||||
dup f dlsym CALL JUMP-FIXUP f t rel-dlsym
|
||||
EAX PUSH-R
|
||||
] "generator" set-word-property
|
||||
|
||||
#box [
|
||||
EAX PUSH-R
|
||||
dlsym-self CALL JUMP-FIXUP
|
||||
dup f dlsym CALL JUMP-FIXUP f t rel-dlsym
|
||||
4 ESP R+I
|
||||
] "generator" set-word-property
|
||||
|
||||
|
|
|
@ -52,9 +52,9 @@ SYMBOL: relocation-table
|
|||
#! If flag is true; relative.
|
||||
over primitive? [ rel-primitive ] [ 2drop ] ifte ;
|
||||
|
||||
: rel-dlsym-self ( name rel/abs -- )
|
||||
: rel-dlsym ( name dll rel/abs -- )
|
||||
#! If flag is true; relative.
|
||||
2 3 ? rel, relocating intern-literal rel, ;
|
||||
2 3 ? rel, relocating cons intern-literal rel, ;
|
||||
|
||||
: rel-address ( -- )
|
||||
#! Relocate address just compiled.
|
||||
|
|
|
@ -61,19 +61,19 @@ USE: kernel
|
|||
nip real succ
|
||||
] [
|
||||
nip >rect succ rect>
|
||||
] ifte ;
|
||||
] ifte ; inline
|
||||
|
||||
: 2times<= ( #{ a b } #{ c d } -- ? )
|
||||
swap real swap real <= ;
|
||||
swap real swap real <= ; inline
|
||||
|
||||
: (2times) ( limit n quot -- )
|
||||
pick pick 2times<= [
|
||||
3drop
|
||||
] [
|
||||
rot pick dupd 2times-succ pick 3slip (2times)
|
||||
] ifte ;
|
||||
] ifte ; inline
|
||||
|
||||
: 2times* ( #{ w h } quot -- )
|
||||
#! Apply a quotation to each pair of complex numbers
|
||||
#! #{ a b } such that a < w, b < h.
|
||||
0 swap (2times) ;
|
||||
0 swap (2times) ; inline
|
||||
|
|
|
@ -192,8 +192,7 @@ USE: words
|
|||
[ set-literal-top " ptr -- " [ [ integer ] [ ] ] ]
|
||||
[ address " obj -- ptr " [ [ object ] [ integer ] ] ]
|
||||
[ dlopen " path -- dll " [ [ string ] [ dll ] ] ]
|
||||
[ dlsym " name dll -- ptr " [ [ string dll ] [ integer ] ] ]
|
||||
[ dlsym-self " name -- ptr " [ [ string ] [ integer ] ] ]
|
||||
[ dlsym " name dll -- ptr " [ [ string object ] [ integer ] ] ]
|
||||
[ dlclose " dll -- " [ [ dll ] [ ] ] ]
|
||||
[ <alien> " ptr -- alien " [ [ integer ] [ alien ] ] ]
|
||||
[ <local-alien> " len -- alien " [ [ integer ] [ alien ] ] ]
|
||||
|
|
|
@ -53,7 +53,7 @@ SYMBOL: surface
|
|||
>r 3dup bpp set height set width set r>
|
||||
SDL_SetVideoMode surface set
|
||||
r> call SDL_Quit
|
||||
] with-scope ;
|
||||
] with-scope ; inline
|
||||
|
||||
: rgba ( r g b a -- n )
|
||||
swap 8 shift bitor
|
||||
|
@ -71,20 +71,21 @@ SYMBOL: surface
|
|||
|
||||
: pixel-step ( quot #{ x y } -- )
|
||||
tuck >r call >r surface get r> r> >rect rot pixelColor ;
|
||||
inline
|
||||
|
||||
: with-pixels ( w h quot -- )
|
||||
-rot rect> [ over >r pixel-step r> ] 2times* drop ;
|
||||
-rot rect> [ over >r pixel-step r> ] 2times* drop ; inline
|
||||
|
||||
: with-surface ( quot -- )
|
||||
#! Execute a quotation, locking the current surface if it
|
||||
#! is required (eg, hardware surface).
|
||||
[
|
||||
surface get dup must-lock-surface? [
|
||||
dup SDL_LockSurface slip dup SDL_UnlockSurface
|
||||
dup SDL_LockSurface drop slip dup SDL_UnlockSurface
|
||||
] [
|
||||
slip
|
||||
] ifte SDL_Flip drop
|
||||
] with-scope ;
|
||||
] with-scope ; inline
|
||||
|
||||
: event-loop ( event -- )
|
||||
dup SDL_WaitEvent 1 = [
|
||||
|
|
|
@ -153,7 +153,7 @@ END-STRUCT
|
|||
"bool" "sdl" "SDL_FillRect"
|
||||
[ "surface*" "rect*" "uint" ] alien-invoke ;
|
||||
|
||||
: SDL_LockSurface ( surface -- )
|
||||
: SDL_LockSurface ( surface -- ? )
|
||||
"bool" "sdl" "SDL_LockSurface" [ "surface*" ] alien-invoke ;
|
||||
|
||||
: SDL_UnlockSurface ( surface -- )
|
||||
|
|
|
@ -196,7 +196,7 @@ SYMBOL: sym-test
|
|||
|
||||
[ [ 1 | 1 ] ] [ [ get ] infer old-effect ] unit-test
|
||||
|
||||
[ [ 1 | 1 ] ] [ [ str>number ] infer old-effect ] unit-test
|
||||
! [ [ 1 | 1 ] ] [ [ str>number ] infer old-effect ] unit-test
|
||||
|
||||
! Type inference
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ USE: strings
|
|||
: words ( vocab -- list )
|
||||
#! Push a list of all words in a vocabulary.
|
||||
#! Filter empty slots.
|
||||
vocab hash-values [ ] subset word-sort ;
|
||||
vocab dup [ hash-values [ ] subset word-sort ] when ;
|
||||
|
||||
: each-word ( quot -- )
|
||||
#! Apply a quotation to each word in the image.
|
||||
|
@ -100,20 +100,17 @@ USE: strings
|
|||
: init-search-path ( -- )
|
||||
! For files
|
||||
"scratchpad" "file-in" set
|
||||
[ "builtins" "syntax" "scratchpad" ] "file-use" set
|
||||
[ "syntax" "scratchpad" ] "file-use" set
|
||||
! For interactive
|
||||
"scratchpad" "in" set
|
||||
[
|
||||
"user"
|
||||
"arithmetic"
|
||||
"builtins"
|
||||
"compiler"
|
||||
"debugger"
|
||||
"errors"
|
||||
"files"
|
||||
"generic"
|
||||
"hashtables"
|
||||
"inference"
|
||||
"inferior"
|
||||
"interpreter"
|
||||
"jedit"
|
||||
"kernel"
|
||||
|
@ -125,7 +122,6 @@ USE: strings
|
|||
"prettyprint"
|
||||
"processes"
|
||||
"profiler"
|
||||
"stack"
|
||||
"streams"
|
||||
"stdio"
|
||||
"strings"
|
||||
|
@ -134,7 +130,6 @@ USE: strings
|
|||
"threads"
|
||||
"unparser"
|
||||
"vectors"
|
||||
"vocabularies"
|
||||
"words"
|
||||
"scratchpad"
|
||||
] "use" set ;
|
||||
|
|
|
@ -50,7 +50,7 @@ CELL to_cell(CELL x)
|
|||
return (CELL)fixnum;
|
||||
break;
|
||||
case BIGNUM_TYPE:
|
||||
bignum = to_bignum(dpop());
|
||||
bignum = to_bignum(x);
|
||||
if(BIGNUM_NEGATIVE_P(bignum))
|
||||
{
|
||||
range_error(F,0,tag_object(bignum),FIXNUM_MAX);
|
||||
|
@ -63,6 +63,7 @@ CELL to_cell(CELL x)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* FFI calls this */
|
||||
CELL unbox_cell(void)
|
||||
{
|
||||
|
|
36
native/ffi.c
36
native/ffi.c
|
@ -2,20 +2,32 @@
|
|||
|
||||
void primitive_dlopen(void)
|
||||
{
|
||||
DLL* dll;
|
||||
F_STRING* path;
|
||||
|
||||
maybe_garbage_collection();
|
||||
dpush(tag_object(ffi_dlopen(untag_string(dpop()))));
|
||||
|
||||
path = untag_string(dpop());
|
||||
dll = allot_object(DLL_TYPE,sizeof(DLL));
|
||||
dll->path = tag_object(path);
|
||||
ffi_dlopen(dll);
|
||||
|
||||
dpush(tag_object(dll));
|
||||
}
|
||||
|
||||
void primitive_dlsym(void)
|
||||
{
|
||||
DLL *dll;
|
||||
F_STRING *sym;
|
||||
CELL dll;
|
||||
F_STRING* sym;
|
||||
|
||||
maybe_garbage_collection();
|
||||
|
||||
dll = untag_dll(dpop());
|
||||
dll = dpop();
|
||||
sym = untag_string(dpop());
|
||||
dpush(tag_cell(ffi_dlsym(dll, sym)));
|
||||
|
||||
dpush(tag_cell((CELL)ffi_dlsym(
|
||||
dll == F ? NULL : untag_dll(dll),
|
||||
sym)));
|
||||
}
|
||||
|
||||
void primitive_dlclose(void)
|
||||
|
@ -24,12 +36,6 @@ void primitive_dlclose(void)
|
|||
ffi_dlclose(untag_dll(dpop()));
|
||||
}
|
||||
|
||||
void primitive_dlsym_self(void)
|
||||
{
|
||||
maybe_garbage_collection();
|
||||
dpush(tag_cell(ffi_dlsym(NULL, untag_string(dpop()))));
|
||||
}
|
||||
|
||||
DLL* untag_dll(CELL tagged)
|
||||
{
|
||||
DLL* dll = (DLL*)UNTAG(tagged);
|
||||
|
@ -148,7 +154,13 @@ void primitive_set_alien_1(void)
|
|||
|
||||
void fixup_dll(DLL* dll)
|
||||
{
|
||||
dll->dll = NULL;
|
||||
data_fixup(&dll->path);
|
||||
ffi_dlopen(dll);
|
||||
}
|
||||
|
||||
void collect_dll(DLL* dll)
|
||||
{
|
||||
copy_object(&dll->path);
|
||||
}
|
||||
|
||||
void fixup_alien(ALIEN* alien)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
typedef struct {
|
||||
CELL header;
|
||||
/* tagged string */
|
||||
CELL path;
|
||||
/* OS-specific handle */
|
||||
void* dll;
|
||||
} DLL;
|
||||
|
||||
|
@ -18,13 +21,12 @@ INLINE ALIEN* untag_alien(CELL tagged)
|
|||
return (ALIEN*)UNTAG(tagged);
|
||||
}
|
||||
|
||||
DLL *ffi_dlopen(F_STRING *path);
|
||||
void ffi_dlopen(DLL *dll);
|
||||
void *ffi_dlsym(DLL *dll, F_STRING *symbol);
|
||||
void ffi_dlclose(DLL *dll);
|
||||
|
||||
void primitive_dlopen(void);
|
||||
void primitive_dlsym(void);
|
||||
void primitive_dlsym_self(void);
|
||||
void primitive_dlclose(void);
|
||||
void primitive_alien(void);
|
||||
void primitive_local_alien(void);
|
||||
|
|
|
@ -79,6 +79,12 @@ INLINE void collect_object(CELL scan)
|
|||
case PORT_TYPE:
|
||||
collect_port((F_PORT*)scan);
|
||||
break;
|
||||
case ALIEN_TYPE:
|
||||
collect_alien((ALIEN*)scan);
|
||||
break;
|
||||
case DLL_TYPE:
|
||||
collect_dll((ALIEN*)scan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,6 @@ XT primitives[] = {
|
|||
primitive_address,
|
||||
primitive_dlopen,
|
||||
primitive_dlsym,
|
||||
primitive_dlsym_self,
|
||||
primitive_dlclose,
|
||||
primitive_alien,
|
||||
primitive_local_alien,
|
||||
|
|
|
@ -105,8 +105,10 @@ void relocate_primitive(F_REL* rel, bool relative)
|
|||
|
||||
void relocate_dlsym(F_REL* rel, bool relative)
|
||||
{
|
||||
F_STRING* str = untag_string(get(rel->argument));
|
||||
put(rel->offset,(CELL)ffi_dlsym(NULL,str)
|
||||
F_CONS* cons = untag_cons(get(rel->argument));
|
||||
F_STRING* symbol = untag_string(cons->car);
|
||||
DLL* dll = (cons->cdr == F ? NULL : untag_dll(cons->cdr));
|
||||
put(rel->offset,(CELL)ffi_dlsym(dll,symbol)
|
||||
- (relative ? rel->offset + CELLS : 0));
|
||||
}
|
||||
|
||||
|
@ -141,11 +143,11 @@ INLINE CELL relocate_code_next(CELL relocating)
|
|||
case F_ABSOLUTE_PRIMITIVE:
|
||||
relocate_primitive(rel,false);
|
||||
break;
|
||||
case F_RELATIVE_DLSYM_SELF:
|
||||
case F_RELATIVE_DLSYM:
|
||||
code_fixup(&rel->argument);
|
||||
relocate_dlsym(rel,true);
|
||||
break;
|
||||
case F_ABSOLUTE_DLSYM_SELF:
|
||||
case F_ABSOLUTE_DLSYM:
|
||||
code_fixup(&rel->argument);
|
||||
relocate_dlsym(rel,false);
|
||||
break;
|
||||
|
|
|
@ -11,9 +11,10 @@ typedef enum {
|
|||
/* arg is a primitive number */
|
||||
F_RELATIVE_PRIMITIVE,
|
||||
F_ABSOLUTE_PRIMITIVE,
|
||||
/* arg is an pointer in the literal table holding a tagged string */
|
||||
F_RELATIVE_DLSYM_SELF,
|
||||
F_ABSOLUTE_DLSYM_SELF,
|
||||
/* arg is a pointer in the literal table hodling a cons where the
|
||||
car is a symbol string, and the cdr is a dll */
|
||||
F_RELATIVE_DLSYM,
|
||||
F_ABSOLUTE_DLSYM,
|
||||
/* relocate an address to start of code heap */
|
||||
F_ABSOLUTE
|
||||
} F_RELTYPE;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#include "../factor.h"
|
||||
|
||||
DLL *ffi_dlopen(F_STRING *path)
|
||||
void ffi_dlopen(DLL* dll)
|
||||
{
|
||||
#ifdef FFI
|
||||
void* dllptr;
|
||||
DLL* dll;
|
||||
|
||||
dllptr = dlopen(to_c_string(path), RTLD_LAZY);
|
||||
dllptr = dlopen(to_c_string(untag_string(dll->path)), RTLD_LAZY);
|
||||
|
||||
if(dllptr == NULL)
|
||||
{
|
||||
|
@ -14,9 +13,7 @@ DLL *ffi_dlopen(F_STRING *path)
|
|||
from_c_string(dlerror())));
|
||||
}
|
||||
|
||||
dll = allot_object(DLL_TYPE,sizeof(DLL));
|
||||
dll->dll = dllptr;
|
||||
return dll;
|
||||
#else
|
||||
general_error(ERROR_FFI_DISABLED,F);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue