Stream: general

Topic: pulley on wasm32-unk-unk via deserialized module crashes


view this post on Zulip zndvk (Aug 14 2025 at 20:20):

Hi,

First, I serialize a Module on a MacOS 64-bit PC for a pulley32 target.

Then, in the browser, my Rust program built for wasm32-unknown-unknown starts and loads up the wasmtime Module from the serialized bytes, and invokes a function in it.

When running the fn, the VM instantly fails with this error:

wasmtime/crates/wasmtime/src/runtime/vm/traphandlers.rs:569:13
assertion failed: core::ptr::eq(head, self)

Here's the setup:

Host machine (64bit MacOS) (serializes wasmtime pulley module)

        use wasmtime::*;

        let mut config = Config::default();
        config.memory_reservation(0);
        config.memory_reservation_for_growth(2 << 19);
        config.memory_init_cow(false);
        config.target("pulley32").unwrap();

        println!("building module with config: {config:#?}");

        let engine = Engine::new(&config).unwrap();
        let serialized_module = engine
            .precompile_module(&wasm_bytes)
            .expect("Failed to create module for web build from wasm bytes");

works successfully, with output:

building module with config: Config {
    wasm_mutable_global: true,
    wasm_saturating_float_to_int: true,
    wasm_sign_extension: true,
    wasm_reference_types: true,
    wasm_multi_value: true,
    wasm_bulk_memory: true,
    wasm_simd: true,
    wasm_relaxed_simd: true,
    wasm_threads: false,
    wasm_shared_everything_threads: false,
    wasm_tail_call: true,
    wasm_floats: true,
    wasm_multi_memory: true,
    wasm_exceptions: false,
    wasm_memory64: true,
    wasm_extended_const: true,
    wasm_component_model: false,
    wasm_function_references: false,
    wasm_memory_control: false,
    wasm_gc: false,
    wasm_custom_page_sizes: false,
    wasm_legacy_exceptions: false,
    wasm_gc_types: false,
    wasm_stack_switching: false,
    wasm_wide_arithmetic: false,
    wasm_cm_values: false,
    wasm_cm_nested_names: false,
    wasm_cm_async: false,
    wasm_cm_async_stackful: false,
    wasm_cm_async_builtins: false,
    wasm_cm_error_context: false,
    wasm_cm_fixed_size_list: false,
    wasm_cm_gc: false,
    wasm_call_indirect_overlong: true,
    wasm_bulk_memory_opt: true,
    parallel_compilation: true,
    compiler_config: CompilerConfig {
        strategy: Some(
            Cranelift,
        ),
        settings: {
            "enable_verifier": "false",
            "opt_level": "speed",
        },
        flags: {},
        clif_dir: None,
        wmemcheck: false,
    },
    memory_reservation: 0,
    memory_reservation_for_growth: 1048576,
    parse_wasm_debuginfo: false,
    memory_init_cow: false,
}

Then, when I load it up, the config matches completely except the

            let mut config = Config::default();

            config.memory_reservation(0);
            config.memory_reservation_for_growth(2 << 19);
            config.memory_init_cow(false);
            config.target("pulley32").unwrap();

            log::info!("loading engine with config: {config:#?}");

            let engine = Engine::new(&config).expect("Failed to initialize wasmtime engine");
            let module = unsafe {
                Module::deserialize(&engine, &wasm_buf).expect("Failed to create wasmtime module")
            };

this also works fine with output

Config {
    wasm_mutable_global: true,
    wasm_saturating_float_to_int: true,
    wasm_sign_extension: true,
    wasm_reference_types: true,
    wasm_multi_value: true,
    wasm_bulk_memory: true,
    wasm_simd: true,
    wasm_relaxed_simd: true,
    wasm_threads: false,
    wasm_shared_everything_threads: false,
    wasm_tail_call: true,
    wasm_floats: true,
    wasm_multi_memory: true,
    wasm_exceptions: false,
    wasm_memory64: true,
    wasm_extended_const: true,
    wasm_component_model: false,
    wasm_function_references: false,
    wasm_memory_control: false,
    wasm_gc: false,
    wasm_custom_page_sizes: false,
    wasm_legacy_exceptions: false,
    wasm_gc_types: false,
    wasm_stack_switching: false,
    wasm_wide_arithmetic: false,
    wasm_cm_values: false,
    wasm_cm_nested_names: false,
    wasm_cm_async: false,
    wasm_cm_async_stackful: false,
    wasm_cm_async_builtins: false,
    wasm_cm_error_context: false,
    wasm_cm_fixed_size_list: false,
    wasm_cm_gc: false,
    wasm_call_indirect_overlong: true,
    wasm_bulk_memory_opt: true,
    parallel_compilation: true,
    memory_reservation: 0,
    memory_reservation_for_growth: 1048576,
    parse_wasm_debuginfo: false,
    memory_init_cow: false,
}

the only diff of the configs is this:

38,49d37
<     compiler_config: CompilerConfig {
<         strategy: Some(
<             Cranelift,
<         ),
<         settings: {
<             "opt_level": "speed",
<             "enable_verifier": "false",
<         },
<         flags: {},
<         clif_dir: None,
<         wmemcheck: false,
<     },

any ideas?

view this post on Zulip Alex Crichton (Aug 14 2025 at 20:43):

This looks more like a runtime bug rather than a configuration issue. Can you detail more what you're doing in a browser? (or better yet, do you have a reproduction for this?)


Last updated: Dec 06 2025 at 05:03 UTC