Nullary callbacks are working

darcs
slava 2006-02-13 22:16:34 +00:00
parent 3173747fb5
commit 8b74f721b5
12 changed files with 87 additions and 46 deletions

View File

@ -65,14 +65,10 @@
+ misc: + misc:
- aliens are just a special case of displaced aliens -- so we can remove
one built in type
- code walker & exceptions - code walker & exceptions
- slice: if sequence or seq start is changed, abstraction violation - slice: if sequence or seq start is changed, abstraction violation
- delegating generic words with a non-standard picker - delegating generic words with a non-standard picker
- pass an integer stack pos instead of a quotation - pass an integer stack pos instead of a quotation
- make 3.4 bits>double an error - make 3.4 bits>double an error
- 2220.446049250313 [ dup float? [ tanh ] when ]
- call and compile-1 give C{ 0.0/0.0 0.0/0.0 } 0.0/0.0
- 2.718281828459045e+19 [ dup float? [ sech ] when ]
- call/compile-1: C{ 0.0/0.0 0.0/0.0 } 0.0
- 0.0/0.0 next-power-of-2 never terminates -- comparison always returns false
- 0.0/0.0 >fixnum . -> 0 0.0/0.0 >bignum . -> 0

View File

@ -5,7 +5,7 @@ USING: compiler-backend compiler-frontend errors generic
hashtables inference inspector kernel lists namespaces sequences hashtables inference inspector kernel lists namespaces sequences
strings words ; strings words ;
TUPLE: alien-callback return parameters word xt ; TUPLE: alien-callback return parameters quot xt ;
C: alien-callback make-node ; C: alien-callback make-node ;
TUPLE: alien-callback-error ; TUPLE: alien-callback-error ;
@ -13,40 +13,30 @@ TUPLE: alien-callback-error ;
M: alien-callback-error summary ( error -- ) M: alien-callback-error summary ( error -- )
drop "Words calling ``alien-callback'' cannot run in the interpreter. Compile the caller word and try again." ; drop "Words calling ``alien-callback'' cannot run in the interpreter. Compile the caller word and try again." ;
: alien-callback ( ... return parameters word -- ... ) : alien-callback ( ... return parameters quot -- ... )
#! Call a C library function.
#! 'return' is a type spec, and 'parameters' is a list of
#! type specs. 'library' is an entry in the "libraries"
#! namespace.
<alien-callback-error> throw ; <alien-callback-error> throw ;
: check-callback ( node -- )
dup alien-callback-word unit infer dup first
pick alien-callback-parameters length = >r
second swap alien-callback-return "void" = 0 1 ? = r> and [
"Callback word stack effect does not match callback signature" throw
] unless ;
: callback-bottom ( node -- ) : callback-bottom ( node -- )
alien-callback-xt [ word-xt <alien> ] curry infer-quot ; alien-callback-xt [ word-xt <alien> ] curry infer-quot ;
\ alien-callback [ [ string object word ] [ alien ] ] \ alien-callback [ [ string object general-list ] [ alien ] ]
"infer-effect" set-word-prop "infer-effect" set-word-prop
\ alien-callback [ \ alien-callback [
empty-node <alien-callback> empty-node <alien-callback>
pop-literal nip over set-alien-callback-word pop-literal nip over set-alien-callback-quot
pop-literal nip over set-alien-callback-parameters pop-literal nip over set-alien-callback-parameters
pop-literal nip over set-alien-callback-return pop-literal nip over set-alien-callback-return
gensym over set-alien-callback-xt gensym over set-alien-callback-xt
dup check-callback
dup node, dup node,
callback-bottom callback-bottom
] "infer" set-word-prop ] "infer" set-word-prop
: linearize-callback ( node -- ) : linearize-callback ( node -- )
dup alien-callback-xt [ dup alien-callback-xt [
alien-callback-word %jump , "nest_stacks" f %alien-invoke ,
alien-callback-quot %nullary-callback ,
%return ,
] make-linear ; ] make-linear ;
M: alien-callback linearize* ( node -- ) M: alien-callback linearize* ( node -- )

View File

@ -110,6 +110,7 @@ M: alien-invoke-error summary ( error -- )
M: alien-invoke linearize* ( node -- ) M: alien-invoke linearize* ( node -- )
dup alien-invoke-parameters linearize-parameters dup alien-invoke-parameters linearize-parameters
"save_stacks" f %alien-invoke ,
dup alien-invoke-dlsym %alien-invoke , dup alien-invoke-dlsym %alien-invoke ,
dup linearize-cleanup dup linearize-cleanup
dup linearize-return dup linearize-return

