Add missing Wasm intrinsics for i64, f32, f64 - #558
Conversation
When a variable is assigned twice using different-typed values.
`Lowering` and `Elaborator` each named every `wasm.<mod>.<op>` intrinsic one by one, so adding one meant editing three lists that had to agree: the prelude declaration, the builtin symbol, and the `specialBuiltinSymbols` entry. Enumerate the nested modules of `wasm` and their members instead. Every function such a module declares *is* an instruction intrinsic, and which instruction each one emits is decided by the backend's own table, so the prelude is the only place the set needs to be written down. The path carried by `SpecialBuiltin.WasmIntrinsic` goes with them: it was never read, since the use site rebuilds the path from the symbol's owner chain. A name the prelude declares and the backend does not implement is now reported at its use site rather than crashing the compiler, which is what the hand-maintained lists used to rule out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All four Wasm numeric types share one instruction shape: the mnemonic is the type's own prefix followed by the operation name, the operands are the stack arguments, and the result is a value of either the type itself (arithmetic) or `i32` (comparisons and tests). `i32` spelled each of its fifteen instructions out in full, which would have meant three more copies of the same block for `i64`, `f32` and `f64`. Derive the four from a common base instead, leaving only the genuinely per-family parts written down: the `const` immediate, and the operations one of the integer and floating-point types has and the other does not. `i32.eq` already reported an unreachable result when either operand had one; this now holds of every numeric instruction, which is the accurate answer for all of them and not just that one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closes hkust-taco#548. The erased type hierarchy has carried all four unboxed primitives for a while, but only `Int32` had a Wasm counterpart: the other three fell through `wasmType` to `anyref`, and the two sites that zero a slot with no explicit initializer - a struct field under `struct.new_default` and a REPL session global - refused anything but `i32`. Map each primitive to its own Wasm type, and derive both zero values from that one mapping. Declare and implement the `wasm.i64`, `wasm.f32` and `wasm.f64` intrinsics alongside the existing `wasm.i32` ones, so the three types can actually be exercised. `i64` mirrors `i32`; the float families trade `rem_s`/`eqz` and the signed comparisons for `div`, `min`/`max` and the unary `abs`/`neg`/`sqrt`. As on `i32`, a comparison yields an `Int32`, which `wasm.ref.i31` boxes. Their immediates need more than the 32-bit integer literal `i32.const` takes: `i64.const` spans the full signed 64-bit range, and the float ones accept a decimal literal (or an integer one - `1` and `1.0` denote the same float), narrowed to the immediate's own type so that a literal only an `f64` can hold is reported as out of an `f32`'s range rather than emitted as an infinity. An intrinsic's argument is now compiled as an operand only if the intrinsic actually reads it as one. A decimal literal has no representation of its own in this backend, so compiling one eagerly reported *that* rather than the `f64.const` using it perfectly well. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…issing-intrinsics
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Are all these new verbose diff outputs really warranted?
|
Codex found and fixed an issue with mutliple return paths merging into different types. But I'm not sure its solution (in |
I think an IR-level solution is indeed the better way, and I think it's achievable by adding |
|
Yes, it sounds reasonable, if all the information is indeed already there in each node. But it should be calles |
No description provided.