]> gitweb.factorcode.org Git - factor.git/commitdiff
better C type support in FFI
authorSlava Pestov <slava@factorcode.org>
Tue, 21 Sep 2004 01:02:48 +0000 (01:02 +0000)
committerSlava Pestov <slava@factorcode.org>
Tue, 21 Sep 2004 01:02:48 +0000 (01:02 +0000)
18 files changed:
Makefile
TODO.FACTOR.txt
library/compiler/alien-macros.factor [new file with mode: 0644]
library/compiler/alien-types.factor [new file with mode: 0644]
library/compiler/assembler.factor
library/compiler/assembly-x86.factor
library/compiler/compiler-macros.factor [new file with mode: 0644]
library/cross-compiler.factor
library/math/math.factor
library/platform/native/boot-stage2.factor
library/platform/native/primitives.factor
library/test/crashes.factor
library/test/math/bitops.factor
native/ffi.c
native/ffi.h
native/primitives.c
native/primitives.h
native/types.h

index 6d9ffb2200409a3dc0ea8afbd7bdbd0766dd3a1b..7582c93a58996792da57deb3dc8ed66f3a84ce95 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CC = gcc
 
 # On FreeBSD, to use SDL and other libc_r libs:
-CFLAGS = -Os -g -Wall -pthread -export-dynamic
+CFLAGS = -g -Wall -pthread -export-dynamic
 # On PowerPC G5:
 # CFLAGS = -mcpu=970 -mtune=970 -mpowerpc64 -ffast-math -O3
 # On Pentium 4:
index 2e274e549e6213a50118204b0dd2d935e6d77857..d31834f077ab73ed6ada9499613bbfc76e99d1e9 100644 (file)
@@ -4,6 +4,7 @@ FFI:
 [error] SideKick$BufferChangeHandler: We have cplusplus.xml (/home/slava/jEdit/modes/) but got event for DefaultInputHandler.java (/home/slava/jEdit/org/gjt/sp/jedit/gui/)\r
 [error] SideKick$BufferChangeHandler: We have cplusplus.xml (/home/slava/jEdit/modes/) but got event for DefaultInputHandler.java (/home/slava/jEdit/org/gjt/sp/jedit/gui/)\r
 \r
+- profiler is inaccurate: wrong word on cs\r
 - buffer change handler in sidekick is screwed\r
 - dec> bin> oct> hex> throw errors\r
 - parse-number doesn't\r
