The LLVM cell declaration for a lifted def initialiser, pinned in the IR
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.
This commit is contained in:
parent
a4c6b996ff
commit
801c70bd0d
@ -27,6 +27,14 @@
|
||||
;;; 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
|
||||
|
||||
@ -125,6 +125,21 @@ let () =
|
||||
fail "redefinition's own body is interposable";
|
||||
if not (has ir2 "@\"flan.cell.helper\" = external global ptr") then
|
||||
fail "redefinition defines a cell instead of using the host's";
|
||||
(* A def's lifted initialiser as the target, which is what [Session]'s
|
||||
[def_inits] hands in when the form is re-evaluated. [global/paint] is
|
||||
not a sibling — its [fparent] is the global it initialises, not a
|
||||
function in [fns] — so its cell declaration comes from the targets
|
||||
pass in [Emit.redefinition]; without that pass the publish store
|
||||
names a symbol the module never declared and the IR does not compile.
|
||||
The x86 side needs no twin: it reaches a host cell through the GOT by
|
||||
name, declared or not. *)
|
||||
(let irdef =
|
||||
Emit.redefinition ~dev:true ~known p1 ~fns:[ "global/paint" ]
|
||||
in
|
||||
if not (has irdef "@\"flan.cell.global/paint\" = external global ptr")
|
||||
then fail "a lifted def initialiser's cell is not declared";
|
||||
if not (has irdef "define hidden i64 @\"flan.global/paint\"") then
|
||||
fail "a lifted def initialiser's body is missing or interposable");
|
||||
(* A name the host has is a symbol; a name it lacks is a registry lookup
|
||||
cached in a module-local slot. Getting this backwards either fails to
|
||||
link or silently gives each module its own copy. *)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user