flan/test/programs/dev-main-redef.flan
Joseph Ferano 2dfab38d06 A dev build's main is reached through its cell like every other call
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.
2026-09-20 17:57:26 +07:00

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)