diff --git a/library/compiler/alien-macros.factor b/library/compiler/alien-macros.factor
new file mode 100644 (file)
index 0000000..3459058
--- /dev/null
@@ -0,0 +1,51 @@
+! :folding=indent:collapseFolds=1:
+
+! $Id$
+!
+! Copyright (C) 2004 Slava Pestov.
+! 
+! Redistribution and use in source and binary forms, with or without
+! modification, are permitted provided that the following conditions are met:
+! 
+! 1. Redistributions of source code must retain the above copyright notice,
+!    this list of conditions and the following disclaimer.
+! 
+! 2. Redistributions in binary form must reproduce the above copyright notice,
+!    this list of conditions and the following disclaimer in the documentation
+!    and/or other materials provided with the distribution.
+! 
+! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+IN: alien
+USE: compiler
+USE: lists
+USE: namespaces
+USE: stack
+
+: UNBOX ( name -- )
+    #! Move top of datastack to C stack.
+    dlsym-self CALL drop
+    EAX PUSH-R ;
+
+: BOX ( name -- )
+    #! Move EAX to datastack.
+    24 ESP R-I
+    EAX PUSH-R
+    dlsym-self CALL drop
+    28 ESP R+I ;
+
+: PARAMETERS ( list -- )
+    #! Generate code for boxing a list of C types.
+    [ c-type [ "unboxer" get ] bind UNBOX ] each ;
+
+: RETURNS ( type -- )
+    c-type [ "boxer" get ] bind BOX ;
diff --git a/library/compiler/alien-types.factor b/library/compiler/alien-types.factor
new file mode 100644 (file)
index 0000000..9dbb76a
--- /dev/null
@@ -0,0 +1,149 @@
+! :folding=indent:collapseFolds=0:
+
+! $Id$
+!
+! Copyright (C) 2004 Slava Pestov.
+! 
+! Redistribution and use in source and binary forms, with or without
+! modification, are permitted provided that the following conditions are met:
+! 
+! 1. Redistributions of source code must retain the above copyright notice,
+!    this list of conditions and the following disclaimer.
+! 
+! 2. Redistributions in binary form must reproduce the above copyright notice,
+!    this list of conditions and the following disclaimer in the documentation
+!    and/or other materials provided with the distribution.
+! 
+! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+IN: alien
+USE: combinators
+USE: compiler
+USE: errors
+USE: lists
+USE: math
+USE: namespaces
+USE: stack
+USE: strings
+USE: words
+
+! Some code for interfacing with C structures.
+
+: <c-type> ( -- type )
+    <namespace> [
+        [ "No setter" throw ] "setter" set
+        [ "No getter" throw ] "getter" set
+        "no boxer" "boxer" set
+        "no unboxer" "unboxer" set
+        0 "width" set
+    ] extend ;
+
+: c-types ( -- ns )
+    global [ "c-types" get ] bind ;
+
+: c-type ( name -- type )
+    global [
+        dup "c-types" get get* dup [
+            nip
+        ] [
+            drop "No such C type: " swap cat2 throw
+        ] ifte
+    ] bind ;
+
+: define-c-type ( quot name -- )
+    c-types [ >r <c-type> swap extend r> set ] bind ;
+
+: define-getter ( offset type name -- )
+    #! Define a word with stack effect ( alien -- obj ) in the
+    #! current 'in' vocabulary.
+    "in" get create >r
+    [ "getter" get ] bind cons r> swap define-compound ;
+
+: define-setter ( offset type name -- )
+    #! Define a word with stack effect ( obj alien -- ) in the
+    #! current 'in' vocabulary.
+    "set-" swap cat2 "in" get create >r
+    [ "setter" get ] bind cons r> swap define-compound ;
+
+: define-field ( offset spec -- offset )
+    unswons >r c-type dup >r [ "width" get ] bind align r> r>
+    "struct-name" get swap "-" swap cat3
+    ( offset type name -- )
+    3dup define-getter 3dup define-setter
+    drop [ "width" get ] bind + ;
+
+: define-constructor ( len -- )
+    [ <alien> ] cons
+    <% "<" % "struct-name" get % ">" % %> "in" get create swap
+    define-compound ;
+
+: define-struct-type ( len -- )
+    #! For example, if len is 32, make a C type with getter:
+    #! [ 32 >r alien-cell r> <alien> ] cons
+    #! The setter just throws an error for now.
+    [
+        [ >r alien-cell r> <alien> ] cons "getter" set
+        "unbox_alien" "unboxer" set
+        cell "width" set
+    ] "struct-name" get "*" cat2 define-c-type ;
+
+: define-struct ( spec name -- )
+    #! Define a set of words for working with a C structure
+    #! alien.
+    [
+        "struct-name" set
+        0 swap [ define-field ] each
+        dup define-constructor
+        define-struct-type
+    ] with-scope ;
+
+global [ <namespace> "c-types" set ] bind
+
+[
+    [ alien-cell ] "getter" set
+    [ set-alien-cell ] "setter" set
+    cell "width" set
+    "does_not_exist" "boxer" set
+    "unbox_alien" "unboxer" set
+] "void*" define-c-type
+
+[
+    [ alien-4 ] "getter" set
+    [ set-alien-4 ] "setter" set
+    4 "width" set
+    "box_integer" "boxer" set
+    "unbox_integer" "unboxer" set
+] "int" define-c-type
+
+[
+    [ alien-2 ] "getter" set
+    [ set-alien-2 ] "setter" set
+    2 "width" set
+    "box_integer" "boxer" set
+    "unbox_integer" "unboxer" set
+] "short" define-c-type
+
+[
+    [ alien-1 ] "getter" set
+    [ set-alien-1 ] "setter" set
+    1 "width" set
+    "box_integer" "boxer" set
+    "unbox_integer" "unboxer" set
+] "char" define-c-type
+
+[
+    [ alien-4 ] "getter" set
+    [ set-alien-4 ] "setter" set
+    cell "width" set
+    "box_c_string" "boxer" set
+    "unbox_c_string" "unboxer" set
+] "char*" define-c-type
index 1466530bd3569c28d23fb4212c3f607a4b054150..4b772c27464fca4fa6c13c03e5f570b1d9e89d4d 100644 (file)
@@ -38,11 +38,7 @@ USE: stack
     compiled-offset literal-table + set-compiled-offset ;
 
 : compile-aligned ( n -- )
-    dup compiled-offset mod dup 0 = [
-        2drop
-    ] [
-        - compiled-offset + set-compiled-offset
-    ] ifte ;
+    compiled-offset swap align set-compiled-offset ;
 
 : intern-literal ( obj -- lit# )
     address-of
index 36eec34103be689d0c6160bcfef0ff18831f40ec..0b71d35977508b748b892b518cafa11aa667d2a6 100644 (file)
@@ -147,37 +147,6 @@ USE: combinators
         compile-cell
     ] ifte ;
 
-: LITERAL ( cell -- )
-    #! Push literal on data stack.
-    #! Assume that it is ok to clobber EAX without saving.
-    DATASTACK EAX [I]>R
-    EAX I>[R]
-    4 DATASTACK I+[I] ;
-
-: [LITERAL] ( cell -- )
-    #! Push complex literal on data stack by following an
-    #! indirect pointer.
-    ECX PUSH-R
-    ( cell -- ) ECX [I]>R
-    DATASTACK EAX [I]>R
-    ECX EAX R>[R]
-    4 DATASTACK I+[I]
-    ECX POP-R ;
-
-: PUSH-DS ( -- )
-    #! Push contents of EAX onto datastack.
-    ECX PUSH-R
-    DATASTACK ECX [I]>R
-    EAX ECX R>[R]
-    4 DATASTACK I+[I]
-    ECX POP-R ;
-
-: POP-DS ( -- )
-    #! Pop datastack, store pointer to datastack top in EAX.
-    DATASTACK EAX [I]>R
-    4 EAX R-I
-    EAX DATASTACK R>[I] ;
-
 : fixup ( addr where -- )
     #! Encode a relative offset to addr from where at where.
     #! Add 4 because addr is relative to *after* insn.
diff --git a/library/compiler/compiler-macros.factor b/library/compiler/compiler-macros.factor
new file mode 100644 (file)
index 0000000..d2f8440
--- /dev/null
@@ -0,0 +1,59 @@
+! :folding=indent:collapseFolds=1:
+
+! $Id$
+!
+! Copyright (C) 2004 Slava Pestov.
+! 
+! Redistribution and use in source and binary forms, with or without
+! modification, are permitted provided that the following conditions are met:
+! 
+! 1. Redistributions of source code must retain the above copyright notice,
+!    this list of conditions and the following disclaimer.
+! 
+! 2. Redistributions in binary form must reproduce the above copyright notice,
+!    this list of conditions and the following disclaimer in the documentation
+!    and/or other materials provided with the distribution.
+! 
+! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+IN: compiler
+
+: LITERAL ( cell -- )
+    #! Push literal on data stack.
+    #! Assume that it is ok to clobber EAX without saving.
+    DATASTACK EAX [I]>R
+    EAX I>[R]
+    4 DATASTACK I+[I] ;
+
+: [LITERAL] ( cell -- )
+    #! Push complex literal on data stack by following an
+    #! indirect pointer.
+    ECX PUSH-R
+    ( cell -- ) ECX [I]>R
+    DATASTACK EAX [I]>R
+    ECX EAX R>[R]
+    4 DATASTACK I+[I]
+    ECX POP-R ;
+
+: PUSH-DS ( -- )
+    #! Push contents of EAX onto datastack.
+    ECX PUSH-R
+    DATASTACK ECX [I]>R
+    EAX ECX R>[R]
+    4 DATASTACK I+[I]
+    ECX POP-R ;
+
+: POP-DS ( -- )
+    #! Pop datastack, store pointer to datastack top in EAX.
+    DATASTACK EAX [I]>R
+    4 EAX R-I
+    EAX DATASTACK R>[I] ;
index 76a4689d80d626b3b6f5adccf2f5bdde6aefd48d..8641246eed67fc77c98b6e9c4a98645d4f7d8c8f 100644 (file)
@@ -50,6 +50,8 @@ DEFER: alien-cell
 DEFER: set-alien-cell
 DEFER: alien-4
 DEFER: set-alien-4
