FFI relocation

cvs
Slava Pestov 2004-12-25 23:08:20 +00:00
parent 0deedd48f9
commit 54ff898359
23 changed files with 125 additions and 87 deletions

View File

@ -26,6 +26,7 @@
+ ffi: + ffi:
- figure out how to load an image referring to missing libraries
- is signed -vs- unsigned pointers an issue? - is signed -vs- unsigned pointers an issue?
- bitfields in C structs - bitfields in C structs
- SDL_Rect** type - SDL_Rect** type
@ -44,6 +45,7 @@
+ kernel: + kernel:
- do partial objects cause problems?
- profiler is inaccurate: wrong word on cs - profiler is inaccurate: wrong word on cs
- better i/o scheduler - better i/o scheduler
- remove sbufs - remove sbufs

View File

@ -1,9 +1,15 @@
! DeJong attractor renderer. ! 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 ! "examples/dejong.factor" run-file
@ -19,6 +25,8 @@ USE: sdl-video
USE: namespaces USE: namespaces
USE: math USE: math
USE: kernel USE: kernel
USE: test
USE: compiler
SYMBOL: a SYMBOL: a
SYMBOL: b SYMBOL: b
@ -58,6 +66,6 @@ SYMBOL: d
<event> event-loop <event> event-loop
SDL_Quit SDL_Quit
] with-screen ; ] with-screen ; compiled
dejong [ dejong ] time

View File

@ -1,8 +1,15 @@
! A simple space shooter. ! 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 ! "examples/factoroids.factor" run-file

View File

@ -1,9 +1,15 @@
! Graphical mandelbrot fractal renderer. ! 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 ! "examples/mandel.factor" run-file
@ -50,7 +56,7 @@ USE: test
nip nip nip nip
] [ ] [
pred >r sq dupd + r> iter pred >r sq dupd + r> iter
] ifte ; compiled ] ifte ;
: max-color 360 ; : max-color 360 ;
@ -71,17 +77,16 @@ SYMBOL: center
x-inc get * center get real x-inc get width get 2 / * - + >float x-inc get * center get real x-inc get width get 2 / * - + >float
r> r>
y-inc get * center get imaginary y-inc get height get 2 / * - + >float y-inc get * center get imaginary y-inc get height get 2 / * - + >float
rect> ; compiled rect> ;
: render ( -- ) : render ( -- )
init-mandel
width get height get [ width get height get [
c 0 nb-iter get iter dup 0 = [ c 0 nb-iter get iter dup 0 = [
drop 0 drop 0
] [ ] [
cols get [ vector-length mod ] keep vector-nth cols get [ vector-length mod ] keep vector-nth
] ifte ] ifte
] with-pixels ; ] with-pixels ; compiled
: mandel ( -- ) : mandel ( -- )
640 480 32 SDL_HWSURFACE [ 640 480 32 SDL_HWSURFACE [
@ -89,6 +94,7 @@ SYMBOL: center
0.8 zoom-fact set 0.8 zoom-fact set
-0.65 center set -0.65 center set
100 nb-iter set 100 nb-iter set
init-mandel
[ render ] time [ render ] time
"Done." print flush "Done." print flush
] with-surface ] with-surface

View File

@ -57,14 +57,6 @@ USE: kernel-internals
init-random init-random
default-cli-args default-cli-args
parse-command-line 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 init-smart-terminal
run-user-init ; run-user-init ;
@ -89,6 +81,13 @@ init-error-handler
default-cli-args default-cli-args
parse-command-line 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 "Compiling system..." print
"compile" get [ compile-all ] when "compile" get [ compile-all ] when

View File

