]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://github.com/erikcharlebois/factor
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 11 Apr 2010 01:01:19 +0000 (18:01 -0700)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 11 Apr 2010 01:01:19 +0000 (18:01 -0700)
89 files changed:
basis/alien/fortran/fortran.factor
basis/alien/libraries/libraries-docs.factor
basis/alien/libraries/libraries.factor
basis/alien/remote-control/remote-control.factor
basis/cairo/ffi/ffi.factor
basis/cocoa/subclassing/subclassing.factor
basis/compiler/alien/alien.factor
basis/compiler/cfg/builder/builder-tests.factor
basis/compiler/codegen/codegen.factor
basis/compiler/tests/alien.factor
basis/compiler/tests/redefine24.factor
basis/compression/zlib/ffi/ffi.factor
basis/core-foundation/run-loop/run-loop.factor
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/linux/linux.factor
basis/cpu/ppc/macosx/macosx.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/32/32-tests.factor
basis/cpu/x86/32/32.factor
basis/cpu/x86/32/bootstrap.factor
basis/cpu/x86/64/64-tests.factor
basis/cpu/x86/64/64.factor
basis/cpu/x86/64/bootstrap.factor
basis/cpu/x86/64/unix/unix.factor
basis/cpu/x86/64/winnt/winnt.factor
basis/cpu/x86/bootstrap.factor
basis/cpu/x86/features/features.factor
basis/cpu/x86/x86.factor
basis/db/postgresql/ffi/ffi.factor
basis/db/sqlite/ffi/ffi.factor
basis/glib/glib.factor
basis/io/backend/unix/multiplexers/run-loop/run-loop.factor
basis/io/sockets/secure/openssl/openssl.factor
basis/io/sockets/windows/nt/nt.factor
basis/math/floats/env/x86/32/32.factor
basis/math/floats/env/x86/64/64.factor
basis/opengl/gl/macosx/macosx.factor
basis/opengl/gl/unix/unix.factor
basis/opengl/gl/windows/windows.factor
basis/openssl/libcrypto/libcrypto.factor
basis/openssl/libssl/libssl.factor
basis/pango/cairo/cairo.factor
basis/pango/pango.factor
basis/stack-checker/alien/alien.factor
basis/tools/deploy/test/9/9.factor
basis/tools/disassembler/disassembler.factor
basis/tools/disassembler/udis/udis.factor
basis/tools/profiler/profiler-tests.factor
basis/ui/backend/windows/windows.factor
basis/unix/ffi/ffi.factor
basis/windows/ce/ce.factor
basis/windows/com/syntax/syntax.factor
basis/windows/com/wrapper/wrapper.factor
basis/windows/ddk/hid/hid.factor
basis/windows/ddk/setupapi/setupapi.factor
basis/windows/ddk/winusb/winusb.factor
basis/windows/dwmapi/dwmapi.factor
basis/windows/nt/nt.factor
core/alien/alien-docs.factor
core/alien/alien.factor
extra/benchmark/fib6/fib6.factor
extra/chipmunk/ffi/ffi.factor
extra/curses/ffi/ffi.factor
extra/cursors/cursors-tests.factor
extra/freetype/freetype.factor
extra/libusb/libusb.factor
extra/llvm/core/core.factor
extra/llvm/invoker/invoker.factor
extra/ogg/ogg.factor
extra/ogg/theora/theora.factor
extra/ogg/vorbis/vorbis.factor
extra/openal/alut/alut.factor
extra/openal/openal.factor
extra/opencl/ffi/ffi.factor
extra/opengl/glu/glu.factor
extra/tokyo/alien/tcrdb/tcrdb.factor
extra/tokyo/alien/tcutil/tcutil.factor
unmaintained/alien/inline/inline.factor
unmaintained/cryptlib/libcl/libcl.factor
unmaintained/db/mysql/ffi/ffi.factor
unmaintained/jni/jni-internals.factor
unmaintained/ldap/libldap/libldap.factor
unmaintained/lint/lint.factor
unmaintained/odbc/odbc.factor
unmaintained/oracle/liboci/liboci.factor
unmaintained/pdf/libhpdf/libhpdf.factor
vm/factor.cpp
vm/ffi_test.c
vm/ffi_test.h

index 9255c66c9f11afc38d358a23d8d56fc36de1a6bb..8c74aa102a8028753d63ef7cbfff5c938e7c3a23 100644 (file)
@@ -13,8 +13,8 @@ SINGLETONS: f2c-abi g95-abi gfortran-abi intel-unix-abi intel-windows-abi ;
 
 << 
 : add-f2c-libraries ( -- )
-    "I77" "libI77.so" "cdecl" add-library
-    "F77" "libF77.so" "cdecl" add-library ;
+    "I77" "libI77.so" cdecl add-library
+    "F77" "libF77.so" cdecl add-library ;
 
 os netbsd? [ add-f2c-libraries ] when
 >>
@@ -42,11 +42,11 @@ library-fortran-abis [ H{ } clone ] initialize
     [ "__" append ] [ "_" append ] if ;
 
 HOOK: fortran-c-abi fortran-abi ( -- abi )
-M: f2c-abi fortran-c-abi "cdecl" ;
-M: g95-abi fortran-c-abi "cdecl" ;
-M: gfortran-abi fortran-c-abi "cdecl" ;
-M: intel-unix-abi fortran-c-abi "cdecl" ;
-M: intel-windows-abi fortran-c-abi "cdecl" ;
+M: f2c-abi fortran-c-abi cdecl ;
+M: g95-abi fortran-c-abi cdecl ;
+M: gfortran-abi fortran-c-abi cdecl ;
+M: intel-unix-abi fortran-c-abi cdecl ;
+M: intel-windows-abi fortran-c-abi cdecl ;
 
 HOOK: real-functions-return-double? fortran-abi ( -- ? )
 M: f2c-abi real-functions-return-double? t ;
index 59142733b93df8fd76f9250a5036328f9036f7b9..8676ac8c58295629d4c52e3daedbfa8531a1d359 100644 (file)
@@ -6,7 +6,7 @@ IN: alien.libraries
 
 HELP: <library>
 { $values
-     { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
+     { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $link cdecl } " or " { $link stdcall } }
      { "library" library } }
 { $description "Opens a C library using the path and ABI parameters and outputs a library tuple." }
 { $notes "User code should use " { $link add-library } " so that the opened library is added to a global hashtable, " { $link libraries } "." } ;