+DEFER: alien-2
+DEFER: set-alien-2
 DEFER: alien-1
 DEFER: set-alien-1
 
@@ -370,6 +372,8 @@ IN: image
         set-alien-cell
         alien-4
         set-alien-4
+        alien-2
+        set-alien-2
         alien-1
         set-alien-1
     ] [
index ecc3897a6a6658150e15af3ebc032f2517f53b2d..3c122868888f7f24d9d38b81af9c62cd2bae3720 100644 (file)
@@ -78,3 +78,6 @@ USE: stack
 
 : polar> ( abs arg -- z )
     cis * ; inline
+
+: align ( offset width -- offset )
+    2dup mod dup 0 = [ 2drop ] [ - + ] ifte ;
index b0027006d60fab07096567cc3a73857ccc62dacf..d194b4526787f9d0d2b66cb27fe9f5998e03979a 100644 (file)
@@ -133,8 +133,11 @@ USE: stdio
 
     "/library/compiler/assembler.factor"
     "/library/compiler/assembly-x86.factor"
+    "/library/compiler/compiler-macros.factor"
     "/library/compiler/compiler.factor"
     "/library/compiler/words.factor"
+    "/library/compiler/alien-types.factor"
+    "/library/compiler/alien-macros.factor"
 
     "/library/platform/native/primitives.factor"
 
index aa8bb6b7c4f66a7a1627f1fabc8c8155c19f65f3..f9937d04dc4aa3fb36093a40312fca22cb4f0405 100644 (file)
@@ -228,6 +228,8 @@ USE: words
     [ set-alien-cell         | " n alien off -- " ]
     [ alien-4                | " alien off -- n " ]
     [ set-alien-4            | " n alien off -- " ]
+    [ alien-2                | " alien off -- n " ]
+    [ set-alien-2            | " n alien off -- " ]
     [ alien-1                | " alien off -- n " ]
     [ set-alien-1            | " n alien off -- " ]
 ] [
index f528f0e45b010a878e5a3c15a0beeb83e637e691..e9a1c63a38a7a0590f63402ee245e324cc436dcc 100644 (file)
@@ -8,6 +8,7 @@ USE: stack
 USE: strings
 USE: test
 USE: vectors
+USE: lists
 
 ! Various things that broke CFactor at various times.
 ! This should run without issue (and tests nothing useful)
@@ -32,3 +33,25 @@ USE: vectors
 10 [ [ -1000000 <vector> ] [ drop ] catch ] times
 
 10 [ [ -1000000 <sbuf> ] [ drop ] catch ] times
+
+! Make sure various type checks don't run into header untagging
+! problems etc.
+
+! Lotype -vs- lotype
+[ ] [ [ 4 car ] [ drop ] catch ] unit-test
+
+! Lotype -vs- hitype
+[ ] [ [ 4 vector-length ] [ drop ] catch ] unit-test
+[ ] [ [ [ 4 3 ] vector-length ] [ drop ] catch ] unit-test
+
+! Hitype -vs- lotype
+[ ] [ [ "hello" car ] [ drop ] catch ] unit-test
+
+! Hitype -vs- hitype
+[ ] [ [ "hello" vector-length ] [ drop ] catch ] unit-test
+
+! f -vs- lotype
+[ ] [ [ f car ] [ drop ] catch ] unit-test
+
+! f -vs- hitype
+[ ] [ [ f vector-length ] [ drop ] catch ] unit-test
index a31c8a4159f794096655d15a060f1ed72adbd467..fd39b8c9927015db4915986435149cf8292f75fc 100644 (file)
@@ -48,3 +48,9 @@ USE: lists
         -1 over shift swap -1 >bignum swap shift = and
     ] each
 ] unit-test
