| 
									
										
										
										
											2008-02-18 06:07:40 -05:00
										 |  |  | ! Copyright (C) 2006, 2008 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: arrays generator generator.registers generator.fixup | 
					
						
							|  |  |  | hashtables kernel math namespaces sequences words | 
					
						
							| 
									
										
										
										
											2008-01-01 14:54:14 -05:00
										 |  |  | inference.state inference.backend inference.dataflow system | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  | math.parser classes alien.arrays alien.c-types alien.strings | 
					
						
							|  |  |  | alien.structs alien.syntax cpu.architecture alien inspector | 
					
						
							|  |  |  | quotations assocs kernel.private threads continuations.private | 
					
						
							|  |  |  | libc combinators compiler.errors continuations layouts accessors | 
					
						
							|  |  |  | ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: alien.compiler | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | TUPLE: #alien-node < node return parameters abi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: #alien-callback < #alien-node quot xt ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: #alien-indirect < #alien-node ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: #alien-invoke < #alien-node library function ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : large-struct? ( ctype -- ? )
 | 
					
						
							|  |  |  |     dup c-struct? [ | 
					
						
							|  |  |  |         heap-size struct-small-enough? not
 | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |     ] [ drop f ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : alien-node-parameters* ( node -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     dup parameters>> | 
					
						
							| 
									
										
										
										
											2008-03-31 20:18:05 -04:00
										 |  |  |     swap return>> large-struct? [ "void*" prefix ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : alien-node-return* ( node -- ctype )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     return>> dup large-struct? [ drop "void" ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  | : c-type-stack-align ( type -- align )
 | 
					
						
							|  |  |  |     dup c-type-stack-align? [ c-type-align ] [ drop cell ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : parameter-align ( n type -- n delta )
 | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  |     over >r c-type-stack-align align dup r> - ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : parameter-sizes ( types -- total offsets )
 | 
					
						
							|  |  |  |     #! Compute stack frame locations. | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         0 [ | 
					
						
							|  |  |  |             [ parameter-align drop dup , ] keep stack-size +
 | 
					
						
							|  |  |  |         ] reduce cell align
 | 
					
						
							|  |  |  |     ] { } make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : return-size ( ctype -- n )
 | 
					
						
							|  |  |  |     #! Amount of space we reserve for a return value. | 
					
						
							|  |  |  |     dup large-struct? [ heap-size ] [ drop 0 ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : alien-stack-frame ( node -- n )
 | 
					
						
							|  |  |  |     alien-node-parameters* parameter-sizes drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : alien-invoke-frame ( node -- n )
 | 
					
						
							|  |  |  |     #! One cell is temporary storage, temp@ | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     dup return>> return-size | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     swap alien-stack-frame +
 | 
					
						
							|  |  |  |     cell + ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : set-stack-frame ( n -- )
 | 
					
						
							|  |  |  |     dup [ frame-required ] when* \ stack-frame set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-stack-frame ( n quot -- )
 | 
					
						
							|  |  |  |     swap set-stack-frame | 
					
						
							|  |  |  |     call
 | 
					
						
							|  |  |  |     f set-stack-frame ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 17:30:34 -04:00
										 |  |  | GENERIC: reg-size ( register-class -- n )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: int-regs reg-size drop cell ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  | M: single-float-regs reg-size drop 4 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: double-float-regs reg-size drop 8 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: reg-class-variable ( register-class -- symbol )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: reg-class reg-class-variable ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: float-regs reg-class-variable drop float-regs ;
 | 
					
						
							| 
									
										
										
										
											2007-09-27 17:30:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | GENERIC: inc-reg-class ( register-class -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  | M: reg-class inc-reg-class | 
					
						
							|  |  |  |     dup reg-class-variable inc
 | 
					
						
							| 
									
										
										
										
											2007-09-27 17:30:34 -04:00
										 |  |  |     fp-shadows-int? [ reg-size stack-params +@ ] [ drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: float-regs inc-reg-class | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  |     dup call-next-method | 
					
						
							| 
									
										
										
										
											2007-10-31 21:51:38 -04:00
										 |  |  |     fp-shadows-int? [ reg-size cell /i int-regs +@ ] [ drop ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-27 17:30:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : reg-class-full? ( class -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  |     [ reg-class-variable get ] [ param-regs length ] bi >= ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : spill-param ( reg-class -- n reg-class )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  |     stack-params get
 | 
					
						
							|  |  |  |     >r reg-size stack-params +@ r> | 
					
						
							|  |  |  |     stack-params ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : fastcall-param ( reg-class -- n reg-class )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  |     [ reg-class-variable get ] [ inc-reg-class ] [ ] tri ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : alloc-parameter ( parameter -- reg reg-class )
 | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  |     c-type-reg-class dup reg-class-full? | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     [ spill-param ] [ fastcall-param ] if
 | 
					
						
							|  |  |  |     [ param-reg ] keep ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (flatten-int-type) ( size -- )
 | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  |     cell /i "void*" c-type <repetition> % ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: flatten-value-type ( type -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object flatten-value-type , ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  | M: struct-type flatten-value-type ( type -- )
 | 
					
						
							|  |  |  |     stack-size cell align (flatten-int-type) ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  | M: long-long-type flatten-value-type ( type -- )
 | 
					
						
							|  |  |  |     stack-size cell align (flatten-int-type) ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : flatten-value-types ( params -- params )
 | 
					
						
							|  |  |  |     #! Convert value type structs to consecutive void*s. | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         0 [ | 
					
						
							|  |  |  |             c-type | 
					
						
							|  |  |  |             [ parameter-align (flatten-int-type) ] keep
 | 
					
						
							|  |  |  |             [ stack-size cell align + ] keep
 | 
					
						
							|  |  |  |             flatten-value-type | 
					
						
							|  |  |  |         ] reduce drop
 | 
					
						
							|  |  |  |     ] { } make ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : each-parameter ( parameters quot -- )
 | 
					
						
							|  |  |  |     >r [ parameter-sizes nip ] keep r> 2each ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : reverse-each-parameter ( parameters quot -- )
 | 
					
						
							|  |  |  |     >r [ parameter-sizes nip ] keep r> 2reverse-each ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : reset-freg-counts ( -- )
 | 
					
						
							|  |  |  |     { int-regs float-regs stack-params } [ 0 swap set ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-param-regs ( quot -- )
 | 
					
						
							|  |  |  |     #! In quot you can call alloc-parameter | 
					
						
							|  |  |  |     [ reset-freg-counts call ] with-scope ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : move-parameters ( node word -- )
 | 
					
						
							|  |  |  |     #! Moves values from C stack to registers (if word is | 
					
						
							|  |  |  |     #! %load-param-reg) and registers to C stack (if word is | 
					
						
							|  |  |  |     #! %save-param-reg). | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  |     >r | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     alien-node-parameters* | 
					
						
							|  |  |  |     flatten-value-types | 
					
						
							| 
									
										
										
										
											2007-10-09 18:06:44 -04:00
										 |  |  |     r> [ >r alloc-parameter r> execute ] curry each-parameter ;
 | 
					
						
							|  |  |  |     inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : if-void ( type true false -- )
 | 
					
						
							|  |  |  |     pick "void" = [ drop nip call ] [ nip call ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : alien-invoke-stack ( node extra -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     over parameters>> length + dup reify-curries | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     over consume-values | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     dup return>> "void" = 0 1 ?
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     swap produce-values ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  | : (param-prep-quot) ( parameters -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup empty? [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |         unclip c-type c-type-unboxer-quot % | 
					
						
							|  |  |  |         \ >r , (param-prep-quot) \ r> , | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  | : param-prep-quot ( node -- quot )
 | 
					
						
							|  |  |  |     parameters>> [ <reversed> (param-prep-quot) ] [ ] make ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : unbox-parameters ( offset node -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     parameters>> [ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         %prepare-unbox >r over + r> unbox-parameter | 
					
						
							|  |  |  |     ] reverse-each-parameter drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : prepare-box-struct ( node -- offset )
 | 
					
						
							|  |  |  |     #! Return offset on C stack where to store unboxed | 
					
						
							|  |  |  |     #! parameters. If the C function is returning a structure, | 
					
						
							|  |  |  |     #! the first parameter is an implicit target area pointer, | 
					
						
							|  |  |  |     #! so we need to use a different offset. | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     return>> dup large-struct? | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     [ heap-size %prepare-box-struct cell ] [ drop 0 ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : objects>registers ( node -- )
 | 
					
						
							|  |  |  |     #! Generate code for unboxing a list of C types, then | 
					
						
							|  |  |  |     #! generate code for moving these parameters to register on | 
					
						
							|  |  |  |     #! architectures where parameters are passed in registers. | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ prepare-box-struct ] keep
 | 
					
						
							|  |  |  |         [ unbox-parameters ] keep
 | 
					
						
							|  |  |  |         \ %load-param-reg move-parameters | 
					
						
							|  |  |  |     ] with-param-regs ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : box-return* ( node -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     return>> [ ] [ box-return ] if-void ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  | : (return-prep-quot) ( parameters -- )
 | 
					
						
							|  |  |  |     dup empty? [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         unclip c-type c-type-boxer-quot % | 
					
						
							|  |  |  |         \ >r , (return-prep-quot) \ r> , | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : callback-prep-quot ( node -- quot )
 | 
					
						
							|  |  |  |     parameters>> [ <reversed> (return-prep-quot) ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : return-prep-quot ( node -- quot )
 | 
					
						
							|  |  |  |     [ return>> [ ] [ 1array (return-prep-quot) ] if-void ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | M: alien-invoke-error summary | 
					
						
							| 
									
										
										
										
											2007-11-16 01:43:29 -05:00
										 |  |  |     drop
 | 
					
						
							|  |  |  |     "Words calling ``alien-invoke'' must be compiled with the optimizing compiler." ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : pop-parameters pop-literal nip [ expand-constants ] map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 01:43:15 -05:00
										 |  |  | : stdcall-mangle ( symbol node -- symbol )
 | 
					
						
							|  |  |  |     "@" | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     swap parameters>> parameter-sizes drop
 | 
					
						
							| 
									
										
										
										
											2007-11-17 01:43:15 -05:00
										 |  |  |     number>string 3append ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-10 21:32:48 -05:00
										 |  |  | TUPLE: no-such-library name ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: no-such-library summary | 
					
						
							|  |  |  |     drop "Library not found" ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | M: no-such-library compiler-error-type | 
					
						
							|  |  |  |     drop +linkage+ ;
 | 
					
						
							| 
									
										
										
										
											2008-02-10 21:32:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | : no-such-library ( name -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     \ no-such-library boa
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  |     compiling-word get compiler-error ;
 | 
					
						
							| 
									
										
										
										
											2007-11-17 01:43:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | TUPLE: no-such-symbol name ;
 | 
					
						
							| 
									
										
										
										
											2007-11-17 01:43:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: no-such-symbol summary | 
					
						
							|  |  |  |     drop "Symbol not found" ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | M: no-such-symbol compiler-error-type | 
					
						
							|  |  |  |     drop +linkage+ ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : no-such-symbol ( name -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     \ no-such-symbol boa
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  |     compiling-word get compiler-error ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-dlsym ( symbols dll -- )
 | 
					
						
							|  |  |  |     dup dll-valid? [ | 
					
						
							|  |  |  |         dupd [ dlsym ] curry contains? | 
					
						
							|  |  |  |         [ drop ] [ no-such-symbol ] if
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         dll-path no-such-library drop
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-11-17 01:43:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  | : alien-invoke-dlsym ( node -- symbols dll )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     dup function>> dup pick stdcall-mangle 2array
 | 
					
						
							|  |  |  |     swap library>> library dup [ dll>> ] when
 | 
					
						
							| 
									
										
										
										
											2008-02-16 01:54:54 -05:00
										 |  |  |     2dup check-dlsym ;
 | 
					
						
							| 
									
										
										
										
											2007-11-17 01:43:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | \ alien-invoke [ | 
					
						
							|  |  |  |     ! Four literals | 
					
						
							|  |  |  |     4 ensure-values | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     #alien-invoke new
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ! Compile-time parameters | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     pop-parameters >>parameters | 
					
						
							|  |  |  |     pop-literal nip >>function | 
					
						
							|  |  |  |     pop-literal nip >>library | 
					
						
							|  |  |  |     pop-literal nip >>return | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ! Quotation which coerces parameters to required types | 
					
						
							| 
									
										
										
										
											2008-04-29 02:49:06 -04:00
										 |  |  |     dup param-prep-quot recursive-state get infer-quot | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     ! Set ABI | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |     dup library>> library [ abi>> ] [ "cdecl" ] if* >>abi | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ! Add node to IR | 
					
						
							|  |  |  |     dup node, | 
					
						
							|  |  |  |     ! Magic #: consume exactly the number of inputs | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |     dup 0 alien-invoke-stack | 
					
						
							|  |  |  |     ! Quotation which coerces return value to required type | 
					
						
							| 
									
										
										
										
											2008-04-29 02:49:06 -04:00
										 |  |  |     return-prep-quot recursive-state get infer-quot | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ] "infer" set-word-prop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | M: #alien-invoke generate-node | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup alien-invoke-frame [ | 
					
						
							|  |  |  |         end-basic-block | 
					
						
							|  |  |  |         %prepare-alien-invoke | 
					
						
							|  |  |  |         dup objects>registers | 
					
						
							| 
									
										
										
										
											2007-10-30 01:46:41 -04:00
										 |  |  |         %prepare-var-args | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         dup alien-invoke-dlsym %alien-invoke | 
					
						
							|  |  |  |         dup %cleanup | 
					
						
							|  |  |  |         box-return* | 
					
						
							|  |  |  |         iterate-next | 
					
						
							|  |  |  |     ] with-stack-frame ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: alien-indirect-error summary | 
					
						
							| 
									
										
										
										
											2007-11-16 01:43:29 -05:00
										 |  |  |     drop "Words calling ``alien-indirect'' must be compiled with the optimizing compiler." ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | \ alien-indirect [ | 
					
						
							|  |  |  |     ! Three literals and function pointer | 
					
						
							|  |  |  |     4 ensure-values | 
					
						
							|  |  |  |     4 reify-curries | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     #alien-indirect new
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ! Compile-time parameters | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     pop-literal nip >>abi | 
					
						
							|  |  |  |     pop-parameters >>parameters | 
					
						
							|  |  |  |     pop-literal nip >>return | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ! Quotation which coerces parameters to required types | 
					
						
							| 
									
										
										
										
											2008-04-29 02:49:06 -04:00
										 |  |  |     dup param-prep-quot [ dip ] curry recursive-state get infer-quot | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ! Add node to IR | 
					
						
							|  |  |  |     dup node, | 
					
						
							|  |  |  |     ! Magic #: consume the function pointer, too | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |     dup 1 alien-invoke-stack | 
					
						
							|  |  |  |     ! Quotation which coerces return value to required type | 
					
						
							| 
									
										
										
										
											2008-04-29 02:49:06 -04:00
										 |  |  |     return-prep-quot recursive-state get infer-quot | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ] "infer" set-word-prop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | M: #alien-indirect generate-node | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup alien-invoke-frame [ | 
					
						
							|  |  |  |         ! Flush registers | 
					
						
							|  |  |  |         end-basic-block | 
					
						
							|  |  |  |         ! Save registers for GC | 
					
						
							|  |  |  |         %prepare-alien-invoke | 
					
						
							|  |  |  |         ! Save alien at top of stack to temporary storage | 
					
						
							|  |  |  |         %prepare-alien-indirect | 
					
						
							|  |  |  |         dup objects>registers | 
					
						
							| 
									
										
										
										
											2007-10-30 01:46:41 -04:00
										 |  |  |         %prepare-var-args | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         ! Call alien in temporary storage | 
					
						
							|  |  |  |         %alien-indirect | 
					
						
							|  |  |  |         dup %cleanup | 
					
						
							|  |  |  |         box-return* | 
					
						
							|  |  |  |         iterate-next | 
					
						
							|  |  |  |     ] with-stack-frame ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Callbacks are registered in a global hashtable. If you clear | 
					
						
							|  |  |  | ! this hashtable, they will all be blown away by code GC, beware | 
					
						
							|  |  |  | SYMBOL: callbacks | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-25 03:48:22 -05:00
										 |  |  | callbacks global [ H{ } assoc-like ] change-at
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : register-callback ( word -- ) dup callbacks get set-at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: alien-callback-error summary | 
					
						
							| 
									
										
										
										
											2007-11-16 01:43:29 -05:00
										 |  |  |     drop "Words calling ``alien-callback'' must be compiled with the optimizing compiler." ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : callback-bottom ( node -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  |     xt>> [ word-xt drop <alien> ] curry
 | 
					
						
							| 
									
										
										
										
											2008-04-29 02:49:06 -04:00
										 |  |  |     recursive-state get infer-quot ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | \ alien-callback [ | 
					
						
							|  |  |  |     4 ensure-values | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     #alien-callback new dup node, | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     pop-literal nip >>quot | 
					
						
							|  |  |  |     pop-literal nip >>abi | 
					
						
							|  |  |  |     pop-parameters >>parameters | 
					
						
							|  |  |  |     pop-literal nip >>return | 
					
						
							|  |  |  |     gensym dup register-callback >>xt | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     callback-bottom | 
					
						
							|  |  |  | ] "infer" set-word-prop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : box-parameters ( node -- )
 | 
					
						
							|  |  |  |     alien-node-parameters* [ box-parameter ] each-parameter ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : registers>objects ( node -- )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         dup \ %save-param-reg move-parameters | 
					
						
							|  |  |  |         "nest_stacks" f %alien-invoke | 
					
						
							|  |  |  |         box-parameters | 
					
						
							|  |  |  |     ] with-param-regs ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: callback-context ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : current-callback 2 getenv ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : wait-to-return ( token -- )
 | 
					
						
							|  |  |  |     dup current-callback eq? [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         yield wait-to-return | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : do-callback ( quot token -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-27 20:23:22 -05:00
										 |  |  |     init-catchstack | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup 2 setenv | 
					
						
							|  |  |  |     slip | 
					
						
							|  |  |  |     wait-to-return ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  | : callback-return-quot ( ctype -- quot )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |     return>> { | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         { [ dup "void" = ] [ drop [ ] ] } | 
					
						
							|  |  |  |         { [ dup large-struct? ] [ heap-size [ memcpy ] curry ] } | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |         [ c-type c-type-unboxer-quot ] | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : wrap-callback-quot ( node -- quot )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |         [ callback-prep-quot ] | 
					
						
							|  |  |  |         [ quot>> ] | 
					
						
							|  |  |  |         [ callback-return-quot ] tri 3append , | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |         [ callback-context new do-callback ] % | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] [ ] make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : %unnest-stacks ( -- ) "unnest_stacks" f %alien-invoke ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : callback-unwind ( node -- n )
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-03-20 21:13:13 -04:00
										 |  |  |         { [ dup abi>> "stdcall" = ] [ alien-stack-frame ] } | 
					
						
							|  |  |  |         { [ dup return>> large-struct? ] [ drop 4 ] } | 
					
						
							| 
									
										
										
										
											2008-04-11 13:53:22 -04:00
										 |  |  |         [ drop 0 ] | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : %callback-return ( node -- )
 | 
					
						
							|  |  |  |     #! All the extra book-keeping for %unwind is only for x86. | 
					
						
							|  |  |  |     #! On other platforms its an alias for %return. | 
					
						
							|  |  |  |     dup alien-node-return* | 
					
						
							|  |  |  |     [ %unnest-stacks ] [ %callback-value ] if-void | 
					
						
							|  |  |  |     callback-unwind %unwind ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : generate-callback ( node -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:46:30 -04:00
										 |  |  |     dup xt>> dup [ | 
					
						
							| 
									
										
										
										
											2007-10-29 01:12:27 -04:00
										 |  |  |         init-templates | 
					
						
							| 
									
										
										
										
											2007-10-28 04:33:36 -04:00
										 |  |  |         %prologue-later | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         dup alien-stack-frame [ | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  |             [ registers>objects ] | 
					
						
							|  |  |  |             [ wrap-callback-quot %alien-callback ] | 
					
						
							|  |  |  |             [ %callback-return ] | 
					
						
							|  |  |  |             tri
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         ] with-stack-frame | 
					
						
							| 
									
										
										
										
											2008-02-13 00:27:05 -05:00
										 |  |  |     ] with-generator ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | M: #alien-callback generate-node | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     end-basic-block generate-callback iterate-next ;
 |