Odin icon indicating copy to clipboard operation
Odin copied to clipboard

js_wasm32 target's $startup_runtime is not a function.

Open JesseRMeyer opened this issue 3 years ago • 1 comments

Context

js_wasm32 binaries produced by the compiler do not appear to be correctly generated. Attempting to instantiate them on Firefox results in the error message:

LinkError: import object field 'env..__$startup_runtime' is not a Function

whereas on Chromium based browsers:

Uncaught (in promise) LinkError: WebAssembly.instantiate(): Import #1 module="env" function="env..__$startup_runtime" error: function import requires a callable

Apparently similar behavior is observed with other wasm runtimes like wasmtime.

The behavior observed with and without -debug odin build . -debug -target=js_wasm32

package main

import "core:fmt"

main :: proc() {
	fmt.println("Hellope!")
}
const runWasm = async (wasm_path) => {
	let wasmMemoryInterface = new WasmMemoryInterface();

	let consoleElement = null;
	let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement);
		
	const response = await fetch(wasm_path);
	const file = await response.arrayBuffer();
	const wasm = await WebAssembly.instantiate(file, imports); // !! This call fails !!
	const exports = wasm.instance.exports;
	wasmMemoryInterface.setMemory(exports.memory);
	
	exports._start();
	
	return;
};

runWasm("./src.wasm");
  • Operating System & Odin Version:
        Odin: dev-2022-03
        OS:   Windows 10 Home Basic (version: 21H2), build 19044.1586
        CPU:  Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz
        RAM:  32717 MiB

JesseRMeyer avatar Mar 22 '22 13:03 JesseRMeyer

Looking a bit at the compiler's source, I found the wasm-only renaming in check_decl.cpp check_proc_decl(). This will rename all foreign functions, so they begin with their special module name, even the special function startup_runtime (__$startup_runtime) which gets created by the compiler. For this, I believe that the startup_runtime function should instead of foreign be marked as builtin like the other compiler provided functions.

I did a quick workaround by adding if (foreign_library != nullptr || name != "__$startup_runtime") before the actual rename (name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name);, was line 1034) but this is not an adequate solution. Though with this problem worked around, compiling wasm normally by just giving the -target=js_wasm32 cmdline option did work.

fabiansperber avatar Apr 05 '22 18:04 fabiansperber

Fixed in https://github.com/odin-lang/Odin/commit/53c70da0b83f573d8c1d0572d7a57fd0bac759fc.

JesseRMeyer avatar Sep 05 '22 14:09 JesseRMeyer