Skip to content

Webassembly linker does not export symbols #1570

@josephg

Description

@josephg

Given this zig program:

export fn add(a: i32, b: i32) i32 {
    return a + b;
}

Compiled with zig build-exe --release-small --target-arch wasm32 wasm.zig, the output doesn't export the function.

Run through wasm2wat, the exported output is:

(module
  (type (;0;) (func (param i32 i32) (result i32)))
  (func $add (type 0) (param i32 i32) (result i32)
    get_local 1
    get_local 0
    i32.add)
  (table (;0;) 1 1 anyfunc)
  (memory (;0;) 0))

... Which doesn't export the add function like it should:

$ node
> m = new WebAssembly.Module(fs.readFileSync('wasm'))
Module [WebAssembly.Module] {}
> i = new WebAssembly.Instance(m, {})
Instance [WebAssembly.Instance] {}
> i.exports.add(1,2)
TypeError: i.exports.add is not a function

Linking with wasm-ld from llvm 7 works fine, and produces this:

sephsmac:zig josephg$ zig build-obj --release-small --target-arch wasm32 wasm.zig 
sephsmac:zig josephg$ wasm-ld wasm.o -o xyz -O2 --no-entry
sephsmac:zig josephg$ wasm2wat xyz
(module
  (type (;0;) (func))
  (type (;1;) (func (param i32 i32) (result i32)))
  (func $__wasm_call_ctors (type 0))
  (func $add (type 1) (param i32 i32) (result i32)
    get_local 1
    get_local 0
    i32.add)
  (table (;0;) 1 1 anyfunc)
  (memory (;0;) 2)
  (global (;0;) (mut i32) (i32.const 66560))
  (global (;1;) i32 (i32.const 66560))
  (global (;2;) i32 (i32.const 1024))
  (export "memory" (memory 0))
  (export "__heap_base" (global 1))
  (export "__data_end" (global 2))
  (export "add" (func $add)))

... Which works just fine. (Notice the export "add" at the end)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions