Trying to use --closure 1 and addFunction

96 views
Skip to first unread message

Sampo Syrjänen

unread,
Nov 12, 2019, 9:11:45 AM11/12/19
to emscripten-discuss
Hello! I have trouble getting addFunction to work with closure compiler enabled. There's a minimal project here to reproduce the issue:

// lib.c
typedef int (*callback_t)(int a);

int func(callback_t callback, int a)
{
    return callback(a);
}

// test.js
const lib = require("./lib.js");
setTimeout(() => {
    const callback = (a) => {
        return 40 + a;
    };
    const callbackPtr = lib.addFunction(callback, "ii");
    console.log(lib._func(callbackPtr, 2));
}, 100);

# Makefile
lib.js: lib.c
emcc -s EXPORTED_FUNCTIONS="['_func']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['addFunction']" -s RESERVED_FUNCTION_POINTERS=1 --closure 1 -o $@ $^

.PHONY: clean
clean:
$(RM) lib.js lib.wasm

test: lib.js
node test.js


With make test I get this:

node test.js
C:\work\closure\lib.js:28
    throw b;
    ^

LinkError: WebAssembly.Instance(): Import #0 module="e" function="f" error: function import requires a callable
    at Object.a.addFunction (C:\work\closure\lib.js:629:10)
    at Timeout._onTimeout (C:\work\closure\test.js:6:29)
[90m    at listOnTimeout (internal/timers.js:531:17) [39m
[90m    at processTimers (internal/timers.js:475:7) [39m
gmake: *** [Makefile:9: test] Error 7

What am I missing? How should I compile to make addFunction work?

Sampo Syrjänen

unread,
Nov 12, 2019, 9:16:45 AM11/12/19
to emscripten-discuss
emsdk version is 1.39.2

Floh

unread,
Nov 12, 2019, 6:11:43 PM11/12/19
to emscripten-discuss
I'm not sure if your's is the same problem, but I seem to remember that I had very weird errors with closure in the past where I was using one- or two-character-variables and function names in my JS code which then collided with names minified by closure. Error messages for this were all over the place, but IFIR some of them looked quite similar to yours. Since then I'm only using long and descriptive variable and function names in my JS code :)

Alon Zakai

unread,
Nov 13, 2019, 5:22:30 PM11/13/19
to emscripte...@googlegroups.com
The testcase works for me on 1.39.2, strange. But perhaps there is something nondeterministic in how closure works that ends up with different variable names, hitting or not hitting the bug.

Perhaps build it with -g1 (to not minify whitespace) and see what the bad value is there? Please attach a build with that if you can.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/7f93bf40-3bfe-42da-a01c-439f03c0a1b3%40googlegroups.com.
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

Sampo Syrjänen

unread,
Nov 14, 2019, 3:50:54 AM11/14/19
to emscripten-discuss
I built with -g1. lib.js is attached as .txt file. The output from the test is

node test.js
C:\work\closure\lib.js:28
    throw b;
    ^

LinkError: WebAssembly.Instance(): Import #0 module="e" function="f" error: function import requires a callable
    at Object.a.addFunction (C:\work\closure\lib.js:629:10)
    at Timeout._onTimeout (C:\work\closure\test.js:6:29)
[90m    at listOnTimeout (internal/timers.js:531:17) [39m
[90m    at processTimers (internal/timers.js:475:7) [39m
gmake: *** [Makefile:9: test] Error 7

On Thursday, November 14, 2019 at 12:22:30 AM UTC+2, Alon Zakai wrote:
The testcase works for me on 1.39.2, strange. But perhaps there is something nondeterministic in how closure works that ends up with different variable names, hitting or not hitting the bug.

Perhaps build it with -g1 (to not minify whitespace) and see what the bad value is there? Please attach a build with that if you can.

To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.
lib.js.txt

Alon Zakai

unread,
Nov 15, 2019, 5:15:28 PM11/15/19
to emscripte...@googlegroups.com
Please also attach the wasm file, as otherwise when I try to run it it errors on not finding that.

To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/88702128-1e83-4223-9fbd-a56324fd30af%40googlegroups.com.

Sampo Syrjänen

unread,
Nov 18, 2019, 3:28:17 AM11/18/19
to emscripten-discuss
Ok, the wasm file is attached here.


On Tuesday, November 12, 2019 at 4:11:45 PM UTC+2, Sampo Syrjänen wrote:
lib.wasm

Alon Zakai

unread,
Nov 19, 2019, 1:57:55 PM11/19/19
to emscripte...@googlegroups.com
Thanks Sampo! I think I figured out what's wrong. Fix should be in


Please test if you can.

- Alon


--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

Sampo Syrjänen

unread,
Nov 20, 2019, 4:22:35 AM11/20/19
to emscripten-discuss
Hi Alon, thanks for help! I tested the patch and got this from the test

node test.js
C:\work\closure\lib.js:28
    throw b;
    ^

TypeError: WebAssembly.Table.set(): Argument 1 must be null or a WebAssembly function
    at Object.a.addFunction (C:\work\closure\lib.js:630:7)
    at Timeout._onTimeout (C:\work\closure\test.js:6:29)
    at listOnTimeout (internal/timers.js:531:17)
    at processTimers (internal/timers.js:475:7)
gmake: *** [Makefile:9: test] Error 7

I added one more change to the patch and then the test worked:

  var module = new WebAssembly.Module(bytes);
  var instance = new WebAssembly.Instance(module, {
    'e': {
      'f': func
    }
  });
  var wrappedFunc = instance.exports['f'];
  return wrappedFunc;

So I changed instance.exports.f -> instance.exports['f'] and now it seems to work. In my tests, I applied the patch directly to 1.39.2, if that matters.

On Tuesday, November 12, 2019 at 4:11:45 PM UTC+2, Sampo Syrjänen wrote:

Alon Zakai

unread,
Nov 20, 2019, 9:28:19 AM11/20/19
to emscripte...@googlegroups.com
Thanks! Yes, that is necessary too, adding.

(Sadly it's very hard to test closure issues like this, so I couldn't verify myself...)

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages