Further work on callbacks
parent
5c27196a07
commit
2d1ef84911
|
@ -67,6 +67,8 @@
|
||||||
- [ [ dup call ] dup call ] infer hangs
|
- [ [ dup call ] dup call ] infer hangs
|
||||||
- the invalid recursion form case needs to be fixed, for inlines too
|
- the invalid recursion form case needs to be fixed, for inlines too
|
||||||
- code gc
|
- code gc
|
||||||
|
- clean up C stack frame assembly code to avoid moving spilled arguments
|
||||||
|
twice
|
||||||
|
|
||||||
+ misc:
|
+ misc:
|
||||||
|
|
||||||
|
@ -77,3 +79,4 @@
|
||||||
- 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
|
||||||
|
- colorcoded prettyprinting for vocabularies
|
||||||
|
|
|
@ -32,9 +32,21 @@ M: alien-callback-error summary ( error -- )
|
||||||
callback-bottom
|
callback-bottom
|
||||||
] "infer" set-word-prop
|
] "infer" set-word-prop
|
||||||
|
|
||||||
|
: box-parameters ( parameters -- )
|
||||||
|
[ box-parameter , ] reverse-each-parameter ;
|
||||||
|
|
||||||
|
: registers>objects ( parameters -- )
|
||||||
|
#! The corresponding unnest_stacks() call is made by the
|
||||||
|
#! run_nullary_callback() and run_unary_callback() runtime
|
||||||
|
#! functions.
|
||||||
|
dup stack-space %parameters ,
|
||||||
|
dup \ %freg>stack move-parameters
|
||||||
|
"nest_stacks" f %alien-invoke ,
|
||||||
|
box-parameters ;
|
||||||
|
|
||||||
: linearize-callback ( node -- )
|
: linearize-callback ( node -- )
|
||||||
dup alien-callback-xt [
|
dup alien-callback-xt [
|
||||||
"nest_stacks" f %alien-invoke ,
|
dup alien-callback-parameters registers>objects
|
||||||
alien-callback-quot %nullary-callback ,
|
alien-callback-quot %nullary-callback ,
|
||||||
%return ,
|
%return ,
|
||||||
] make-linear ;
|
] make-linear ;
|
||||||
|
|
|
@ -43,65 +43,25 @@ M: alien-invoke-error summary ( error -- )
|
||||||
node,
|
node,
|
||||||
] "infer" set-word-prop
|
] "infer" set-word-prop
|
||||||
|
|
||||||
: parameter-size c-size cell align ;
|
|
||||||
|
|
||||||
: stack-space ( parameters -- n )
|
|
||||||
0 [ parameter-size + ] reduce ;
|
|
||||||
|
|
||||||
: unbox-parameter ( stack# type -- node )
|
: unbox-parameter ( stack# type -- node )
|
||||||
c-type [ "reg-class" get "unboxer" get ] bind call ;
|
c-type [ "reg-class" get "unboxer" get ] bind call ;
|
||||||
|
|
||||||
: unbox-parameters ( params -- )
|
: unbox-parameters ( parameters -- )
|
||||||
reverse
|
[ unbox-parameter , ] reverse-each-parameter ;
|
||||||
[ stack-space ] keep
|
|
||||||
[ [ parameter-size - dup ] keep unbox-parameter , ] each
|
|
||||||
drop ;
|
|
||||||
|
|
||||||
: reg-class-full? ( class -- ? )
|
: objects>registers ( parameters -- )
|
||||||
dup class get swap fastcall-regs length >= ;
|
|
||||||
|
|
||||||
: spill-param ( reg-class -- n reg-class )
|
|
||||||
reg-size stack-params dup get -rot +@ T{ stack-params } ;
|
|
||||||
|
|
||||||
: fastcall-param ( reg-class -- n reg-class )
|
|
||||||
[ dup class get swap inc-reg-class ] keep ;
|
|
||||||
|
|
||||||
: load-parameter ( n parameter -- node )
|
|
||||||
#! n is a stack location, and the value of the class
|
|
||||||
#! variable is a register number.
|
|
||||||
c-type "reg-class" swap hash dup reg-class-full?
|
|
||||||
[ spill-param ] [ fastcall-param ] if %parameter ;
|
|
||||||
|
|
||||||
: flatten-value-types ( params -- params )
|
|
||||||
#! Convert value type structs to consecutive void*s.
|
|
||||||
[
|
|
||||||
dup c-struct?
|
|
||||||
[ c-size cell / "void*" <array> ] [ 1array ] if
|
|
||||||
] map concat ;
|
|
||||||
|
|
||||||
: load-parameters ( params -- )
|
|
||||||
[
|
|
||||||
flatten-value-types
|
|
||||||
0 { int-regs float-regs stack-params } [ set ] each-with
|
|
||||||
0 [ 2dup load-parameter , parameter-size + ] reduce drop
|
|
||||||
] with-scope ;
|
|
||||||
|
|
||||||
: linearize-parameters ( parameters -- )
|
|
||||||
#! Generate code for boxing a list of C types, then generate
|
#! Generate code for boxing a list of C types, then generate
|
||||||
#! code for moving these parameters to register on
|
#! code for moving these parameters to register on
|
||||||
#! architectures where parameters are passed in registers
|
#! architectures where parameters are passed in registers
|
||||||
#! (PowerPC).
|
#! (PowerPC, AMD64).
|
||||||
dup stack-space %parameters ,
|
dup stack-space %parameters ,
|
||||||
dup unbox-parameters
|
dup unbox-parameters
|
||||||
"save_stacks" f %alien-invoke ,
|
"save_stacks" f %alien-invoke ,
|
||||||
load-parameters ;
|
\ %stack>freg move-parameters ;
|
||||||
|
|
||||||
: linearize-return ( node -- )
|
: box-return ( node -- )
|
||||||
alien-invoke-return dup "void" = [
|
alien-invoke-return dup "void" =
|
||||||
drop
|
[ drop ] [ f swap box-parameter , ] if ;
|
||||||
] [
|
|
||||||
c-type [ "reg-class" get "boxer" get ] bind call ,
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
: linearize-cleanup ( node -- )
|
: linearize-cleanup ( node -- )
|
||||||
dup alien-invoke-library library-abi "stdcall" = [
|
dup alien-invoke-library library-abi "stdcall" = [
|
||||||
|
@ -111,10 +71,10 @@ M: alien-invoke-error summary ( error -- )
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
M: alien-invoke linearize* ( node -- )
|
M: alien-invoke linearize* ( node -- )
|
||||||
dup alien-invoke-parameters linearize-parameters
|
dup alien-invoke-parameters objects>registers
|
||||||
dup alien-invoke-dlsym %alien-invoke ,
|
dup alien-invoke-dlsym %alien-invoke ,
|
||||||
dup linearize-cleanup
|
dup linearize-cleanup
|
||||||
dup linearize-return
|
dup box-return
|
||||||
linearize-next ;
|
linearize-next ;
|
||||||
|
|
||||||
: parse-arglist ( lst -- types stack effect )
|
: parse-arglist ( lst -- types stack effect )
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
! Copyright (C) 2006 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
IN: alien
|
||||||
|
USING: arrays compiler-backend generic hashtables kernel
|
||||||
|
kernel-internals math namespaces sequences words ;
|
||||||
|
|
||||||
|
: parameter-size c-size cell align ;
|
||||||
|
|
||||||
|
: parameter-sizes ( types -- offsets )
|
||||||
|
#! Compute stack frame locations.
|
||||||
|
0 [ parameter-size + ] accumulate ;
|
||||||
|
|
||||||
|
: stack-space ( parameters -- n )
|
||||||
|
0 [ parameter-size + ] reduce ;
|
||||||
|
|
||||||
|
: reg-class-full? ( class -- ? )
|
||||||
|
dup class get swap fastcall-regs length >= ;
|
||||||
|
|
||||||
|
: spill-param ( reg-class -- n reg-class )
|
||||||
|
reg-size stack-params dup get -rot +@ T{ stack-params } ;
|
||||||
|
|
||||||
|
: fastcall-param ( reg-class -- n reg-class )
|
||||||
|
[ dup class get swap inc-reg-class ] keep ;
|
||||||
|
|
||||||
|
: alloc-parameter ( parameter -- n reg reg-class )
|
||||||
|
#! Allocate a register and stack frame location.
|
||||||
|
#! n is a stack location, and the value of the class
|
||||||
|
#! variable is a register number.
|
||||||
|
c-type "reg-class" swap hash dup reg-class-full?
|
||||||
|
[ spill-param ] [ fastcall-param ] if ;
|
||||||
|
|
||||||
|
: flatten-value-types ( params -- params )
|
||||||
|
#! Convert value type structs to consecutive void*s.
|
||||||
|
[
|
||||||
|
dup c-struct?
|
||||||
|
[ c-size cell / "void*" <array> ] [ 1array ] if
|
||||||
|
] map concat ;
|
||||||
|
|
||||||
|
: reverse-each-parameter ( parameters quot -- )
|
||||||
|
>r [ parameter-sizes ] keep
|
||||||
|
[ reverse-slice ] 2apply r> 2each ; inline
|
||||||
|
|
||||||
|
: each-parameter ( parameters quot -- )
|
||||||
|
>r [ parameter-sizes ] keep r> 2each ; inline
|
||||||
|
|
||||||
|
: move-parameters ( params vop -- )
|
||||||
|
#! Moves values from C stack to registers (if vop is
|
||||||
|
#! %stack>freg) and registers to C stack (if vop is
|
||||||
|
#! %freg>stack).
|
||||||
|
swap [
|
||||||
|
flatten-value-types
|
||||||
|
0 { int-regs float-regs stack-params } [ set ] each-with
|
||||||
|
[ pick >r alloc-parameter r> execute , ] each-parameter
|
||||||
|
drop
|
||||||
|
] with-scope ; inline
|
||||||
|
|
||||||
|
: box-parameter ( stack# type -- node )
|
||||||
|
c-type [ "reg-class" get "boxer" get ] bind call ;
|
|
@ -140,6 +140,7 @@ vectors words ;
|
||||||
|
|
||||||
"/library/alien/c-types.factor"
|
"/library/alien/c-types.factor"
|
||||||
"/library/alien/structs.factor"
|
"/library/alien/structs.factor"
|
||||||
|
"/library/alien/compiler.factor"
|
||||||
"/library/alien/alien-invoke.factor"
|
"/library/alien/alien-invoke.factor"
|
||||||
"/library/alien/alien-callback.factor"
|
"/library/alien/alien-callback.factor"
|
||||||
"/library/alien/syntax.factor"
|
"/library/alien/syntax.factor"
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
! Copyright (C) 2005 Slava Pestov.
|
! Copyright (C) 2005, 2006 Slava Pestov.
|
||||||
! See http://factor.sf.net/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: compiler-backend
|
IN: compiler-backend
|
||||||
USING: alien assembler kernel math ;
|
USING: alien assembler kernel math sequences ;
|
||||||
|
|
||||||
GENERIC: store-insn ( offset reg-class -- )
|
GENERIC: freg>stack ( stack reg reg-class -- )
|
||||||
|
|
||||||
GENERIC: load-insn ( elt parameter reg-class -- )
|
GENERIC: stack>freg ( stack reg reg-class -- )
|
||||||
|
|
||||||
M: int-regs store-insn drop >r 3 1 r> stack@ STW ;
|
M: int-regs freg>stack drop 1 rot stack@ STW ;
|
||||||
|
|
||||||
M: int-regs load-insn drop 3 + 1 rot stack@ LWZ ;
|
M: int-regs stack>freg drop 1 rot stack@ LWZ ;
|
||||||
|
|
||||||
M: float-regs store-insn
|
: STF float-regs-size 4 = [ STFS ] [ STFD ] if ;
|
||||||
>r >r 1 1 r> stack@ r>
|
|
||||||
float-regs-size 4 = [ STFS ] [ STFD ] if ;
|
|
||||||
|
|
||||||
M: float-regs load-insn
|
M: float-regs freg>stack >r 1 rot stack@ r> STF ;
|
||||||
>r 1+ 1 rot stack@ r>
|
|
||||||
float-regs-size 4 = [ LFS ] [ LFD ] if ;
|
|
||||||
|
|
||||||
M: stack-params load-insn
|
: LF float-regs-size 4 = [ LFS ] [ LFD ] if ;
|
||||||
|
|
||||||
|
M: float-regs stack>freg >r 1 rot stack@ r> LF ;
|
||||||
|
|
||||||
|
M: stack-params stack>freg
|
||||||
drop >r 0 1 rot stack@ LWZ 0 1 r> stack@ STW ;
|
drop >r 0 1 rot stack@ LWZ 0 1 r> stack@ STW ;
|
||||||
|
|
||||||
M: %unbox generate-node ( vop -- )
|
M: %unbox generate-node ( vop -- )
|
||||||
|
@ -27,7 +27,7 @@ M: %unbox generate-node ( vop -- )
|
||||||
! Call the unboxer
|
! Call the unboxer
|
||||||
2 input f compile-c-call
|
2 input f compile-c-call
|
||||||
! Store the return value on the C stack
|
! Store the return value on the C stack
|
||||||
0 input 1 input store-insn ;
|
0 input 1 input [ return-reg ] keep freg>stack ;
|
||||||
|
|
||||||
M: %unbox-struct generate-node ( vop -- )
|
M: %unbox-struct generate-node ( vop -- )
|
||||||
drop
|
drop
|
||||||
|
@ -38,11 +38,23 @@ M: %unbox-struct generate-node ( vop -- )
|
||||||
! Copy the struct to the stack
|
! Copy the struct to the stack
|
||||||
"unbox_value_struct" f compile-c-call ;
|
"unbox_value_struct" f compile-c-call ;
|
||||||
|
|
||||||
M: %parameter generate-node ( vop -- )
|
: (%move) 0 input 1 input 2 input [ fastcall-regs nth ] keep ;
|
||||||
! Move a value from the C stack into the fastcall register
|
|
||||||
drop 0 input 1 input 2 input load-insn ;
|
|
||||||
|
|
||||||
M: %box generate-node ( vop -- ) drop 1 input f compile-c-call ;
|
M: %stack>freg generate-node ( vop -- )
|
||||||
|
! Move a value from the C stack into the fastcall register
|
||||||
|
drop (%move) stack>freg ;
|
||||||
|
|
||||||
|
M: %freg>stack generate-node ( vop -- )
|
||||||
|
! Move a value from a fastcall register to the C stack
|
||||||
|
drop (%move) freg>stack ;
|
||||||
|
|
||||||
|
M: %box generate-node ( vop -- )
|
||||||
|
drop
|
||||||
|
! 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.
|
||||||
|
0 input [ 0 1 input stack>freg ] when*
|
||||||
|
2 input f compile-c-call ;
|
||||||
|
|
||||||
M: %cleanup generate-node ( vop -- ) drop ;
|
M: %cleanup generate-node ( vop -- ) drop ;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ USING: assembler compiler-backend kernel kernel-internals math ;
|
||||||
: vregs { 3 4 5 6 7 8 9 10 } ; inline
|
: vregs { 3 4 5 6 7 8 9 10 } ; inline
|
||||||
|
|
||||||
M: int-regs return-reg drop 3 ;
|
M: int-regs return-reg drop 3 ;
|
||||||
M: int-regs fastcall-regs drop 8 ;
|
M: int-regs fastcall-regs drop { 3 4 5 6 7 8 9 10 } ;
|
||||||
|
|
||||||
M: float-regs return-reg drop 1 ;
|
M: float-regs return-reg drop 1 ;
|
||||||
M: float-regs fastcall-regs drop 8 ;
|
M: float-regs fastcall-regs drop { 1 2 3 4 5 6 7 8 } ;
|
||||||
|
|
||||||
! Mach-O -vs- Linux/PPC
|
! Mach-O -vs- Linux/PPC
|
||||||
: stack@ os "macosx" = 24 8 ? + ;
|
: stack@ os "macosx" = 24 8 ? + ;
|
||||||
|
|
|
@ -43,15 +43,17 @@ M: float-regs inc-reg-class
|
||||||
dup class inc
|
dup class inc
|
||||||
os "macosx" = [ reg-size 4 / int-regs +@ ] [ drop ] if ;
|
os "macosx" = [ reg-size 4 / int-regs +@ ] [ drop ] if ;
|
||||||
|
|
||||||
|
! A pseudo-register class for parameters spilled on the stack
|
||||||
|
TUPLE: stack-params ;
|
||||||
|
|
||||||
|
M: stack-params fastcall-regs drop 0 ;
|
||||||
|
|
||||||
! A data stack location.
|
! A data stack location.
|
||||||
TUPLE: ds-loc n ;
|
TUPLE: ds-loc n ;
|
||||||
|
|
||||||
! A call stack location.
|
! A call stack location.
|
||||||
TUPLE: cs-loc n ;
|
TUPLE: cs-loc n ;
|
||||||
|
|
||||||
! A pseudo-register class for parameters spilled on the stack
|
|
||||||
TUPLE: stack-params ;
|
|
||||||
|
|
||||||
GENERIC: v>operand
|
GENERIC: v>operand
|
||||||
|
|
||||||
M: integer v>operand tag-bits shift ;
|
M: integer v>operand tag-bits shift ;
|
||||||
|
@ -353,9 +355,13 @@ C: %parameters make-vop ;
|
||||||
M: %parameters stack-reserve vop-inputs first ;
|
M: %parameters stack-reserve vop-inputs first ;
|
||||||
: %parameters ( n -- vop ) src-vop <%parameters> ;
|
: %parameters ( n -- vop ) src-vop <%parameters> ;
|
||||||
|
|
||||||
TUPLE: %parameter ;
|
TUPLE: %stack>freg ;
|
||||||
C: %parameter make-vop ;
|
C: %stack>freg make-vop ;
|
||||||
: %parameter ( n reg reg-class -- vop ) 3-in-vop <%parameter> ;
|
: %stack>freg ( n reg reg-class -- vop ) 3-in-vop <%stack>freg> ;
|
||||||
|
|
||||||
|
TUPLE: %freg>stack ;
|
||||||
|
C: %freg>stack make-vop ;
|
||||||
|
: %freg>stack ( n reg reg-class -- vop ) 3-in-vop <%freg>stack> ;
|
||||||
|
|
||||||
TUPLE: %cleanup ;
|
TUPLE: %cleanup ;
|
||||||
C: %cleanup make-vop ;
|
C: %cleanup make-vop ;
|
||||||
|
@ -372,7 +378,7 @@ C: %unbox-struct make-vop ;
|
||||||
|
|
||||||
TUPLE: %box ;
|
TUPLE: %box ;
|
||||||
C: %box make-vop ;
|
C: %box make-vop ;
|
||||||
: %box ( reg-class func -- vop ) 2-in-vop <%box> ;
|
: %box ( n reg-class func -- vop ) 3-in-vop <%box> ;
|
||||||
|
|
||||||
TUPLE: %alien-invoke ;
|
TUPLE: %alien-invoke ;
|
||||||
C: %alien-invoke make-vop ;
|
C: %alien-invoke make-vop ;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
IN: temporary
|
IN: temporary
|
||||||
USING: alien compiler errors inference io kernel memory
|
USING: alien compiler errors inference io kernel math memory
|
||||||
namespaces test threads ;
|
namespaces test threads ;
|
||||||
|
|
||||||
: callback-1 "void" { } [ ] alien-callback ; compiled
|
: callback-1 "void" { } [ ] alien-callback ; compiled
|
||||||
|
@ -52,3 +52,16 @@ FUNCTION: void callback_test_1 void* callback ; compiled
|
||||||
"void" { } [ yield "hi" print flush yield ] alien-callback ; compiled
|
"void" { } [ yield "hi" print flush yield ] alien-callback ; compiled
|
||||||
|
|
||||||
[ ] [ callback-7 callback_test_1 ] unit-test
|
[ ] [ callback-7 callback_test_1 ] unit-test
|
||||||
|
|
||||||
|
: callback-8
|
||||||
|
"void" { "int" "int" } [ / "x" set ] alien-callback ;
|
||||||
|
compiled
|
||||||
|
|
||||||
|
! FUNCTION: void callback_test_2 void* callback int x int y ;
|
||||||
|
! compiled
|
||||||
|
!
|
||||||
|
! [ 3/4 ] [
|
||||||
|
! [
|
||||||
|
! "x" off callback-8 3 4 callback_test_2 "x" get
|
||||||
|
! ] with-scope
|
||||||
|
! ] unit-test
|
||||||
|
|
|
@ -44,21 +44,21 @@ void *alien_offset(CELL object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pop ( alien n ) from datastack, return alien's address plus n */
|
|
||||||
INLINE void *alien_pointer(void)
|
|
||||||
{
|
|
||||||
F_FIXNUM offset = unbox_signed_cell();
|
|
||||||
return alien_offset(dpop()) + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pop an object representing a C pointer */
|
/* pop an object representing a C pointer */
|
||||||
void *unbox_alien(void)
|
void *unbox_alien(void)
|
||||||
{
|
{
|
||||||
return alien_offset(dpop());
|
return alien_offset(dpop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pop ( alien n ) from datastack, return alien's address plus n */
|
||||||
|
INLINE void *alien_pointer(void)
|
||||||
|
{
|
||||||
|
F_FIXNUM offset = unbox_signed_cell();
|
||||||
|
return unbox_alien() + offset;
|
||||||
|
}
|
||||||
|
|
||||||
/* make an alien */
|
/* make an alien */
|
||||||
ALIEN *alien(void* ptr)
|
ALIEN *alien(void *ptr)
|
||||||
{
|
{
|
||||||
ALIEN* alien = allot_object(ALIEN_TYPE,sizeof(ALIEN));
|
ALIEN* alien = allot_object(ALIEN_TYPE,sizeof(ALIEN));
|
||||||
alien->ptr = ptr;
|
alien->ptr = ptr;
|
||||||
|
|
|
@ -61,7 +61,7 @@ int main(int argc, char** argv)
|
||||||
printf(" +Xn Code heap size, megabytes\n");
|
printf(" +Xn Code heap size, megabytes\n");
|
||||||
printf("Other options are handled by the Factor library.\n");
|
printf("Other options are handled by the Factor library.\n");
|
||||||
printf("See the documentation for details.\n");
|
printf("See the documentation for details.\n");
|
||||||
printf("Send bug reports to Slava Pestov <slava@jedit.org>.\n");
|
printf("Send bug reports to Slava Pestov <slava@factorcode.org>.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,3 +91,12 @@ void callback_test_1(void (*callback)())
|
||||||
printf("callback_test_1 leaving\n");
|
printf("callback_test_1 leaving\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void callback_test_2(void (*callback)(int x, int y), int x, int y)
|
||||||
|
{
|
||||||
|
printf("callback_test_2 entry\n");
|
||||||
|
fflush(stdout);
|
||||||
|
callback(x,y);
|
||||||
|
printf("callback_test_2 leaving\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
|
@ -84,7 +84,6 @@ void run_nullary_callback(CELL quot)
|
||||||
{
|
{
|
||||||
call(quot);
|
call(quot);
|
||||||
run(false);
|
run(false);
|
||||||
unnest_stacks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by compiled callbacks after nest_stacks() and boxing registers */
|
/* Called by compiled callbacks after nest_stacks() and boxing registers */
|
||||||
|
@ -92,7 +91,6 @@ CELL run_unary_callback(CELL quot)
|
||||||
{
|
{
|
||||||
CELL retval;
|
CELL retval;
|
||||||
|
|
||||||
nest_stacks();
|
|
||||||
call(quot);
|
call(quot);
|
||||||
run(false);
|
run(false);
|
||||||
retval = dpeek();
|
retval = dpeek();
|
||||||
|
|
Loading…
Reference in New Issue