View File

@ -45,3 +45,8 @@ M: %parameter generate-node ( vop -- )
M: %box generate-node ( vop -- ) drop 1 input f compile-c-call ; M: %box generate-node ( vop -- ) drop 1 input f compile-c-call ;
M: %cleanup generate-node ( vop -- ) drop ; M: %cleanup generate-node ( vop -- ) drop ;
M: %nullary-callback generate-node ( vop -- )
drop
3 0 input load-indirect
"run_nullary_callback" f compile-c-call ;

View File

@ -377,3 +377,7 @@ C: %box make-vop ;
TUPLE: %alien-invoke ; TUPLE: %alien-invoke ;
C: %alien-invoke make-vop ; C: %alien-invoke make-vop ;
: %alien-invoke ( func lib -- vop ) 2-in-vop <%alien-invoke> ; : %alien-invoke ( func lib -- vop ) 2-in-vop <%alien-invoke> ;
TUPLE: %nullary-callback ;
C: %nullary-callback make-vop ;
: %nullary-callback ( quot -- vop ) src-vop <%nullary-callback> ;

View File

@ -1,18 +1,54 @@
IN: temporary IN: temporary
USING: alien compiler inference namespaces test ; USING: alien compiler errors inference io kernel memory
namespaces test threads ;
: no-op ; : callback-1 "void" { } [ ] alien-callback ; compiled
: callback-1 "void" { } \ no-op alien-callback ; compiled
[ { 0 1 } ] [ [ callback-1 ] infer ] unit-test [ { 0 1 } ] [ [ callback-1 ] infer ] unit-test
: callback-1-bad "int" { } \ no-op alien-callback ;
[ [ callback-1-bad ] infer ] unit-test-fails
[ t ] [ callback-1 alien? ] unit-test [ t ] [ callback-1 alien? ] unit-test
FUNCTION: void callback_test_1 void* callback ; compiled FUNCTION: void callback_test_1 void* callback ; compiled
[ ] [ callback-1 callback_test_1 ] unit-test [ ] [ callback-1 callback_test_1 ] unit-test
: callback-2 "void" { } [ 5 throw ] alien-callback ; compiled
[ 5 ] [ [ callback-2 callback_test_1 ] catch ] unit-test
: callback-3 "void" { } [ 5 "x" set ] alien-callback ; compiled
[ t ] [
namestack*
3 "x" set callback-3 callback_test_1
namestack* eq?
] unit-test
[ 5 ] [
[
3 "x" set callback-3 callback_test_1 "x" get
] with-scope
] unit-test
: callback-4 "void" { } [ "Hello world" write ] alien-callback ; compiled
[ "Hello world" ] [
[ callback-4 callback_test_1 ] string-out
] unit-test
: callback-5
"void" { } [ full-gc ] alien-callback ; compiled
[ "testing" ] [
"testing" callback-5 callback_test_1
] unit-test
: callback-6
"void" { } [ [ continue ] callcc0 ] alien-callback ; compiled
[ ] [ callback-6 callback_test_1 ] unit-test
: callback-7
"void" { } [ yield "hi" print flush yield ] alien-callback ; compiled
[ ] [ callback-7 callback_test_1 ] unit-test

View File

@ -39,8 +39,8 @@ INLINE bool factor_arg(const char* str, const char* arg, CELL* value)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
char *image; char *image;
CELL ds_size = 512; CELL ds_size = 128;
CELL cs_size = 512; CELL cs_size = 128;
CELL generations = 2; CELL generations = 2;
CELL young_size = 2 * CELLS; CELL young_size = 2 * CELLS;
CELL aging_size = 4 * CELLS; CELL aging_size = 4 * CELLS;

View File

@ -85,7 +85,9 @@ int ffi_test_12(int a, int b, struct rect c, int d, int e, int f)
void callback_test_1(void (*callback)()) void callback_test_1(void (*callback)())
{ {
printf("callback_test_1 entry"); printf("callback_test_1 entry\n");
fflush(stdout);
callback(); callback();
printf("callback_test_1 leaving"); printf("callback_test_1 leaving\n");
fflush(stdout);
} }

View File

