VM: always use undecorated names when loading ffi functions

For win32, Factor tries four different function names when loading
stdcall and fastcall functions, in case decorated names are used in the
dll. It seems to not be necessary because a dll meant for 3rd party use
will always export undecorated
names (http://blogs.msdn.com/b/oldnewthing/archive/2004/01/12/57833.aspx).
db4
Björn Lindqvist 2015-09-01 14:40:32 +02:00
parent da3de080ee
commit bc7f9ee669
6 changed files with 56 additions and 72 deletions

View File

@ -116,7 +116,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
rc $< rc $<
libfactor-ffi-test.dll: vm/ffi_test.obj libfactor-ffi-test.dll: vm/ffi_test.obj
link $(LINK_FLAGS) /out:libfactor-ffi-test.dll /dll vm/ffi_test.obj link $(LINK_FLAGS) /out:libfactor-ffi-test.dll /dll /def:vm\ffi_test.def vm/ffi_test.obj
factor.dll.lib: $(DLL_OBJS) factor.dll.lib: $(DLL_OBJS)
link $(LINK_FLAGS) /implib:factor.dll.lib /out:factor.dll /dll $(DLL_OBJS) link $(LINK_FLAGS) /implib:factor.dll.lib /out:factor.dll /dll $(DLL_OBJS)
@ -160,6 +160,9 @@ clean:
if exist factor.exe del factor.exe if exist factor.exe del factor.exe
if exist factor.dll del factor.dll if exist factor.dll del factor.dll
if exist factor.dll.lib del factor.dll.lib if exist factor.dll.lib del factor.dll.lib
if exist libfactor-ffi-test.dll del libfactor-ffi-test.dll
if exist libfactor-ffi-test.exp del libfactor-ffi-test.exp
if exist libfactor-ffi-test.lib del libfactor-ffi-test.lib
.PHONY: all default x86-32 x86-64 x86-32-vista x86-64-vista clean .PHONY: all default x86-32 x86-64 x86-32-vista x86-64-vista clean

View File

@ -1,5 +1,6 @@
USING: help.markup help.syntax literals make multiline sequences USING: alien alien.libraries compiler.cfg.builder help.markup
stack-checker.alien ; help.syntax literals make multiline sequences stack-checker.alien
strings ;
IN: compiler.cfg.builder.alien IN: compiler.cfg.builder.alien
<< <<
@ -16,11 +17,29 @@ USING: compiler.cfg.builder.alien make prettyprint ;
; ;
>> >>
HELP: caller-linkage
{ $values
{ "params" alien-node-params }
{ "symbol" string }
{ "dll" dll }
}
{ $description "This word gets the name and library to use when linking to a function in a dynamically loaded dll. It is assumed that the library exports the undecorated name, regardless of calling convention." } ;
HELP: caller-return HELP: caller-return
{ $values { "params" alien-node-params } } { $values { "params" alien-node-params } }
{ $description "If the last alien call returns a value, then this word will emit an instruction to the current sequence being constructed by " { $link make } " that boxes it." } { $description "If the last alien call returns a value, then this word will emit an instruction to the current sequence being constructed by " { $link make } " that boxes it." }
{ $examples { $unchecked-example $[ ex-caller-return ] } } ; { $examples { $unchecked-example $[ ex-caller-return ] } } ;
HELP: check-dlsym
{ $values { "symbol" string } { "library" library } }
{ $description "Checks that a symbol with the given name exists in the given library. Throws an error if not." } ;
HELP: unbox-parameters HELP: unbox-parameters
{ $values { "parameters" sequence } { "vregs" sequence } { "reps" sequence } } { $values { "parameters" sequence } { "vregs" sequence } { "reps" sequence } }
{ $description "Unboxes a sequence of parameters to send to an ffi function." } ; { $description "Unboxes a sequence of parameters to send to an ffi function." } ;
ARTICLE: "compiler.cfg.builder.alien"
"CFG node emitter for alien nodes"
"The " { $vocab-link "compiler.cfg.builder.alien" } " vocab implements " { $link emit-node } " methods for alien nodes." ;
ABOUT: "compiler.cfg.builder.alien"

View File

@ -59,38 +59,21 @@ IN: compiler.cfg.builder.alien
[ stack-params get ] dip [ return>> ] [ abi>> ] bi stack-cleanup [ stack-params get ] dip [ return>> ] [ abi>> ] bi stack-cleanup
stack-params get ; stack-params get ;
GENERIC# dlsym-valid? 1 ( symbols dll -- ? ) : check-dlsym ( symbol library -- )
M: string dlsym-valid? dlsym ;
M: array dlsym-valid? '[ _ dlsym ] any? ;
: check-dlsym ( symbols library -- )
{ {
{ [ dup library-dll dll-valid? not ] [ { [ dup library-dll dll-valid? not ] [
[ library-dll dll-path ] [ dlerror>> ] bi [ library-dll dll-path ] [ dlerror>> ] bi
cfg get word>> no-such-library-error drop cfg get word>> no-such-library-error drop
] } ] }
{ [ 2dup library-dll dlsym-valid? not ] [ { [ 2dup library-dll dlsym not ] [
drop dlerror cfg get word>> no-such-symbol-error drop dlerror cfg get word>> no-such-symbol-error
] } ] }
[ 2drop ] [ 2drop ]
} cond ; } cond ;
: decorated-symbol ( params -- symbols ) : caller-linkage ( params -- symbol dll )
[ function>> ] [ parameters>> [ stack-size ] map-sum number>string ] bi [ function>> ] [ library>> lookup-library ] bi
{ 2dup check-dlsym library-dll ;
[ drop ]
[ "@" glue ]
[ "@" glue "_" prepend ]
[ "@" glue "@" prepend ]
} 2cleave
4array ;
: caller-linkage ( params -- symbols dll )
[ dup abi>> callee-cleanup? [ decorated-symbol ] [ function>> ] if ]
[ library>> lookup-library ]
bi 2dup check-dlsym library-dll ;
: caller-return ( params -- ) : caller-return ( params -- )
return>> [ ] [ return>> [ ] [
@ -186,10 +169,7 @@ M: #alien-assembly emit-node ( node -- )
M: #alien-callback emit-node M: #alien-callback emit-node
dup params>> xt>> dup dup params>> xt>> dup
[ [
needs-frame-pointer needs-frame-pointer begin-word
begin-word
{ {
[ params>> callee-parameters ##callback-inputs, ] [ params>> callee-parameters ##callback-inputs, ]
[ params>> box-parameters ] [ params>> box-parameters ]
@ -197,6 +177,5 @@ M: #alien-callback emit-node
[ params>> emit-callback-return ] [ params>> emit-callback-return ]
[ params>> callback-stack-cleanup ] [ params>> callback-stack-cleanup ]
} cleave } cleave
basic-block get [ end-word ] when basic-block get [ end-word ] when
] with-cfg-builder ; ] with-cfg-builder ;

View File

@ -718,46 +718,32 @@ mingw? [
: fastcall-struct-return-iii-indirect ( x y z ptr -- result ) : fastcall-struct-return-iii-indirect ( x y z ptr -- result )
test-struct-11 { int int int } fastcall alien-indirect ; test-struct-11 { int int int } fastcall alien-indirect ;
: win32? ( -- ? ) os windows? cpu x86.32? and ;
[ 8 ] [ [ 8 ] [
3 4 3 4 &: ffi_test_50 fastcall-ii-indirect
win32? [ &: @ffi_test_50@8 ] [ &: ffi_test_50 ] if
fastcall-ii-indirect
] unit-test ] unit-test
[ 13 ] [ [ 13 ] [
3 4 5 3 4 5 &: ffi_test_51 fastcall-iii-indirect
win32? [ &: @ffi_test_51@12 ] [ &: ffi_test_51 ] if
fastcall-iii-indirect
] unit-test ] unit-test
mingw? [ mingw? [
[ 13 ] [ [ 13 ] [
3 4.0 5 3 4.0 5 &: ffi_test_52 fastcall-ifi-indirect
win32? [ &: @ffi_test_52@12 ] [ &: ffi_test_52 ] if
fastcall-ifi-indirect
] unit-test ] unit-test
[ 19 ] [ [ 19 ] [
3 4.0 5 6 3 4.0 5 6 &: ffi_test_53 fastcall-ifii-indirect
win32? [ &: @ffi_test_53@16 ] [ &: ffi_test_53 ] if
fastcall-ifii-indirect
] unit-test ] unit-test
] unless ] unless
[ S{ test-struct-11 f 7 -1 } ] [ S{ test-struct-11 f 7 -1 } ]
[ [
3 4 3 4 &: ffi_test_57 fastcall-struct-return-ii-indirect
win32? [ &: @ffi_test_57@8 ] [ &: ffi_test_57 ] if
fastcall-struct-return-ii-indirect
] unit-test ] unit-test
[ S{ test-struct-11 f 7 -3 } ] [ S{ test-struct-11 f 7 -3 } ]
[ [
3 4 7 3 4 7 &: ffi_test_58 fastcall-struct-return-iii-indirect
win32? [ &: @ffi_test_58@12 ] [ &: ffi_test_58 ] if
fastcall-struct-return-iii-indirect
] unit-test ] unit-test
: fastcall-ii-callback ( -- ptr ) : fastcall-ii-callback ( -- ptr )

View File

@ -156,28 +156,11 @@ cell factor_vm::compute_dlsym_address(array* parameters,
if (d != NULL && !d->handle) if (d != NULL && !d->handle)
return undef; return undef;
cell type = TAG(symbol); FACTOR_ASSERT(TAG(symbol) == BYTE_ARRAY_TYPE);
if (type == BYTE_ARRAY_TYPE) { symbol_char* name = alien_offset(symbol);
cell sym = ffi_dlsym_raw(d, name);
symbol_char* name = alien_offset(symbol); sym = toc ? FUNCTION_TOC_POINTER(sym) : FUNCTION_CODE_POINTER(sym);
cell sym = ffi_dlsym_raw(d, name); return sym ? sym : undef;
sym = toc ? FUNCTION_TOC_POINTER(sym) : FUNCTION_CODE_POINTER(sym);
return sym ? sym : undef;
} else if (type == ARRAY_TYPE) {
array* names = untag<array>(symbol);
for (cell i = 0; i < array_capacity(names); i++) {
symbol_char* name = alien_offset(array_nth(names, i));
cell sym = ffi_dlsym_raw(d, name);
sym = toc ? FUNCTION_TOC_POINTER(sym) : FUNCTION_CODE_POINTER(sym);
if (sym)
return sym;
}
return undef;
}
return -1;
} }
cell factor_vm::compute_vm_address(cell arg) { cell factor_vm::compute_vm_address(cell arg) {

14
vm/ffi_test.def Normal file
View File

@ -0,0 +1,14 @@
EXPORTS
ffi_test_0
ffi_test_18
ffi_test_19
ffi_test_49
ffi_test_50
ffi_test_51
ffi_test_52
ffi_test_53
ffi_test_54
ffi_test_55
ffi_test_56
ffi_test_57
ffi_test_58