+
+[ 12 ] [ 11 4 align ] unit-test
+[ 12 ] [ 12 4 align ] unit-test
+[ 12 ] [ 10 2 align ] unit-test
+[ 14 ] [ 13 2 align ] unit-test
+[ 11 ] [ 11 1 align ] unit-test
index 8b600b42514f7b8d21c81b0526f8f054b76841f9..e2d737ff95669205bf9120d91ee7815ed18deaae 100644 (file)
@@ -81,6 +81,11 @@ void primitive_alien(void)
 #endif
 }
 
+ALIEN* unbox_alien(void)
+{
+       return untag_alien(dpop())->ptr;
+}
+
 INLINE CELL alien_pointer(void)
 {
        FIXNUM offset = unbox_integer();
@@ -135,6 +140,27 @@ void primitive_set_alien_4(void)
 #endif
 }
 
+void primitive_alien_2(void)
+{
+#ifdef FFI
+       CELL ptr = alien_pointer();
+       box_integer(*(CHAR*)ptr);
+#else
+       general_error(ERROR_FFI_DISABLED,F);
+#endif
+}
+
+void primitive_set_alien_2(void)
+{
+#ifdef FFI
+       CELL ptr = alien_pointer();
+       CELL value = unbox_integer();
+       *(CHAR*)ptr = value;
+#else
+       general_error(ERROR_FFI_DISABLED,F);
+#endif
+}
+
 void primitive_alien_1(void)
 {
 #ifdef FFI
index 90309ec00a08db5a91abe7ce11bd4be9a9d258b8..f5cf6c2d540f9ec8cb263ae58c2a76f5c7608469 100644 (file)
@@ -26,9 +26,12 @@ void primitive_dlsym(void);
 void primitive_dlsym_self(void);
 void primitive_dlclose(void);
 void primitive_alien(void);
+ALIEN* unbox_alien(void);
 void primitive_alien_cell(void);
 void primitive_set_alien_cell(void);
 void primitive_alien_4(void);
 void primitive_set_alien_4(void);
+void primitive_alien_2(void);
+void primitive_set_alien_2(void);
 void primitive_alien_1(void);
 void primitive_set_alien_1(void);
index 52012aceb7822dc42519f2c99cb46e6e40d40770..bfd229424c64d94c1fb230dad0012fe604f8de44 100644 (file)
@@ -187,6 +187,8 @@ XT primitives[] = {
        primitive_set_alien_cell,
        primitive_alien_4,
        primitive_set_alien_4,
+       primitive_alien_2,
+       primitive_set_alien_2,
        primitive_alien_1,
        primitive_set_alien_1
 };
index 7698bf623a20e3c4586a4875943444375e7f4e91..521fd4500be710a1a8d3a7228b8a14e33498f841 100644 (file)
@@ -1,4 +1,4 @@
 extern XT primitives[];
-#define PRIMITIVE_COUNT 188
+#define PRIMITIVE_COUNT 190
 
 CELL primitive_to_xt(CELL primitive);
index b75fcaadc7e87773c5f90a76cb005d751ca3503d..c25d03e7e36f4506e95913de9c83f2828b1cc80b 100644 (file)
@@ -83,11 +83,21 @@ INLINE void type_check(CELL type, CELL tagged)
 {
        if(type < HEADER_TYPE)
        {
-               if(TAG(tagged) != type)
-                       type_error(type,tagged);
+               if(TAG(tagged) == type)
+                       return;
        }
-       else if(object_type(tagged) != type)
-               type_error(type,tagged);
+       else if(tagged == F)
+       {
+               if(type == F_TYPE)
+                       return;
+       }
+       else if(TAG(tagged) == OBJECT_TYPE
+               && object_type(tagged) == type)
+       {
+               return;
+       }
+
+       type_error(type,tagged);
 }
 
 void* allot_object(CELL type, CELL length);