AOT build: set per-ns ns context and register aliases
The source loader sets the current ns and registers :as aliases per file. The
build flattened every app namespace into one image with no such markers, so all
app forms ran under the last-set ns ("user"). Two breakages followed, both only
in a built binary:
- defmulti/defmethod resolve their target var through chez-current-ns, so they
registered the multifn under "user" while compiled var-derefs used the baked
ns — the multifn the app saw was uninitialized ("not a fn nil" on dispatch).
- a quoted alias-qualified symbol (a (defmethod ig/foo …) on an aliased multifn)
resolves its ns through chez-resolve-alias, but the stripped (ns …) form left
the alias table empty, so it landed in ns "ig".
bld-ns-prelude now emits (set-chez-ns! ns) plus chez-register-alias! for each
ns's :as aliases before that ns's forms, in both the normal and tree-shake emit
paths. The build-app fixture gains a :default multimethod and an aliased cross-ns
defmethod so buildsmoke covers both across all build modes.
This commit is contained in:
parent
ea609d72eb
commit
66ad475722
5 changed files with 79 additions and 4 deletions
|
|
@ -2,10 +2,17 @@
|
|||
(:require [app.util :as util]
|
||||
[clojure.java.io :as io]))
|
||||
|
||||
;; An aliased cross-ns defmethod: 'util/greet is passed quoted to defmethod-setup,
|
||||
;; so the AOT build must register the `util` alias for app.core or it resolves to
|
||||
;; ns "util" and never reaches app.util/greet (the dispatch falls to :default).
|
||||
(defmethod util/greet :loud [_] "greet:loud")
|
||||
|
||||
(defn -main [& args]
|
||||
;; the resource is baked into the binary (deps.edn :jolt/build :embed), so this
|
||||
;; resolves with no resources/ dir on disk, run from any cwd.
|
||||
(println (slurp (io/resource "greeting.txt")))
|
||||
(util/twice (println (util/shout "hello from a built binary")))
|
||||
(println "args:" (vec args))
|
||||
(println "sum:" (reduce + (map count args))))
|
||||
(println "sum:" (reduce + (map count args)))
|
||||
(println "greet-default:" (util/greet :unknown))
|
||||
(println "greet-loud:" (util/greet :loud)))
|
||||
|
|
|
|||
|
|
@ -6,3 +6,10 @@
|
|||
|
||||
(defmacro twice [x]
|
||||
`(do ~x ~x))
|
||||
|
||||
;; A multimethod with a :default method. The AOT build must set the per-ns
|
||||
;; current ns before these forms run, or the defmethod registers app.util/greet
|
||||
;; under the wrong ns and a dispatch to :default crashes (not a fn nil). app.core
|
||||
;; adds an aliased method (util/greet :loud) — see there.
|
||||
(defmulti greet (fn [kind] kind))
|
||||
(defmethod greet :default [_] "greet:default")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue