The entry point was the one call site a redefinition could not reach. A dev build gives every Flan function an indirection cell and routes every call through it, which is what makes C-c C-c land on the sites that already exist; the emitted C main called the Flan-level main by symbol instead. So flan_program_main — what M-x flan-rerun re-enters — ran the body main had at the initial build for the life of the process, and redefining main compiled, installed, reported ok and changed nothing anyone could see. Both backends had the same direct call and both get the same split. LLVM loads the cell and calls the loaded pointer; x86 does what call_flan's `Cell target does, one load because emit_cells defines the cell in this same object. Release builds keep the symbol, so emit and emit --x86 are byte-identical to what they were. The cell is initialised to the body this build compiled, so the first run is the run it always was. What is left is an off-by-one that belongs to lib/dev.ml: a body delivered while parked installs at the next frame boundary, which a re-run reaches inside main, so a generation runs one re-run later than the key press. FIX.org has the one-call close and why it is not done here.
20 lines
821 B
Plaintext
20 lines
821 B
Plaintext
;;;; main, redefined while the program is parked, and re-entered.
|
|
;;;;
|
|
;;;; Every call a dev build makes goes through an indirection cell, which is
|
|
;;;; what makes a C-c C-c redefinition reach the call sites that already
|
|
;;;; exist. The emitted C [main] used to be the one exception: it called the
|
|
;;;; Flan-level [main] by symbol, so the body the daemon re-enters on a
|
|
;;;; [rerun] was always the body [main] had at the initial build, however many
|
|
;;;; times [main] itself had been redefined.
|
|
;;;;
|
|
;;;; So this fixture is deliberately almost empty: what it prints is the
|
|
;;;; question, and every later generation of it arrives over the socket.
|
|
(import agent "vendor:agent")
|
|
|
|
(defn main [] i32
|
|
(agent/start "/tmp/flan-dev-main-redef-fallback.sock")
|
|
(println "generation 1")
|
|
(dotimes [i 40]
|
|
(agent/wait 5))
|
|
0)
|