version 1.65, 2010/12/30 21:46:14
|
version 1.78, 2012/12/31 15:25:18
|
Line 1
|
Line 1
|
\ libcc.fs foreign function interface implemented using a C compiler |
\ libcc.fs foreign function interface implemented using a C compiler |
|
|
\ Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. |
\ Copyright (C) 2006,2007,2008,2009,2010,2011,2012 Free Software Foundation, Inc. |
|
|
\ This file is part of Gforth. |
\ This file is part of Gforth. |
|
|
Line 64
|
Line 64
|
\ wrapper again. This is all done by loading the index file(s?), |
\ wrapper again. This is all done by loading the index file(s?), |
\ which define words for the wrappers in a separate wordlist. |
\ which define words for the wrappers in a separate wordlist. |
|
|
\ The files are built in .../lib/gforth/$VERSION/libcc/ or |
\ The files are built in .../lib/gforth$ARCH/$VERSION/libcc/ or |
\ ~/.gforth/libcc/$HOST/. |
\ ~/.gforth$ARCH/libcc/$HOST/. |
|
|
\ Todo: conversion between function pointers and xts (both directions) |
\ Todo: conversion between function pointers and xts (both directions) |
|
|
Line 217 end-struct list%
|
Line 217 end-struct list%
|
|
|
2variable c-libs \ library names in a string (without "lib") |
2variable c-libs \ library names in a string (without "lib") |
|
|
|
: lib-prefix ( -- addr u ) s" libgf" ; |
|
|
: add-lib ( c-addr u -- ) \ gforth |
: add-lib ( c-addr u -- ) \ gforth |
\G Add library lib@i{string} to the list of libraries, where |
\G Add library lib@i{string} to the list of libraries, where |
\G @i{string} is represented by @i{c-addr u}. |
\G @i{string} is represented by @i{c-addr u}. |
Line 266 defer save-c-prefix-line ( c-addr u -- )
|
Line 268 defer save-c-prefix-line ( c-addr u -- )
|
\G One line of C declarations for the C interface |
\G One line of C declarations for the C interface |
-1 parse save-c-prefix-line ; |
-1 parse save-c-prefix-line ; |
|
|
s" #include <gforth/" version-string s+ s" /libcc.h>" append ( c-addr u ) |
s" #include <gforth" arch-modifier s+ s" /" append version-string append s" /libcc.h>" append ( c-addr u ) |
2dup save-c-prefix-line drop free throw |
2dup save-c-prefix-line drop free throw |
|
|
\ Types (for parsing) |
\ Types (for parsing) |
Line 318 drop
|
Line 320 drop
|
c, 0 c, ; |
c, 0 c, ; |
|
|
: parse-variable-type ( -- addr ) |
: parse-variable-type ( -- addr ) |
c-var c, here |
c-var c, here |
s" a" libcc-type c, 0 c, ; |
s" a" libcc-type c, 0 c, ; |
|
|
|
0 Value is-funptr? |
|
: parse-funptr-types ( "{libcc-type}" "--" "libcc-type" -- addr ) |
|
true to is-funptr? parse-function-types ; |
|
|
: type-letter ( n -- c ) |
: type-letter ( n -- c ) |
chars s" nadrfv" drop + c@ ; |
chars s" nadrfv" drop + c@ ; |
Line 447 create gen-wrapped-types
|
Line 453 create gen-wrapped-types
|
: gen-wrapped-stmt ( pars c-name fp-change1 sp-change1 ret -- fp-change sp-change ) |
: gen-wrapped-stmt ( pars c-name fp-change1 sp-change1 ret -- fp-change sp-change ) |
cells gen-wrapped-types + @ execute ; |
cells gen-wrapped-types + @ execute ; |
|
|
|
: sanitize ( addr u -- ) |
|
bounds ?DO |
|
I c@ |
|
dup 'a' 'z' 1+ within |
|
over 'A' 'Z' 1+ within or |
|
over '0' '9' 1+ within or |
|
swap '_' = or 0= IF '_' I c! THEN |
|
LOOP ; |
|
|
: wrapper-function-name ( addr -- c-addr u ) |
: wrapper-function-name ( addr -- c-addr u ) |
\ addr points to the return type index of a c-function descriptor |
\ addr points to the return type index of a c-function descriptor |
count { r-type } count { d: pars } |
count { r-type } count { d: pars } |
Line 460 create gen-wrapped-types
|
Line 475 create gen-wrapped-types
|
i c@ type-letter front-char |
i c@ type-letter front-char |
loop |
loop |
'_ front-char r-type type-letter front-char assert( dup 0= ) |
'_ front-char r-type type-letter front-char assert( dup 0= ) |
2drop c-addr u ; |
2drop c-addr u 2dup sanitize ; |
|
|
: gen-wrapper-function ( addr -- ) |
: gen-wrapper-function ( addr -- ) |
\ addr points to the return type index of a c-function descriptor |
\ addr points to the return type index of a c-function descriptor |
dup { descriptor } |
dup { descriptor } |
count { ret } count 2dup { d: pars } chars + count { d: c-name } |
count { ret } count 2dup { d: pars } chars + count { d: c-name } |
." void " lib-modulename 2@ type ." _LTX_" descriptor wrapper-function-name 2dup type drop free throw |
." void " |
|
[ lib-suffix s" .la" str= [IF] ] lib-prefix type lib-modulename 2@ type ." _LTX_" [ [THEN] ] |
|
descriptor wrapper-function-name 2dup type drop free throw |
.\" (GFORTH_ARGS)\n" |
.\" (GFORTH_ARGS)\n" |
.\" {\n Cell MAYBE_UNUSED *sp = gforth_SP;\n Float MAYBE_UNUSED *fp = gforth_FP;\n " |
.\" {\n Cell MAYBE_UNUSED *sp = gforth_SP;\n Float MAYBE_UNUSED *fp = gforth_FP;\n " |
|
is-funptr? IF .\" Cell ptr = *sp++;\n " 0 to is-funptr? THEN |
pars c-name 2over count-stacks ret gen-wrapped-stmt .\" ;\n" |
pars c-name 2over count-stacks ret gen-wrapped-stmt .\" ;\n" |
?dup-if |
?dup-if |
." gforth_SP = sp+" .nb .\" ;\n" |
." gforth_SP = sp+" .nb .\" ;\n" |
Line 504 create gen-wrapped-types
|
Line 522 create gen-wrapped-types
|
libcc-named-dir-v 2@ ; |
libcc-named-dir-v 2@ ; |
|
|
: libcc-tmp-dir ( -- c-addr u ) |
: libcc-tmp-dir ( -- c-addr u ) |
s" ~/.gforth/libcc-tmp/" ; |
s" ~/.gforth" arch-modifier s+ s" /libcc-tmp/" s+ ; |
|
|
: prepend-dirname ( c-addr1 u1 c-addr2 u2 -- c-addr3 u3 ) |
: prepend-dirname ( c-addr1 u1 c-addr2 u2 -- c-addr3 u3 ) |
2over s+ 2swap drop free throw ; |
2over s+ 2swap drop free throw ; |
|
|
: open-wrappers ( -- addr|0 ) |
: open-wrappers ( -- addr|0 ) |
lib-filename 2@ s" .la" s+ |
lib-filename 2@ dirname lib-prefix s+ |
|
lib-filename 2@ basename append lib-suffix append |
2dup libcc-named-dir string-prefix? if ( c-addr u ) |
2dup libcc-named-dir string-prefix? if ( c-addr u ) |
\ see if we can open it in the path |
\ see if we can open it in the path |
libcc-named-dir nip /string |
libcc-named-dir nip /string |
Line 605 DEFER compile-wrapper-function ( -- )
|
Line 624 DEFER compile-wrapper-function ( -- )
|
libtool-cc append libtool-flags append s" -module -rpath " s+ ] sliteral |
libtool-cc append libtool-flags append s" -module -rpath " s+ ] sliteral |
lib-filename 2@ dirname replace-rpath s+ s" " append |
lib-filename 2@ dirname replace-rpath s+ s" " append |
lib-filename 2@ append s" .lo -o " append |
lib-filename 2@ append s" .lo -o " append |
lib-filename 2@ append s" .la" append ( c-addr u ) |
lib-filename 2@ dirname append lib-prefix append |
|
lib-filename 2@ basename append s" .la" append ( c-addr u ) |
c-libs 2@ append |
c-libs 2@ append |
\ 2dup type cr |
\ 2dup type cr |
2dup system drop free throw $? abort" libtool link failed" |
2dup system drop free throw $? abort" libtool link failed" |
Line 659 DEFER compile-wrapper-function ( -- )
|
Line 679 DEFER compile-wrapper-function ( -- )
|
\G specified stack effect and calls the C function @code{c-name}. |
\G specified stack effect and calls the C function @code{c-name}. |
['] parse-function-types (c-function) ; |
['] parse-function-types (c-function) ; |
|
|
: c-value ( "forth-name" "c-name" "[---]" "type" -- ) \ gforth |
: c-value ( "forth-name" "c-name" "---" "type" -- ) \ gforth |
\G Define a Forth word @i{forth-name}. @i{Forth-name} has the |
\G Define a Forth word @i{forth-name}. @i{Forth-name} has the |
\G specified stack effect and gives the C value of @code{c-name}. |
\G specified stack effect and gives the C value of @code{c-name}. |
['] parse-value-type (c-function) ; |
['] parse-value-type (c-function) ; |
Line 669 DEFER compile-wrapper-function ( -- )
|
Line 689 DEFER compile-wrapper-function ( -- )
|
\G address of @code{c-name}. |
\G address of @code{c-name}. |
['] parse-variable-type (c-function) ; |
['] parse-variable-type (c-function) ; |
|
|
|
: c-funptr ( "forth-name" "c-typecast" "@{type@}" "---" "type" -- ) \ gforth |
|
\G Define a Forth word @i{forth-name}. @i{Forth-name} has the |
|
\G specified stack effect and calls the C function pointer |
|
\G ptr using the typecast or struct access @code{c-typecast}. |
|
['] parse-funptr-types (c-function) ; |
|
|
: clear-libs ( -- ) \ gforth |
: clear-libs ( -- ) \ gforth |
\G Clear the list of libs |
\G Clear the list of libs |
c-source-file-id @ if |
c-source-file-id @ if |
Line 697 clear-libs
|
Line 723 clear-libs
|
compile-wrapper-function1 ; |
compile-wrapper-function1 ; |
|
|
: init-libcc ( -- ) |
: init-libcc ( -- ) |
s" ~/.gforth/libcc-named/" libcc-named-dir-v 2! |
s" ~/.gforth" arch-modifier s+ s" /libcc-named/" s+ libcc-named-dir-v 2! |
[IFDEF] make-path |
[IFDEF] $init |
libcc-path make-path |
libcc-path $init |
libcc-named-dir libcc-path also-path |
libcc-named-dir libcc-path also-path |
[ s" libccdir" getenv ] sliteral libcc-path also-path |
[ s" libccdir" getenv ] sliteral libcc-path also-path |
[THEN] |
[THEN] |