Annotation of gforth/libffi.fs, revision 1.1
1.1 ! pazsan 1: \ libffi.fs shared library support package 14aug05py
! 2:
! 3: \ Copyright (C) 1995,1996,1997,1998,2000,2003,2005 Free Software Foundation, Inc.
! 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
! 9: \ as published by the Free Software Foundation; either version 2
! 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
! 18: \ along with this program; if not, write to the Free Software
! 19: \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
! 20:
! 21: \ common stuff, same as fflib.fs
! 22:
! 23: Variable libs 0 libs !
! 24: \ links between libraries
! 25: Variable thisproc
! 26: Variable thislib
! 27:
! 28: Variable revdec revdec off
! 29: \ turn revdec on to compile bigFORTH libraries
! 30: Variable revarg revarg off
! 31: \ turn revarg on to compile declarations with reverse arguments
! 32: Variable legacy legacy off
! 33: \ turn legacy on to compile bigFORTH legacy libraries
! 34:
! 35: Vocabulary c-decl
! 36: Vocabulary cb-decl
! 37:
! 38: : @lib ( lib -- )
! 39: \G obtains library handle
! 40: cell+ dup 2 cells + count open-lib
! 41: dup 0= abort" Library not found" swap ! ;
! 42:
! 43: : @proc ( lib addr -- )
! 44: \G obtains symbol address
! 45: cell+ tuck cell+ @ count rot cell+ @
! 46: lib-sym dup 0= abort" Proc not found!" swap ! ;
! 47:
! 48: : proc, ( lib -- )
! 49: \G allocates and initializes proc stub
! 50: \G stub format:
! 51: \G linked list in library
! 52: \G address of proc
! 53: \G ptr to OS name of symbol as counted string
! 54: \G threaded code for invocation
! 55: here dup thisproc !
! 56: swap 2 cells + dup @ A, !
! 57: 0 , 0 A, ;
! 58:
! 59: Defer legacy-proc ' noop IS legacy-proc
! 60:
! 61: : proc: ( lib "name" -- )
! 62: \G Creates a named proc stub
! 63: Create proc, 0 also c-decl
! 64: legacy @ IF legacy-proc THEN
! 65: DOES> ( x1 .. xn -- r )
! 66: 3 cells + >r ;
! 67:
! 68: : library ( "name" "file" -- )
! 69: \G loads library "file" and creates a proc defining word "name"
! 70: \G library format:
! 71: \G linked list of libraries
! 72: \G library handle
! 73: \G linked list of library's procs
! 74: \G OS name of library as counted string
! 75: Create here libs @ A, dup libs !
! 76: 0 , 0 A, parse-name string, @lib
! 77: DOES> ( -- ) dup thislib ! proc: ;
! 78:
! 79: : init-shared-libs ( -- )
! 80: defers 'cold libs
! 81: 0 libs BEGIN @ dup WHILE dup REPEAT drop
! 82: BEGIN dup WHILE >r
! 83: r@ @lib
! 84: r@ 2 cells + BEGIN @ dup WHILE r@ over @proc REPEAT
! 85: drop rdrop
! 86: REPEAT drop ;
! 87:
! 88: ' init-shared-libs IS 'cold
! 89:
! 90: : symbol, ( "c-symbol" -- )
! 91: here thisproc @ 2 cells + ! parse-name s,
! 92: thislib @ thisproc @ @proc ;
! 93:
! 94: \ stuff for libffi
! 95:
! 96: \ libffi uses a parameter array for the input
! 97:
! 98: $20 Value maxargs
! 99:
! 100: Create retbuf 2 cells allot
! 101: Create argbuf maxargs 2* cells allot
! 102: Create argptr maxargs 0 [DO] argbuf [I] 2* cells + A, [LOOP]
! 103:
! 104: \ "forward" when revarg is on
! 105:
! 106: \ : >c+ ( char buf -- buf' ) tuck c! cell+ cell+ ;
! 107: : >i+ ( n buf -- buf' ) tuck ! cell+ cell+ ;
! 108: : >p+ ( addr buf -- buf' ) tuck ! cell+ cell+ ;
! 109: : >d+ ( d buf -- buf' ) dup >r ffi-2! r> cell+ cell+ ;
! 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:
! 115: \ : >c- ( char buf -- buf' ) tuck c! 2 cells - ;
! 116: : >i- ( n buf -- buf' ) 2 cells - tuck ! ;
! 117: : >p- ( addr buf -- buf' ) 2 cells - tuck ! ;
! 118: : >d- ( d buf -- buf' ) 2 cells - dup >r ffi-2! r> ;
! 119: : >sf- ( r buf -- buf' ) 2 cells - dup sf! ;
! 120: : >df- ( r buf -- buf' ) 2 cells - dup df! ;
! 121:
! 122: \ return value
! 123:
! 124: \ : c> ( -- c ) retbuf c@ ;
! 125: : i>x ( -- n ) retbuf @ ;
! 126: : p>x ( -- addr ) retbuf @ ;
! 127: : d>x ( -- d ) retbuf ffi-2@ ;
! 128: : sf>x ( -- r ) retbuf sf@ ;
! 129: : df>x ( -- r ) retbuf df@ ;
! 130:
! 131: wordlist constant cifs
! 132:
! 133: Variable cifbuf $40 allot \ maximum: 64 parameters
! 134: cifbuf cell+ cifbuf !
! 135: Variable args args off
! 136:
! 137: : argtype ( bkxt fwxt type "name" -- )
! 138: Create , , , DOES> 1 args +! ;
! 139:
! 140: : arg@ ( arg -- type pushxt )
! 141: dup @ swap cell+
! 142: revarg @ IF cell+ THEN @ ;
! 143:
! 144: : arg, ( xt -- )
! 145: dup ['] noop = IF drop EXIT THEN compile, ;
! 146:
! 147: : start, ( n -- ) cifbuf cell+ cifbuf !
! 148: revarg @ IF drop 0 ELSE 2* cells THEN argbuf +
! 149: postpone Literal ;
! 150:
! 151: : ffi-call, ( -- lit-cif )
! 152: postpone drop postpone argptr postpone retbuf
! 153: thisproc @ cell+ postpone literal postpone @
! 154: 0 postpone literal here cell -
! 155: postpone ffi-call ;
! 156:
! 157: : cif, ( n -- )
! 158: cifbuf @ c! 1 cifbuf +! ;
! 159:
! 160: : cif@ ( -- addr u )
! 161: cifbuf cell+ cifbuf @ over - ;
! 162:
! 163: : make-cif ( rtype -- addr ) cif,
! 164: cif@ cifs search-wordlist
! 165: IF execute EXIT THEN
! 166: get-current >r cifs set-current
! 167: cif@ nextname Create here >r
! 168: cif@ 1- bounds ?DO I c@ ffi-type , LOOP
! 169: r> cif@ 1- tuck + c@ ffi-type here dup >r 0 ffi-size allot
! 170: ffi-prep-cif throw
! 171: r> r> set-current ;
! 172:
! 173: : decl, ( 0 arg1 .. argn call rtype start -- )
! 174: start, { retxt rtype }
! 175: revdec @ IF 0 >r
! 176: BEGIN dup WHILE >r REPEAT
! 177: BEGIN r> dup WHILE arg@ arg, REPEAT
! 178: ffi-call, retxt compile, postpone EXIT
! 179: BEGIN dup WHILE cif, REPEAT drop
! 180: ELSE 0 >r
! 181: BEGIN dup WHILE arg@ arg, >r REPEAT drop
! 182: ffi-call, retxt compile, postpone EXIT
! 183: BEGIN r> dup WHILE cif, REPEAT drop
! 184: THEN rtype make-cif swap ! here thisproc @ 2 cells + ! ;
! 185:
! 186: : rettype ( endxt n "name" -- )
! 187: Create 2,
! 188: DOES> 2@ args @ decl, symbol, previous revarg off args off ;
! 189:
! 190: also c-decl definitions
! 191:
! 192: : <rev> revarg on ;
! 193:
! 194: ' >i+ ' >i- 6 argtype int
! 195: ' >p+ ' >p- &12 argtype ptr
! 196: ' >d+ ' >d- 8 argtype llong
! 197: ' >sf+ ' >sf- 9 argtype sf
! 198: ' >df+ ' >df- &10 argtype df
! 199:
! 200: ' noop 0 rettype (void)
! 201: ' i>x 6 rettype (int)
! 202: ' p>x &12 rettype (ptr)
! 203: ' d>x 8 rettype (llong)
! 204: ' sf>x 9 rettype (sf)
! 205: ' df>x &10 rettype (fp)
! 206:
! 207: previous definitions
! 208:
! 209: \ legacy support for old library interfaces
! 210: \ interface to old vararg stuff not implemented yet
! 211:
! 212: also c-decl
! 213:
! 214: :noname ( n 0 -- 0 int1 .. intn )
! 215: legacy @ 0< revarg !
! 216: swap 0 ?DO int LOOP (int)
! 217: ; IS legacy-proc
! 218:
! 219: : (int) ( n -- )
! 220: >r ' execute r> 0 ?DO int LOOP (int) ;
! 221: : (void) ( n -- )
! 222: >r ' execute r> 0 ?DO int LOOP (void) ;
! 223: : (float) ( n -- )
! 224: >r ' execute r> 0 ?DO df LOOP (fp) ;
! 225:
! 226: previous
! 227:
! 228: \ callback stuff
! 229:
! 230: 0 [IF]
! 231: Variable callbacks
! 232: \G link between callbacks
! 233:
! 234: : callback ( -- )
! 235: Create 0 ] postpone >r also cb-decl
! 236: DOES>
! 237: Create here >r 0 , callbacks @ A, r@ callbacks !
! 238: swap postpone Literal postpone call , postpone EXIT
! 239: r> dup cell+ cell+ alloc-callback swap !
! 240: DOES> @ ;
! 241:
! 242: : callback; ( 0 xt1 .. xtn -- )
! 243: BEGIN over WHILE compile, REPEAT
! 244: postpone r> postpone execute compile, drop
! 245: postpone EXIT postpone [ previous ; immediate
! 246:
! 247: : va-ret ( xt xt -- )
! 248: Create A, A, immediate
! 249: DOES> 2@ compile, ;
! 250:
! 251: : init-callbacks ( -- )
! 252: defers 'cold callbacks cell -
! 253: BEGIN cell+ @ dup WHILE dup cell+ cell+ alloc-callback over !
! 254: REPEAT drop ;
! 255:
! 256: ' init-callbacks IS 'cold
! 257:
! 258: also cb-decl definitions
! 259:
! 260: \ arguments
! 261:
! 262: ' va-arg-int Alias int
! 263: ' va-arg-float Alias sf
! 264: ' va-arg-double Alias df
! 265: ' va-arg-longlong Alias llong
! 266: ' va-arg-ptr Alias ptr
! 267:
! 268: ' va-return-void ' va-start-void va-ret (void)
! 269: ' va-return-int ' va-start-int va-ret (int)
! 270: ' va-return-float ' va-start-float va-ret (sf)
! 271: ' va-return-double ' va-start-double va-ret (fp)
! 272: ' va-return-longlong ' va-start-longlong va-ret (llong)
! 273: ' va-return-ptr ' va-start-ptr va-ret (ptr)
! 274:
! 275: previous definitions
! 276:
! 277: [THEN]
! 278:
! 279: \ testing stuff
! 280:
! 281: [ifdef] testing
! 282:
! 283: library libc libc.so.6
! 284:
! 285: libc sleep int (int) sleep
! 286: libc open int int ptr (int) open
! 287: libc lseek int llong int (llong) lseek64
! 288: libc read int ptr int (int) read
! 289: libc close int (int) close
! 290:
! 291: library libm libm.so.6
! 292:
! 293: libm fmodf sf sf (sf) fmodf
! 294: libm fmod df df (fp) fmod
! 295:
! 296: \ example for a windows callback
! 297:
! 298: callback wincall (int) int int int int callback;
! 299:
! 300: :noname ( a b c d -- e ) 2drop 2drop 0 ; wincall do_timer
! 301:
! 302: \ test a callback
! 303:
! 304: callback 2:1 (int) int int callback;
! 305:
! 306: : cb-test ( a b -- c )
! 307: cr ." Testing callback"
! 308: cr ." arguments: " .s
! 309: cr ." result " + .s cr ;
! 310: ' cb-test 2:1 c_plus
! 311:
! 312: : test c_plus av-start-int >r >r av-int-r av-int-r av-call-int ;
! 313:
! 314: \ 3 4 test
! 315:
! 316: \ bigFORTH legacy library test
! 317:
! 318: library libX11 libX11.so.6
! 319:
! 320: legacy on
! 321:
! 322: 1 libX11 XOpenDisplay XOpenDisplay ( name -- dpy )
! 323: 5 libX11 XInternAtoms XInternAtoms ( atoms flag count names dpy -- status )
! 324:
! 325: legacy off
! 326:
! 327: [then]
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>