Skip to content

Setting a global enum on WASM fails silently #21558

Closed
@knexator

Description

@knexator

Zig Version

0.14.0-dev.1694+3b465ebec

Steps to Reproduce and Observed Behavior

A global variable, of type an enum with 4 fields, sometimes updates incorrectly on WASM :

src/main.zig:

const std = @import("std");

pub fn main() !void {
    buggy_fn(2);
}

var my_global_value: Direction = undefined;

export fn buggy_fn(new_value: u32) void {
    std.debug.print("input to fn was: {d}\n", .{new_value});
    my_global_value = Direction.num2dir(new_value);
    std.debug.print("global is now: {d}\n", .{Direction.dir2num(my_global_value)});
}

const Direction = enum {
    Left,
    Right,
    Up,
    Down,

    fn dir2num(d: Direction) u32 {
        return switch (d) {
            .Up => 0,
            .Down => 1,
            .Left => 2,
            .Right => 3,
        };
    }

    fn num2dir(n: u32) Direction {
        return switch (n) {
            0 => .Up,
            1 => .Down,
            2 => .Left,
            3 => .Right,
            else => unreachable,
        };
    }
};

build.zig:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.resolveTargetQuery(.{
        .cpu_arch = .wasm32,
        .os_tag = .wasi,
    });

    const optimize: std.builtin.OptimizeMode = .ReleaseSmall;

    const exe = b.addExecutable(.{
        .name = "main",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    b.installArtifact(exe);

    const run_exe = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run");
    run_step.dependOn(&run_exe.step);
}

zig build run -fwasmtime outputs, on my machine:

input to fn was: 2
global is now: 0

Expected Behavior

The output should be:

input to fn was: 2
global is now: 2

The issue only happens in WASM, with optimize mode set to ReleaseSmall. It also works correctly if Direction is an enum(u3), but not if it's an enum(u2) (despite having 4 values).

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch-wasm32-bit and 64-bit WebAssemblybackend-llvmThe LLVM backend outputs an LLVM IR Module.bugObserved behavior contradicts documented or intended behaviorupstreamAn issue with a third party project that Zig uses.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions