Session hands global/<n> to the redefinition when a def is re-evaluated, and that target is not a sibling — its fparent is the global — so its cell declaration comes from Emit.redefinition's targets pass, a path no test compiled: the dev-rerun leg runs on x86 merged, which reaches host cells through the GOT and never needed the declaration. reload.flan carries a (def paint i64 7) now and test_reload greps the module text for the cell extern and the hidden body, which is the idiom the file already uses.
56 lines
2.7 KiB
Plaintext
56 lines
2.7 KiB
Plaintext
;;;; The reload primitive's fixture, v1 (NEXT.md, dev loop step 1 and 2).
|
|
;;;;
|
|
;;;; There is deliberately no [main]: the host is reload_host.c, which links
|
|
;;;; this program and then dlopens two rebuilt copies of [bump].
|
|
;;;;
|
|
;;;; [counter] is the state that has to survive a reload — a redefinition
|
|
;;;; module declares it [external], so the loaded object writes the host's copy
|
|
;;;; and not a new one. [outer] is the call site that has to *follow* a reload:
|
|
;;;; it is compiled once, into the host, and never rebuilt, so if a redefined
|
|
;;;; [bump] runs when the host calls [outer] then the cell is doing its job.
|
|
;;;; The string is not decoration either — a redefinition module has to carry
|
|
;;;; its own constants, and a one-function module usually has none.
|
|
(defonce counter i64)
|
|
|
|
;;; A move-only global, which is allowed because reading one is always a borrow
|
|
;;; (spec-memory.md, "Globals of move-only type"). It is here for the reload
|
|
;;; question rather than the ownership one: a redefinition module declares it
|
|
;;; [external] like any other host global, so a load must not hand the module
|
|
;;; its own zeroed header -- that would drop the storage the running process is
|
|
;;; still using, which is the failure a plain i64 counter cannot exhibit
|
|
;;; because a re-zeroed i64 merely looks wrong.
|
|
(defonce tally (Vec u8))
|
|
|
|
;;; Unused, and that is the point: the session's compatibility rules only get a
|
|
;;; chance to speak about a change the *checker* accepts, and retyping a var
|
|
;;; something else reads is an ordinary type error long before it is a layout
|
|
;;; question.
|
|
(defonce spare i64)
|
|
|
|
;;; Unused too, and here for the redefinition-module question a [def] adds:
|
|
;;; its initialiser is lifted into [global/paint] whatever it is — a literal
|
|
;;; included — so re-evaluating the form republishes that function through
|
|
;;; its cell, and [global/paint] is a *non-sibling* target (its parent is the
|
|
;;; global, not a function in the form). test_reload greps the module's IR
|
|
;;; for the cell declaration that publish needs.
|
|
(def paint i64 7)
|
|
|
|
;;; Also unused, and for the same reason: a defconst's value and an enum
|
|
;;; member are folded into every call site, so a session has to refuse changing
|
|
;;; either. Nothing here reads them, so the checker has no opinion and the
|
|
;;; session's rule is the only thing that can speak.
|
|
(defconst folded i64 7)
|
|
;;; ...and one that is not: an array constant is never an array length, so its
|
|
;;; value is only ever read at run time and a dev build can store a new one.
|
|
(defconst palette [2 u32] [1 2])
|
|
(defenum Colour [red 0 green 1])
|
|
|
|
(defn helper [x i64] i64 (* x 2))
|
|
|
|
(defn bump [] i64
|
|
(println "v1")
|
|
(set counter (+ counter 1))
|
|
(helper counter))
|
|
|
|
(defn outer [] i64 (bump))
|