Read wasi-sdk's version instead of guessing it, and pin the one ABI path left
The wasi-sdk candidate had an LLVM version in it, which moves release to release — so the path advertised as the proper article would have matched only by coincidence, while the emscripten one beside it was derived. Both are derived now. calc-me on wasm32 covers what the other three cases cannot: flan_argv hands Flan an array of flan_slice built in C, so what it pins is the element stride of a ptr+len pair — 16 bytes native, 12 on wasm32 — rather than a field offset. It is also the claim in this file's own header, that the table runs on the second target, honoured for the first time. flan emit refuses --target rather than stripping it. The IR really is target-free, so ignoring it is correct and silence about it is not.
This commit is contained in:
parent
046593acf1
commit
8a175ebec5
@ -100,6 +100,15 @@ let () =
|
||||
(Flan.Types.to_string f.ret) (Array.length f.slots))
|
||||
p.fns))
|
||||
files
|
||||
(* The IR is target-independent — [Emit] writes no triple and no datalayout,
|
||||
which is what lets one .ll serve both targets — so there is nothing for a
|
||||
target to change here. Refused rather than accepted and ignored: silently
|
||||
swallowing a flag is the shape the house rule exists to prevent. *)
|
||||
| _ :: "emit" :: args when target_of args <> None ->
|
||||
prerr_endline
|
||||
"flan emit: --target is refused — the emitted IR carries no triple and \
|
||||
no datalayout, and the target is chosen at build.";
|
||||
exit 2
|
||||
| _ :: "emit" :: args when List.exists (fun a -> not (is_flag a)) args ->
|
||||
let checks = not (List.mem no_checks_flag args) in
|
||||
let dev = List.mem dev_flag args in
|
||||
|
||||
13
lib/build.ml
13
lib/build.ml
@ -107,7 +107,18 @@ let wasm_sysroot () =
|
||||
links and runs, and the sand hash matches native byte for byte, but a
|
||||
session reading this should know the joint is glued. *)
|
||||
let wasm_builtins_candidates () =
|
||||
[ "/opt/wasi-sdk/lib/clang/20/lib/wasm32-unknown-wasi/libclang_rt.builtins.a" ]
|
||||
(* wasi-sdk's own resource directory, whichever LLVM that release bundled —
|
||||
the version is in the path and moves release to release, so it is read
|
||||
rather than guessed. Same rule as [clang_resource_dir]. *)
|
||||
(let root = "/opt/wasi-sdk/lib/clang" in
|
||||
match Sys.readdir root with
|
||||
| vs ->
|
||||
Array.sort compare vs;
|
||||
Array.to_list vs
|
||||
|> List.map (fun v ->
|
||||
Filename.concat root
|
||||
(Filename.concat v "lib/wasm32-unknown-wasi/libclang_rt.builtins.a"))
|
||||
| exception Sys_error _ -> [])
|
||||
@ (match on_path "emcc" with
|
||||
| None -> []
|
||||
| Some e ->
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
(glob_files programs/*.flan)
|
||||
; The reload primitive's host: a C main that dlopens what Build.shared made.
|
||||
(file reload_host.c)
|
||||
; The WASI host the wasm32 case runs its module under, when no wasmtime or
|
||||
; wasmer is installed.
|
||||
(file wasm-run.mjs)
|
||||
; test_dev runs the compiler itself: flan dev launches and owns a program.
|
||||
(file %{workspace_root}/bin/main.exe)
|
||||
; The Emacs client, which test_emacs drives against a real daemon.
|
||||
(glob_files %{workspace_root}/emacs/*.el)))
|
||||
(glob_files %{workspace_root}/emacs/*.el)
|
||||
; The WASI host the wasm32 case runs its module under, when no wasmtime or
|
||||
; wasmer is installed.
|
||||
(file wasm-run.mjs)))
|
||||
|
||||
@ -356,11 +356,12 @@ let () =
|
||||
~opts:{ Build.default with opt; target = Some "wasm32-wasi" }
|
||||
~csrcs:l.Load.csrcs ~lflags:l.Load.lflags p ~out)
|
||||
in
|
||||
let wasm_run runner wasm =
|
||||
let wasm_run ?arg runner wasm =
|
||||
let out = Filename.concat scratch "flan-acceptance-wasm.out" in
|
||||
let code =
|
||||
Sys.command
|
||||
(Printf.sprintf "%s %s > %s 2>&1" runner (Filename.quote wasm)
|
||||
(Printf.sprintf "%s %s %s > %s 2>&1" runner (Filename.quote wasm)
|
||||
(match arg with None -> "" | Some a -> Filename.quote a)
|
||||
(Filename.quote out))
|
||||
in
|
||||
let text = In_channel.with_open_bin out In_channel.input_all in
|
||||
@ -389,14 +390,14 @@ let () =
|
||||
| Error why ->
|
||||
Printf.printf "acceptance: skipping the wasm32 case (%s)\n" why
|
||||
| Ok () ->
|
||||
let wasm_case name ?opt path expected =
|
||||
let wasm_case name ?opt ?arg path expected =
|
||||
let wasm =
|
||||
Filename.concat scratch
|
||||
("flan-w-" ^ Filename.remove_extension (Filename.basename path)
|
||||
^ ".wasm")
|
||||
in
|
||||
wasm_build ?opt path wasm;
|
||||
let code, text = wasm_run runner wasm in
|
||||
let code, text = wasm_run ?arg runner wasm in
|
||||
if text <> expected || code <> 0 then begin
|
||||
incr failures;
|
||||
Printf.printf
|
||||
@ -418,7 +419,16 @@ let () =
|
||||
likely to go wrong and these are where it would show. *)
|
||||
wasm_case "value semantics, wasm32" "programs/values.flan" values_out;
|
||||
wasm_case "machine surface, wasm32" "programs/machine.flan"
|
||||
machine_out));
|
||||
machine_out;
|
||||
(* calc-me, for the one host-ABI path the three above do not touch:
|
||||
[flan_argv] builds an array of flan_slice in C and Flan indexes it
|
||||
as [string], so what is pinned here is the element *stride* of a
|
||||
ptr+len pair, which is 16 bytes native and 12 on wasm32 — not a
|
||||
field offset, and nothing else in the table reaches it. This is
|
||||
also the file header's own claim, that the table runs on wasm32
|
||||
too, honoured for the first time. *)
|
||||
wasm_case "calc-me, wasm32" "../calc-me.flan"
|
||||
~arg:"1 + 2 * (3 - 0.5) / 2" "3.5\n"));
|
||||
|
||||
if !failures = 0 then print_endline "acceptance: all tests passed"
|
||||
else begin
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user