compiler: a test program may hold a phase handler - the test runner called @rt_init whenever the program had systems, and a handler alone makes none (LLVM: use of undefined value '@rt_init'); it calls it only when it exists, as an entry program's main does; a ludic test case with a handler (added, not run); reseeded, bootstrap-cfree fixpoint holds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
eaeadc6a52
commit
9a0011c38f
5 changed files with 3187 additions and 3150 deletions
6
changes/test-handler-rt-init.md
Normal file
6
changes/test-handler-rt-init.md
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
bump: patch
|
||||||
|
type: fix
|
||||||
|
**A test program may hold a phase handler.** A program with `test` blocks and a `handler ... phase`
|
||||||
|
(its own, or one a module it imports declares) failed to compile with LLVM's "use of undefined value
|
||||||
|
'@rt_init'": the test runner called the runtime's `rt_init` whenever the program had systems, and a
|
||||||
|
handler alone makes none. It now calls it only when it exists, as an `entry` program's `main` does.
|
||||||
|
|
@ -161,7 +161,7 @@ function emit_test_runner() -> void {
|
||||||
emit(`{lrun0}:\n`)
|
emit(`{lrun0}:\n`)
|
||||||
emit(" call void @L_init_runtime()\n")
|
emit(" call void @L_init_runtime()\n")
|
||||||
if has_ecs() { emit(" call void @L_grow(i32 1)\n") }
|
if has_ecs() { emit(" call void @L_grow(i32 1)\n") }
|
||||||
if has_ecs() { emit(" call void @rt_init()\n") }
|
if (find_fn("rt_init") != null) { emit(" call void " + fn_sym("rt_init") + "()\n") } # as emit_main: a handler alone makes no rt_init
|
||||||
emit(" call void @L_init_globals()\n")
|
emit(" call void @L_init_globals()\n")
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(g_tests) {
|
while i < len(g_tests) {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -786,6 +786,11 @@ function test_dir_case() -> void {
|
||||||
if not shq(`cd {work} && {root}/bin/ludic test pk/tests -j 2 > out3.txt 2>&1`) { bad2(lbl2, capture(`cat {work}/out3.txt`)); return }
|
if not shq(`cd {work} && {root}/bin/ludic test pk/tests -j 2 > out3.txt 2>&1`) { bad2(lbl2, capture(`cat {work}/out3.txt`)); return }
|
||||||
if not shq(`grep -q 'pk/tests/scratch.ludic (2 tests)' {work}/out3.txt`) { bad2(lbl2, capture(`cat {work}/out3.txt`)); return }
|
if not shq(`grep -q 'pk/tests/scratch.ludic (2 tests)' {work}/out3.txt`) { bad2(lbl2, capture(`cat {work}/out3.txt`)); return }
|
||||||
ok(lbl2)
|
ok(lbl2)
|
||||||
|
# a test program holding a phase handler: the runner boots no frame loop and calls no rt_init it lacks
|
||||||
|
let lbl3 = "ludic test: a program with a phase handler compiles and runs its tests"
|
||||||
|
write_file(`{work}/pk/tests/handler.ludic`, "program D {\n handler K phase Input { }\n test \"d\" {\n expect_eq(1, 1)\n }\n}\n")
|
||||||
|
if not shq(`cd {work} && {root}/bin/ludic test pk/tests/handler.ludic > out4.txt 2>&1`) { bad2(lbl3, capture(`cat {work}/out4.txt`)); return }
|
||||||
|
ok(lbl3)
|
||||||
}
|
}
|
||||||
|
|
||||||
# package.ludic drives the CLI: `entry` (or the one program under src/) is what
|
# package.ludic drives the CLI: `entry` (or the one program under src/) is what
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue