Annotation of gforth/libffi.fs, revision 1.15
1.1 pazsan 1: \ libffi.fs shared library support package 14aug05py
2:
1.15 ! anton 3: \ Copyright (C) 1995,1996,1997,1998,2000,2003,2005,2006,2007 Free Software Foundation, Inc.
1.1 pazsan 4:
5: \ This file is part of Gforth.
6:
7: \ Gforth is free software; you can redistribute it and/or
8: \ modify it under the terms of the GNU General Public License
1.14 anton 9: \ as published by the Free Software Foundation, either version 3
1.1 pazsan 10: \ of the License, or (at your option) any later version.
11:
12: \ This program is distributed in the hope that it will be useful,
13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: \ GNU General Public License for more details.
16:
17: \ You should have received a copy of the GNU General Public License
1.14 anton 18: \ along with this program. If not, see http://www.gnu.org/licenses/.
1.1 pazsan 19:
20: \ common stuff, same as fflib.fs
21:
22: Variable libs 0 libs !
23: \ links between libraries
24: Variable thisproc
25: Variable thislib
26:
27: Variable revdec revdec off
28: \ turn revdec on to compile bigFORTH libraries
29: Variable revarg revarg off
30: \ turn revarg on to compile declarations with reverse arguments
31: Variable legacy legacy off
32: \ turn legacy on to compile bigFORTH legacy libraries
33:
34: Vocabulary c-decl
35: Vocabulary cb-decl
36:
37: : @lib ( lib -- )
38: \G obtains library handle
39: cell+ dup 2 cells + count open-lib
40: dup 0= abort" Library not found" swap ! ;
41:
42: : @proc ( lib addr -- )
43: \G obtains symbol address
44: cell+ tuck cell+ @ count rot cell+ @
45: lib-sym dup 0= abort" Proc not found!" swap ! ;
46:
47: : proc, ( lib -- )
48: \G allocates and initializes proc stub
49: \G stub format:
50: \G linked list in library
51: \G address of proc
52: \G ptr to OS name of symbol as counted string
53: \G threaded code for invocation
54: here dup thisproc !
55: swap 2 cells + dup @ A, !
56: 0 , 0 A, ;
57:
58: Defer legacy-proc ' noop IS legacy-proc
59:
60: : proc: ( lib "name" -- )
61: \G Creates a named proc stub
62: Create proc, 0 also c-decl
63: legacy @ IF legacy-proc THEN
64: DOES> ( x1 .. xn -- r )
65: 3 cells + >r ;
66:
67: : library ( "name" "file" -- )
68: \G loads library "file" and creates a proc defining word "name"
69: \G library format:
70: \G linked list of libraries
71: \G library handle
72: \G linked list of library's procs
73: \G OS name of library as counted string
74: Create here libs @ A, dup libs !
75: 0 , 0 A, parse-name string, @lib
76: DOES> ( -- ) dup thislib ! proc: ;
77:
78: : init-shared-libs ( -- )
79: defers 'cold libs
80: 0 libs BEGIN @ dup WHILE dup REPEAT drop
81: BEGIN dup WHILE >r
82: r@ @lib
83: r@ 2 cells + BEGIN @ dup WHILE r@ over @proc REPEAT
84: drop rdrop
85: REPEAT drop ;
86:
87: ' init-shared-libs IS 'cold
88:
89: : symbol, ( "c-symbol" -- )
90: here thisproc @ 2 cells + ! parse-name s,
91: thislib @ thisproc @ @proc ;
92:
93: \ stuff for libffi
94:
95: \ libffi uses a parameter array for the input
96:
97: $20 Value maxargs
98:
99: Create retbuf 2 cells allot
100: Create argbuf maxargs 2* cells allot
101: Create argptr maxargs 0 [DO] argbuf [I] 2* cells + A, [LOOP]
102:
103: \ "forward" when revarg is on
104:
105: \ : >c+ ( char buf -- buf' ) tuck c! cell+ cell+ ;
1.8 pazsan 106: : >i+ ( n buf -- buf' ) tuck l! cell+ cell+ ;
1.1 pazsan 107: : >p+ ( addr buf -- buf' ) tuck ! cell+ cell+ ;
108: : >d+ ( d buf -- buf' ) dup >r ffi-2! r> cell+ cell+ ;
1.12 pazsan 109: : >dl+ ( d buf -- buf' ) nip dup >r ! r> cell+ cell+ ;
1.1 pazsan 110: : >sf+ ( r buf -- buf' ) dup sf! cell+ cell+ ;
111: : >df+ ( r buf -- buf' ) dup df! cell+ cell+ ;
112:
113: \ "backward" when revarg is off
114:
1.7 pazsan 115: : >i- ( n buf -- buf' ) 2 cells - tuck l! ;
1.1 pazsan 116: : >p- ( addr buf -- buf' ) 2 cells - tuck ! ;
117: : >d- ( d buf -- buf' ) 2 cells - dup >r ffi-2! r> ;
1.12 pazsan 118: : >dl- ( d buf -- buf' ) 2 cells - nip dup >r ! r> ;
1.1 pazsan 119: : >sf- ( r buf -- buf' ) 2 cells - dup sf! ;
120: : >df- ( r buf -- buf' ) 2 cells - dup df! ;
121:
122: \ return value
123:
1.7 pazsan 124: : i>x ( -- n ) retbuf l@ ;
125: : is>x ( -- n ) retbuf sl@ ;
1.1 pazsan 126: : p>x ( -- addr ) retbuf @ ;
1.12 pazsan 127: : dl>x ( -- d ) retbuf @ s>d ;
1.1 pazsan 128: : d>x ( -- d ) retbuf ffi-2@ ;
129: : sf>x ( -- r ) retbuf sf@ ;
130: : df>x ( -- r ) retbuf df@ ;
131:
132: wordlist constant cifs
133:
134: Variable cifbuf $40 allot \ maximum: 64 parameters
1.2 pazsan 135: : cifreset cifbuf cell+ cifbuf ! ;
136: cifreset
1.1 pazsan 137: Variable args args off
138:
139: : argtype ( bkxt fwxt type "name" -- )
140: Create , , , DOES> 1 args +! ;
141:
142: : arg@ ( arg -- type pushxt )
143: dup @ swap cell+
144: revarg @ IF cell+ THEN @ ;
145:
146: : arg, ( xt -- )
147: dup ['] noop = IF drop EXIT THEN compile, ;
148:
149: : start, ( n -- ) cifbuf cell+ cifbuf !
150: revarg @ IF drop 0 ELSE 2* cells THEN argbuf +
151: postpone Literal ;
152:
1.8 pazsan 153: Variable ind-call ind-call off
1.10 pazsan 154: : fptr ind-call on Create here thisproc !
1.8 pazsan 155: 0 , 0 , 0 , 0 also c-decl DOES> cell+ dup cell+ cell+ >r ! ;
156:
1.1 pazsan 157: : ffi-call, ( -- lit-cif )
158: postpone drop postpone argptr postpone retbuf
159: thisproc @ cell+ postpone literal postpone @
160: 0 postpone literal here cell -
161: postpone ffi-call ;
162:
163: : cif, ( n -- )
164: cifbuf @ c! 1 cifbuf +! ;
165:
166: : cif@ ( -- addr u )
167: cifbuf cell+ cifbuf @ over - ;
168:
1.6 pazsan 169: : create-cif ( rtype -- addr ) cif,
1.1 pazsan 170: cif@ cifs search-wordlist
171: IF execute EXIT THEN
172: get-current >r cifs set-current
173: cif@ nextname Create here >r
1.6 pazsan 174: cif@ 1- bounds ?DO I c@ ffi-type , LOOP r>
175: r> set-current ;
176:
177: : make-cif ( rtype -- addr ) create-cif
178: cif@ 1- tuck + c@ ffi-type here 0 ffi-size allot
179: dup >r ffi-prep-cif throw r> ;
1.1 pazsan 180:
181: : decl, ( 0 arg1 .. argn call rtype start -- )
1.2 pazsan 182: start, { retxt rtype } cifreset
1.1 pazsan 183: revdec @ IF 0 >r
184: BEGIN dup WHILE >r REPEAT
185: BEGIN r> dup WHILE arg@ arg, REPEAT
186: ffi-call, retxt compile, postpone EXIT
187: BEGIN dup WHILE cif, REPEAT drop
188: ELSE 0 >r
189: BEGIN dup WHILE arg@ arg, >r REPEAT drop
190: ffi-call, retxt compile, postpone EXIT
191: BEGIN r> dup WHILE cif, REPEAT drop
192: THEN rtype make-cif swap ! here thisproc @ 2 cells + ! ;
193:
194: : rettype ( endxt n "name" -- )
195: Create 2,
1.8 pazsan 196: DOES> 2@ args @ decl, ind-call @ 0= IF symbol, THEN
197: previous revarg off args off ind-call off ;
1.1 pazsan 198:
1.12 pazsan 199: 6 1 cells 4 > 2* - Constant _long
200:
1.1 pazsan 201: also c-decl definitions
202:
203: : <rev> revarg on ;
204:
205: ' >i+ ' >i- 6 argtype int
1.12 pazsan 206: ' >p+ ' >p- _long argtype long
1.1 pazsan 207: ' >p+ ' >p- &12 argtype ptr
208: ' >d+ ' >d- 8 argtype llong
1.12 pazsan 209: ' >dl+ ' >dl- 6 argtype dlong
1.1 pazsan 210: ' >sf+ ' >sf- 9 argtype sf
211: ' >df+ ' >df- &10 argtype df
212:
213: ' noop 0 rettype (void)
1.6 pazsan 214: ' is>x 6 rettype (int)
1.11 pazsan 215: ' i>x 5 rettype (uint)
1.12 pazsan 216: ' p>x _long rettype (long)
1.1 pazsan 217: ' p>x &12 rettype (ptr)
218: ' d>x 8 rettype (llong)
1.12 pazsan 219: ' dl>x 6 rettype (dlong)
1.1 pazsan 220: ' sf>x 9 rettype (sf)
221: ' df>x &10 rettype (fp)
222:
1.3 pazsan 223: : (addr) thisproc @ cell+ postpone Literal postpone @ postpone EXIT
1.4 pazsan 224: drop symbol, previous revarg off args off ;
1.3 pazsan 225:
1.1 pazsan 226: previous definitions
227:
228: \ legacy support for old library interfaces
229: \ interface to old vararg stuff not implemented yet
230:
231: also c-decl
232:
233: :noname ( n 0 -- 0 int1 .. intn )
234: legacy @ 0< revarg !
235: swap 0 ?DO int LOOP (int)
236: ; IS legacy-proc
237:
238: : (int) ( n -- )
239: >r ' execute r> 0 ?DO int LOOP (int) ;
240: : (void) ( n -- )
241: >r ' execute r> 0 ?DO int LOOP (void) ;
242: : (float) ( n -- )
243: >r ' execute r> 0 ?DO df LOOP (fp) ;
244:
245: previous
246:
247: \ callback stuff
248:
249: Variable callbacks
250: \G link between callbacks
251:
1.2 pazsan 252: Variable rtype
253:
1.8 pazsan 254: : alloc-callback ( ip -- addr )
255: rtype @ make-cif here 1 ffi-size allot
256: dup >r ffi-prep-closure throw r> ;
1.2 pazsan 257:
1.1 pazsan 258: : callback ( -- )
1.2 pazsan 259: Create 0 ] postpone >r also cb-decl cifreset
1.1 pazsan 260: DOES>
1.8 pazsan 261: 0 Value -1 cells allot
262: here >r 0 , callbacks @ A, r@ callbacks !
1.1 pazsan 263: swap postpone Literal postpone call , postpone EXIT
1.8 pazsan 264: r@ cell+ cell+ alloc-callback r> ! ;
1.1 pazsan 265:
1.2 pazsan 266: : callback; ( 0 arg1 .. argn -- )
1.1 pazsan 267: BEGIN over WHILE compile, REPEAT
268: postpone r> postpone execute compile, drop
269: postpone EXIT postpone [ previous ; immediate
270:
1.2 pazsan 271: : rettype' ( xt n -- )
272: Create , A, immediate
273: DOES> 2@ rtype ! ;
274: : argtype' ( xt n -- )
275: Create , A, immediate
276: DOES> 2@ cif, ;
1.1 pazsan 277:
278: : init-callbacks ( -- )
279: defers 'cold callbacks cell -
280: BEGIN cell+ @ dup WHILE dup cell+ cell+ alloc-callback over !
281: REPEAT drop ;
282:
283: ' init-callbacks IS 'cold
284:
285: also cb-decl definitions
286:
287: \ arguments
288:
1.2 pazsan 289: ' ffi-arg-int 6 argtype' int
290: ' ffi-arg-float 9 argtype' sf
291: ' ffi-arg-double &10 argtype' df
1.12 pazsan 292: ' ffi-arg-long _long argtype' long
1.2 pazsan 293: ' ffi-arg-longlong 8 argtype' llong
1.12 pazsan 294: ' ffi-arg-dlong 6 argtype' dlong
1.2 pazsan 295: ' ffi-arg-ptr &12 argtype' ptr
296:
297: ' ffi-ret-void 0 rettype' (void)
298: ' ffi-ret-int 6 rettype' (int)
299: ' ffi-ret-float 9 rettype' (sf)
300: ' ffi-ret-double &10 rettype' (fp)
301: ' ffi-ret-longlong 8 rettype' (llong)
1.12 pazsan 302: ' ffi-ret-long _long rettype' (long)
303: ' ffi-ret-dlong _long rettype' (dlong)
1.2 pazsan 304: ' ffi-ret-ptr &12 rettype' (ptr)
1.1 pazsan 305:
306: previous definitions
307:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>