craigmc08
craigmc08

Reputation: 195

WebAssembly LinkError: function import requires a callable

I've recently started working with WebAssembly. I hit a problem trying to use log in my C code. I recreated the error in the simplest way I could. The error I get is

Uncaught (in promise) LinkError: WebAssembly.Instance(): Import #1 module="env" function="_log" error: function import requires a callable

The error points to this function, specifically WebAsembly.Instance(module, imports)

function loadWebAssembly(filename, imports = {}) {
  return fetch(filename)
    .then((response) => response.arrayBuffer())
    .then((buffer) => WebAssembly.compile(buffer))
    .then((module) => {
      imports.env = imports.env || {}
      Object.assign(imports.env, {
        memoryBase: 0,
        tableBase: 0,
        memory: new WebAssembly.Memory({
          initial: 256,
          maximum: 512,
        }),
        table: new WebAssembly.Table({
          initial: 0,
          maximum: 0,
          element: 'anyfunc',
        }),
      })
      return new WebAssembly.Instance(module, imports)
    })
}

(I call this function with loadWebAssembly('/test.wasm'))

My C code is

#include <math.h>

double test(v) {
  return log(v)
}

and gets no errors when compiled with

emcc test.c -Os -s WASM=1 -s SIDE_MODULE=1 -o test.wasm

I haven't been able to fix this error, I hope someone can help me out.

Upvotes: 18

Views: 20014

Answers (2)

Nobir
Nobir

Reputation: 11

I might be wrong but I think your C code is wrong

By default emscripten exports only main function others are as dead code

you need to tell the emscripten to keep alive the test function by using macro EMSCRIPTEN_KEEPALIVE

and don't forget to include header file emscripten/emscripten.h

For more info go to this link

test.c

#include <stdio.h>
#include <emscripten/emscripten.h>
#include <math.h>

EMSCRIPTEN_KEEPALIVE
double test(double x)
{
    return log(x);
}

and you can access your function in js

JavaScript

loadWebAssembly('test.wasm')
    .then((data) => {
        console.log(data.exports) // {__wasm_call_ctors: ƒ, log10: ƒ}
    }).
    catch((err) => {
        console.log(err);
    });

Upvotes: 1

Ghillie
Ghillie

Reputation: 909

You aren't providing an implementation of log() in imports.env

Object.assign(imports.env, {
    memoryBase: 0,
    tableBase: 0,
    memory: new WebAssembly.Memory({
        initial: 256,
        maximum: 512,
    }),
    table: new WebAssembly.Table({
        initial: 0,
        maximum: 0,
        element: 'anyfunc',
    }),
    _log: Math.log,
})

Upvotes: 7

Related Questions