flan/lib/mangle.ml
Joseph Ferano e6ac833626 The follow-ups the day's reviews left behind, each re-verified
flan.abi.require was spelled by hand in both backends, which is the one
job Mangle has. Moved; emit and x86 produce byte-identical output on the
reload path either way.

Four comments in the dyn-cast code asserted things that are not true.
The warning's location prefix now reads like every other loc-bearing
runtime diagnostic instead of inventing a shape. widen's contract says
what cast_dyn actually does with it. The thread-safety note names the
torn {ptr,len} overread rather than a duplicated line, and says why no
lock. The site table's borrowed loc pointer names what keeps it valid.

The memory op's note claimed a completeness it does not have: dyn push
and put may allocate and are deliberately silent. Said so, in the note,
in the classifier, and in FIX.org where the decision belongs.

The documented flycheck form only matched warnings, so a real error
made it say the checker returned non-zero and found nothing.

flan-clear-memory cleared one buffer where the toggle clears all.

Two comments claimed test/dyn_ops.c calls every function flan_dyn.h
declares; six are declared and never called there.

flan_dyn_stub.c's deadness is written into FIX.org for the author to
decide on. Not deleted here.
2026-09-20 14:32:17 +07:00

53 lines
2.7 KiB
OCaml

(* The symbol names a Flan build puts into an object, spelled once.
Both backends emit the same names — that is not a nicety, it is the link:
an [--x86] host and a redefinition module built by LLVM bind against each
other, so [@"flan.cell.<n>"] has to be byte-for-byte the same string on
both sides or the dlopen fails and the piece served nothing. The macro
loader and the daemon's disassembler look up the same names from outside
the backends entirely.
So the prefixes live here, unquoted and without a sigil. Quoting is each
backend's own — LLVM writes [@"..."], the assembler writes ["..."] — and a
Flan name holds -, ?, > and /, which is why every emitted name is quoted
at all. This module only decides *which string* is quoted.
Not here: the ABI marker itself. [Emit.abi_marker] is ["flan.abi.llvm"] and
[X86.abi_marker] is ["flan.abi.x86"], and the two must stay distinct —
a crossed pair is refused at [dlopen] precisely because the marker one
image defines is not the one the other references. Sharing that string
would delete the mechanism. The *label* a module hangs its requirement on
is the other half of that mechanism and is shared, so it is here: see
[abi_require] below. *)
(* The prefix itself. It keeps the Flan [main] from colliding with C's, and
it is what makes every Flan symbol recognisable in a disassembly. *)
let prefix = "flan."
(* A function or a global. One namespace, because the language has one: a
[defn] and a [defvar] cannot share a name, so nothing here has to keep
them apart. The compiler's own names go through this too — [.init-globals]
and [.init-data] start with a dot no reader token can produce. *)
let sym n = prefix ^ n
(* A dev build's indirection cell: a mutable global holding the address of the
function that is currently this name's body. *)
let cell n = prefix ^ "cell." ^ n
(* The two module-local caches a name the host was never built with is reached
through — one for a function, one for a global. *)
let cellptr n = prefix ^ "cellp." ^ n
let globalptr n = prefix ^ "gp." ^ n
(* A compiled macro's entry point, which the expander dlsyms by this name out
of the module [Build.macro_module] wrote. *)
let macro n = prefix ^ "macro." ^ n
(* The datum a redefinition module puts its host's ABI marker into. Nothing
outside the module names it — the relocation against the marker is the
whole of what it does — but both backends emit it, so the string is spelled
once here rather than twice, beside every other name that has to read the
same on both sides. What it *holds* is each backend's own marker, and that
pair stays distinct; see the paragraph at the top. *)
let abi_require = prefix ^ "abi.require"