@ -197,7 +197,6 @@ vocabularies get [
[ "kernel" | "address" ] [ "kernel" | "address" ]
[ "alien" | "dlopen" ] [ "alien" | "dlopen" ]
[ "alien" | "dlsym" ] [ "alien" | "dlsym" ]
[ "alien" | "dlsym-self" ]
[ "alien" | "dlclose" ] [ "alien" | "dlclose" ]
[ "alien" | "<alien>" ] [ "alien" | "<alien>" ]
[ "alien" | "<local-alien>" ] [ "alien" | "<local-alien>" ]

View File

@ -70,10 +70,15 @@ M: alien = ( obj obj -- ? )
: library ( name -- object ) : library ( name -- object )
dup [ "libraries" get hash ] when ; dup [ "libraries" get hash ] when ;
: load-dll ( library -- dll ) : load-dll ( name -- dll )
"dll" get dup [ #! Higher level wrapper around dlopen primitive.
drop "name" get dlopen dup "dll" set library dup [
] unless ; [
"dll" get dup [
drop "name" get dlopen dup "dll" set
] unless
] bind
] when ;
: add-library ( library name abi -- ) : add-library ( library name abi -- )
"libraries" get [ "libraries" get [
@ -93,9 +98,6 @@ SYMBOL: #box ( move EAX to datastack )
: library-abi ( library -- abi ) : library-abi ( library -- abi )
library [ [ "abi" get ] bind ] [ "cdecl" ] ifte* ; library [ [ "abi" get ] bind ] [ "cdecl" ] ifte* ;
: alien-symbol ( function library -- address )
library [ [ load-dll ] bind dlsym ] [ dlsym-self ] ifte* ;
SYMBOL: #alien-invoke SYMBOL: #alien-invoke
! These are set in the #alien-invoke dataflow IR node. ! These are set in the #alien-invoke dataflow IR node.
@ -149,7 +151,7 @@ SYMBOL: alien-parameters
: linearize-alien ( node -- ) : linearize-alien ( node -- )
dup linearize-parameters >r dup linearize-parameters >r
dup [ node-param get ] bind #c-call swons , 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 r> swap [ drop ] [ #cleanup swons , ] ifte
linearize-returns ; linearize-returns ;

View File

@ -34,12 +34,12 @@ USE: words
USE: lists USE: lists
USE: math USE: math
: DS ( -- address ) "ds" dlsym-self ; : DS ( -- address ) "ds" f dlsym ;
: absolute-ds ( -- ) : absolute-ds ( -- )
#! Add an entry to the relocation table for the 32-bit #! Add an entry to the relocation table for the 32-bit
#! immediate just compiled. #! immediate just compiled.
"ds" f rel-dlsym-self ; "ds" f f rel-dlsym ;
: POP-DS ( -- ) : POP-DS ( -- )
#! Pop datastack to EAX. #! Pop datastack to EAX.
@ -129,17 +129,17 @@ USE: math
] "generator" set-word-property ] "generator" set-word-property
#c-call [ #c-call [
uncons alien-symbol CALL JUMP-FIXUP uncons load-dll 2dup dlsym CALL JUMP-FIXUP t rel-dlsym
] "generator" set-word-property ] "generator" set-word-property
#unbox [ #unbox [
dlsym-self CALL JUMP-FIXUP dup f dlsym CALL JUMP-FIXUP f t rel-dlsym
EAX PUSH-R EAX PUSH-R
] "generator" set-word-property ] "generator" set-word-property
#box [ #box [
EAX PUSH-R EAX PUSH-R
dlsym-self CALL JUMP-FIXUP dup f dlsym CALL JUMP-FIXUP f t rel-dlsym
4 ESP R+I 4 ESP R+I
] "generator" set-word-property ] "generator" set-word-property

View File

@ -52,9 +52,9 @@ SYMBOL: relocation-table
#! If flag is true; relative. #! If flag is true; relative.
over primitive? [ rel-primitive ] [ 2drop ] ifte ; over primitive? [ rel-primitive ] [ 2drop ] ifte ;
: rel-dlsym-self ( name rel/abs -- ) : rel-dlsym ( name dll rel/abs -- )
#! If flag is true; relative. #! If flag is true; relative.
2 3 ? rel, relocating intern-literal rel, ; 2 3 ? rel, relocating cons intern-literal rel, ;
: rel-address ( -- ) : rel-address ( -- )
#! Relocate address just compiled. #! Relocate address just compiled.

View File

