A wrong DWARF member offset does not crash anything. It prints a plausible value for the wrong field, which is the failure this project has met over and over at the FFI boundary, and it is the only way the debug info can be wrong without saying so. A table of expected offsets written in this test would be wrong in exactly the ways the code is wrong, so it checks against LLVM instead: ptrtoint of a getelementptr through a null pointer, over the struct type text lifted out of the emitted module, folded by llc into a .quad and read back. That is the same idiom Emit already uses for the size it hands flan_dev_global — it is just not expressible inside metadata, where offset: must be an integer literal. Then the same struct again with its fields permuted, and an assertion that the two disagree. A check that cannot come out differently is not checking anything: an offset table that ignored declaration order would satisfy either ordering alone. It fails when it should. Making a slice 4-byte aligned moves Cell.name from 24 to 20; the test says so by name, and lldb — which is the point — prints len = 21474836480 for a five-character string. The lldb cases are the only ones that say a person can debug a Flan program rather than that the metadata is self-consistent: a breakpoint on a Flan function by name, a backtrace naming .flan files and lines, and locals with their own types and values. Skipped where there is no lldb, since it is not a build dependency. The --dev case is there because "the stack goes missing under --dev" is the sort of thing found late. It does not: a cell changes how the callee is found, not how the frame is laid out.
26 lines
934 B
Plaintext
26 lines
934 B
Plaintext
;;;; debug.flan with the fields of Cell in a different order and nothing else
|
|
;;;; changed. The program prints the same four lines; the struct is a different
|
|
;;;; shape, and every member sits at a different offset.
|
|
;;;;
|
|
;;;; name at 0 (16), id at 16, alive at 20, 3 of padding, heat at 24 — so a
|
|
;;;; DWARF offset table that is right for debug.flan is wrong for all four
|
|
;;;; members here, which is what makes the pair a test rather than an
|
|
;;;; observation.
|
|
|
|
(defstruct Cell [name string id i32 alive bool heat f64])
|
|
|
|
(defn tick [c (Ptr Cell) n i32] i32
|
|
(let [bump (+ n 1)]
|
|
(set (.heat c) (+ (.heat c) 1.5))
|
|
(set (.id c) bump)
|
|
bump))
|
|
|
|
(defn main [] i32
|
|
(let [c (Cell {:alive true :heat 3.25 :id 7 :name "grain"})]
|
|
(let [r (tick (addr c) 41)]
|
|
(print-i64 (i64 r)) (newline)
|
|
(print-f64 (.heat c)) (newline)
|
|
(print-i64 (i64 (.id c))) (newline)
|
|
(print-str (.name c)) (newline)
|
|
0)))
|