FFI relocation
parent
0deedd48f9
commit
54ff898359
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>" ]
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ] ] ]
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
|
@ -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 -- )
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
36
native/ffi.c
36
native/ffi.c
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue