From c72a9195260f2b3cb80fc19d9e39f45ea1201716 Mon Sep 17 00:00:00 2001 From: slava Date: Sat, 9 Sep 2006 05:19:43 +0000 Subject: [PATCH] AMD64 alien-indirect support; document alien-indirect --- doc/handbook/alien.facts | 2 ++ library/compiler/alien/alien-callback.facts | 2 +- library/compiler/alien/alien-indirect.facts | 13 +++++++++++++ library/compiler/alien/alien-invoke.facts | 2 +- library/compiler/amd64/alien.factor | 6 +++++- library/compiler/load.factor | 1 + library/compiler/x86/architecture.factor | 3 ++- 7 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 library/compiler/alien/alien-indirect.facts diff --git a/doc/handbook/alien.facts b/doc/handbook/alien.facts index a0046d8963..303baa6336 100644 --- a/doc/handbook/alien.facts +++ b/doc/handbook/alien.facts @@ -30,6 +30,8 @@ ARTICLE: "alien-invoke" "Calling C from Factor" $terpri "The above parsing words create word definitions which call a lower-level word; you can use it directly, too:" { $subsection alien-invoke } +"Sometimes it is necessary to invoke a C function pointer, rather than a named C function:" +{ $subsection alien-indirect } "There are some details concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-types" } "." ; ARTICLE: "alien-callback" "Calling Factor from C" diff --git a/library/compiler/alien/alien-callback.facts b/library/compiler/alien/alien-callback.facts index 159c75cfe3..316f5fbc2d 100644 --- a/library/compiler/alien/alien-callback.facts +++ b/library/compiler/alien/alien-callback.facts @@ -21,4 +21,4 @@ HELP: alien-callback } } { $errors "Throws an " { $link alien-callback-error } " if the word calling " { $link alien-callback } " is not compiled." } -{ $see-also alien-invoke } ; +{ $see-also alien-invoke alien-indirect } ; diff --git a/library/compiler/alien/alien-indirect.facts b/library/compiler/alien/alien-indirect.facts new file mode 100644 index 0000000000..084138f55a --- /dev/null +++ b/library/compiler/alien/alien-indirect.facts @@ -0,0 +1,13 @@ +IN: alien +USING: errors help ; + +HELP: alien-indirect-error +{ $error-description "Thrown when " { $link alien-indirect } " is called in the interpreter. Words using " { $link alien-indirect } " must be compiled first, and all three inputs to " { $link alien-indirect } " must be literals." } ; + +HELP: alien-indirect +{ $values { "funcptr" "a C function pointer" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } } +{ $description + "Invokes a C function pointer passed on the data stack. Input parameters are taken from the data stack following the function pointer, and the return value is pushed on the data stack after the function returns. A return type of " { $snippet "\"void\"" } " indicates that no value is to be expected." +} +{ $errors "Throws an " { $link alien-indirect-error } " if the word calling " { $link alien-indirect } " is not compiled." } +{ $see-also alien-invoke alien-callback } ; diff --git a/library/compiler/alien/alien-invoke.facts b/library/compiler/alien/alien-invoke.facts index b9d715c13b..8dfcc211bf 100644 --- a/library/compiler/alien/alien-invoke.facts +++ b/library/compiler/alien/alien-invoke.facts @@ -8,7 +8,7 @@ HELP: alien-invoke { $values { "return" "a C return type" } { "library" "a logical library name" } { "function" "a C function name" } { "parameters" "a sequence of C parameter types" } } { $description "Calls a C library function with the given name. Input parameters are taken from the data stack, and the return value is pushed on the data stack after the function returns. A return type of " { $snippet "\"void\"" } " indicates that no value is to be expected." } { $errors "Throws an " { $link alien-invoke-error } " if the word calling " { $link alien-invoke } " is not compiled." } -{ $see-also alien-callback } ; +{ $see-also alien-indirect alien-callback } ; HELP: define-c-word { $values { "return" "a C return type" } { "library" "a logical library name" } { "function" "a C function name" } { "parameters" "a sequence of C parameter types" } } diff --git a/library/compiler/amd64/alien.factor b/library/compiler/amd64/alien.factor index 8aaec60244..64490c1cbd 100644 --- a/library/compiler/amd64/alien.factor +++ b/library/compiler/amd64/alien.factor @@ -48,8 +48,12 @@ M: stack-params %freg>stack : %alien-invoke ( symbol dll -- ) reset-sse compile-c-call ; +: alien-temp ( quot -- ) + 0 R11 MOV "alien_temp" f rel-absolute-cell rel-dlsym + R11 swap call ; inline + : %alien-indirect ( -- ) - "unbox_alien" f %alien-invoke RAX CALL ; + reset-sse [ CALL ] alien-temp ; : %alien-callback ( quot -- ) RDI load-indirect "run_callback" f compile-c-call ; diff --git a/library/compiler/load.factor b/library/compiler/load.factor index 14c7dbc095..207e7a4f41 100644 --- a/library/compiler/load.factor +++ b/library/compiler/load.factor @@ -33,6 +33,7 @@ PROVIDE: library/compiler { "alien/syntax.factor" "alien/alien-callback.facts" + "alien/alien-indirect.facts" "alien/alien-invoke.facts" "alien/aliens.facts" "alien/c-types.facts" diff --git a/library/compiler/x86/architecture.factor b/library/compiler/x86/architecture.factor index 73c6ab53a7..76e7a8fc04 100644 --- a/library/compiler/x86/architecture.factor +++ b/library/compiler/x86/architecture.factor @@ -30,10 +30,11 @@ M: cs-loc v>operand cs-loc-n cs-reg reg-stack ; : alien-temp ( quot -- ) 0 [] swap call "alien_temp" f rel-absolute rel-dlsym ; + inline : %prepare-alien-indirect ( -- ) "unbox_alien" f %alien-invoke - [ EAX MOV ] alien-temp ; + [ T{ int-regs } return-reg MOV ] alien-temp ; : %alien-indirect ( -- ) [ CALL ] alien-temp ;