@ -61,19 +61,19 @@ USE: kernel
nip real succ nip real succ
] [ ] [
nip >rect succ rect> nip >rect succ rect>
] ifte ; ] ifte ; inline
: 2times<= ( #{ a b } #{ c d } -- ? ) : 2times<= ( #{ a b } #{ c d } -- ? )
swap real swap real <= ; swap real swap real <= ; inline
: (2times) ( limit n quot -- ) : (2times) ( limit n quot -- )
pick pick 2times<= [ pick pick 2times<= [
3drop 3drop
] [ ] [
rot pick dupd 2times-succ pick 3slip (2times) rot pick dupd 2times-succ pick 3slip (2times)
] ifte ; ] ifte ; inline
: 2times* ( #{ w h } quot -- ) : 2times* ( #{ w h } quot -- )
#! Apply a quotation to each pair of complex numbers #! Apply a quotation to each pair of complex numbers
#! #{ a b } such that a < w, b < h. #! #{ a b } such that a < w, b < h.
0 swap (2times) ; 0 swap (2times) ; inline

View File

@ -192,8 +192,7 @@ USE: words
[ set-literal-top " ptr -- " [ [ integer ] [ ] ] ] [ set-literal-top " ptr -- " [ [ integer ] [ ] ] ]
[ address " obj -- ptr " [ [ object ] [ integer ] ] ] [ address " obj -- ptr " [ [ object ] [ integer ] ] ]
[ dlopen " path -- dll " [ [ string ] [ dll ] ] ] [ dlopen " path -- dll " [ [ string ] [ dll ] ] ]
[ dlsym " name dll -- ptr " [ [ string dll ] [ integer ] ] ] [ dlsym " name dll -- ptr " [ [ string object ] [ integer ] ] ]
[ dlsym-self " name -- ptr " [ [ string ] [ integer ] ] ]
[ dlclose " dll -- " [ [ dll ] [ ] ] ] [ dlclose " dll -- " [ [ dll ] [ ] ] ]
[ <alien> " ptr -- alien " [ [ integer ] [ alien ] ] ] [ <alien> " ptr -- alien " [ [ integer ] [ alien ] ] ]
[ <local-alien> " len -- alien " [ [ integer ] [ alien ] ] ] [ <local-alien> " len -- alien " [ [ integer ] [ alien ] ] ]

View File

@ -53,7 +53,7 @@ SYMBOL: surface
>r 3dup bpp set height set width set r> >r 3dup bpp set height set width set r>
SDL_SetVideoMode surface set SDL_SetVideoMode surface set
r> call SDL_Quit r> call SDL_Quit
] with-scope ; ] with-scope ; inline
: rgba ( r g b a -- n ) : rgba ( r g b a -- n )
swap 8 shift bitor swap 8 shift bitor
@ -71,20 +71,21 @@ SYMBOL: surface
: pixel-step ( quot #{ x y } -- ) : pixel-step ( quot #{ x y } -- )
tuck >r call >r surface get r> r> >rect rot pixelColor ; tuck >r call >r surface get r> r> >rect rot pixelColor ;
inline
: with-pixels ( w h quot -- ) : 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 -- ) : with-surface ( quot -- )
#! Execute a quotation, locking the current surface if it #! Execute a quotation, locking the current surface if it
#! is required (eg, hardware surface). #! is required (eg, hardware surface).
[ [
surface get dup must-lock-surface? [ surface get dup must-lock-surface? [
dup SDL_LockSurface slip dup SDL_UnlockSurface dup SDL_LockSurface drop slip dup SDL_UnlockSurface
] [ ] [
slip slip
] ifte SDL_Flip drop ] ifte SDL_Flip drop
] with-scope ; ] with-scope ; inline
: event-loop ( event -- ) : event-loop ( event -- )
dup SDL_WaitEvent 1 = [ dup SDL_WaitEvent 1 = [

View File

@ -153,7 +153,7 @@ END-STRUCT
"bool" "sdl" "SDL_FillRect" "bool" "sdl" "SDL_FillRect"
[ "surface*" "rect*" "uint" ] alien-invoke ; [ "surface*" "rect*" "uint" ] alien-invoke ;
: SDL_LockSurface ( surface -- ) : SDL_LockSurface ( surface -- ? )
"bool" "sdl" "SDL_LockSurface" [ "surface*" ] alien-invoke ; "bool" "sdl" "SDL_LockSurface" [ "surface*" ] alien-invoke ;
: SDL_UnlockSurface ( surface -- ) : SDL_UnlockSurface ( surface -- )

View File

@ -196,7 +196,7 @@ SYMBOL: sym-test
[ [ 1 | 1 ] ] [ [ get ] infer old-effect ] unit-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 ! Type inference

View File

@ -50,7 +50,7 @@ USE: strings
: words ( vocab -- list ) : words ( vocab -- list )
#! Push a list of all words in a vocabulary. #! Push a list of all words in a vocabulary.
#! Filter empty slots. #! Filter empty slots.
vocab hash-values [ ] subset word-sort ; vocab dup [ hash-values [ ] subset word-sort ] when ;
: each-word ( quot -- ) : each-word ( quot -- )
#! Apply a quotation to each word in the image. #! Apply a quotation to each word in the image.
@ -100,20 +100,17 @@ USE: strings
: init-search-path ( -- ) : init-search-path ( -- )
! For files ! For files
"scratchpad" "file-in" set "scratchpad" "file-in" set
[ "builtins" "syntax" "scratchpad" ] "file-use" set [ "syntax" "scratchpad" ] "file-use" set
! For interactive ! For interactive
"scratchpad" "in" set "scratchpad" "in" set
[ [
"user"
"arithmetic"
"builtins"
"compiler" "compiler"
"debugger" "debugger"
"errors" "errors"
"files" "files"
"generic"
"hashtables" "hashtables"
"inference" "inference"
"inferior"
"interpreter" "interpreter"
"jedit" "jedit"
"kernel" "kernel"
@ -125,7 +122,6 @@ USE: strings
"prettyprint" "prettyprint"
"processes" "processes"
"profiler" "profiler"
"stack"
"streams" "streams"
"stdio" "stdio"
"strings" "strings"
@ -134,7 +130,6 @@ USE: strings
"threads" "threads"
"unparser" "unparser"
"vectors" "vectors"
"vocabularies"
"words" "words"
"scratchpad" "scratchpad"
] "use" set ; ] "use" set ;

View File

@ -50,7 +50,7 @@ CELL to_cell(CELL x)
return (CELL)fixnum; return (CELL)fixnum;
break; break;
case BIGNUM_TYPE: case BIGNUM_TYPE:
bignum = to_bignum(dpop()); bignum = to_bignum(x);
if(BIGNUM_NEGATIVE_P(bignum)) if(BIGNUM_NEGATIVE_P(bignum))
{ {
range_error(F,0,tag_object(bignum),FIXNUM_MAX); range_error(F,0,tag_object(bignum),FIXNUM_MAX);
@ -63,6 +63,7 @@ CELL to_cell(CELL x)
return 0; return 0;
} }
} }
/* FFI calls this */ /* FFI calls this */
CELL unbox_cell(void) CELL unbox_cell(void)
{ {

View File

@ -2,20 +2,32 @@
void primitive_dlopen(void) void primitive_dlopen(void)
{ {
DLL* dll;
F_STRING* path;
maybe_garbage_collection(); 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) void primitive_dlsym(void)
{ {
DLL *dll; CELL dll;
F_STRING *sym; F_STRING* sym;
maybe_garbage_collection(); maybe_garbage_collection();
dll = untag_dll(dpop()); dll = dpop();
sym = untag_string(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) void primitive_dlclose(void)
@ -24,12 +36,6 @@ void primitive_dlclose(void)
ffi_dlclose(untag_dll(dpop())); 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* untag_dll(CELL tagged)
{ {
DLL* dll = (DLL*)UNTAG(tagged); DLL* dll = (DLL*)UNTAG(tagged);
@ -148,7 +154,13 @@ void primitive_set_alien_1(void)
void fixup_dll(DLL* dll) 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) void fixup_alien(ALIEN* alien)

View File

@ -1,5 +1,8 @@
typedef struct { typedef struct {
CELL header; CELL header;
/* tagged string */
CELL path;
/* OS-specific handle */
void* dll; void* dll;
} DLL; } DLL;
@ -18,13 +21,12 @@ INLINE ALIEN* untag_alien(CELL tagged)
return (ALIEN*)UNTAG(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_dlsym(DLL *dll, F_STRING *symbol);
void ffi_dlclose(DLL *dll); void ffi_dlclose(DLL *dll);
void primitive_dlopen(void); void primitive_dlopen(void);
void primitive_dlsym(void); void primitive_dlsym(void);
void primitive_dlsym_self(void);
void primitive_dlclose(void); void primitive_dlclose(void);
void primitive_alien(void); void primitive_alien(void);
void primitive_local_alien(void); void primitive_local_alien(void);

View File

@ -79,6 +79,12 @@ INLINE void collect_object(CELL scan)
case PORT_TYPE: case PORT_TYPE:
collect_port((F_PORT*)scan); collect_port((F_PORT*)scan);
break; break;
case ALIEN_TYPE:
collect_alien((ALIEN*)scan);
break;
case DLL_TYPE:
collect_dll((ALIEN*)scan);
break;
} }
} }

View File

@ -150,7 +150,6 @@ XT primitives[] = {
primitive_address, primitive_address,
primitive_dlopen, primitive_dlopen,
primitive_dlsym, primitive_dlsym,
primitive_dlsym_self,
primitive_dlclose, primitive_dlclose,
primitive_alien, primitive_alien,
primitive_local_alien, primitive_local_alien,

View File

@ -105,8 +105,10 @@ void relocate_primitive(F_REL* rel, bool relative)
void relocate_dlsym(F_REL* rel, bool relative) void relocate_dlsym(F_REL* rel, bool relative)
{ {
F_STRING* str = untag_string(get(rel->argument)); F_CONS* cons = untag_cons(get(rel->argument));
put(rel->offset,(CELL)ffi_dlsym(NULL,str) 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)); - (relative ? rel->offset + CELLS : 0));
} }
@ -141,11 +143,11 @@ INLINE CELL relocate_code_next(CELL relocating)
case F_ABSOLUTE_PRIMITIVE: case F_ABSOLUTE_PRIMITIVE:
relocate_primitive(rel,false); relocate_primitive(rel,false);
break; break;
case F_RELATIVE_DLSYM_SELF: case F_RELATIVE_DLSYM:
code_fixup(&rel->argument); code_fixup(&rel->argument);
relocate_dlsym(rel,true); relocate_dlsym(rel,true);
break; break;
case F_ABSOLUTE_DLSYM_SELF: case F_ABSOLUTE_DLSYM:
code_fixup(&rel->argument); code_fixup(&rel->argument);
relocate_dlsym(rel,false); relocate_dlsym(rel,false);
break; break;

View File

@ -11,9 +11,10 @@ typedef enum {
/* arg is a primitive number */ /* arg is a primitive number */
F_RELATIVE_PRIMITIVE, F_RELATIVE_PRIMITIVE,
F_ABSOLUTE_PRIMITIVE, F_ABSOLUTE_PRIMITIVE,
/* arg is an pointer in the literal table holding a tagged string */ /* arg is a pointer in the literal table hodling a cons where the
F_RELATIVE_DLSYM_SELF, car is a symbol string, and the cdr is a dll */
F_ABSOLUTE_DLSYM_SELF, F_RELATIVE_DLSYM,
F_ABSOLUTE_DLSYM,
/* relocate an address to start of code heap */ /* relocate an address to start of code heap */
F_ABSOLUTE F_ABSOLUTE
} F_RELTYPE; } F_RELTYPE;

View File

@ -1,12 +1,11 @@
#include "../factor.h" #include "../factor.h"
DLL *ffi_dlopen(F_STRING *path) void ffi_dlopen(DLL* dll)
{ {
#ifdef FFI #ifdef FFI
void* dllptr; 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) if(dllptr == NULL)
{ {
@ -14,9 +13,7 @@ DLL *ffi_dlopen(F_STRING *path)
from_c_string(dlerror()))); from_c_string(dlerror())));
} }
dll = allot_object(DLL_TYPE,sizeof(DLL));
dll->dll = dllptr; dll->dll = dllptr;
return dll;
#else #else
general_error(ERROR_FFI_DISABLED,F); general_error(ERROR_FFI_DISABLED,F);
#endif #endif