From c30f2f30f4ea9539e3c8b2deaa30945aec9dd274 Mon Sep 17 00:00:00 2001 From: slava Date: Sat, 11 Mar 2006 03:16:46 +0000 Subject: [PATCH] Value type struct inputs, for PowerPC --- library/alien/structs.factor | 1 + library/compiler/ppc/alien.factor | 12 ++++++++---- library/compiler/vops.factor | 5 +++++ library/test/compiler/callbacks.factor | 17 +++++++++++++++++ native/alien.c | 10 ++++++++++ native/alien.h | 1 + native/array.c | 16 +++++++++++----- native/array.h | 5 +++-- native/ffi_test.c | 9 +++++++++ native/ffi_test.h | 1 + 10 files changed, 66 insertions(+), 11 deletions(-) diff --git a/library/alien/structs.factor b/library/alien/structs.factor index 78bc909489..65a86504e6 100644 --- a/library/alien/structs.factor +++ b/library/alien/structs.factor @@ -36,6 +36,7 @@ sequences strings words ; bootstrap-cell "align" set [ swap ] "getter" set "width" get [ %unbox-struct ] curry "unboxer" set + "width" get [ %box-struct ] curry "boxer" set "struct" on ] "struct-name" get define-c-type "struct-name" get in get init-c-type ; diff --git a/library/compiler/ppc/alien.factor b/library/compiler/ppc/alien.factor index c7633834d0..e63628370e 100644 --- a/library/compiler/ppc/alien.factor +++ b/library/compiler/ppc/alien.factor @@ -36,14 +36,18 @@ M: %unbox generate-node ( vop -- ) ! Store the return value on the C stack 0 input 1 input [ return-reg ] keep freg>stack ; -M: %unbox-struct generate-node ( vop -- ) - drop +: struct-ptr/size ( func -- ) ! Load destination address 3 1 0 input stack@ ADDI ! Load struct size 2 input 4 LI - ! Copy the struct to the stack - "unbox_value_struct" f compile-c-call ; + f compile-c-call ; + +M: %unbox-struct generate-node ( vop -- ) + drop "unbox_value_struct" struct-ptr/size ; + +M: %box-struct generate-node ( vop -- ) + drop "box_value_struct" struct-ptr/size ; : (%move) 0 input 1 input 2 input [ fastcall-regs nth ] keep ; diff --git a/library/compiler/vops.factor b/library/compiler/vops.factor index 402d0d2457..9740901a30 100644 --- a/library/compiler/vops.factor +++ b/library/compiler/vops.factor @@ -375,6 +375,11 @@ TUPLE: %box ; C: %box make-vop ; : %box ( n reg-class func -- vop ) 3-in-vop <%box> ; +TUPLE: %box-struct ; +C: %box-struct make-vop ; +: %box-struct ( n reg-class size -- vop ) + 3-in-vop <%box-struct> ; + TUPLE: %alien-invoke ; C: %alien-invoke make-vop ; : %alien-invoke ( func lib -- vop ) 2-in-vop <%alien-invoke> ; diff --git a/library/test/compiler/callbacks.factor b/library/test/compiler/callbacks.factor index 18c26dac7b..5987335d7e 100644 --- a/library/test/compiler/callbacks.factor +++ b/library/test/compiler/callbacks.factor @@ -109,3 +109,20 @@ FUNCTION: void callback_test_4 void* callback int a1 int a2 int a3 int a4 int a5 "stack" get ] with-scope ] unit-test + +BEGIN-STRUCT: foo + FIELD: int x + FIELD: int y +END-STRUCT + +: make-foo ( x y -- foo ) + "foo" [ set-foo-y ] keep [ set-foo-x ] keep ; + +: callback-10 + "int" + { "foo" } + [ dup foo-x swap foo-y / ] alien-callback ; compiled + +FUNCTION: int callback_test_8 void* callback foo x ; + +[ 5 ] [ callback-10 10 2 make-foo callback_test_8 ] unit-test diff --git a/native/alien.c b/native/alien.c index bac2b21015..70074d7f64 100644 --- a/native/alien.c +++ b/native/alien.c @@ -151,3 +151,13 @@ void unbox_value_struct(void *dest, CELL size) { memcpy(dest,unbox_alien(),size); } + +/* for FFI callbacks receiving structs by value */ +void box_value_struct(void *src, CELL size) +{ + F_ARRAY *array; + maybe_gc(0); + array = byte_array(size); + memcpy(array + 1,src,size); + dpush(tag_object(array)); +} diff --git a/native/alien.h b/native/alien.h index 3ca68a1690..5de46a97ee 100644 --- a/native/alien.h +++ b/native/alien.h @@ -53,3 +53,4 @@ void primitive_alien_double(void); void primitive_set_alien_double(void); DLLEXPORT void unbox_value_struct(void *dest, CELL size); +DLLEXPORT void box_value_struct(void *src, CELL size); diff --git a/native/array.c b/native/array.c index cfdc26cbce..5ac8e6154f 100644 --- a/native/array.c +++ b/native/array.c @@ -1,8 +1,8 @@ #include "factor.h" /* the array is full of undefined data, and must be correctly filled before the -next GC. */ -F_ARRAY* allot_array(CELL type, F_FIXNUM capacity) +next GC. size is in cells */ +F_ARRAY *allot_array(CELL type, F_FIXNUM capacity) { F_ARRAY *array; @@ -24,6 +24,13 @@ F_ARRAY* array(CELL type, F_FIXNUM capacity, CELL fill) return array; } +/* size is in bytes this time */ +F_ARRAY *byte_array(F_FIXNUM size) +{ + F_FIXNUM byte_size = (size + sizeof(CELL) - 1) / sizeof(CELL); + return array(BYTE_ARRAY_TYPE,byte_size,0); +} + /* push a new array on the stack */ void primitive_array(void) { @@ -47,9 +54,8 @@ void primitive_tuple(void) void primitive_byte_array(void) { F_FIXNUM size = to_fixnum(dpop()); - maybe_gc(array_size(size)); - F_FIXNUM byte_size = (size + sizeof(CELL) - 1) / sizeof(CELL); - dpush(tag_object(array(BYTE_ARRAY_TYPE,byte_size,0))); + maybe_gc(0); + dpush(tag_object(byte_array(size))); } F_ARRAY* resize_array(F_ARRAY* array, F_FIXNUM capacity, CELL fill) diff --git a/native/array.h b/native/array.h index b2dbbad44c..783e2c7667 100644 --- a/native/array.h +++ b/native/array.h @@ -25,8 +25,9 @@ INLINE CELL array_size(CELL size) return align8(sizeof(F_ARRAY) + size * CELLS); } -F_ARRAY* allot_array(CELL type, F_FIXNUM capacity); -F_ARRAY* array(CELL type, F_FIXNUM capacity, CELL fill); +F_ARRAY *allot_array(CELL type, F_FIXNUM capacity); +F_ARRAY *array(CELL type, F_FIXNUM capacity, CELL fill); +F_ARRAY *byte_array(F_FIXNUM size); void primitive_array(void); void primitive_tuple(void); diff --git a/native/ffi_test.c b/native/ffi_test.c index f95c835c8f..005ab9381b 100644 --- a/native/ffi_test.c +++ b/native/ffi_test.c @@ -150,3 +150,12 @@ double callback_test_7(double (*callback)(void)) printf("callback_test_7 exit\n"); return x; } + +int callback_test_8(int (*callback)(struct foo x), struct foo x) +{ + int x; + printf("callback_test_8 entry\n"); + x = callback(x); + printf("callback_test_8 exit\n"); + return x; +} diff --git a/native/ffi_test.h b/native/ffi_test.h index 52e9f7461f..46ff6f1bf5 100644 --- a/native/ffi_test.h +++ b/native/ffi_test.h @@ -21,3 +21,4 @@ DLLEXPORT void callback_test_4(void (*callback)(int a1, int a2, int a3, int a4, DLLEXPORT int callback_test_5(int (*callback)(void)); DLLEXPORT float callback_test_6(float (*callback)(void)); DLLEXPORT double callback_test_7(double (*callback)(void)); +DLLEXPORT int callback_test_8(int (*callback)(struct foo x), struct foo x);