Bubaya
Bubaya

Reputation: 823

Emscripten triggers spurious function calls

I'm trying to get myself used to emscripten, and I have to admit that my JS is quite rusty. Anyway, as a start, I tried to compile

#include <vector>
extern "C" {
    int add(int a, int b){
        return a+b;
    }
}

with emscripten: em++ test.cpp -sEXPORTED_FUNCTIONS=_add -sEXPORTED_RUNTIME_METHODS=ccall,cwrap. I wrote the following basic HTML page:

<!DOCTYPE html>
<html>
    <head>
        <script src="a.out.js"></script>
        <script>
            function run(){
                alert("Run!");
                var add = cwrap("add", "number", ["number"]);
                var result = add(12, 13);
                document.getElementById('output').value = result;
            }
        </script>
    </head>
    <body>
        <button onclick="run();">Run!</button>
        <input id="output">
    </body>
</html>

The strange thing is than run() is called immediately on loading the page, which firefox unsurprisingly does not like:

Uncaught (in promise) RuntimeError: Aborted(Assertion failed: native function `add` called before runtime initialization)

and is not intended anyway. If I remove the line <script src="a.out.js"></script>, then the spurious call to run() disappears. Of course, this renders the page dysfunctional.

How to do it properly?

I am using Firefox 107.0.1 (MacOS) and em++ 3.1.28-git from Homebrew.

Upvotes: 1

Views: 125

Answers (1)

zakki
zakki

Reputation: 2353

Emscripten creates hundreds of variable and function into the global namespace by default, and run is one of them. MODULARIZE prevents namespace polution.

em++ test.cpp -sEXPORTED_FUNCTIONS=_add -sEXPORTED_RUNTIME_METHODS=ccall,cwrap -sMODULARIZE -s 'EXPORT_NAME="createModule"'

And use that module.

<!DOCTYPE html>
<html>
  <head>
    <script src="a.out.js"></script>
    <script>
      var module = null;
      var add = null;
      createModule().then(m => {
        module = m;
        add = module.cwrap("add", "number", ["number"]);
      });
      function run(){
        alert("Run!");
        var result = add(12, 13);
        document.getElementById('output').value = result;
      }
    </script>
  </head>
  <body>
    <button onclick="run();">Run!</button>
    <input id="output">
  </body>
</html>

Upvotes: 3

Related Questions