Search code examples
javascriptcwebassembly

Calling a C style function pointer in a WebAssembly from JavaScript


Is there any way to get access to function pointers living inside a WebAssembly module?

For example, given the following "module" compiled to WebAssembly:

extern void set_callback(void (*callback)(void *arg), void *arg);

static void callback(void *arg)
{
  /* ... */
}

int main() {
  set_callback(&callback, 0);
  return 0;
}

Can an implementation of do_callback in JavaScript invoke the callback without having to rely on an intermediary C function export to do the actual function call?

var instance = new WebAssembly.Instance(module, {
  memory: /* ... */
  env: {
    set_callback: function set_callback(callbackptr, argptr) {
      // We only got the pointer, is there any  
    },
  },
}); 

By intermediary function export, I mean that I could add an internal function with public visibility.

do_callback(void (*callback)(void *arg), void *arg)
{
  callback();
} 

Then the JavaScript set_callback function can call the function pointer via the delegate do_callback function.

function set_callback(callbackptr, argptr) {
  instance.exports.do_callback(callbackptr, argptr);
}

But, it's preferable to do this without having to go through that explicit indirection, is it possible, with function tables maybe?


Solution

  • The issue back then was that Clang basically did not implement call_indirect and did not actually populate the function table with anything during code generation.

    Has been resolved in the current version of LLVM.