@@ -19,7 +19,7 @@ HELP: library
 { $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
     { $list
         { { $snippet "name" } " - the full path of the C library binary" }
-        { { $snippet "abi" } " - the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
+        { { $snippet "abi" } " - the ABI used by the library, either " { $link cdecl } " or " { $link stdcall } }
         { { $snippet "dll" } " - an instance of the " { $link dll } " class; only set if the library is loaded" }
     }
 } ;
@@ -43,7 +43,7 @@ HELP: load-library
 { $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
 
 HELP: add-library
-{ $values { "name" string } { "path" string } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
+{ $values { "name" string } { "path" string } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } }
 { $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } " and the specified ABI. The logical library name can then be used by a " { $link POSTPONE: LIBRARY: } " form to specify the logical library for subsequent " { $link POSTPONE: FUNCTION: } " definitions." }
 { $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " must be placed within a " { $snippet "<< ... >>" } " parse-time evaluation block."
 $nl
@@ -53,8 +53,8 @@ $nl
 { $examples "Here is a typical usage of " { $link add-library } ":"
 { $code
     "<< \"freetype\" {"
-    "    { [ os macosx? ] [ \"libfreetype.6.dylib\" \"cdecl\" add-library ] }"
-    "    { [ os windows? ] [ \"freetype6.dll\" \"cdecl\" add-library ] }"
+    "    { [ os macosx? ] [ \"libfreetype.6.dylib\" cdecl add-library ] }"
+    "    { [ os windows? ] [ \"freetype6.dll\" cdecl add-library ] }"
     "    [ drop ]"
     "} cond >>"
 }
index 47e34fe5fffa495699b6487b5393eece7a23d6a6..5a042fd436d9dee831f923904a9b5e031daad896 100644 (file)
@@ -36,7 +36,7 @@ M: library dispose dll>> [ dispose ] when* ;
     [ <library> swap libraries get set-at ] 3bi ;
 
 : library-abi ( library -- abi )
-    library [ abi>> ] [ "cdecl" ] if* ;
+    library [ abi>> ] [ cdecl ] if* ;
 
 SYMBOL: deploy-libraries
 
index c305d720f000081563af648f556ff4e7f2970bfc..50902809453660cee76c5461e596544d1725390f 100644 (file)
@@ -6,14 +6,14 @@ eval ;
 IN: alien.remote-control
 
 : eval-callback ( -- callback )
-    void* { c-string } "cdecl"
+    void* { c-string } cdecl
     [ eval>string utf8 malloc-string ] alien-callback ;
 
 : yield-callback ( -- callback )
-    void { } "cdecl" [ yield ] alien-callback ;
+    void { } cdecl [ yield ] alien-callback ;
 
 : sleep-callback ( -- callback )
-    void { long } "cdecl" [ sleep ] alien-callback ;
+    void { long } cdecl [ sleep ] alien-callback ;
 
 : ?callback ( word -- alien )
     dup optimized? [ execute ] [ drop f ] if ; inline
index c357f856de78b9b3528b2c2a54ec62f57a80122b..fafc41af2679ec763ac12512b4f9d37c4f0bfb12 100644 (file)
@@ -12,8 +12,8 @@ alien.libraries classes.struct ;
 
 IN: cairo.ffi
 << {
-    { [ os winnt? ] [ "cairo" "libcairo-2.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "cairo" "/opt/local/lib/libcairo.dylib" "cdecl" add-library ] }
+    { [ os winnt? ] [ "cairo" "libcairo-2.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "cairo" "/opt/local/lib/libcairo.dylib" cdecl add-library ] }
     { [ os unix? ] [ ] }
 } cond >>
 
@@ -40,7 +40,7 @@ TYPEDEF: void* cairo_pattern_t
 
 TYPEDEF: void* cairo_destroy_func_t
 : cairo-destroy-func ( quot -- callback )
-    [ void { pointer: void } "cdecl" ] dip alien-callback ; inline
+    [ void { pointer: void } cdecl ] dip alien-callback ; inline
 
 ! See cairo.h for details
 STRUCT: cairo_user_data_key_t
@@ -80,11 +80,11 @@ CONSTANT: CAIRO_CONTENT_COLOR_ALPHA HEX: 3000
 
 TYPEDEF: void* cairo_write_func_t
 : cairo-write-func ( quot -- callback )
-    [ cairo_status_t { pointer: void c-string int } "cdecl" ] dip alien-callback ; inline
+    [ cairo_status_t { pointer: void c-string int } cdecl ] dip alien-callback ; inline
                           
 TYPEDEF: void* cairo_read_func_t
 : cairo-read-func ( quot -- callback )
-    [ cairo_status_t { pointer: void c-string int } "cdecl" ] dip alien-callback ; inline
+    [ cairo_status_t { pointer: void c-string int } cdecl ] dip alien-callback ; inline
 
 ! Functions for manipulating state objects
 FUNCTION: cairo_t*
index e4db56221f33a40e0c7ba5911bb0e7d3a04f6896..1accb1e8dc1390c9683a80f57b58b021b6676cd5 100644 (file)
@@ -40,7 +40,7 @@ IN: cocoa.subclassing
 
 : prepare-method ( ret types quot -- type imp )
     [ [ encode-types ] 2keep ] dip
-    '[ _ _ "cdecl" _ alien-callback ]
+    '[ _ _ cdecl _ alien-callback ]
     (( -- callback )) define-temp ;
 
 : prepare-methods ( methods -- methods )
index 7426d7e9408770a921027d075010bd99c621cecb..63df85be05aef215a475c7b6474f849af3001604 100644 (file)
@@ -9,7 +9,7 @@ IN: compiler.alien
 
 : alien-parameters ( params -- seq )
     dup parameters>>
-    swap return>> large-struct? [ void* prefix ] when ;
+    swap return>> large-struct? [ struct-return-pointer-type prefix ] when ;
 
 : alien-return ( params -- type )
     return>> dup large-struct? [ drop void ] when ;
index 7f1b6aa6f28fa742777184c1718e1f4484d7136f..b2c05edf7361e00d06260775db6e0457be72c15f 100644 (file)
@@ -68,8 +68,8 @@ IN: compiler.cfg.builder.tests
     [ [ dup ] loop ]
     [ [ 2 ] [ 3 throw ] if 4 ]
     [ int f "malloc" { int } alien-invoke ]
-    [ int { int } "cdecl" alien-indirect ]
-    [ int { int } "cdecl" [ ] alien-callback ]
+    [ int { int } cdecl alien-indirect ]
+    [ int { int } cdecl [ ] alien-callback ]
     [ swap - + * ]
     [ swap slot ]
     [ blahblah ]
index 4208fec0a73fb544f6c88d0456cc7174a536232a..ffccf9f11828d69c46099580a9b67464020c2c09 100755 (executable)
@@ -300,12 +300,12 @@ M: float-rep next-fastcall-param
 M: double-rep next-fastcall-param
     float-regs inc [ ?dummy-stack-params ] [ ?dummy-int-params ] bi ;
 
-GENERIC: reg-class-full? ( reg-class -- ? )
+GENERIC# reg-class-full? 1 ( reg-class abi -- ? )
 
-M: stack-params reg-class-full? drop t ;
+M: stack-params reg-class-full? 2drop t ;
 
 M: reg-class reg-class-full?
-    [ get ] [ param-regs length ] bi >= ;
+    [ get ] swap '[ _ param-regs length ] bi >= ;
 
 : alloc-stack-param ( rep -- n reg-class rep )
     stack-params get
@@ -315,13 +315,22 @@ M: reg-class reg-class-full?
 : alloc-fastcall-param ( rep -- n reg-class rep )
     [ [ reg-class-of get ] [ reg-class-of ] [ next-fastcall-param ] tri ] keep ;
 
-: alloc-parameter ( parameter -- reg rep )
-    c-type-rep dup reg-class-of reg-class-full?
+:: alloc-parameter ( parameter abi -- reg rep )
+    parameter c-type-rep dup reg-class-of abi reg-class-full?
     [ alloc-stack-param ] [ alloc-fastcall-param ] if
-    [ param-reg ] dip ;
+    [ abi param-reg ] dip ;
+
+SYMBOL: (stack-value)
+<< void* c-type clone \ (stack-value) define-primitive-type
+stack-params \ (stack-value) c-type (>>rep) >>
+
+: ((flatten-type)) ( type to-type -- seq )
+    [ stack-size cell align cell /i ] dip c-type <repetition> ; inline
 
 : (flatten-int-type) ( type -- seq )
-    stack-size cell align cell /i void* c-type <repetition> ;
+    void* ((flatten-type)) ;
+: (flatten-stack-type) ( type -- seq )
+    (stack-value) ((flatten-type)) ;
 
 GENERIC: flatten-value-type ( type -- types )
 
@@ -355,8 +364,8 @@ M: c-type-name flatten-value-type c-type flatten-value-type ;
     #! Moves values from C stack to registers (if word is
     #! %load-param-reg) and registers to C stack (if word is
     #! %save-param-reg).
-    [ alien-parameters flatten-value-types ]
-    [ '[ alloc-parameter _ execute ] ]
+    [ [ alien-parameters flatten-value-types ] [ abi>> ] bi ]
+    [ '[ alloc-parameter _ execute ] ]
     bi* each-parameter ; inline
 
 : reverse-each-parameter ( parameters quot -- )
@@ -412,7 +421,7 @@ M: array dlsym-valid? '[ _ dlsym ] any? ;
     3array ;
 
 : alien-invoke-dlsym ( params -- symbols dll )
-    [ dup abi>> "stdcall" = [ stdcall-mangle ] [ function>> ] if ]
+    [ dup abi>> stdcall = [ stdcall-mangle ] [ function>> ] if ]
     [ library>> load-library ]
     bi 2dup check-dlsym ;
 
index ceac1b094c58efdb39b06a6a6f51b08bd1c7bd23..8735d7cae4ef8fba73f26503926a5a47ca2cf35b 100755 (executable)
@@ -1,10 +1,11 @@
 USING: accessors alien alien.c-types alien.libraries
 alien.syntax arrays classes.struct combinators
-compiler continuations effects io io.backend io.pathnames
-io.streams.string kernel math memory namespaces
-namespaces.private parser quotations sequences
-specialized-arrays stack-checker stack-checker.errors
-system threads tools.test words alien.complex concurrency.promises ;
+compiler continuations effects generalizations io
+io.backend io.pathnames io.streams.string kernel
+math memory namespaces namespaces.private parser
+quotations sequences specialized-arrays stack-checker
+stack-checker.errors system threads tools.test words
+alien.complex concurrency.promises ;
 FROM: alien.c-types => float short ;
 SPECIALIZED-ARRAY: float
 SPECIALIZED-ARRAY: char
@@ -19,9 +20,11 @@ IN: compiler.tests.alien
         { [ os unix?  ]  [ "libfactor-ffi-test.so" ] }
     } cond append-path ;
 
-"f-cdecl" libfactor-ffi-tests-path "cdecl" add-library
+"f-cdecl" libfactor-ffi-tests-path cdecl add-library
 
-"f-stdcall" libfactor-ffi-tests-path "stdcall" add-library
+"f-stdcall" libfactor-ffi-tests-path stdcall add-library
+
+"f-fastcall" libfactor-ffi-tests-path fastcall add-library
 >>
 
 LIBRARY: f-cdecl
@@ -90,7 +93,7 @@ FUNCTION: TINY ffi_test_17 int x ;
 [ [ alien-indirect ] infer ] [ inference-error? ] must-fail-with
 
 : indirect-test-1 ( ptr -- result )
-    int { } "cdecl" alien-indirect ;
+    int { } cdecl alien-indirect ;
 
 { 1 1 } [ indirect-test-1 ] must-infer-as
 
@@ -99,7 +102,7 @@ FUNCTION: TINY ffi_test_17 int x ;
 [ 3 ] [ &: ffi_test_1 indirect-test-1 ] unit-test
 
 : indirect-test-1' ( ptr -- )
-    int { } "cdecl" alien-indirect drop ;
+    int { } cdecl alien-indirect drop ;
 
 { 1 0 } [ indirect-test-1' ] must-infer-as
 
@@ -108,7 +111,7 @@ FUNCTION: TINY ffi_test_17 int x ;
 [ -1 indirect-test-1 ] must-fail
 
 : indirect-test-2 ( x y ptr -- result )
-    int { int int } "cdecl" alien-indirect gc ;
+    int { int int } cdecl alien-indirect gc ;
 
 { 3 1 } [ indirect-test-2 ] must-infer-as
 
@@ -117,11 +120,11 @@ FUNCTION: TINY ffi_test_17 int x ;
 unit-test
 
 : indirect-test-3 ( a b c d ptr -- result )
-    int { int int int int } "stdcall" alien-indirect
+    int { int int int int } stdcall alien-indirect
     gc ;
 
 [ f ] [ "f-stdcall" load-library f = ] unit-test
-[ "stdcall" ] [ "f-stdcall" library abi>> ] unit-test
+[ stdcall ] [ "f-stdcall" library abi>> ] unit-test
 
 : ffi_test_18 ( w x y z -- int )
     int "f-stdcall" "ffi_test_18" { int int int int }
@@ -137,6 +140,14 @@ unit-test
     11 6 -7 ffi_test_19 [ x>> ] [ y>> ] [ z>> ] tri
 ] unit-test
 
+: multi_ffi_test_18 ( w x y z w' x' y' z' -- int int )
+    [ int "f-stdcall" "ffi_test_18" { int int int int } alien-invoke ]
+    4 ndip
+    int "f-stdcall" "ffi_test_18" { int int int int } alien-invoke
+    gc ;
+
+[ 25 85 ] [ 2 3 4 5 6 7 8 9 multi_ffi_test_18 ] unit-test
+
 FUNCTION: double ffi_test_6 float x float y ;
 [ 6.0 ] [ 3.0 2.0 ffi_test_6 ] unit-test
 [ "a" "b" ffi_test_6 ] must-fail
@@ -314,21 +325,21 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
 
 ! Test callbacks
 
-: callback-1 ( -- callback ) void { } "cdecl" [ ] alien-callback ;
+: callback-1 ( -- callback ) void { } cdecl [ ] alien-callback ;
 
 [ 0 1 ] [ [ callback-1 ] infer [ in>> length ] [ out>> length ] bi ] unit-test
 
 [ t ] [ callback-1 alien? ] unit-test
 
-: callback_test_1 ( ptr -- ) void { } "cdecl" alien-indirect ;
+: callback_test_1 ( ptr -- ) void { } cdecl alien-indirect ;
 
 [ ] [ callback-1 callback_test_1 ] unit-test
 
-: callback-2 ( -- callback ) void { } "cdecl" [ [ 5 throw ] ignore-errors ] alien-callback ;
+: callback-2 ( -- callback ) void { } cdecl [ [ 5 throw ] ignore-errors ] alien-callback ;
 
 [ ] [ callback-2 callback_test_1 ] unit-test
 
-: callback-3 ( -- callback ) void { } "cdecl" [ 5 "x" set ] alien-callback ;
+: callback-3 ( -- callback ) void { } cdecl [ 5 "x" set ] alien-callback ;
 
 [ t 3 5 ] [
     [
@@ -340,38 +351,38 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ;
 ] unit-test
 
 : callback-5 ( -- callback )
-    void { } "cdecl" [ gc ] alien-callback ;
+    void { } cdecl [ gc ] alien-callback ;
 
 [ "testing" ] [
     "testing" callback-5 callback_test_1
 ] unit-test
 
 : callback-5b ( -- callback )
-    void { } "cdecl" [ compact-gc ] alien-callback ;
+    void { } cdecl [ compact-gc ] alien-callback ;
 
 [ "testing" ] [
     "testing" callback-5b callback_test_1
 ] unit-test
 
 : callback-6 ( -- callback )
-    void { } "cdecl" [ [ continue ] callcc0 ] alien-callback ;
+    void { } cdecl [ [ continue ] callcc0 ] alien-callback ;
 
 [ 1 2 3 ] [ callback-6 callback_test_1 1 2 3 ] unit-test
 
 : callback-7 ( -- callback )
-    void { } "cdecl" [ 1000000 sleep ] alien-callback ;
+    void { } cdecl [ 1000000 sleep ] alien-callback ;
 
 [ 1 2 3 ] [ callback-7 callback_test_1 1 2 3 ] unit-test
 
 [ f ] [ namespace global eq? ] unit-test
 
 : callback-8 ( -- callback )
-    void { } "cdecl" [ [ ] in-thread yield ] alien-callback ;
+    void { } cdecl [ [ ] in-thread yield ] alien-callback ;
 
 [ ] [ callback-8 callback_test_1 ] unit-test
 
 : callback-9 ( -- callback )
-    int { int int int } "cdecl" [
+    int { int int int } cdecl [
         + + 1 +
     ] alien-callback ;
 
@@ -429,12 +440,12 @@ STRUCT: double-rect
     } cleave ;
 
 : double-rect-callback ( -- alien )
-    void { void* void* double-rect } "cdecl"
+    void { void* void* double-rect } cdecl
     [ "example" set-global 2drop ] alien-callback ;
 
 : double-rect-test ( arg callback -- arg' )
     [ f f ] 2dip
-    void { void* void* double-rect } "cdecl" alien-indirect
+    void { void* void* double-rect } cdecl alien-indirect
     "example" get-global ;
 
 [ 1.0 2.0 3.0 4.0 ]
@@ -455,7 +466,7 @@ FUNCTION: test_struct_14 ffi_test_40 ( double x1, double x2 ) ;
 ] unit-test
 
 : callback-10 ( -- callback )
-    test_struct_14 { double double } "cdecl"
+    test_struct_14 { double double } cdecl
     [
         test_struct_14 <struct>
             swap >>x2
@@ -463,7 +474,7 @@ FUNCTION: test_struct_14 ffi_test_40 ( double x1, double x2 ) ;
     ] alien-callback ;
 
 : callback-10-test ( x1 x2 callback -- result )
-    test_struct_14 { double double } "cdecl" alien-indirect ;
+    test_struct_14 { double double } cdecl alien-indirect ;
 
 [ 1.0 2.0 ] [
     1.0 2.0 callback-10 callback-10-test
@@ -478,7 +489,7 @@ FUNCTION: test-struct-12 ffi_test_41 ( int a, double x ) ;
 ] unit-test
 
 : callback-11 ( -- callback )
-    test-struct-12 { int double } "cdecl"
+    test-struct-12 { int double } cdecl
     [
         test-struct-12 <struct>
             swap >>x
@@ -486,7 +497,7 @@ FUNCTION: test-struct-12 ffi_test_41 ( int a, double x ) ;
     ] alien-callback ;
 
 : callback-11-test ( x1 x2 callback -- result )
-    test-struct-12 { int double } "cdecl" alien-indirect ;
+    test-struct-12 { int double } cdecl alien-indirect ;
 
 [ 1 2.0 ] [
     1 2.0 callback-11 callback-11-test
@@ -502,7 +513,7 @@ FUNCTION: test_struct_15 ffi_test_42 ( float x, float y ) ;
 [ 1.0 2.0 ] [ 1.0 2.0 ffi_test_42 [ x>> ] [ y>> ] bi ] unit-test
 
 : callback-12 ( -- callback )
-    test_struct_15 { float float } "cdecl"
+    test_struct_15 { float float } cdecl
     [
         test_struct_15 <struct>
             swap >>y
@@ -510,7 +521,7 @@ FUNCTION: test_struct_15 ffi_test_42 ( float x, float y ) ;
     ] alien-callback ;
 
 : callback-12-test ( x1 x2 callback -- result )
-    test_struct_15 { float float } "cdecl" alien-indirect ;
+    test_struct_15 { float float } cdecl alien-indirect ;
 
 [ 1.0 2.0 ] [
     1.0 2.0 callback-12 callback-12-test [ x>> ] [ y>> ] bi
@@ -525,7 +536,7 @@ FUNCTION: test_struct_16 ffi_test_43 ( float x, int a ) ;
 [ 1.0 2 ] [ 1.0 2 ffi_test_43 [ x>> ] [ a>> ] bi ] unit-test
 
 : callback-13 ( -- callback )
-    test_struct_16 { float int } "cdecl"
+    test_struct_16 { float int } cdecl
     [
         test_struct_16 <struct>
             swap >>a
@@ -533,7 +544,7 @@ FUNCTION: test_struct_16 ffi_test_43 ( float x, int a ) ;
     ] alien-callback ;
 
 : callback-13-test ( x1 x2 callback -- result )
-    test_struct_16 { float int } "cdecl" alien-indirect ;
+    test_struct_16 { float int } cdecl alien-indirect ;
 
 [ 1.0 2 ] [
     1.0 2 callback-13 callback-13-test
@@ -584,13 +595,13 @@ FUNCTION: short ffi_test_48 ( bool-field-test x ) ;
 
 ! Test interaction between threads and callbacks
 : thread-callback-1 ( -- callback )
-    int { } "cdecl" [ yield 100 ] alien-callback ;
+    int { } cdecl [ yield 100 ] alien-callback ;
 
 : thread-callback-2 ( -- callback )
-    int { } "cdecl" [ yield 200 ] alien-callback ;
+    int { } cdecl [ yield 200 ] alien-callback ;
 
 : thread-callback-invoker ( callback -- n )
-    int { } "cdecl" alien-indirect ;
+    int { } cdecl alien-indirect ;
 
 <promise> "p" set
 [ thread-callback-1 thread-callback-invoker "p" get fulfill ] in-thread
@@ -603,6 +614,98 @@ FUNCTION: void this_does_not_exist ( ) ;
 [ this_does_not_exist ] [ { "kernel-error" 9 f f } = ] must-fail-with
 
 ! More alien-assembly tests are in cpu.* vocabs
-: assembly-test-1 ( -- ) void { } "cdecl" [ ] alien-assembly ;
+: assembly-test-1 ( -- ) void { } cdecl [ ] alien-assembly ;
 
 [ ] [ assembly-test-1 ] unit-test
+
+[ f ] [ "f-fastcall" load-library f = ] unit-test
+[ fastcall ] [ "f-fastcall" library abi>> ] unit-test
+
+: ffi_test_49 ( x -- int )
+    int "f-fastcall" "ffi_test_49" { int }
+    alien-invoke gc ;
+: ffi_test_50 ( x y -- int )
+    int "f-fastcall" "ffi_test_50" { int int }
+    alien-invoke gc ;
+: ffi_test_51 ( x y z -- int )
+    int "f-fastcall" "ffi_test_51" { int int int }
+    alien-invoke gc ;
+: multi_ffi_test_51 ( x y z x' y' z' -- int int )
+    [ int "f-fastcall" "ffi_test_51" { int int int } alien-invoke ]
+    3dip
+    int "f-fastcall" "ffi_test_51" { int int int } alien-invoke gc ;
+    
+[ 4 ] [ 3 ffi_test_49 ] unit-test
+[ 8 ] [ 3 4 ffi_test_50 ] unit-test
+[ 13 ] [ 3 4 5 ffi_test_51 ] unit-test
+[ 13 22 ] [ 3 4 5 6 7 8 multi_ffi_test_51 ] unit-test
+
+: ffi_test_52 ( x y z -- int )
+    int "f-fastcall" "ffi_test_52" { int float int }
+    alien-invoke gc ;
+: ffi_test_53 ( x y z w -- int )
+    int "f-fastcall" "ffi_test_53" { int float int int }
+    alien-invoke gc ;
+: ffi_test_57 ( x y -- test-struct-11 )
+    test-struct-11 "f-fastcall" "ffi_test_57" { int int }
+    alien-invoke gc ;
+: ffi_test_58 ( x y z -- test-struct-11 )
+    test-struct-11 "f-fastcall" "ffi_test_58" { int int int }
+    alien-invoke gc ;
+
+[ 13 ] [ 3 4.0 5 ffi_test_52 ] unit-test
+[ 19 ] [ 3 4.0 5 6 ffi_test_53 ] unit-test
+[ S{ test-struct-11 f 7 -1 } ] [ 3 4 ffi_test_57 ] unit-test
+[ S{ test-struct-11 f 7 -3 } ] [ 3 4 7 ffi_test_58 ] unit-test
+
+: fastcall-ii-indirect ( x y ptr -- result )
+    int { int int } fastcall alien-indirect ;
+: fastcall-iii-indirect ( x y z ptr -- result )
+    int { int int int } fastcall alien-indirect ;
+: fastcall-ifi-indirect ( x y z ptr -- result )
+    int { int float int } fastcall alien-indirect ;
+: fastcall-ifii-indirect ( x y z w ptr -- result )
+    int { int float int int } fastcall alien-indirect ;
+: fastcall-struct-return-ii-indirect ( x y ptr -- result )
+    test-struct-11 { int int } fastcall alien-indirect ;
+: fastcall-struct-return-iii-indirect ( x y z ptr -- result )
+    test-struct-11 { int int int } fastcall alien-indirect ;
+
+[ 8 ] [ 3 4 &: ffi_test_50 fastcall-ii-indirect ] unit-test
+[ 13 ] [ 3 4 5 &: ffi_test_51 fastcall-iii-indirect ] unit-test
+[ 13 ] [ 3 4.0 5 &: ffi_test_52 fastcall-ifi-indirect ] unit-test
+[ 19 ] [ 3 4.0 5 6 &: ffi_test_53 fastcall-ifii-indirect ] unit-test
+
+[ S{ test-struct-11 f 7 -1 } ]
+[ 3 4 &: ffi_test_57 fastcall-struct-return-ii-indirect ] unit-test
+
+[ S{ test-struct-11 f 7 -3 } ]
+[ 3 4 7 &: ffi_test_58 fastcall-struct-return-iii-indirect ] unit-test
+
+: fastcall-ii-callback ( -- ptr )
+    int { int int } fastcall [ + 1 + ] alien-callback ;
+: fastcall-iii-callback ( -- ptr )
+    int { int int int } fastcall [ + + 1 + ] alien-callback ;
+: fastcall-ifi-callback ( -- ptr )
+    int { int float int } fastcall
+    [ [ >integer ] dip + + 1 + ] alien-callback ;
+: fastcall-ifii-callback ( -- ptr )
+    int { int float int int } fastcall
+    [ [ >integer ] 2dip + + + 1 + ] alien-callback ;
+: fastcall-struct-return-ii-callback ( -- ptr )
+    test-struct-11 { int int } fastcall
+    [ [ + ] [ - ] 2bi test-struct-11 <struct-boa> ] alien-callback ;
+: fastcall-struct-return-iii-callback ( -- ptr )
+    test-struct-11 { int int int } fastcall
+    [ [ drop + ] [ - nip ] 3bi test-struct-11 <struct-boa> ] alien-callback ;
+
+[ 8 ] [ 3 4 fastcall-ii-callback fastcall-ii-indirect ] unit-test
+[ 13 ] [ 3 4 5 fastcall-iii-callback fastcall-iii-indirect ] unit-test
+[ 13 ] [ 3 4.0 5 fastcall-ifi-callback fastcall-ifi-indirect ] unit-test
+[ 19 ] [ 3 4.0 5 6 fastcall-ifii-callback fastcall-ifii-indirect ] unit-test
+
+[ S{ test-struct-11 f 7 -1 } ]
+[ 3 4 fastcall-struct-return-ii-callback fastcall-struct-return-ii-indirect ] unit-test
+
+[ S{ test-struct-11 f 7 -3 } ]
+[ 3 4 7 fastcall-struct-return-iii-callback fastcall-struct-return-iii-indirect ] unit-test
index 391102102edebc18e11981304dcf718a574f345c..90c4e9943d9966d197b2c0b932dfe72bbd260d40 100644 (file)
@@ -7,12 +7,12 @@ TYPEDEF: alien.c-types:int type-1
 TYPEDEF: alien.c-types:int type-3
 
 : callback ( -- ptr )
-    type-3 { type-1 type-1 } "cdecl" [ + >integer ] alien-callback ;
+    type-3 { type-1 type-1 } cdecl [ + >integer ] alien-callback ;
 
 TYPEDEF: alien.c-types:float type-2
 
 : indirect ( x y ptr -- z  )
-    type-3 { type-2 type-2 } "cdecl" alien-indirect ;
+    type-3 { type-2 type-2 } cdecl alien-indirect ;
 
 [ ] [
     "USING: alien.c-types alien.syntax ;
index 553b55cf6e94ed664da1b6afe73787d220d714e3..aede6d562113ce5221ef85b62a5c8deb109ccfa3 100644 (file)
@@ -8,7 +8,7 @@ IN: compression.zlib.ffi
     { [ os winnt? ] [ "zlib1.dll" ] }
     { [ os macosx? ] [ "libz.dylib" ] }
     { [ os unix? ] [ "libz.so" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
 
 LIBRARY: zlib
 
index 14d701ba177e7ac0d7bda8bab0e93f24bb1a0029..793efefbe869b81e663fa2514d737af9a039ed30 100644 (file)
@@ -120,7 +120,7 @@ PRIVATE>
     [ fds>> [ enable-all-callbacks ] each ] bi ;
 
 : timer-callback ( -- callback )
-    void { CFRunLoopTimerRef void* } "cdecl"
+    void { CFRunLoopTimerRef void* } cdecl
     [ 2drop reset-run-loop yield ] alien-callback ;
 
 : init-thread-timer ( -- )
index ad1a4be2eb072f67966b5b641813c1a343965d75..1aaf1bf2eaaec85a235741316b09cb60a9d3b359 100644 (file)
@@ -486,15 +486,15 @@ HOOK: %loop-entry cpu ( -- )
 GENERIC: return-reg ( reg-class -- reg )
 
 ! Sequence of registers used for parameter passing in class
-GENERIC: param-regs ( reg-class -- regs )
+GENERIC# param-regs 1 ( reg-class abi -- regs )
 
-M: stack-params param-regs drop f ;
+M: stack-params param-regs 2drop f ;
 
-GENERIC: param-reg ( n reg-class -- reg )
+GENERIC# param-reg 1 ( n reg-class abi -- reg )
 
 M: reg-class param-reg param-regs nth ;
 
-M: stack-params param-reg drop ;
+M: stack-params param-reg 2drop ;
 
 ! Is this integer small enough to be an immediate operand for
 ! %add-imm, %sub-imm, and %mul-imm?
@@ -504,6 +504,9 @@ HOOK: immediate-arithmetic? cpu ( n -- ? )
 ! %and-imm, %or-imm, and %xor-imm?
 HOOK: immediate-bitwise? cpu ( n -- ? )
 
+! What c-type describes the implicit struct return pointer for large structs?
+HOOK: struct-return-pointer-type cpu ( -- c-type )
+
 ! Is this structure small enough to be returned in registers?
 HOOK: return-struct-in-registers? cpu ( c-type -- ? )
 
@@ -592,6 +595,6 @@ HOOK: %end-callback cpu ( -- )
 
 HOOK: %end-callback-value cpu ( c-type -- )
 
-HOOK: callback-return-rewind cpu ( params -- n )
+HOOK: stack-cleanup cpu ( params -- n )
 
-M: object callback-return-rewind drop 0 ;
+M: object stack-cleanup drop 0 ;
index 5cfa1391c47dc98f8907d66c68efe2404e636c03..0a1e8477e81c74b55bcb029ad57a0e06dba6b824 100644 (file)
@@ -13,7 +13,7 @@ M: linux reserved-area-size 2 cells ;
 
 M: linux lr-save 1 cells ;
 
-M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 } ;
+M: float-regs param-regs 2drop { 1 2 3 4 5 6 7 8 } ;
 
 M: ppc value-struct? drop f ;
 
index 152a3aa7209e81f1c2f982802c27b5a4fb66ca48..49e9768cf67c76d57224b534592bba7501334d6f 100644 (file)
@@ -8,7 +8,7 @@ M: macosx reserved-area-size 6 cells ;
 
 M: macosx lr-save 2 cells ;
 
-M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
+M: float-regs param-regs 2drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
 
 M: ppc value-struct? drop t ;
 
index cf8a8323861b48d6bfce055c6af12dc672b904f5..551693d5c7aa1a0f7f04911e50c3b846d5de9012 100644 (file)
@@ -235,7 +235,7 @@ M: spill-slot float-function-param* [ 1 ] dip n>> spill@ LFD ;
 M: integer float-function-param* FMR ;
 
 : float-function-param ( i src -- )
-    [ float-regs param-regs nth ] dip float-function-param* ;
+    [ float-regs cdecl param-regs nth ] dip float-function-param* ;
 
 : float-function-return ( reg -- )
     float-regs return-reg double-rep %copy ;
@@ -584,7 +584,7 @@ M: ppc %reload ( dst rep src -- )
 M: ppc %loop-entry ;
 
 M: int-regs return-reg drop 3 ;
-M: int-regs param-regs drop { 3 4 5 6 7 8 9 10 } ;
+M: int-regs param-regs 2drop { 3 4 5 6 7 8 9 10 } ;
 M: float-regs return-reg drop 1 ;
 
 M:: ppc %save-param-reg ( stack reg rep -- )
@@ -644,7 +644,7 @@ M:: ppc %box ( n rep func -- )
     ! If the source is a stack location, load it into freg #0.
     ! If the source is f, then we assume the value is already in
     ! freg #0.
-    n [ 0 rep reg-class-of param-reg rep %load-param-reg ] when*
+    n [ 0 rep reg-class-of cdecl param-reg rep %load-param-reg ] when*
     rep double-rep? 5 4 ? %load-vm-addr
     func f %alien-invoke ;
 
@@ -701,6 +701,8 @@ M: ppc immediate-arithmetic? ( n -- ? ) -32768 32767 between? ;
 
 M: ppc immediate-bitwise? ( n -- ? ) 0 65535 between? ;
 
+M: ppc struct-return-pointer-type void* ;
+
 M: ppc return-struct-in-registers? ( c-type -- ? )
     c-type return-in-registers?>> ;
 
index bc07e3a25bfa4e9f2132db3fcb5baf477b63504c..375374806fbe72ce01b19f3a8aa0a15944616262 100644 (file)
@@ -2,6 +2,6 @@ IN: cpu.x86.32.tests
 USING: alien alien.c-types tools.test cpu.x86.assembler
 cpu.x86.assembler.operands ;
 
-: assembly-test-1 ( -- x ) int { } "cdecl" [ EAX 3 MOV ] alien-assembly ;
+: assembly-test-1 ( -- x ) int { } cdecl [ EAX 3 MOV ] alien-assembly ;
 
 [ 3 ] [ assembly-test-1 ] unit-test
index 97f0cfb66845e4b7e08a3bd75c4cba789956ac27..0127d559970ff65abdf8509263ffb177fa3107bd 100755 (executable)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2005, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: locals alien.c-types alien.libraries alien.syntax arrays
-kernel fry math namespaces sequences system layouts io
-vocabs.loader accessors init combinators command-line make
-compiler compiler.units compiler.constants compiler.alien
+USING: locals alien alien.c-types alien.libraries alien.syntax
+arrays kernel fry math namespaces sequences system layouts io
+vocabs.loader accessors init classes.struct combinators command-line
+make compiler compiler.units compiler.constants compiler.alien
 compiler.codegen compiler.codegen.fixup
 compiler.cfg.instructions compiler.cfg.builder
 compiler.cfg.intrinsics compiler.cfg.stack-frame
@@ -67,9 +67,9 @@ M:: x86.32 %dispatch ( src temp -- )
     [ align-code ]
     bi ;
 
-M: x86.32 pic-tail-reg EBX ;
+M: x86.32 pic-tail-reg EDX ;
 
-M: x86.32 reserved-stack-space 4 cells ;
+M: x86.32 reserved-stack-space 0 ;
 
 M: x86.32 %alien-invoke 0 CALL rc-relative rel-dlsym ;
 
@@ -86,14 +86,24 @@ M: x86.32 return-struct-in-registers? ( c-type -- ? )
 : struct-return@ ( n -- operand )
     [ next-stack@ ] [ stack-frame get params>> local@ ] if* ;
 
-! On x86, parameters are never passed in registers.
+! On x86, parameters are usually never passed in registers, except with Microsoft's
+! "thiscall" and "fastcall" abis
 M: int-regs return-reg drop EAX ;
-M: int-regs param-regs drop { } ;
-M: float-regs param-regs drop { } ;
+M: float-regs param-regs 2drop { } ;
+
+M: int-regs param-regs
+    nip {
+        { thiscall [ { ECX     } ] }
+        { fastcall [ { ECX EDX } ] }
+        [ drop { } ]
+    } case ;
 
 GENERIC: load-return-reg ( src rep -- )
 GENERIC: store-return-reg ( dst rep -- )
 
+M: stack-params load-return-reg drop EAX swap MOV ;
+M: stack-params store-return-reg drop EAX MOV ;
+
 M: int-rep load-return-reg drop EAX swap MOV ;
 M: int-rep store-return-reg drop EAX MOV ;
 
@@ -111,19 +121,23 @@ M: x86.32 %prologue ( n -- )
 M: x86.32 %prepare-jump
     pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here ;
 
-M: x86.32 %load-param-reg
-    stack-params assert=
-    [ [ EAX ] dip local@ MOV ] dip
-    stack@ EAX MOV ;
+M: stack-params copy-register*
+    drop
+    {
+        { [ dup  integer? ] [ EAX swap next-stack@ MOV  EAX MOV ] }
+        { [ over integer? ] [ EAX swap MOV              param@ EAX MOV ] }
+    } cond ;
 
-M: x86.32 %save-param-reg 3drop ;
+M: x86.32 %save-param-reg [ local@ ] 2dip %copy ;
+
+M: x86.32 %load-param-reg [ swap local@ ] dip %copy ;
 
 : (%box) ( n rep -- )
     #! If n is f, push the return register onto the stack; we
     #! are boxing a return value of a C function. If n is an
     #! integer, push [ESP+n] on the stack; we are boxing a
     #! parameter being passed to a callback from C.
-    over [ [ next-stack@ ] dip load-return-reg ] [ 2drop ] if ;
+    over [ [ local@ ] dip load-return-reg ] [ 2drop ] if ;
 
 M:: x86.32 %box ( n rep func -- )
     n rep (%box)
@@ -295,27 +309,36 @@ M:: x86.32 %binary-float-function ( dst src1 src2 func -- )
     func "libm" load-library %alien-invoke
     dst float-function-return ;
 
-: stdcall? ( params -- ? )
-    abi>> "stdcall" = ;
-
 : funny-large-struct-return? ( params -- ? )
     #! MINGW ABI incompatibility disaster
     [ return>> large-struct? ]
-    [ abi>> "mingw" = os windows? not or ]
+    [ abi>> mingw = os windows? not or ]
     bi and ;
 
-M: x86.32 %cleanup ( params -- )
-    #! a) If we just called an stdcall function in Windows, it
-    #! cleaned up the stack frame for us. But we don't want that
-    #! so we 'undo' the cleanup since we do that in %epilogue.
-    #! b) If we just called a function returning a struct, we
-    #! have to fix ESP.
+: callee-cleanup? ( abi -- ? )
+    { stdcall fastcall thiscall } member? ;
+
+: stack-arg-size ( params -- n )
+    dup abi>> '[
+        alien-parameters flatten-value-types
+        [ _ alloc-parameter 2drop ] each
+        stack-params get
+    ] with-param-regs ;
+
+M: x86.32 stack-cleanup ( params -- n )
+    #! a) Functions which are stdcall/fastcall/thiscall have to
+    #! clean up the caller's stack frame.
+    #! b) Functions returning large structs on MINGW have to
+    #! fix ESP.
     {
-        { [ dup stdcall? ] [ drop ESP stack-frame get params>> SUB ] }
-        { [ dup funny-large-struct-return? ] [ drop EAX PUSH ] }
-        [ drop ]
+        { [ dup abi>> callee-cleanup? ] [ stack-arg-size ] }
+        { [ dup funny-large-struct-return? ] [ drop 4 ] }
+        [ drop ]
     } cond ;
 
+M: x86.32 %cleanup ( params -- )
+    stack-cleanup [ ESP swap SUB ] unless-zero ;
+
 M:: x86.32 %call-gc ( gc-root-count temp -- )
     temp gc-root-base special@ LEA
     8 save-vm-ptr
@@ -329,18 +352,13 @@ M: x86.32 dummy-int-params? f ;
 
 M: x86.32 dummy-fp-params? f ;
 
-M: x86.32 callback-return-rewind ( params -- n )
-    #! a) If the callback is stdcall, we have to clean up the
-    #! caller's stack frame.
-    #! b) If the callback is returning a large struct, we have
-    #! to fix ESP.
-    {
-        { [ dup stdcall? ] [ <alien-stack-frame> [ params>> ] [ return>> ] bi + ] }
-        { [ dup funny-large-struct-return? ] [ drop 4 ] }
-        [ drop 0 ]
-    } cond ;
-
 ! Dreadful
-M: object flatten-value-type (flatten-int-type) ;
+M: object flatten-value-type (flatten-stack-type) ;
+M: struct-c-type flatten-value-type (flatten-stack-type) ;
+M: long-long-type flatten-value-type (flatten-stack-type) ;
+M: c-type flatten-value-type
+    dup rep>> int-rep? [ (flatten-int-type) ] [ (flatten-stack-type) ] if ;
+
+M: x86.32 struct-return-pointer-type (stack-value) ;
 
 check-sse
index b2cd241df1de6d47ab014faa1f4e14999e7d8591..4eb8335b678974d287a6a5277229a814d544f3ef 100644 (file)
@@ -13,15 +13,16 @@ IN: bootstrap.x86
 : div-arg ( -- reg ) EAX ;
 : mod-arg ( -- reg ) EDX ;
 : temp0 ( -- reg ) EAX ;
-: temp1 ( -- reg ) EDX ;
-: temp2 ( -- reg ) ECX ;
-: temp3 ( -- reg ) EBX ;
+: temp1 ( -- reg ) ECX ;
+: temp2 ( -- reg ) EBX ;
+: temp3 ( -- reg ) EDX ;
+: pic-tail-reg ( -- reg ) EDX ;
 : stack-reg ( -- reg ) ESP ;
 : frame-reg ( -- reg ) EBP ;
-: vm-reg ( -- reg ) ECX ;
+: vm-reg ( -- reg ) EBX ;
 : ctx-reg ( -- reg ) EBP ;
 : nv-regs ( -- seq ) { ESI EDI EBX } ;
-: nv-reg ( -- reg ) EBX ;
+: nv-reg ( -- reg ) ESI ;
 : ds-reg ( -- reg ) ESI ;
 : rs-reg ( -- reg ) EDI ;
 : fixnum>slot@ ( -- ) temp0 2 SAR ;
@@ -40,7 +41,7 @@ IN: bootstrap.x86
 ] jit-prolog jit-define
 
 [
-    temp3 0 MOV rc-absolute-cell rt-here jit-rel
+    pic-tail-reg 0 MOV rc-absolute-cell rt-here jit-rel
     0 JMP rc-relative rt-entry-point-pic-tail jit-rel
 ] jit-word-jump jit-define
 
@@ -53,8 +54,8 @@ IN: bootstrap.x86
 
 : jit-save-context ( -- )
     jit-load-context
-    EDX ESP -4 [+] LEA
-    ctx-reg context-callstack-top-offset [+] EDX MOV
+    ECX ESP -4 [+] LEA
+    ctx-reg context-callstack-top-offset [+] ECX MOV
     ctx-reg context-datastack-offset [+] ds-reg MOV
     ctx-reg context-retainstack-offset [+] rs-reg MOV ;
 
@@ -135,25 +136,25 @@ IN: bootstrap.x86
 
 [
     ! Load callstack object
-    EBX ds-reg [] MOV
+    temp3 ds-reg [] MOV
     ds-reg bootstrap-cell SUB
     ! Get ctx->callstack_bottom
     jit-load-vm
     jit-load-context
-    EAX ctx-reg context-callstack-bottom-offset [+] MOV
+    temp0 ctx-reg context-callstack-bottom-offset [+] MOV
     ! Get top of callstack object -- 'src' for memcpy
-    EBP EBX callstack-top-offset [+] LEA
+    temp1 temp3 callstack-top-offset [+] LEA
     ! Get callstack length, in bytes --- 'len' for memcpy
-    EDX EBX callstack-length-offset [+] MOV
-    EDX tag-bits get SHR
+    temp2 temp3 callstack-length-offset [+] MOV
+    temp2 tag-bits get SHR
     ! Compute new stack pointer -- 'dst' for memcpy
-    EAX EDX SUB
+    temp0 temp2 SUB
     ! Install new stack pointer
-    ESP EAX MOV
+    ESP temp0 MOV
     ! Call memcpy
-    EDX PUSH
-    EBP PUSH
-    EAX PUSH
+    temp2 PUSH
+    temp1 PUSH
+    temp0 PUSH
     "factor_memcpy" jit-call
     ESP 12 ADD
     ! Return with new callstack
@@ -177,7 +178,7 @@ IN: bootstrap.x86
 
 ! Inline cache miss entry points
 : jit-load-return-address ( -- )
-    EBX ESP stack-frame-size bootstrap-cell - [+] MOV ;
+    pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ;
 
 ! These are always in tail position with an existing stack
 ! frame, and the stack. The frame setup takes this into account.
@@ -185,7 +186,7 @@ IN: bootstrap.x86
     jit-load-vm
     jit-save-context
     ESP 4 [+] vm-reg MOV
-    ESP [] EBX MOV
+    ESP [] pic-tail-reg MOV
     "inline_cache_miss" jit-call
     jit-restore-context ;
 
@@ -213,6 +214,7 @@ IN: bootstrap.x86
     [
         ESP [] EAX MOV
         ESP 4 [+] EDX MOV
+        jit-load-vm
         ESP 8 [+] vm-reg MOV
         jit-call
     ]
@@ -237,6 +239,7 @@ IN: bootstrap.x86
         EBX tag-bits get SAR
         ESP [] EBX MOV
         ESP 4 [+] EBP MOV
+        jit-load-vm
         ESP 8 [+] vm-reg MOV
         "overflow_fixnum_multiply" jit-call
     ]
@@ -266,7 +269,7 @@ IN: bootstrap.x86
     ! Load context and parameter from datastack
     EAX ds-reg [] MOV
     EAX EAX alien-offset [+] MOV
-    EBX ds-reg -4 [+] MOV
+    EDX ds-reg -4 [+] MOV
     ds-reg 8 SUB
 
     ! Make the new context active
@@ -280,7 +283,7 @@ IN: bootstrap.x86
 
     ! Store parameter to datastack
     ds-reg 4 ADD
-    ds-reg [] EBX MOV ;
+    ds-reg [] EDX MOV ;
 
 [ jit-set-context ] \ (set-context) define-sub-primitive
 
@@ -291,14 +294,14 @@ IN: bootstrap.x86
     "new_context" jit-call
 
     ! Save pointer to quotation and parameter
-    EBX ds-reg MOV
+    EDX ds-reg MOV
     ds-reg 8 SUB
 
     ! Make the new context active
     EAX jit-switch-context
 
     ! Push parameter
-    EAX EBX -4 [+] MOV
+    EAX EDX -4 [+] MOV
     ds-reg 4 ADD
     ds-reg [] EAX MOV
 
@@ -309,7 +312,7 @@ IN: bootstrap.x86
     0 PUSH
 
     ! Jump to initial quotation
-    EAX EBX [] MOV
+    EAX EDX [] MOV
     jit-jump-quot ;
 
 [ jit-start-context ] \ (start-context) define-sub-primitive
index 6d171af7eaf6a58b4f9bb0dc2beb8679e2ebb4b2..2d2c89441c019b22f1abd681d5cf8180938a086a 100644 (file)
@@ -2,12 +2,12 @@ USING: alien alien.c-types cpu.architecture cpu.x86.64
 cpu.x86.assembler cpu.x86.assembler.operands tools.test ;
 IN: cpu.x86.64.tests
 
-: assembly-test-1 ( -- x ) int { } "cdecl" [ RAX 3 MOV ] alien-assembly ;
+: assembly-test-1 ( -- x ) int { } cdecl [ RAX 3 MOV ] alien-assembly ;
 
 [ 3 ] [ assembly-test-1 ] unit-test
 
 : assembly-test-2 ( a b -- x )
-    int { int int } "cdecl" [
+    int { int int } cdecl [
         param-reg-0 param-reg-1 ADD
         int-regs return-reg param-reg-0 MOV
     ] alien-assembly ;
index 4dfb250348f1a62026ccb694343494222fb9deb8..432d210bec63eef45ab7e0b86ef77daf5b37a40f 100644 (file)
@@ -11,10 +11,10 @@ cpu.architecture vm ;
 FROM: layouts => cell cells ;
 IN: cpu.x86.64
 
-: param-reg-0 ( -- reg ) 0 int-regs param-reg ; inline
-: param-reg-1 ( -- reg ) 1 int-regs param-reg ; inline
-: param-reg-2 ( -- reg ) 2 int-regs param-reg ; inline
-: param-reg-3 ( -- reg ) 3 int-regs param-reg ; inline
+: param-reg-0 ( -- reg ) 0 int-regs cdecl param-reg ; inline
+: param-reg-1 ( -- reg ) 1 int-regs cdecl param-reg ; inline
+: param-reg-2 ( -- reg ) 2 int-regs cdecl param-reg ; inline
+: param-reg-3 ( -- reg ) 3 int-regs cdecl param-reg ; inline
 
 M: x86.64 pic-tail-reg RBX ;
 
@@ -52,8 +52,6 @@ M: x86.64 %set-vm-field ( src offset -- )
 M: x86.64 %vm-field-ptr ( dst offset -- )
     [ vm-reg ] dip [+] LEA ;
 
-: param@ ( n -- op ) reserved-stack-space + stack@ ;
-
 M: x86.64 %prologue ( n -- )
     temp-reg -7 [RIP+] LEA
     dup PUSH
@@ -157,7 +155,7 @@ M:: x86.64 %unbox-large-struct ( n c-type -- )
     "to_value_struct" f %alien-invoke ;
 
 : load-return-value ( rep -- )
-    [ [ 0 ] dip reg-class-of param-reg ]
+    [ [ 0 ] dip reg-class-of cdecl param-reg ]
     [ reg-class-of return-reg ]
     [ ]
     tri %copy ;
@@ -165,7 +163,7 @@ M:: x86.64 %unbox-large-struct ( n c-type -- )
 M:: x86.64 %box ( n rep func -- )
     n [
         n
-        0 rep reg-class-of param-reg
+        0 rep reg-class-of cdecl param-reg
         rep %load-param-reg
     ] [
         rep load-return-value
@@ -253,7 +251,7 @@ M: x86.64 %end-callback-value ( ctype -- )
     unbox-return ;
 
 : float-function-param ( i src -- )
-    [ float-regs param-regs nth ] dip double-rep %copy ;
+    [ float-regs cdecl param-regs nth ] dip double-rep %copy ;
 
 : float-function-return ( reg -- )
     float-regs return-reg double-rep %copy ;
@@ -281,6 +279,8 @@ M:: x86.64 %call-gc ( gc-root-count temp -- )
     ! Call GC
     "inline_gc" f %alien-invoke ;
 
+M: x86.64 struct-return-pointer-type void* ;
+
 ! The result of reading 4 bytes from memory is a fixnum on
 ! x86-64.
 enable-alien-4-intrinsics
index 68c3d8b7025dc7a89322ca62262f8d4091729d52..39046bce6a0adbf5c1b8884914a2c9d6d2600138 100644 (file)
@@ -11,10 +11,11 @@ IN: bootstrap.x86
 : shift-arg ( -- reg ) RCX ;
 : div-arg ( -- reg ) RAX ;
 : mod-arg ( -- reg ) RDX ;
-: temp0 ( -- reg ) RDI ;
-: temp1 ( -- reg ) RSI ;
+: temp0 ( -- reg ) RAX ;
+: temp1 ( -- reg ) RCX ;
 : temp2 ( -- reg ) RDX ;
 : temp3 ( -- reg ) RBX ;
+: pic-tail-reg ( -- reg ) RBX ;
 : return-reg ( -- reg ) RAX ;
 : nv-reg ( -- reg ) RBX ;
 : stack-reg ( -- reg ) RSP ;
@@ -42,7 +43,7 @@ IN: bootstrap.x86
 ] jit-prolog jit-define
 
 [
-    temp3 5 [RIP+] LEA
+    pic-tail-reg 5 [RIP+] LEA
     0 JMP rc-relative rt-entry-point-pic-tail jit-rel
 ] jit-word-jump jit-define
 
index 2fb32ce733cfa8086d46bd77f37afe018dffabdc..a1868a3bc89ca60d666395bf50ad429b59067df1 100644 (file)
@@ -7,18 +7,13 @@ compiler.cfg.registers ;
 IN: cpu.x86.64.unix
 
 M: int-regs param-regs
-    drop { RDI RSI RDX RCX R8 R9 } ;
+    2drop { RDI RSI RDX RCX R8 R9 } ;
 
 M: float-regs param-regs
-    drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
+    2drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
 
 M: x86.64 reserved-stack-space 0 ;
 
-SYMBOL: (stack-value)
-! The ABI for passing structs by value is pretty great
-<< void* c-type clone \ (stack-value) define-primitive-type
-stack-params \ (stack-value) c-type (>>rep) >>
-
 : struct-types&offset ( struct-type -- pairs )
     fields>> [
         [ type>> ] [ offset>> ] bi 2array
@@ -36,8 +31,7 @@ stack-params \ (stack-value) c-type (>>rep) >>
     ] map ;
 
 : flatten-large-struct ( c-type -- seq )
-    heap-size cell align
-    cell /i \ (stack-value) c-type <repetition> ;
+    (flatten-stack-type) ;
 
 : flatten-struct ( c-type -- seq )
     dup heap-size 16 > [
index c75bb5a1b93ba9e80a4499bda6d90bcf3c86af73..5d8ecc5cfbb469aca2e088586d5775f3776d287e 100644 (file)
@@ -5,9 +5,9 @@ compiler.cfg.registers cpu.architecture cpu.x86.assembler cpu.x86
 cpu.x86.assembler.operands ;
 IN: cpu.x86.64.winnt
 
-M: int-regs param-regs drop { RCX RDX R8 R9 } ;
+M: int-regs param-regs 2drop { RCX RDX R8 R9 } ;
 
-M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ;
+M: float-regs param-regs 2drop { XMM0 XMM1 XMM2 XMM3 } ;
 
 M: x86.64 reserved-stack-space 4 cells ;
 
index 80b56f9f9159f581433fba9d18876048e75d6478..7accc4b1cbc0d30805250f5d270a7e252fc314d3 100644 (file)
@@ -12,8 +12,9 @@ big-endian off
 [
     ! Optimizing compiler's side of callback accesses
     ! arguments that are on the stack via the frame pointer.
-    ! On x86-64, some arguments are passed in registers, and
-    ! so the only register that is safe for use here is nv-reg.
+    ! On x86-32 fastcall, and x86-64, some arguments are passed
+    ! in registers, and so the only registers that are safe for
+    ! use here are frame-reg, nv-reg and vm-reg.
     frame-reg PUSH
     frame-reg stack-reg MOV
 
@@ -65,23 +66,24 @@ big-endian off
 
     frame-reg POP
 
-    ! Callbacks which return structs, or use stdcall, need a
-    ! parameter here. See the comment in callback-return-rewind
-    ! in cpu.x86.32
+    ! Callbacks which return structs, or use stdcall/fastcall/thiscall,
+    ! need a parameter here.
+
+    ! See the comment for M\ x86.32 stack-cleanup in cpu.x86.32
     HEX: ffff RET rc-absolute-2 rt-untagged jit-rel
 ] callback-stub jit-define
 
 [
     ! Load word
-    nv-reg 0 MOV rc-absolute-cell rt-literal jit-rel
+    temp0 0 MOV rc-absolute-cell rt-literal jit-rel
     ! Bump profiling counter
-    nv-reg profile-count-offset [+] 1 tag-fixnum ADD
+    temp0 profile-count-offset [+] 1 tag-fixnum ADD
     ! Load word->code
-    nv-reg nv-reg word-code-offset [+] MOV
+    temp0 temp0 word-code-offset [+] MOV
     ! Compute word entry point
-    nv-reg compiled-header-size ADD
+    temp0 compiled-header-size ADD
     ! Jump to entry point
-    nv-reg JMP
+    temp0 JMP
 ] jit-profiling jit-define
 
 [
@@ -200,7 +202,7 @@ big-endian off
 
 ! ! ! Polymorphic inline caches
 
-! The PIC stubs are not permitted to touch temp3.
+! The PIC stubs are not permitted to touch pic-tail-reg.
 
 ! Load a value from a stack position
 [
@@ -477,23 +479,23 @@ big-endian off
     ! load value
     temp3 ds-reg [] MOV
     ! make a copy
-    temp1 temp3 MOV
-    ! compute positive shift value in temp1
-    temp1 CL SHL
+    temp2 temp3 MOV
+    ! compute positive shift value in temp2
+    temp2 CL SHL
     shift-arg NEG
     ! compute negative shift value in temp3
     temp3 CL SAR
     temp3 tag-mask get bitnot AND
     shift-arg 0 CMP
-    ! if shift count was negative, move temp0 to temp1
-    temp1 temp3 CMOVGE
+    ! if shift count was negative, move temp0 to temp2
+    temp2 temp3 CMOVGE
     ! push to stack
-    ds-reg [] temp1 MOV
+    ds-reg [] temp2 MOV
 ] \ fixnum-shift-fast define-sub-primitive
 
 : jit-fixnum-/mod ( -- )
     ! load second parameter
-    temp3 ds-reg [] MOV
+    temp1 ds-reg [] MOV
     ! load first parameter
     div-arg ds-reg bootstrap-cell neg [+] MOV
     ! make a copy
@@ -501,7 +503,7 @@ big-endian off
     ! sign-extend
     mod-arg bootstrap-cell-bits 1 - SAR
     ! divide
-    temp3 IDIV ;
+    temp1 IDIV ;
 
 [
     jit-fixnum-/mod
index 30b2ce3b57accf63cd05a6aaa80bbcd16f89e275..7913489178493267c5628a09419c077e5958cfcb 100644 (file)
@@ -9,7 +9,7 @@ IN: cpu.x86.features
 <PRIVATE
 
 : (sse-version) ( -- n )
-    int { } "cdecl" [
+    int { } cdecl [
         "sse-42" define-label
         "sse-41" define-label
         "ssse-3" define-label
@@ -97,12 +97,12 @@ MEMO: sse-version ( -- n )
 HOOK: instruction-count cpu ( -- n )
 
 M: x86.32 instruction-count
-    longlong { } "cdecl" [
+    longlong { } cdecl [
         RDTSC
     ] alien-assembly ;
 
 M: x86.64 instruction-count
-    longlong { } "cdecl" [
+    longlong { } cdecl [
         RAX 0 MOV
         RDTSC
         RDX 32 SHL
index acd2e1358dbdb9b7f1e95dd041728f5f6b37ee74..028cca48e3774f300309edd1f796fec15c7726f6 100644 (file)
@@ -41,6 +41,8 @@ HOOK: extra-stack-space cpu ( stack-frame -- n )
 
 : gc-root@ ( n -- op ) gc-root-offset special@ ;
 
+: param@ ( n -- op ) reserved-stack-space + stack@ ;
+
 : decr-stack-reg ( n -- )
     dup 0 = [ drop ] [ stack-reg swap SUB ] if ;
 
index 812507a20f64efc6d425e3d68666c7d6787aed98..99078ca85d0b87aeea9c2e65d449060f11a506b1 100644 (file)
@@ -9,7 +9,7 @@ IN: db.postgresql.ffi
     { [ os winnt? ]  [ "libpq.dll" ] }
     { [ os macosx? ] [ "libpq.dylib" ] }
     { [ os unix?  ]  [ "libpq.so" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
 
 ! ConnSatusType
 CONSTANT: CONNECTION_OK                     HEX: 0
index f93b9617994950861ce3613e366cd3e1419e929a..d9da317c89b3b47c09062302e81a9c64f6c51b75 100644 (file)
@@ -10,7 +10,7 @@ IN: db.sqlite.ffi
         { [ os winnt? ]  [ "sqlite3.dll" ] }
         { [ os macosx? ] [ "/usr/lib/libsqlite3.dylib" ] }
         { [ os unix? ]  [ "libsqlite3.so" ] }
-    } cond "cdecl" add-library >>
+    } cond cdecl add-library >>
 
 ! Return values from sqlite functions
 CONSTANT: SQLITE_OK           0 ! Successful result
index 157a426e19e783769ba82c6fd44910ca2ae8def2..7447f24151e2d26bad9afe23970e202781d08820 100644 (file)
@@ -8,14 +8,14 @@ IN: glib
 <<
 
 {
-    { [ os winnt? ] [ "glib" "libglib-2.0-0.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "glib" "/opt/local/lib/libglib-2.0.0.dylib" "cdecl" add-library ] }
+    { [ os winnt? ] [ "glib" "libglib-2.0-0.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "glib" "/opt/local/lib/libglib-2.0.0.dylib" cdecl add-library ] }
     { [ os unix? ] [ ] }
 } cond
 
 {
-    { [ os winnt? ] [ "gobject" "libgobject-2.0-0.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "gobject" "/opt/local/lib/libgobject-2.0.0.dylib" "cdecl" add-library ] }
+    { [ os winnt? ] [ "gobject" "libgobject-2.0-0.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "gobject" "/opt/local/lib/libgobject-2.0.0.dylib" cdecl add-library ] }
     { [ os unix? ] [ ] }
 } cond
 
index 05328b48dc9e34f438ee3af44460638e73c7f486..ea31292c065027af73c3573a77599fa877c669c0 100644 (file)
@@ -11,7 +11,7 @@ TUPLE: run-loop-mx kqueue-mx ;
 
 : file-descriptor-callback ( -- callback )
     void { CFFileDescriptorRef CFOptionFlags void* }
-    "cdecl" [
+    cdecl [
         3drop
         0 mx get kqueue-mx>> wait-for-events
         reset-run-loop
index b3cf28a497909e1b22c91992d15e82157f3e10df..ca7ba0cd497671f4e234ffc5ecb173e0e28addb4 100644 (file)
@@ -31,7 +31,7 @@ TUPLE: openssl-context < secure-context aliens sessions ;
     ] [ drop ] if ;
 
 : password-callback ( -- alien )
-    int { void* int bool void* } "cdecl"
+    int { void* int bool void* } cdecl
     [| buf size rwflag password! |
         password [ B{ 0 } password! ] unless
 
index 8eb2df5b4624f3725f89e608c9c198350f5c1883..7a961518a0463506366880ac4db4c912b1ef582d 100644 (file)
@@ -57,7 +57,7 @@ TUPLE: ConnectEx-args port
     } cleave
     int
     { SOCKET void* int PVOID DWORD LPDWORD void* }
-    "stdcall" alien-indirect drop
+    stdcall alien-indirect drop
     winsock-error-string [ throw ] when* ; inline
 
 M: object establish-connection ( client-out remote -- )
index ea3bee424f7763ccc7867da201db82eef40286f1..7d45f01337e79b03a21974f48d836f82e48f073d 100644 (file)
@@ -3,26 +3,26 @@ cpu.x86.assembler.operands math.floats.env.x86 system ;
 IN: math.floats.env.x86.32
 
 M: x86.32 get-sse-env
-    void { void* } "cdecl" [
+    void { void* } cdecl [
         EAX ESP [] MOV
         EAX [] STMXCSR
     ] alien-assembly ;
 
 M: x86.32 set-sse-env
-    void { void* } "cdecl" [
+    void { void* } cdecl [
         EAX ESP [] MOV
         EAX [] LDMXCSR
     ] alien-assembly ;
 
 M: x86.32 get-x87-env
-    void { void* } "cdecl" [
+    void { void* } cdecl [
         EAX ESP [] MOV
         EAX [] FNSTSW
         EAX 2 [+] FNSTCW
     ] alien-assembly ;
 
 M: x86.32 set-x87-env
-    void { void* } "cdecl" [
+    void { void* } cdecl [
         EAX ESP [] MOV
         FNCLEX
         EAX 2 [+] FLDCW
index b6f8ee151f71229bda479d6798ac27db7a22b1ad..93cb11104f9af8945f0e4cc654a008fa26969603 100644 (file)
@@ -3,23 +3,23 @@ cpu.x86.assembler.operands math.floats.env.x86 sequences system ;
 IN: math.floats.env.x86.64
 
 M: x86.64 get-sse-env
-    void { void* } "cdecl" [
-        int-regs param-regs first [] STMXCSR
+    void { void* } cdecl [
+        int-regs cdecl param-regs first [] STMXCSR
     ] alien-assembly ;
 
 M: x86.64 set-sse-env
-    void { void* } "cdecl" [
-        int-regs param-regs first [] LDMXCSR
+    void { void* } cdecl [
+        int-regs cdecl param-regs first [] LDMXCSR
     ] alien-assembly ;
 
 M: x86.64 get-x87-env
-    void { void* } "cdecl" [
-        int-regs param-regs first [] FNSTSW
-        int-regs param-regs first 2 [+] FNSTCW
+    void { void* } cdecl [
+        int-regs cdecl param-regs first [] FNSTSW
+        int-regs cdecl param-regs first 2 [+] FNSTCW
     ] alien-assembly ;
 
 M: x86.64 set-x87-env
-    void { void* } "cdecl" [
+    void { void* } cdecl [
         FNCLEX
-        int-regs param-regs first 2 [+] FLDCW
+        int-regs cdecl param-regs first 2 [+] FLDCW
     ] alien-assembly ;
index 9e095a62e6b205314023943dfde6fca03fc893e7..aeaa5da4eb759dfdb75e84b038abad88ca6bd104 100644 (file)
@@ -3,4 +3,4 @@ IN: opengl.gl.macosx
 
 : gl-function-context ( -- context ) 0 ; inline
 : gl-function-address ( name -- address ) f dlsym ; inline
-: gl-function-calling-convention ( -- str ) "cdecl" ; inline
+: gl-function-calling-convention ( -- str ) cdecl ; inline
index 3352b18350264dbc39055abfa731a89e969beb3b..c0a0218ed2fc4854ce891d58b4f84b3a0621e25e 100644 (file)
@@ -1,6 +1,6 @@
-USING: kernel x11.glx ;
+USING: alien kernel x11.glx ;
 IN: opengl.gl.unix
 
 : gl-function-context ( -- context ) glXGetCurrentContext ; inline
 : gl-function-address ( name -- address ) glXGetProcAddressARB ; inline
-: gl-function-calling-convention ( -- str ) "cdecl" ; inline
+: gl-function-calling-convention ( -- str ) cdecl ; inline
index 8bceb865e2aff33c2d6b5f5cb7896ac5b6af59ab..eda1e3178e7cbe08b84ea251d196eb22ada91e94 100644 (file)
@@ -1,4 +1,4 @@
-USING: alien.c-types alien.syntax kernel windows.types ;
+USING: alien alien.c-types alien.syntax kernel windows.types ;
 IN: opengl.gl.windows
 
 LIBRARY: gl
@@ -8,4 +8,4 @@ FUNCTION: void* wglGetProcAddress ( c-string name ) ;
 
 : gl-function-context ( -- context ) wglGetCurrentContext ; inline
 : gl-function-address ( name -- address ) wglGetProcAddress ; inline
-: gl-function-calling-convention ( -- str ) "stdcall" ; inline
+: gl-function-calling-convention ( -- str ) stdcall ; inline
index f9983d7813522c6caa730fadcd92d7b7f9b28cee..fb39a8e51bef955c6c4fa5666914ac3bea53f078 100644 (file)
@@ -14,9 +14,9 @@ IN: openssl.libcrypto
 {
     { [ os openbsd? ] [ ] } ! VM is linked with it
     { [ os netbsd? ] [ ] }
-    { [ os winnt? ] [ "libcrypto" "libeay32.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "libcrypto" "libcrypto.dylib" "cdecl" add-library ] }
-    { [ os unix? ] [ "libcrypto" "libcrypto.so" "cdecl" add-library ] }
+    { [ os winnt? ] [ "libcrypto" "libeay32.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "libcrypto" "libcrypto.dylib" cdecl add-library ] }
+    { [ os unix? ] [ "libcrypto" "libcrypto.so" cdecl add-library ] }
 } cond
 >>
 
index 96d235d271fc5c98f8842f900b72a98067747e45..272b1bb17ebaef2819a6f255c8d03a5aecc9d174 100644 (file)
@@ -10,9 +10,9 @@ IN: openssl.libssl
 << {
     { [ os openbsd? ] [ ] } ! VM is linked with it
     { [ os netbsd? ] [ ] }
-    { [ os winnt? ] [ "libssl" "ssleay32.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "libssl" "libssl.dylib" "cdecl" add-library ] }
-    { [ os unix? ] [ "libssl" "libssl.so" "cdecl" add-library ] }
+    { [ os winnt? ] [ "libssl" "ssleay32.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "libssl" "libssl.dylib" cdecl add-library ] }
+    { [ os unix? ] [ "libssl" "libssl.so" cdecl add-library ] }
 } cond >>
 
 CONSTANT: X509_FILETYPE_PEM       1
index d6baaffe2e77da6557751c3b40d320e5ff6819e1..85d4cef4241ac77d9f9dff47c339e41fee374f2f 100644 (file)
@@ -12,8 +12,8 @@ classes.struct cairo cairo.ffi ;
 IN: pango.cairo
 
 << {
-    { [ os winnt? ] [ "pangocairo" "libpangocairo-1.0-0.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "pangocairo" "/opt/local/lib/libpangocairo-1.0.0.dylib" "cdecl" add-library ] }
+    { [ os winnt? ] [ "pangocairo" "libpangocairo-1.0-0.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "pangocairo" "/opt/local/lib/libpangocairo-1.0.0.dylib" cdecl add-library ] }
     { [ os unix? ] [ ] }
 } cond >>
 
index 6dc48e39fe261e4c682ac6fcf5de1998393a7e68..3a249c664c6a99be83cfe5f6d45e227bf997ac70 100644 (file)
@@ -11,8 +11,8 @@ IN: pango
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 << {
-    { [ os winnt? ] [ "pango" "libpango-1.0-0.dll" "cdecl" add-library ] }
-    { [ os macosx? ] [ "pango" "/opt/local/lib/libpango-1.0.0.dylib" "cdecl" add-library ] }
+    { [ os winnt? ] [ "pango" "libpango-1.0-0.dll" cdecl add-library ] }
+    { [ os macosx? ] [ "pango" "/opt/local/lib/libpango-1.0.0.dylib" cdecl add-library ] }
     { [ os unix? ] [ ] }
 } cond >>
 
index 9039c5d3f0e4c59ac4773a49134520455778eaab..1c6b37b7dff2fe5521e00b14b9ca4dd085792ed6 100644 (file)
@@ -107,8 +107,7 @@ TUPLE: alien-callback-params < alien-node-params quot xt ;
     [ callbacks get ] dip '[ _ <callback> ] cache ;
 
 : callback-bottom ( params -- )
-    [ xt>> ] [ callback-return-rewind ] bi
-    '[ _ _ callback-xt ] infer-quot-here ;
+    [ xt>> ] [ stack-cleanup ] bi '[ _ _ callback-xt ] infer-quot-here ;
 
 : infer-alien-callback ( -- )
     alien-callback-params new
index 642ee48e6769a8b6f3a58e8154d5f198ff6ad6bc..73dade6657f409d6a9eeb747acccc1688f0e47ac 100644 (file)
@@ -2,9 +2,9 @@ USING: alien alien.c-types kernel math ;
 IN: tools.deploy.test.9
 
 : callback-test ( -- callback )
-    int { int } "cdecl" [ 1 + ] alien-callback ;
+    int { int } cdecl [ 1 + ] alien-callback ;
 
 : indirect-test ( -- )
-    10 callback-test int { int } "cdecl" alien-indirect 11 assert= ;
+    10 callback-test int { int } cdecl alien-indirect 11 assert= ;
 
 MAIN: indirect-test
index c0b3c9a586cedb2f8e506bc515f63280a9a65993..c8df2f1094d851949ac8d7634dc4c9dce4f84159 100644 (file)
@@ -15,6 +15,11 @@ HOOK: disassemble* disassembler-backend ( from to -- lines )
 
 TR: tabs>spaces "\t" "\s" ;
 
+GENERIC: (>address) ( object -- n )
+
+M: integer (>address) ;
+M: alien (>address) alien-address ;
+
 PRIVATE>
 
 M: byte-array disassemble 
@@ -24,7 +29,7 @@ M: byte-array disassemble
         2array disassemble
     ] with-destructors ;
 
-M: pair disassemble first2 disassemble* [ tabs>spaces print ] each ;
+M: pair disassemble first2 [ (>address) ] bi@ disassemble* [ tabs>spaces print ] each ;
 
 M: word disassemble word-code 2array disassemble ;
 
index 5e46a3468230922928e0ca8cbd3f2f9d2a32e384..e998a5cfdb2af984fa3a327533b70e5e63ff9134 100644 (file)
@@ -12,7 +12,7 @@ IN: tools.disassembler.udis
     { [ os macosx? ] [ "libudis86.0.dylib" ] }
     { [ os unix? ] [ "libudis86.so.0" ] }
     { [ os winnt? ] [ "libudis86.dll" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
 >>
 
 LIBRARY: libudis86
index 5c31cdaeb481b664ca6359db8db32939178e0bba..b02b800463f2b94a5044dc6d0e83a1834793e32e 100644 (file)
@@ -21,9 +21,9 @@ IN: tools.profiler.tests
 
 [ ] [ \ + usage-profile. ] unit-test
 
-: callback-test ( -- callback ) void { } "cdecl" [ ] alien-callback ;
+: callback-test ( -- callback ) void { } cdecl [ ] alien-callback ;
 
-: indirect-test ( callback -- ) void { } "cdecl" alien-indirect ;
+: indirect-test ( callback -- ) void { } cdecl alien-indirect ;
 
 : foobar ( -- ) ;
 
index c0829e5c8dada706571cf4c3e319899aedfcc526..e0be2e7c9971ccc2f7f836a3a1fe17ea6608ebe8 100644 (file)
@@ -609,7 +609,7 @@ SYMBOL: trace-messages?
 
 ! return 0 if you handle the message, else just let DefWindowProc return its val
 : ui-wndproc ( -- object )
-    uint { void* uint long long } "stdcall" [
+    uint { void* uint long long } stdcall [
         pick
         trace-messages? get-global [ dup windows-message-name name>> print flush ] when
         wm-handlers get-global at* [ call ] [ drop DefWindowProc ] if
index 555bab32e4a7659b652ca849bcd195dc868674ad..1809ee4b687bc09b7b51ab1326f22d4af2e67e8b 100644 (file)
@@ -156,4 +156,4 @@ FUNCTION: int unlink ( c-string path ) ;
 FUNCTION: int utimes ( c-string path, timeval[2] times ) ;
 FUNCTION: ssize_t write ( int fd, void* buf, size_t nbytes ) ;
 
-"librt" "librt.so" "cdecl" add-library
+"librt" "librt.so" cdecl add-library
index ff6a9ad4fcb4eeaeca9c7a429f230227bd07b961..614a535ea0ce747eea02c17fd2e9b4414e74c659 100644 (file)
@@ -1,14 +1,14 @@
 USING: alien sequences alien.libraries ;
 {
-    { "advapi32" "\\windows\\coredll.dll" "stdcall" }
-    { "gdi32"    "\\windows\\coredll.dll" "stdcall" }
-    { "user32"   "\\windows\\coredll.dll" "stdcall" }
-    { "kernel32" "\\windows\\coredll.dll" "stdcall" }
-    { "winsock"  "\\windows\\ws2.dll" "stdcall" }
-    { "mswsock"  "\\windows\\ws2.dll" "stdcall" }
-    { "libc"     "\\windows\\coredll.dll" "stdcall"   }
-    { "libm"     "\\windows\\coredll.dll" "stdcall"   }
-    ! { "gl"       "libGLES_CM.dll"         "stdcall" }
-    ! { "glu"      "libGLES_CM.dll"         "stdcall" }
-    { "ole32"    "ole32.dll"    "stdcall" }
+    { "advapi32" "\\windows\\coredll.dll" stdcall }
+    { "gdi32"    "\\windows\\coredll.dll" stdcall }
+    { "user32"   "\\windows\\coredll.dll" stdcall }
+    { "kernel32" "\\windows\\coredll.dll" stdcall }
+    { "winsock"  "\\windows\\ws2.dll" stdcall }
+    { "mswsock"  "\\windows\\ws2.dll" stdcall }
+    { "libc"     "\\windows\\coredll.dll" stdcall   }
+    { "libm"     "\\windows\\coredll.dll" stdcall   }
+    ! { "gl"       "libGLES_CM.dll"         stdcall }
+    ! { "glu"      "libGLES_CM.dll"         stdcall }
+    { "ole32"    "ole32.dll"    stdcall }
 } [ first3 add-library ] each
index 78a3c0e6d2c5280c2a7f577c48bb3c29c5c0328e..9d74ac49f894cb7cad0d1dae932e82e4db71be83 100644 (file)
@@ -12,7 +12,7 @@ MACRO: com-invoke ( n return parameters -- )
     [ 2nip length ] 3keep
     '[
         _ npick *void* _ cell * alien-cell _ _
-        "stdcall" alien-indirect
+        stdcall alien-indirect
     ] ;
 
 TUPLE: com-interface-definition word parent iid functions ;
index 25861659dc6d80f2661e736c1c30eeac45445367..6f92c8b860cfd8f97f0481b4f7f6e7feef210110 100644 (file)
@@ -114,7 +114,7 @@ unless
         ] [
             first2 (finish-thunk)
         ] bi*
-        "stdcall" swap compile-alien-callback
+        stdcall swap compile-alien-callback
     ] 2map ;
 
 : (make-callbacks) ( implementations -- sequence )
index 6c760fd014387d3e675431ba1157d24af00e6607..d832a9d40559b7ae3242dfe8ac5cf87dc97c1dd3 100644 (file)
@@ -4,7 +4,7 @@ USING: alien.c-types alien.libraries alien.syntax classes.struct
 kernel math windows.types windows.ole32 ;
 IN: windows.ddk.hid
 
-<< "hid" "hid.dll" "stdcall" add-library >>
+<< "hid" "hid.dll" stdcall add-library >>
 LIBRARY: hid
 
 TYPEDEF: LONG   NTSTATUS
index f3289506485c0bc372d78ef87acc7dafd47b8cae..e4658b6e750682f5ccb565baeed979b80b275dfb 100644 (file)
@@ -4,7 +4,7 @@ USING: literals windows.kernel32 math alien.syntax windows.types classes.struct
 alien.c-types windows.errors windows.ole32 windows.advapi32 alien.libraries ;
 IN: windows.ddk.setupapi
 
-<< "setupapi" "setupapi.dll" "stdcall" add-library >>
+<< "setupapi" "setupapi.dll" stdcall add-library >>
 LIBRARY: setupapi
 
 TYPEDEF: DWORDLONG SP_LOG_TOKEN
index 5e43b7f884821e95a34242f01a78c60237030843..d40c994b19bd695daaa6ce1f544e852fbc268ae3 100644 (file)
@@ -4,7 +4,7 @@ USING: alien.c-types alien.syntax classes.struct windows.kernel32
 windows.types alien.libraries ;
 IN: windows.ddk.winusb
 
-<< "winusb" "winusb.dll" "stdcall" add-library >>
+<< "winusb" "winusb.dll" stdcall add-library >>
 LIBRARY: winusb
 
 TYPEDEF: PVOID WINUSB_INTERFACE_HANDLE
index 998846ebc2bbe272ab9a9abb8cc029ad1b87ee88..8f68643e0a5da839241055a5f4b740c192e85cee 100644 (file)
@@ -21,7 +21,7 @@ STRUCT: DWM_BLURBEHIND
 : full-window-margins ( -- MARGINS )
     -1 -1 -1 -1 <MARGINS> ; inline
 
-<< "dwmapi" "dwmapi.dll" "stdcall" add-library >>
+<< "dwmapi" "dwmapi.dll" stdcall add-library >>
 
 LIBRARY: dwmapi
 
index 8e831e153e0cf7f9399fb829efc4081e0f2cda39..4b119ba5faced6e1fbd3b6a678bd43d71345c9ca 100644 (file)
@@ -1,35 +1,35 @@
 USING: alien sequences alien.libraries ;
 {
-    { "advapi32"    "advapi32.dll"       "stdcall" }
-    { "dinput"      "dinput8.dll"        "stdcall" }
-    { "gdi32"       "gdi32.dll"          "stdcall" }
-    { "user32"      "user32.dll"         "stdcall" }
-    { "kernel32"    "kernel32.dll"       "stdcall" }
-    { "winsock"     "ws2_32.dll"         "stdcall" }
-    { "mswsock"     "mswsock.dll"        "stdcall" }
-    { "shell32"     "shell32.dll"        "stdcall" }
-    { "libc"        "msvcrt.dll"         "cdecl"   }
-    { "libm"        "msvcrt.dll"         "cdecl"   }
-    { "gl"          "opengl32.dll"       "stdcall" }
-    { "glu"         "glu32.dll"          "stdcall" }
-    { "ole32"       "ole32.dll"          "stdcall" }
-    { "usp10"       "usp10.dll"          "stdcall" }
-    { "psapi"       "psapi.dll"          "stdcall" }
-    { "xinput"      "xinput1_3.dll"      "stdcall" }
-    { "dxgi"        "dxgi.dll"           "stdcall" }
-    { "d2d1"        "d2d1.dll"           "stdcall" }
-    { "d3d9"        "d3d9.dll"           "stdcall" }
-    { "d3d10"       "d3d10.dll"          "stdcall" }
-    { "d3d10_1"     "d3d10_1.dll"        "stdcall" }
-    { "d3d11"       "d3d11.dll"          "stdcall" }
-    { "d3dcompiler" "d3dcompiler_42.dll" "stdcall" } 
-    { "d3dcsx"      "d3dcsx_42.dll"      "stdcall" }
-    { "d3dx9"       "d3dx9_42.dll"       "stdcall" }
-    { "d3dx10"      "d3dx10_42.dll"      "stdcall" }
-    { "d3dx11"      "d3dx11_42.dll"      "stdcall" }
-    { "dwrite"      "dwrite.dll"         "stdcall" }
-    { "x3daudio"    "x3daudio1_6.dll"    "stdcall" }
-    { "xactengine"  "xactengine3_5.dll"  "stdcall" }
-    { "xapofx"      "xapofx1_3.dll"      "stdcall" }
-    { "xaudio2"     "xaudio2_5.dll"      "stdcall" }
+    { "advapi32"    "advapi32.dll"       stdcall }
+    { "dinput"      "dinput8.dll"        stdcall }
+    { "gdi32"       "gdi32.dll"          stdcall }
+    { "user32"      "user32.dll"         stdcall }
+    { "kernel32"    "kernel32.dll"       stdcall }
+    { "winsock"     "ws2_32.dll"         stdcall }
+    { "mswsock"     "mswsock.dll"        stdcall }
+    { "shell32"     "shell32.dll"        stdcall }
+    { "libc"        "msvcrt.dll"         cdecl   }
+    { "libm"        "msvcrt.dll"         cdecl   }
+    { "gl"          "opengl32.dll"       stdcall }
+    { "glu"         "glu32.dll"          stdcall }
+    { "ole32"       "ole32.dll"          stdcall }
+    { "usp10"       "usp10.dll"          stdcall }
+    { "psapi"       "psapi.dll"          stdcall }
+    { "xinput"      "xinput1_3.dll"      stdcall }
+    { "dxgi"        "dxgi.dll"           stdcall }
+    { "d2d1"        "d2d1.dll"           stdcall }
+    { "d3d9"        "d3d9.dll"           stdcall }
+    { "d3d10"       "d3d10.dll"          stdcall }
+    { "d3d10_1"     "d3d10_1.dll"        stdcall }
+    { "d3d11"       "d3d11.dll"          stdcall }
+    { "d3dcompiler" "d3dcompiler_42.dll" stdcall } 
+    { "d3dcsx"      "d3dcsx_42.dll"      stdcall }
+    { "d3dx9"       "d3dx9_42.dll"       stdcall }
+    { "d3dx10"      "d3dx10_42.dll"      stdcall }
+    { "d3dx11"      "d3dx11_42.dll"      stdcall }
+    { "dwrite"      "dwrite.dll"         stdcall }
+    { "x3daudio"    "x3daudio1_6.dll"    stdcall }
+    { "xactengine"  "xactengine3_5.dll"  stdcall }
+    { "xapofx"      "xapofx1_3.dll"      stdcall }
+    { "xaudio2"     "xaudio2_5.dll"      stdcall }
 } [ first3 add-library ] each
index 5f91d4c695fd552c0740db49ed28a40ee1ecb356..96eb9002be7a340da8117bd09d7904725afea218 100644 (file)
@@ -5,6 +5,21 @@ alien.libraries alien.c-types quotations kernel
 sequences ;
 IN: alien
 
+HELP: cdecl
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that the standard C calling convention should be used, where the caller cleans up the stack frame after calling the function. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+HELP: stdcall
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that the Windows API calling convention should be used, where the called function cleans up its own stack frame before returning to the caller. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+HELP: fastcall
+{ $warning "In the current implementation this ABI only works for functions that take only integer and pointer arguments." }
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that the \"fast call\" calling convention should be used, where the first two integer or pointer arguments are passed in registers and the function cleans up its own stack frame before returning to the caller. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+HELP: thiscall
+{ $description "This symbol is passed as the " { $snippet "abi" } " argument to " { $link alien-indirect } ", " { $link alien-callback } ", " { $link alien-assembly } ", and " { $link add-library } " to indicate that Microsoft Visual C++ calling convention should be used, where the first argument (which must be a \"this\" pointer) is passed in a register and the function cleans up its own stack frame before returning to the caller. This symbol only has meaning on 32-bit x86 platforms." } ;
+
+{ cdecl stdcall fastcall thiscall } related-words
+
 HELP: >c-ptr
 { $values { "obj" object } { "c-ptr" c-ptr } }
 { $contract "Outputs a pointer to the binary data of this object." } ;
@@ -85,7 +100,7 @@ HELP: alien-indirect-error
 } ;
 
 HELP: alien-indirect
-{ $values { "args..." "zero or more objects passed to the C function" } { "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\"" } } { "return..." "the return value of the function, if not " { $link void } } }
+{ $values { "args..." "zero or more objects passed to the C function" } { "funcptr" "a C function pointer" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } { "return..." "the return value of the function, if not " { $link void } } }
 { $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 " { $link void } " indicates that no value is to be expected."
 }
@@ -101,7 +116,7 @@ HELP: alien-callback-error
 } ;
 
 HELP: alien-callback
-{ $values { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } { "quot" quotation } { "alien" alien } }
+{ $values { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } { "quot" quotation } { "alien" alien } }
 { $description
     "Defines a callback from C to Factor which accepts the given set of parameters from the C caller, pushes them on the data stack, calls the quotation, and passes a return value back to the C caller. A return type of " { $snippet "void" } " indicates that no value is to be returned."
     $nl
@@ -114,7 +129,7 @@ HELP: alien-callback
     "A simple example, showing a C function which returns the difference of two given integers:"
     { $code
         ": difference-callback ( -- alien )"
-        "    int { int int } \"cdecl\" [ - ] alien-callback ;"
+        "    int { int int } cdecl [ - ] alien-callback ;"
     }
 }
 { $errors "Throws an " { $link alien-callback-error } " if the word calling " { $link alien-callback } " is not compiled." } ;
@@ -128,7 +143,7 @@ HELP: alien-assembly-error
 } ;
 
 HELP: alien-assembly
-{ $values { "args..." "zero or more objects passed to the C function" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } { "quot" quotation } { "return..." "the return value of the function, if not " { $link void } } }
+{ $values { "args..." "zero or more objects passed to the C function" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } { "quot" quotation } { "return..." "the return value of the function, if not " { $link void } } }
 { $description
     "Invokes arbitrary machine code, generated at compile-time by the quotation. 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 " { $link void } " indicates that no value is to be expected."
 }
index a44d703fbc316b083097f2163617b7daf0652f7f..27e326a55777e3b4c76775a01cc1a5e4afdabbb3 100644 (file)
@@ -64,6 +64,10 @@ M: alien equal?
 M: pinned-alien hashcode*
     nip dup expired>> [ drop 1234 ] [ alien-address ] if ;
 
+SINGLETONS: stdcall thiscall fastcall cdecl mingw ;
+
+UNION: abi stdcall thiscall fastcall cdecl mingw ;
+
 ERROR: alien-callback-error ;
 
 : alien-callback ( return parameters abi quot -- alien )
index 561110d941d0624760c000a1a22e4f9cd8695008..1ae1c6a34da1d625c8ef3316d00c2df9a6ac0a2e 100644 (file)
@@ -2,12 +2,12 @@ USING: math kernel alien alien.c-types ;
 IN: benchmark.fib6\r
 \r
 : fib ( x -- y )\r
-    int { int } "cdecl" [\r
+    int { int } cdecl [\r
         dup 1 <= [ drop 1 ] [\r
             1 - dup fib swap 1 - fib +\r
         ] if\r
     ] alien-callback\r
-    int { int } "cdecl" alien-indirect ;\r
+    int { int } cdecl alien-indirect ;\r
 \r
 : fib-main ( -- ) 32 fib drop ;\r
 \r
index 7e46baf551c46a4ce18c3e5e641888971feb5b1f..857e746d260215e2fb438b718acd7029c942ed25 100644 (file)
@@ -1,8 +1,9 @@
 ! Copyright (C) 2010 Erik Charlebois
 ! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types alien.syntax classes.struct combinators
-combinators.short-circuit kernel math math.order sequences
-typed specialized-arrays locals system alien.libraries ;
+USING: accessors alien alien.c-types alien.libraries
+alien.syntax classes.struct combinators combinators.short-circuit
+kernel math math.order sequences typed specialized-arrays locals
+system ;
 SPECIALIZED-ARRAY: void*
 IN: chipmunk.ffi
 
@@ -11,7 +12,7 @@ IN: chipmunk.ffi
     { [ os windows? ] [ "chipmunk.dll" ] }
     { [ os macosx? ] [ "libchipmunk.dylib"  ] }
     { [ os unix?  ] [ "libchipmunk.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
 
 "chipmunk" deploy-library
 >>
index 222885b72c7e6c85bd6829ff01b813c2b52e63bc..2b52d0ec566d3a84b5afd096f489ce447bf0e679 100644 (file)
@@ -8,7 +8,7 @@ IN: curses.ffi
     { [ os winnt? ]  [ "libcurses.dll" ] }
     { [ os macosx? ] [ "libcurses.dylib" ] }
     { [ os unix?  ]  [ "libcurses.so" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
 
 C-TYPE: WINDOW
 C-TYPE: SCREEN
index 44eb6bc16c4640eeb3fe4c4e0c0b564872e1446d..df168a900878da7c5f4e0c52c252c79917b4f6d8 100644 (file)
@@ -1,5 +1,5 @@
 ! (c)2010 Joe Groff bsd license
-USING: accessors cursors make math sequences sorting tools.test ;
+USING: accessors cursors kernel make math sequences sorting tools.test ;
 FROM: cursors => each map assoc-each assoc>map ;
 IN: cursors.tests
 
@@ -12,6 +12,10 @@ IN: cursors.tests
     T{ linear-cursor f 1 1 } T{ linear-cursor f 5 1 } [ value>> 3 mod zero? ] -find
 ] unit-test
 
+[ T{ linear-cursor f 5 1 } ] [
+    T{ linear-cursor f 1 1 } T{ linear-cursor f 5 1 } [ value>> 6 = ] -find
+] unit-test
+
 [ { 1 3 } ] [
     [ T{ linear-cursor f 1 2 } T{ linear-cursor f 5 2 } [ value>> , ] -each ]
     { } make
index 588f1670c219d4ebf3cbc98a42dcb42057bcb667..497ae883c10edcdec70a7d49bd41aa4dd17eb2b4 100644 (file)
@@ -5,8 +5,8 @@ alien.libraries classes.struct ;
 IN: freetype
 
 << "freetype" {
-    { [ os macosx? ] [ "/usr/X11R6/lib/libfreetype.6.dylib" "cdecl" add-library ] }
-    { [ os windows? ] [ "freetype6.dll" "cdecl" add-library ] }
+    { [ os macosx? ] [ "/usr/X11R6/lib/libfreetype.6.dylib" cdecl add-library ] }
+    { [ os windows? ] [ "freetype6.dll" cdecl add-library ] }
     { [ t ] [ drop ] }
 } cond >>
 
index e2ef40d81ea6fcbe063a9d4f56ba2251151ed033..10306c4816612889b056fabf1a10c558ad71537e 100644 (file)
@@ -11,7 +11,7 @@ IN: libusb
         { [ os windows? ] [ "libusb-1.0.dll" ] }
         { [ os macosx? ] [ "libusb-1.0.dylib"  ] }
         { [ os unix?  ] [ "libusb-1.0.so" ] }
-    } cond "cdecl" add-library >>
+    } cond cdecl add-library >>
 LIBRARY: libusb
 
 : libusb_cpu_to_le16 ( x -- y )
index b15a7150bfdb59baaa1caa8a13239dc75050da54..0ab43c6ab6b51085e0e1573100d0bd56c49cb4f3 100644 (file)
@@ -12,7 +12,7 @@ IN: llvm.core
         { [ os macosx? ] [ "/usr/local/lib/lib" ".dylib" surround ] }
         { [ os windows? ] [ ".dll" append ] }
         { [ os unix? ] [ "lib" ".so" surround ] }
-    } cond "cdecl" add-library ;
+    } cond cdecl add-library ;
 
 "LLVMSystem" add-llvm-library
 "LLVMSupport" add-llvm-library
index 87f39944d934b1fbc050d3ed600cfe1f77961478..cc3480fe49c586b5268eb4ea64a955cce39d2485 100644 (file)
@@ -41,7 +41,7 @@ TUPLE: function name alien return params ;
         dup name>> function-pointer ,
         dup return>> c-type ,
         dup params>> [ second c-type ] map ,
-        "cdecl" , \ alien-indirect ,
+        cdecl , \ alien-indirect ,
     ] [ ] make swap function-effect [ define-declared ] with-compilation-unit ;
 
 : install-module ( name -- )
index d7abece8bc4b50da2ee1ea422458ae3b484ef6bd..51e462147618b2d415dca1f0bb1b418e246a8284 100644 (file)
@@ -18,7 +18,7 @@ IN: ogg
     { [ os winnt? ]  [ "ogg.dll" ] }
     { [ os macosx? ] [ "libogg.0.dylib" ] }
     { [ os unix? ]   [ "libogg.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
 
 "ogg" deploy-library
 >>
index eb79613496a0490080d0471a9d188e1c16908387..82f4a7db5166e12b49b2991d8d7ebfbe333d2ee5 100644 (file)
@@ -19,13 +19,13 @@ IN: ogg.theora
     { [ os winnt? ]  [ "theoradec.dll" ] }
     { [ os macosx? ] [ "libtheoradec.0.dylib" ] }
     { [ os unix? ]   [ "libtheoradec.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
 
 "theoraenc" {
     { [ os winnt? ]  [ "theoraenc.dll" ] }
     { [ os macosx? ] [ "libtheoraenc.0.dylib" ] }
     { [ os unix? ]   [ "libtheoraenc.so" ] }
-} cond "cdecl" add-library
+} cond cdecl add-library
 >>
 
 CONSTANT: TH-EFAULT      -1
index ad43750e2741ff0a3fc98ce0ea92854987bf2257..3cefbeebec517a7f7e4b25b607ae1822620b5c5c 100644 (file)
@@ -19,7 +19,7 @@ IN: ogg.vorbis
     { [ os winnt? ]  [ "vorbis.dll" ] }
     { [ os macosx? ] [ "libvorbis.0.dylib" ] }
     { [ os unix? ]   [ "libvorbis.so" ] }
-} cond "cdecl" add-library 
+} cond cdecl add-library 
 
 "vorbis" deploy-library
 >>
index 0bf851164709589cff6ea148c847cfb45b4dc0bb..07b2e4c2b610bf09585040a4801706354628c269 100755 (executable)
@@ -14,7 +14,7 @@ IN: openal.alut
             "/System/Library/Frameworks/OpenAL.framework/OpenAL"
         ] }
         { [ os unix?  ]  [ "libalut.so" ] }
-    } cond "cdecl" add-library >>
+    } cond cdecl add-library >>
 
 << os macosx? [ "alut" deploy-library ] unless >>
 
index bbe61f9dc377f750b26db9dc0c60c365671c6966..853b33b38627b2a1d31034000be6006d2acd6c72 100755 (executable)
@@ -14,7 +14,7 @@ IN: openal
             "/System/Library/Frameworks/OpenAL.framework/OpenAL"
         ] }
         { [ os unix?  ]  [ "libopenal.so" ] }
-    } cond "cdecl" add-library >>
+    } cond cdecl add-library >>
 
 << os macosx? [ "openal" deploy-library ] unless >>
 
index 8f0400dd20f23370446744858f7ddfb9e93e7868..9ee2135cb63e9de97f086a2a2e981c98e07b3284 100644 (file)
@@ -8,7 +8,7 @@ IN: opencl.ffi
         { [ os windows? ] [ "OpenCL.dll" ] }
         { [ os macosx? ] [ "/System/Library/Frameworks/OpenCL.framework/OpenCL" ] }
         { [ os unix? ] [ "libOpenCL.so" ] }
-    } cond "stdcall" add-library >>
+    } cond stdcall add-library >>
 LIBRARY: opencl
 
 ! cl_platform.h
index 86936fdd65654210e3f2b58a7d6f9984b261bbfc..856740d22956cad3d5c2ce5c49d53c37c236a466 100644 (file)
@@ -9,7 +9,7 @@ IN: opengl.glu
 os {
     { [ dup macosx? ] [ drop ] }
     { [ dup windows? ] [ drop ] }
-    { [ dup unix? ] [ drop "glu" "libGLU.so.1" "cdecl" add-library ] }
+    { [ dup unix? ] [ drop "glu" "libGLU.so.1" cdecl add-library ] }
 } cond
 
 >>
index 32938264ae746e38df2b3627d6513558f08d770a..0da3feafb51b48f11295355f925301557bf4f993 100644 (file)
@@ -9,7 +9,7 @@ IN: tokyo.alien.tcrdb
     { [ os macosx? ] [ "/opt/local/lib/libtokyotyrant.dylib" ] }
     { [ os unix? ] [ "libtokyotyrant.so" ] }
     { [ os windows? ] [ "tokyotyrant.dll" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
 
 LIBRARY: tokyotyrant
 
index 14ddbe99d1aea96fec86e1c8bc9070086e0b4a90..e5db5328cbcea273498d0781250ba7f559821409 100644 (file)
@@ -8,7 +8,7 @@ IN: tokyo.alien.tcutil
     { [ os macosx? ] [ "/opt/local/lib/libtokyocabinet.dylib" ] }
     { [ os unix? ] [ "libtokyocabinet.so" ] }
     { [ os windows? ] [ "tokyocabinet.dll" ] }
-} cond "cdecl" add-library >>
+} cond cdecl add-library >>
 
 LIBRARY: tokyocabinet
 
index ee69d954eafe13c785eb949914ce1887440cf762..6428bead751fdc9383f89409b9d041d95ceb2374 100644 (file)
@@ -76,7 +76,7 @@ PRIVATE>
 
 : compile-c-library ( -- )
     compile-library? [ compile-library ] when
-    c-library get dup library-path "cdecl" add-library ;
+    c-library get dup library-path cdecl add-library ;
 
 : define-c-function ( function types effect body -- )
     [
index 946364efc16eea7869b65e7af9f15f64910803ed..02bd38d0455017fc2316a02f87cac46c1a410a75 100644 (file)
@@ -13,9 +13,9 @@ USING: alien kernel system combinators alien.syntax ;
 IN: cryptlib.libcl
 
 << "libcl" {
-        { [ win32? ] [ "cl32.dll" "stdcall" ] }
-        { [ macosx? ] [ "libcl.dylib" "cdecl" ] }
-        { [ unix? ] [ "libcl.so" "cdecl" ] }
+        { [ win32? ] [ "cl32.dll" stdcall ] }
+        { [ macosx? ] [ "libcl.dylib" cdecl ] }
+        { [ unix? ] [ "libcl.so" cdecl ] }
     } cond add-library >>
 
 ! ===============================================
index c047393c99978165815f361667639f7a55c89ba8..98fd0b38cb403674a2fa63f68f251cb72f70504f 100644 (file)
@@ -6,9 +6,9 @@ USING: alien alien.syntax combinators kernel system ;
 IN: db.mysql.ffi
 
 << "mysql" {
-    { [ os winnt? ] [ "libmySQL.dll" "stdcall" ] }
-    { [ os macosx? ] [ "libmysqlclient.14.dylib" "cdecl" ] }
-    { [ os unix? ] [ "libmysqlclient.so.14" "cdecl" ] }
+    { [ os winnt? ] [ "libmySQL.dll" stdcall ] }
+    { [ os macosx? ] [ "libmysqlclient.14.dylib" cdecl ] }
+    { [ os unix? ] [ "libmysqlclient.so.14" cdecl ] }
 } cond add-library >>
 
 LIBRARY: mysql
index 49bc57b108033f0d8e0cfc6485b011e41cc00850..d809d899de82e7d58dd0f8d6b853747089ca8a5a 100644 (file)
@@ -296,61 +296,61 @@ FUNCTION: jint JNI_CreateJavaVM ( void** pvm, void** penv, void* args ) ;
   ] when ;
 
 : (destroy-java-vm) 
-  "int" { "void*" } "cdecl" alien-indirect ;
+  "int" { "void*" } cdecl alien-indirect ;
 
 : (attach-current-thread) 
-  "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ;
+  "int" { "void*" "void*" "void*" } cdecl alien-indirect ;
 
 : (detach-current-thread) 
-  "int" { "void*" } "cdecl" alien-indirect ;
+  "int" { "void*" } cdecl alien-indirect ;
 
 : (get-env) 
-  "int" { "void*" "void*" "int" } "cdecl" alien-indirect ;
+  "int" { "void*" "void*" "int" } cdecl alien-indirect ;
 
 : (attach-current-thread-as-daemon) 
-  "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ;
+  "int" { "void*" "void*" "void*" } cdecl alien-indirect ;
 
 : destroy-java-vm ( javavm -- int )
   dup JavaVM-functions JNIInvokeInterface-DestroyJavaVM (destroy-java-vm) ;
 
 : (get-version) 
-  "jint" { "JNIEnv*" } "cdecl" alien-indirect ;
+  "jint" { "JNIEnv*" } cdecl alien-indirect ;
 
 : get-version ( jnienv -- int )
   dup JNIEnv-functions JNINativeInterface-GetVersion (get-version) ;
   
 : (find-class) 
-  "void*" { "JNINativeInterface*" "char*" } "cdecl" alien-indirect ;
+  "void*" { "JNINativeInterface*" "char*" } cdecl alien-indirect ;
 
 : find-class ( name jnienv -- int )
   dup swapd JNIEnv-functions JNINativeInterface-FindClass (find-class) ;
 
 : (get-static-field-id) 
-  "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ;
+  "void*" { "JNINativeInterface*" "void*" "char*" "char*" } cdecl alien-indirect ;
 
 : get-static-field-id ( class name sig jnienv -- int )
   dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetStaticFieldID (get-static-field-id) ;
 
 : (get-static-object-field) 
-  "void*" { "JNINativeInterface*" "void*" "void*" } "cdecl" alien-indirect ;
+  "void*" { "JNINativeInterface*" "void*" "void*" } cdecl alien-indirect ;
 
 : get-static-object-field ( class id jnienv -- int )
   dup >r >r 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-GetStaticObjectField (get-static-object-field) ;
 
 : (get-method-id) 
-  "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ;
+  "void*" { "JNINativeInterface*" "void*" "char*" "char*" } cdecl alien-indirect ;
 
 : get-method-id ( class name sig jnienv -- int )
   dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetMethodID (get-method-id) ;
 
 : (new-string) 
-  "void*" { "JNINativeInterface*" "char*" "int" } "cdecl" alien-indirect ;
+  "void*" { "JNINativeInterface*" "char*" "int" } cdecl alien-indirect ;
 
 : new-string ( str jnienv -- str )
   dup >r >r dup length 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-NewString (new-string) ;
 
 : (call1) 
-  "void" { "JNINativeInterface*" "void*" "void*" "int" } "cdecl" alien-indirect ;
+  "void" { "JNINativeInterface*" "void*" "void*" "int" } cdecl alien-indirect ;
 
 : call1 ( obj method-id jstr jnienv -- )
   dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-CallObjectMethod (call1) ;
index 6db68840712a579f7a7f5d94978f7410288e44c6..9b7dd36a699345b7f53e49c115bbfe9e534e8d5b 100644 (file)
@@ -10,9 +10,9 @@ USING: alien alien.syntax combinators kernel system ;
 IN: ldap.libldap
 
 << "libldap" {
-    { [ win32? ]  [ "libldap.dll" "stdcall" ] }
-    { [ macosx? ] [ "libldap.dylib" "cdecl" ] }
-    { [ unix? ]   [ "libldap.so" "cdecl" ] }
+    { [ win32? ]  [ "libldap.dll" stdcall ] }
+    { [ macosx? ] [ "libldap.dylib" cdecl ] }
+    { [ unix? ]   [ "libldap.so" cdecl ] }
 } cond add-library >>
  
 : LDAP_VERSION1     1 ; inline
index 9877c700626d53e4945da172855eb3bebf0a28b7..093a110fba130a27d654ffb3e63583bae6c7edf8 100644 (file)
@@ -52,7 +52,7 @@ SYMBOL: def-hash-keys
         [ t ] [ f ]
         [ { } ]
         [ drop f ]
-        [ "cdecl" ]
+        [ cdecl ]
         [ first ] [ second ] [ third ] [ fourth ]
         [ ">" write ] [ "/>" write ]
     } ;
index 06d47b8937542bf6c4da3facc7e3081b355b2ce7..6dcddb5bd53f426c7c351ed37b8934c4c23e1ed4 100644 (file)
@@ -5,7 +5,7 @@ combinators alien.c-types strings sequences namespaces make
 words math threads io.encodings.ascii ;
 IN: odbc
 
-<< "odbc" "odbc32.dll" "stdcall" add-library >>
+<< "odbc" "odbc32.dll" stdcall add-library >>
 
 LIBRARY: odbc
 
index aa04aef39fb894848b9b32f951c1be8a95bf1275..4e8ebfc860b88548e6b4210dcf11f8cb786dfddf 100644 (file)
@@ -12,9 +12,9 @@ USING: alien alien.syntax combinators kernel system ;
 IN: oracle.liboci
 
 "oci" {
-    { [ os winnt? ] [ "oci.dll" "stdcall" ] }
-    { [ os macosx? ] [ "$DYLD_LIBRARY_PATH/libclntsh.dylib" "cdecl" ] }
-    { [ os unix? ] [ "$DYLD_LIBRARY_PATH/libclntsh.so.10.1" "cdecl" ] }
+    { [ os winnt? ] [ "oci.dll" stdcall ] }
+    { [ os macosx? ] [ "$DYLD_LIBRARY_PATH/libclntsh.dylib" cdecl ] }
+    { [ os unix? ] [ "$DYLD_LIBRARY_PATH/libclntsh.so.10.1" cdecl ] }
 } cond add-library
 
 ! ===============================================
index c980ab0baf5548a1328e0ee59a5396ba8047bf1e..f01feb494df0308d88f464a3635fd85b12c6248b 100644 (file)
@@ -10,9 +10,9 @@ USING: alien alien.syntax combinators system ;
 IN: pdf.libhpdf
 
 << "libhpdf" {
-    { [ win32? ] [ "libhpdf.dll" "stdcall" ] }
-    { [ macosx? ] [ "libhpdf.dylib" "cdecl" ] }
-    { [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" "cdecl" ] }
+    { [ win32? ] [ "libhpdf.dll" stdcall ] }
+    { [ macosx? ] [ "libhpdf.dylib" cdecl ] }
+    { [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" cdecl ] }
 } cond add-library >>
 
 ! compression mode
index 89da7a2db7be4a0ea6c93204dc50d01f0c1d104c..60508e8a27762d182e680604c712e6ec7d1abba8 100755 (executable)
@@ -15,7 +15,9 @@ void factor_vm::default_parameters(vm_parameters *p)
        p->datastack_size = 32 * sizeof(cell);
        p->retainstack_size = 32 * sizeof(cell);
 
-#ifdef FACTOR_PPC
+#if defined(__OpenBSD__) && defined(FACTOR_X86)
+       p->callstack_size = 64 * sizeof(cell);
+#elif defined(FACTOR_PPC)
        p->callstack_size = 256 * sizeof(cell);
 #else
        p->callstack_size = 128 * sizeof(cell);
index 11f7498f307445737de372a1c8cb7a45d1a69692..993ca18fa3039d15bccf9dbbfc283e3b3a8a5e64 100755 (executable)
@@ -329,3 +329,39 @@ short ffi_test_48(struct bool_field_test x)
 }
 
 #endif
+
+FACTOR_FASTCALL(int) ffi_test_49(int x) { return x + 1; }
+FACTOR_FASTCALL(int) ffi_test_50(int x, int y) { return x + y + 1; }
+FACTOR_FASTCALL(int) ffi_test_51(int x, int y, int z) { return x + y + z + 1; }
+FACTOR_FASTCALL(int) ffi_test_52(int x, float y, int z) { return x + y + z + 1; }
+FACTOR_FASTCALL(int) ffi_test_53(int x, float y, int z, int w)
+{
+       return x + y + z + w + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_54(struct test_struct_11 x, int y)
+{
+       return x.x + x.y + y + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_55(struct test_struct_11 x, int y, int z)
+{
+       return x.x + x.y + y + z + 1;
+}
+
+FACTOR_FASTCALL(int) ffi_test_56(struct test_struct_11 x, int y, int z, int w)
+{
+       return x.x + x.y + y + z + w + 1;
+}
+
+FACTOR_FASTCALL(struct test_struct_11) ffi_test_57(int x, int y)
+{
+       struct test_struct_11 r = { x + y, x - y };
+       return r;
+}
+
+FACTOR_FASTCALL(struct test_struct_11) ffi_test_58(int x, int y, int z)
+{
+       struct test_struct_11 r = { x + y, y - z };
+       return r;
+}
index c61c95d6df835517b1202fdce9e5290851f0e0a8..08b8f95c397adce3552c2fe55e4a7999dccd7e7c 100755 (executable)
@@ -1,9 +1,12 @@
 #if defined(_MSC_VER)
        #define FACTOR_STDCALL(return_type) return_type __stdcall
+       #define FACTOR_FASTCALL(return_type) return_type __fastcall
 #elif defined(i386) || defined(__i386) || defined(__i386__)
        #define FACTOR_STDCALL(return_type) __attribute__((stdcall)) return_type
+       #define FACTOR_FASTCALL(return_type) __attribute__((fastcall)) return_type
 #else
        #define FACTOR_STDCALL(return_type) return_type
+       #define FACTOR_FASTCALL(return_type) return_type
 #endif
 
 #if defined(__APPLE__)
@@ -119,3 +122,14 @@ struct bool_field_test {
 FACTOR_EXPORT short ffi_test_48(struct bool_field_test x);
 
 #endif
+
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_49(int x);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_50(int x, int y);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_51(int x, int y, int z);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_52(int x, float y, int z);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_53(int x, float y, int z, int w);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_54(struct test_struct_11 x, int y);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_55(struct test_struct_11 x, int y, int z);
+FACTOR_EXPORT FACTOR_FASTCALL(int) ffi_test_56(struct test_struct_11 x, int y, int z, int w);
+FACTOR_EXPORT FACTOR_FASTCALL(struct test_struct_11) ffi_test_57(int x, int y);
+FACTOR_EXPORT FACTOR_FASTCALL(struct test_struct_11) ffi_test_58(int x, int y, int z);