0

I have compiled a niche interpretter with WASM and the below works fine on the first function call. However any successive calls do absolutely nothing.

My understanding is WASM js made with Emscripten effectively "runs once" and is even kept alive on exit, so to invoke my wasm-js many times you'd need to remove it from the DOM each team and re-add it. I assume this understanding must be incorrect or I have some weird cache issue going on where things are being ignored...

Any help is appreciated!

export function runWASM(newCodeString) {
    return new Promise((resolve) => {
        const oldScript = document.getElementById('code-script');
        if (oldScript) {
            console.log('Removing old script');
            oldScript.remove();
        }
       
        window.Module = {
            arguments: ['code.sno'],
            print: (text) => console.log(text),
            // printErr: (text) => console.error(text),
            preRun: [
                function () {
                    window.FS.createDataFile('/', 'code.sno', newCodeString, true, false, false);
                }
            ],
            postRun: [
                function () {
                    const doneRun = true;
                    resolve(doneRun);
                }
            ],
            noInitialRun: false,
            noExitRuntime: false
        };

        console.log('Module:', window.Module);

        // Add new script
        const script = document.createElement('script');
        script.src = '/interpretter.js';
        script.id = 'code-script';
        document.body.appendChild(script);
    });
}
2
  • Why would you need to invoke emscripten multiple times--is there an issue with loading/defining it once, and calling your emscripten functions as necessary? Commented Jul 6 at 5:34
  • Thanks I got around the issue by compiling as ES6 module Commented Jul 6 at 16:58

1 Answer 1

0

The solution I found here is to compile as ES6 module instead, by linking the object files with the below.

emcc *.o -o main.mjs -s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORTED_RUNTIME_METHODS=FS -s EXIT_RUNTIME=1

Then as a generic example in your JS:

import createModule from './main.mjs';

// Create the virtual file 'foo.txt' with some content
const fooContent = 'Hello from foo.txt!\nSecond line.\n';
const fooFileName = 'foo.txt';

const moduleArgs = ['main', fooFileName];

const moduleOptions = {
  arguments: moduleArgs,
  preRun: [function(Module) {
    // Write foo.txt into the virtual file system
    Module.FS.writeFile(fooFileName, fooContent);
  }],
  print: (text) => { console.log(text); },
  printErr: (text) => { console.error(text); }
};

// Instantiate and run the module
createModule(moduleOptions).then(Module => {
  // main() is called automatically if you compiled with a main function
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.