ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.74k stars 2.48k forks source link

On wasm fmt print of u64 packed struct triggers WebAssembly translation error #20966

Open rootbeer opened 1 month ago

rootbeer commented 1 month ago

Zig Version

0.14.0-dev.878+c6995e6de

Steps to Reproduce and Observed Behavior

The following main.zig compiles and runs just fine on my default target (x86_64 linux):

const std = @import("std");

const T = packed struct(u64) {
    foo: bool = false,
    _: u63 = 0,
};

pub fn main() !void {
    const t: T = .{};
    std.debug.print("default {any}\n", .{ t });
}

working version:

$ zig run main.zig
default main.T{ .foo = false, ._ = 0 }

But if I compile and run this on wasm the compile succeeds, but wasmtime fails to run it:

$ zig build-exe main.zig -target wasm32-wasi && wasmtime ./main.wasm
Error: WebAssembly translation error

Caused by:
    Invalid input WebAssembly code at offset 8333: type mismatch: expected i64, found i32

It looks like fmt has caused a similar problem in the past (#15609) but I think the details are different in this time, so I filed a new bug.

Dropping the packed or reducing the u64 to u32 avoids the problem.

Some additional details:

$ wasmtime --version
wasmtime-cli 23.0.1

wasm-decompile doesn't like it either:

$  wasm-decompile ./main.wasm
./main.wasm:0002093: error: type mismatch in call, expected [i32, i64, i32, i32, i32] but got [i32, i32, i32, i32, i32]
./main.wasm:00066d9: error: type mismatch at end of function, expected [] but got [i32]

Expected Behavior

wasm target should work like the native target

rootbeer commented 1 month ago

Poking at this a bit more, it seems the problem is greater-than-32-bit fields of the packed struct. So replacing the T declaration with:

const T = packed struct(u64) {
    a: u32 = 0,
    b: u32 = 0,
};

works fine, but shifting to:

const T = packed struct(u64) {
    a: u31 = 0,
    b: u33 = 0,
};

Triggers the error.

The error is basically the same on wasm v10.0.2 as on v23.0.1, too.