@ -80,8 +80,8 @@ INLINE void call(CELL quot)
void run(bool handle_errors); void run(bool handle_errors);
void run_toplevel(void); void run_toplevel(void);
void run_nullary_callback(CELL quot); DLLEXPORT void run_nullary_callback(CELL quot);
CELL run_unary_callback(CELL quot); DLLEXPORT CELL run_unary_callback(CELL quot);
void platform_run(void); void platform_run(void);
void undefined(F_WORD *word); void undefined(F_WORD *word);
void docol(F_WORD *word); void docol(F_WORD *word);

View File

@ -22,9 +22,13 @@ void fix_stacks(void)
reset_callstack(); reset_callstack();
} }
/* called before entry into foreign C code */ /* called before entry into foreign C code. Note that ds and cs are stored
in registers, so callbacks must save and restore the correct values */
void save_stacks(void) void save_stacks(void)
{ {
/* we want to save the current callframe along with the call stack */
call(F);
stack_chain->ds = ds; stack_chain->ds = ds;
stack_chain->cs = cs; stack_chain->cs = cs;
} }
@ -33,6 +37,9 @@ void save_stacks(void)
void nest_stacks(void) void nest_stacks(void)
{ {
STACKS *new_stacks = malloc(sizeof(STACKS)); STACKS *new_stacks = malloc(sizeof(STACKS));
if(new_stacks == NULL)
fatal_error("Cannot allocate saved stacks struct",0);
new_stacks->ds_save = ds; new_stacks->ds_save = ds;
new_stacks->cs_save = cs; new_stacks->cs_save = cs;
new_stacks->ds_region = alloc_bounded_block(ds_size); new_stacks->ds_region = alloc_bounded_block(ds_size);
@ -49,7 +56,7 @@ void unnest_stacks(void)
dealloc_bounded_block(stack_chain->ds_region); dealloc_bounded_block(stack_chain->ds_region);
dealloc_bounded_block(stack_chain->cs_region); dealloc_bounded_block(stack_chain->cs_region);
ds = stack_chain->ds_save; ds = stack_chain->ds_save;
ds = stack_chain->cs_save; cs = stack_chain->cs_save;
stack_chain = stack_chain->next; stack_chain = stack_chain->next;
} }

View File

@ -21,9 +21,9 @@ CELL ds_size, cs_size;
void reset_datastack(void); void reset_datastack(void);
void reset_callstack(void); void reset_callstack(void);
void fix_stacks(void); void fix_stacks(void);
void save_stacks(void); DLLEXPORT void save_stacks(void);
void nest_stacks(void); DLLEXPORT void nest_stacks(void);
void unnest_stacks(void); DLLEXPORT void unnest_stacks(void);
void init_stacks(CELL ds_size, CELL cs_size); void init_stacks(CELL ds_size, CELL cs_size);
void primitive_drop(void); void primitive_drop(void);

View File

@ -4,7 +4,7 @@ BOUNDED_BLOCK *alloc_bounded_block(CELL size)
{ {
int pagesize = getpagesize(); int pagesize = getpagesize();
char* array = mmap((void*)0,pagesize + size + pagesize, char *array = mmap((void*)0,pagesize + size + pagesize,
PROT_READ | PROT_WRITE | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE,-1,0); MAP_ANON | MAP_PRIVATE,-1,0);
@ -12,10 +12,10 @@ BOUNDED_BLOCK *alloc_bounded_block(CELL size)
fatal_error("Cannot allocate memory region",0); fatal_error("Cannot allocate memory region",0);
if(mprotect(array,pagesize,PROT_NONE) == -1) if(mprotect(array,pagesize,PROT_NONE) == -1)
fatal_error("Cannot allocate low guard page",(CELL)array); fatal_error("Cannot protect low guard page",(CELL)array);
if(mprotect(array + pagesize + size,pagesize,PROT_NONE) == -1) if(mprotect(array + pagesize + size,pagesize,PROT_NONE) == -1)
fatal_error("Cannot allocate high guard page",(CELL)array); fatal_error("Cannot protect high guard page",(CELL)array);
BOUNDED_BLOCK *retval = malloc(sizeof(BOUNDED_BLOCK)); BOUNDED_BLOCK *retval = malloc(sizeof(BOUNDED_BLOCK));
if(retval == NULL) if(retval == NULL)
@ -34,7 +34,7 @@ void dealloc_bounded_block(BOUNDED_BLOCK *block)
int retval = munmap((void*)(block->start - pagesize), int retval = munmap((void*)(block->start - pagesize),
pagesize + block->size + pagesize); pagesize + block->size + pagesize);
if(!retval) if(retval)
fatal_error("Failed to unmap region",0); fatal_error("Failed to unmap region",0);
free(block); free(block);