
Really, `raco demod` is adapted here to work with any linklet-based VM by compiling modules to machine-independent form, which is essentially a wrapper around linklet S-expressions. The BC-specific implementation remains in place, and it has the advantage of being able to work with existing module compilations, while the implementation based on machine-independent form must recompile all modules before attempting to combine them (but that recompilation is easily cached). Use `--work <dir>` to use `<dir>` as a cache for multiple demodularizations. Getting `raco demod` to work involved several incidental improvements: * make `racket/linklet` work with machine-independent forms; * add `linklet-body-reserved-symbol?`; * fix schemify for linklets that have unexported definitions (which the expander never generates, but the demodularizer does); * add `current-multi-compile-any` to expose CM's multi-target compilation mode programmatically; and * repair a bug in CS JIT mode. The demodularizer could be a lot smarter to prune demodularized code before sending it off to the compiler. Of course, the compiler should be able to figure out improvements itself, but sending a smaller chunk of code to the compiler can avoid the hybrid interpreter--compiler mode that is used for large linklets and that prevents optimizers like cp0 from doing much to prune definitions. The demodularizer has a lot in common with the expander's flattener that is used for bootstrapping, and a smarter demodularizer would have even more in common. It would be nice to have one implementation instead of two.
96 lines
3.2 KiB
Racket
96 lines
3.2 KiB
Racket
#lang racket/base
|
|
(require racket/match
|
|
racket/linklet
|
|
compiler/zo-structs
|
|
compiler/private/deserialize)
|
|
|
|
(provide linklet*-exports
|
|
linklet*-internals
|
|
linklet*-importss
|
|
linklet*-internal-exports
|
|
linklet*-internal-importss
|
|
linklet*-import-shapess
|
|
linklet*-lifts
|
|
linklet*-body
|
|
s-exp->linklet)
|
|
|
|
(define (get-exports linkl select)
|
|
(cond
|
|
[(linkl? linkl) (linkl-exports linkl)]
|
|
[(faslable-correlated-linklet? linkl)
|
|
(match (faslable-correlated-linklet-expr linkl)
|
|
[`(linklet ,imports ,exports . ,_) (for/list ([ex (in-list exports)])
|
|
(strip-correlated
|
|
(if (pair? ex)
|
|
(select ex)
|
|
ex)))])]
|
|
[else (unsupported linkl)]))
|
|
|
|
(define (linklet*-exports linkl)
|
|
(get-exports linkl cadr))
|
|
|
|
(define (linklet*-internal-exports linkl)
|
|
(get-exports linkl car))
|
|
|
|
(define (linklet*-internals linkl)
|
|
(cond
|
|
[(linkl? linkl) (linkl-internals linkl)]
|
|
[(faslable-correlated-linklet? linkl)
|
|
(match (faslable-correlated-linklet-expr linkl)
|
|
[`(linklet ,imports ,exports . ,body)
|
|
(for/fold ([l '()]) ([form (in-list body)])
|
|
(match form
|
|
[`(define-values ,ids ,_)
|
|
(append (map strip-correlated ids) l)]
|
|
[else l]))])]
|
|
[else (unsupported linkl)]))
|
|
|
|
(define (linklet*-importss linkl)
|
|
(get-importss linkl car))
|
|
|
|
(define (linklet*-internal-importss linkl)
|
|
(get-importss linkl cadr))
|
|
|
|
(define (get-importss linkl select)
|
|
(cond
|
|
[(linkl? linkl) (linkl-importss linkl)]
|
|
[(faslable-correlated-linklet? linkl)
|
|
(match (faslable-correlated-linklet-expr linkl)
|
|
[`(linklet ,importss ,exports . ,_) (for/list ([imports (in-list importss)])
|
|
(for/list ([im (in-list imports)])
|
|
(strip-correlated
|
|
(if (pair? im)
|
|
(select im)
|
|
im))))])]
|
|
[else (unsupported linkl)]))
|
|
|
|
(define (linklet*-import-shapess linkl)
|
|
(cond
|
|
[(linkl? linkl) (linkl-import-shapess linkl)]
|
|
[(faslable-correlated-linklet? linkl)
|
|
(match (faslable-correlated-linklet-expr linkl)
|
|
[`(linklet ,importss ,exports . ,_) (for/list ([imports (in-list importss)])
|
|
(for/list ([im (in-list imports)])
|
|
#f))])]
|
|
[else (unsupported linkl)]))
|
|
|
|
(define (linklet*-lifts linkl)
|
|
(cond
|
|
[(linkl? linkl) (linkl-lifts linkl)]
|
|
[(faslable-correlated-linklet? linkl) '()]
|
|
[else (unsupported linkl)]))
|
|
|
|
(define (linklet*-body linkl)
|
|
(cond
|
|
[(faslable-correlated-linklet? linkl)
|
|
(match (faslable-correlated-linklet-expr linkl)
|
|
[`(linklet ,imports ,exports . ,body)
|
|
(strip-correlated body)])]
|
|
[else #f]))
|
|
|
|
(define (s-exp->linklet name expr)
|
|
(faslable-correlated-linklet expr name))
|
|
|
|
(define (unsupported linkl)
|
|
(error 'demodularize "unsupported linklet format"))
|