emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.67k stars 3.29k forks source link

emscripten settings about MEMORY #22169

Open AAT290 opened 3 months ago

AAT290 commented 3 months ago

Browsers are usually divided into 32-bit and 64-bit,When I use Emscripten Camppiller to compile a webassembly file,I can set the initial memory and maximum memory with INITIAL_MEMORY and MAXIMUM_MEMORY settings, In fact, with a webassembly file in a 32-bit browser, the maximum memory is usually not allowed to exceed 1G, otherwise it may not work, while with a webassembly file in a 64-bit browser, it can be set to 2G or more,My problem is how to use some settings to adaptively set the memory according to the number of bits in the browser when compiling the webassembly file, so that the final result is that the maximum memory of the compiled webassembly file is 1G in a 32-bit browser and 2G in a 64-bit browser。I would like to inquire if there is a solution to this problem?Thank you。

sbc100 commented 3 months ago

A 32-bit browser should be able to load a wasm file if it has enough memory to allocated the INITIAL_MEMORY, regardless of what that MAXIMUM_MEMORY is set to. If the browser is refusing the load a file purely based on the MAXIMUM_MEMORY that sounds like a browser bug. Are you seeing this in practice? On which browser?

To work around this issue you could use -sIMPORTED_MEMORY and then create the memory dynamically in JavaScript. (You would do something like Module["wasmMemory"] = createMyMemory().

AAT290 commented 1 month ago

Here are the compilation instructions I'm using now,I use these directives to compile a C++ file into a wasm file and a js(JavaScript plumbing)file: -s INITIAL_MEMORY=500MB -s MAXIMUM_MEMORY=1023MB -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_NAME='JSPlayerModule' Then I create a new JavaScript file referencing the compiled js file,The specific code is as follows: window.JSPlayerModule().then(instance => { oJSPlayerWasm = instance; //do something } If I use this command -s IMPORTED_MEMORY,Where should I add Module["wasmMemory"] = createMyMemory() in this case?

sbc100 commented 1 month ago

In the MODULARIZE case you supply your module argument to the constructor function.

So you would so something like this:

window.JSPlayerModule({"wasmMemory":createMyMemory()}).then(...
AAT290 commented 1 month ago

I'm a newbie in this field,So I'd like to ask you to give me some more guidance,Thank you so much;Under your guidance, I have made the following modifications:

Here are the compilation instructions I'm using now,I've added this compilation directive -s IMPORTED_MEMORY=1; -s INITIAL_MEMORY=500MB -s MAXIMUM_MEMORY=1023MB -s ALLOW_MEMORY_GROWTH=1 -s IMPORTED_MEMORY=1 -s EXPORT_NAME='JSPlayerModule' -s MODULARIZE=1

The JavaScript code is modified to look like this: wasmMemory = new WebAssembly.Memory({initial: 8192, maximum: 16368}); window.JSPlayerModule({"wasmMemory":wasmMemory}).then(instance => { oJSPlayerWasm = instance; //do something }

However, an error will be reported when it is modified,The following error message is displayed: wasm streaming compile failed: LinkError: WebAssembly.instantiate(): mismatch in shared state of memory, declared = 1, imported = 0

Do you know what the reason is,How can I fix this?

sbc100 commented 1 month ago

It looks like your program expects a shared memory? Are you building with -pthread perhaps? In that case you can just add shared: true to your memory constructor params.