native/hashtable.o \
native/icache.o \
native/io.o \
- native/wrapper.o
+ native/wrapper.o \
+ native/ffi_test.o
default:
@echo "Run 'make' with one of the following parameters:"
! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: compiler-backend
-USING: alien assembler kernel math ;
+USING: alien assembler kernel math sequences ;
+
+GENERIC: store-insn ( offset reg-class -- )
+
+GENERIC: load-insn ( elt parameter reg-class -- )
+
+M: int-regs store-insn drop >r 3 1 r> stack@ STW ;
+
+M: int-regs load-insn drop 3 + 1 rot stack@ LWZ ;
M: %unbox generate-node ( vop -- )
- drop ;
+ drop
+ ! Call the unboxer
+ 1 input f compile-c-call
+ ! Store the return value on the C stack
+ 0 input 2 input store-insn ;
M: %parameter generate-node ( vop -- )
! Move a value from the C stack into the fastcall register
- drop ;
+ drop 0 input 1 input 2 input load-insn ;
-M: %box generate-node ( vop -- ) drop ;
+M: %box generate-node ( vop -- )
+ drop
+ ! Move return value of C function into input register
+ param-regs first RAX MOV
+ 0 input f compile-c-call ;
M: %cleanup generate-node ( vop -- ) drop ;
: vregs { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ; inline
-: alien-regs { RDI RSI RDX RCX R8 R9 } ; inline
-
: param-regs { RDI RSI RDX RCX R8 R9 } ; inline
: compile-c-call ( symbol dll -- )
param-regs swap [ MOV ] 2each compile-c-call ;
M: int-regs return-reg drop RAX ;
-M: int-regs fastcall-regs drop alien-regs length ;
+M: int-regs fastcall-regs drop param-regs length ;
M: float-regs fastcall-regs drop 0 ;
IN: compiler-backend
USING: alien assembler kernel math ;
-GENERIC: store-insn ( to offset reg-class -- )
+GENERIC: store-insn ( offset reg-class -- )
GENERIC: load-insn ( elt parameter reg-class -- )
--- /dev/null
+USING: compiler test ;
+
+FUNCTION: void ffi_test_0 ; compiled
+[ ] [ ffi_test_0 ] unit-test
+
+FUNCTION: int ffi_test_1 ; compiled
+[ 3 ] [ ffi_test_1 ] unit-test
+
--- /dev/null
+/* This file is linked into the runtime for the sole purpose
+ * of testing FFI code. */
+
+void ffi_test_0(void)
+{
+ printf("ffi_test_0()\n");
+}
+
+int ffi_test_1(void)
+{
+ printf("ffi_test_1()\n");
+ return 3;
+}
+
+int ffi_test_2(int x, int y)
+{
+ printf("ffi_test_2(%d,%d)\n",x,y);
+ return x + y;
+}