1 ! Copyright (C) 2007, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays accessors io.backend io.streams.c init fry
4 namespaces math make assocs kernel parser parser.notes lexer
5 strings.parser vocabs sequences sequences.deep sequences.private
6 words memory kernel.private continuations io vocabs.loader
7 system strings sets vectors quotations byte-arrays sorting
8 compiler.units definitions generic generic.standard
9 generic.single tools.deploy.config combinators classes
10 classes.builtin slots.private grouping ;
11 QUALIFIED: bootstrap.stage2
12 QUALIFIED: command-line
13 QUALIFIED: compiler.errors
14 QUALIFIED: continuations
15 QUALIFIED: definitions
18 QUALIFIED: source-files
19 QUALIFIED: source-files.errors
21 IN: tools.deploy.shaker
23 ! This file is some hairy shit.
25 : strip-init-hooks ( -- )
26 "Stripping startup hooks" show
35 [ init-hooks get delete-at ] each
37 "threads" init-hooks get delete-at
40 "io.thread" init-hooks get delete-at
43 "io.files" init-hooks get delete-at
44 "io.backend" init-hooks get delete-at
45 "io.thread" init-hooks get delete-at
53 } [ init-hooks get delete-at ] each
56 : strip-debugger ( -- )
57 strip-debugger? "debugger" vocab and [
58 "Stripping debugger" show
59 "vocab:tools/deploy/shaker/strip-debugger.factor"
65 "Stripping manual memory management debug code" show
66 "vocab:tools/deploy/shaker/strip-libc.factor"
70 : strip-destructors ( -- )
71 "Stripping destructor debug code" show
72 "vocab:tools/deploy/shaker/strip-destructors.factor"
75 : strip-struct-arrays ( -- )
76 "struct-arrays" vocab [
77 "Stripping dynamic struct array code" show
78 "vocab:tools/deploy/shaker/strip-struct-arrays.factor"
83 "Stripping stack effect checking from call( and execute(" show
84 "vocab:tools/deploy/shaker/strip-call.factor" run-file ;
88 "Stripping unused Cocoa methods" show
89 "vocab:tools/deploy/shaker/strip-cocoa.factor"
93 : strip-word-names ( words -- )
94 "Stripping word names" show
95 [ f >>name f >>vocabulary drop ] each ;
97 : strip-word-defs ( words -- )
98 "Stripping symbolic word definitions" show
99 [ "no-def-strip" word-prop not ] filter
100 [ [ ] >>def drop ] each ;
102 : sift-assoc ( assoc -- assoc' ) [ nip ] assoc-filter ;
104 : strip-word-props ( stripped-props words -- )
105 "Stripping word properties" show
109 [ drop _ member? not ] assoc-filter sift-assoc
115 [ [ _ [ ] cache ] map ] change-props drop
119 : stripped-word-props ( -- seq )
127 "compiled-generic-uses"
136 "default-output-classes"
169 "predicate-definition"
208 : strip-words ( props -- )
210 deploy-word-props? get [ 2dup strip-word-props ] unless
211 deploy-word-defs? get [ dup strip-word-defs ] unless
212 strip-word-names? [ dup strip-word-names ] when
215 : compiler-classes ( -- seq )
216 { "compiler" "stack-checker" }
217 [ child-vocabs [ words ] map concat [ class? ] filter ]
220 : prune-decision-tree ( tree classes -- )
221 [ tuple class>type ] 2dip '[
227 [ drop _ key? not ] assoc-filter
235 : strip-compiler-classes ( -- )
237 "Stripping compiler classes" show
238 [ single-generic? ] instances
239 compiler-classes '[ "decision-tree" word-prop _ prune-decision-tree ] each
242 : recursive-subst ( seq old new -- )
247 { [ 3dup drop eq? ] [ 2nip ] }
248 ! recurse into arrays
249 { [ pick array? ] [ [ dup ] 2dip recursive-subst ] }
250 ! otherwise do nothing
255 : strip-default-method ( generic new-default -- )
257 [ "decision-tree" word-prop ]
258 [ "default-method" word-prop ] bi
262 : new-default-method ( -- gensym )
263 [ [ "No method" throw ] (( -- * )) define-temp ] with-compilation-unit ;
265 : strip-default-methods ( -- )
266 ! In a development image, each generic has its own default method.
267 ! This gives better error messages for runtime type errors, but
268 ! takes up space. For deployment we merge them all together.
270 "Stripping default methods" show
271 [ single-generic? ] instances
272 new-default-method '[ _ strip-default-method ] each
275 : strip-vocab-globals ( except names -- words )
276 [ child-vocabs [ words ] map concat ] map concat
277 swap [ first2 lookup ] map sift diff ;
279 : stripped-globals ( -- seq )
281 "inspector-hook" "inspector" lookup ,
285 continuations:error-continuation
286 continuations:error-thread
287 continuations:restarts
289 source-files:source-files
295 "io-thread" "io.thread" lookup ,
297 "disposables" "destructors" lookup ,
299 "functor-words" "functors.backend" lookup ,
302 "initial-thread" "threads" lookup ,
305 strip-io? [ io-backend , ] when
315 } strip-vocab-globals %
318 "libraries" "alien" lookup ,
320 { { "yield-hook" "compiler.utilities" } }
321 { "cpu" "compiler" } strip-vocab-globals %
326 next-method-quot-cache
331 classes-intersect-cache
334 command-line:main-vocab-hook
336 compiled-generic-crossref
338 compiler.errors:compiler-errors
342 source-files.errors:error-types
343 source-files.errors:error-observers
345 vocabs:load-vocab-hook
346 vocabs:vocab-observers
351 { } { "layouts" } strip-vocab-globals %
353 { } { "math.partial-dispatch" } strip-vocab-globals %
355 { } { "peg" } strip-vocab-globals %
359 { } { "prettyprint.config" } strip-vocab-globals %
364 compiler.errors:compiler-errors
365 continuations:thread-error-hook
369 "ui-error-hook" "ui.gadgets.worlds" lookup ,
373 deploy-c-types? get [
374 "c-types" "alien.c-types" lookup ,
377 "windows-messages" "windows.messages" lookup [ , ] when*
380 : strip-globals ( stripped-globals -- )
382 "Stripping globals" show
384 '[ drop _ member? not ] assoc-filter
385 [ drop string? not ] assoc-filter ! strip CLI args
392 deploy-io get 3 = os windows? not and
396 "io.streams.c" forget-vocab
397 "io-thread-running?" "io.thread" lookup [
400 ] with-compilation-unit
403 : compress ( pred post-process string -- )
404 "Compressing " prepend show
405 [ instances dup H{ } clone [ [ ] cache ] curry map ] dip call
408 : compress-object? ( obj -- ? )
410 { [ dup array? ] [ empty? ] }
411 { [ dup byte-array? ] [ drop t ] }
412 { [ dup string? ] [ drop t ] }
413 { [ dup wrapper? ] [ drop t ] }
417 : compress-objects ( -- )
418 [ compress-object? ] [ ] "objects" compress ;
420 : remain-compiled ( old new -- old new )
421 ! Quotations which were formerly compiled must remain
424 2dup [ quot-compiled? ] [ quot-compiled? not ] bi* and
425 [ nip jit-compile ] [ 2drop ] if
428 : compress-quotations ( -- )
429 [ quotation? ] [ remain-compiled ] "quotations" compress
430 [ quotation? ] instances [ f >>cached-effect f >>cache-counter drop ] each ;
434 : [:c] ( -- word ) ":c" "debugger" lookup ;
436 : [print-error] ( -- word ) "print-error" "debugger" lookup ;
438 : deploy-boot-quot ( word -- )
441 init-hooks get values concat %
442 strip-debugger? [ , ] [
443 ! Don't reference 'try' directly since we don't want
444 ! to pull in the debugger and prettyprinter into every
449 [ _ execute( obj -- ) ] [
450 _ execute( obj -- ) nl
455 strip-io? [ [ flush ] % ] unless
460 : init-stripper ( -- )
462 f output-stream set-global ;
464 : next-method* ( method -- quot )
465 [ "method-class" word-prop ]
466 [ "method-generic" word-prop ] bi
469 : calls-next-method? ( method -- ? )
470 def>> flatten \ (call-next-method) swap memq? ;
472 : compute-next-methods ( -- )
473 [ standard-generic? ] instances [
474 "methods" word-prop values [ calls-next-method? ] filter
475 [ dup next-method* "next-method" set-word-prop ] each
477 "vocab:tools/deploy/shaker/next-methods.factor" run-file ;
479 : (clear-megamorphic-cache) ( i array -- )
480 ! Can't do any dispatch while clearing caches since that
481 ! might leave them in an inconsistent state.
483 2dup [ f ] 2dip set-array-nth
484 [ 1 + ] dip (clear-megamorphic-cache)
487 : clear-megamorphic-cache ( array -- )
488 [ 0 ] dip (clear-megamorphic-cache) ;
490 : find-megamorphic-caches ( -- seq )
491 "Finding megamorphic caches" show
492 [ standard-generic? ] instances [ def>> third ] map ;
494 : clear-megamorphic-caches ( cache -- )
495 "Clearing megamorphic caches" show
496 [ clear-megamorphic-cache ] each ;
509 strip-default-methods
510 strip-compiler-classes
511 f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore
512 deploy-vocab get vocab-main deploy-boot-quot
513 find-megamorphic-caches
515 stripped-globals strip-globals
519 clear-megamorphic-caches ;
521 : deploy-error-handler ( quot -- )
524 [ error-continuation get call>> callstack>array die 1 exit ]
525 ! Don't reference these words literally, if we're stripping the
526 ! debugger out we don't want to load the prettyprinter at all
527 [ [:c] execute( -- ) nl [print-error] execute( error -- ) flush ] if
531 : (deploy) ( final-image vocab config -- )
532 #! Does the actual work of a deployment in the slave
540 "ui.debugger" require
544 deploy-vocab get require
545 deploy-vocab get vocab-main [
546 "Vocabulary has no MAIN: word." print flush 1 exit
549 "Saving final image" show
551 ] deploy-error-handler
557 "Deploying " write dup write "..." print
558 "deploy-config" get parse-file first