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))
|
(Flan.Types.to_string f.ret) (Array.length f.slots))
|
||||||
p.fns))
|
p.fns))
|
||||||
files
|
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 ->
|
| _ :: "emit" :: args when List.exists (fun a -> not (is_flag a)) args ->
|
||||||
let checks = not (List.mem no_checks_flag args) in
|
let checks = not (List.mem no_checks_flag args) in
|
||||||
let dev = List.mem dev_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
|
links and runs, and the sand hash matches native byte for byte, but a
|
||||||
session reading this should know the joint is glued. *)
|
session reading this should know the joint is glued. *)
|
||||||
let wasm_builtins_candidates () =
|
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
|
@ (match on_path "emcc" with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some e ->
|
| Some e ->
|
||||||
|
|||||||
@ -15,10 +15,10 @@
|
|||||||
(glob_files programs/*.flan)
|
(glob_files programs/*.flan)
|
||||||
; The reload primitive's host: a C main that dlopens what Build.shared made.
|
; The reload primitive's host: a C main that dlopens what Build.shared made.
|
||||||
(file reload_host.c)
|
(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.
|
; test_dev runs the compiler itself: flan dev launches and owns a program.
|
||||||
(file %{workspace_root}/bin/main.exe)
|
(file %{workspace_root}/bin/main.exe)
|
||||||
; The Emacs client, which test_emacs drives against a real daemon.
|
; 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" }
|
~opts:{ Build.default with opt; target = Some "wasm32-wasi" }
|
||||||
~csrcs:l.Load.csrcs ~lflags:l.Load.lflags p ~out)
|
~csrcs:l.Load.csrcs ~lflags:l.Load.lflags p ~out)
|
||||||
in
|
in
|
||||||
let wasm_run runner wasm =
|
let wasm_run ?arg runner wasm =
|
||||||
let out = Filename.concat scratch "flan-acceptance-wasm.out" in
|
let out = Filename.concat scratch "flan-acceptance-wasm.out" in
|
||||||
let code =
|
let code =
|
||||||
Sys.command
|
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))
|
(Filename.quote out))
|
||||||
in
|
in
|
||||||
let text = In_channel.with_open_bin out In_channel.input_all in
|
let text = In_channel.with_open_bin out In_channel.input_all in
|
||||||
@ -389,14 +390,14 @@ let () =
|
|||||||
| Error why ->
|
| Error why ->
|
||||||
Printf.printf "acceptance: skipping the wasm32 case (%s)\n" why
|
Printf.printf "acceptance: skipping the wasm32 case (%s)\n" why
|
||||||
| Ok () ->
|
| Ok () ->
|
||||||
let wasm_case name ?opt path expected =
|
let wasm_case name ?opt ?arg path expected =
|
||||||
let wasm =
|
let wasm =
|
||||||
Filename.concat scratch
|
Filename.concat scratch
|
||||||
("flan-w-" ^ Filename.remove_extension (Filename.basename path)
|
("flan-w-" ^ Filename.remove_extension (Filename.basename path)
|
||||||
^ ".wasm")
|
^ ".wasm")
|
||||||
in
|
in
|
||||||
wasm_build ?opt path wasm;
|
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
|
if text <> expected || code <> 0 then begin
|
||||||
incr failures;
|
incr failures;
|
||||||
Printf.printf
|
Printf.printf
|
||||||
@ -418,7 +419,16 @@ let () =
|
|||||||
likely to go wrong and these are where it would show. *)
|
likely to go wrong and these are where it would show. *)
|
||||||
wasm_case "value semantics, wasm32" "programs/values.flan" values_out;
|
wasm_case "value semantics, wasm32" "programs/values.flan" values_out;
|
||||||
wasm_case "machine surface, wasm32" "programs/machine.flan"
|
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"
|
if !failures = 0 then print_endline "acceptance: all tests passed"
|
||||||
else begin
|
else begin
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user