Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasmer-js import issue in nodejs v16.15.1 #298

Closed
mhykes opened this issue Aug 3, 2022 · 3 comments
Closed

wasmer-js import issue in nodejs v16.15.1 #298

mhykes opened this issue Aug 3, 2022 · 3 comments

Comments

@mhykes
Copy link

mhykes commented Aug 3, 2022

Issue:
When I pass imports to wasi.instantiate() and have a module that tries to import those imports, I get an error and my module won't load. This isn't related to the chrome browser issue since this is 100% server side. I've only tested this in nodejs v16.15.1 so far, but I'd be very surprised of this was related to the version of nodejs.

Example:
Create a nodejs project with npm init.
Run npm i @wasmer/wasi wabt
Save the code below as index.js

Expected: I can run node index.js and get back

==RESULTS==
{ nopResult: { resultCode: 0 }, minResult: { resultCode: 0 } }
==DONE==

Actual: I run node index.js and get back

ERROR: minimal import test
 Error: Failed to instantiate WASI: RuntimeError: `
    at B.wbg.__wbg_new_342a24ca698edd87 (/home/***/webassembly/wasmer/wasmInJs/minimal/node_modules/@wasmer/wasi/dist/Library.cjs.min.js:26:11276)
    at wasm://wasm/0024ee5a:wasm-function[823]:0x7c9d3
    at wasm://wasm/0024ee5a:wasm-function[79]:0x19d5a
    at s.instantiate (/home/***/webassembly/wasmer/wasmInJs/minimal/node_modules/@wasmer/wasi/dist/Library.cjs.min.js:26:6805)
    at startWasiTask (/home/***/webassembly/wasmer/wasmInJs/minimal/index.js:64:35)
    at async run (/home/***/webassembly/wasmer/wasmInJs/minimal/index.js:75:17)
SUCCESS: nop
==RESULTS==
{ nopResult: { resultCode: 0 }, minResult: undefined }
==DONE==

NodeJs File: index.js

const fs = require("fs")
const { init, WASI } = require("@wasmer/wasi");
const { exit } = require("process");
const wabtFactory = require("wabt");

async function run() {

  // Load the WASI library
  await init();

  // Construct wabt
  const wabt = await wabtFactory();


  // A minimal wat that does nothing
  //  also import from wasi_unstable so it is recognized as wasi
  const nopWat = `(module 
    (import "wasi_unstable" "fd_write" (func (param i32 i32 i32 i32) (result i32)))
    (memory (export "memory") 0 32)
    (func $run )
    (export "_start" (func $run)))`;

  // A minimal wat with a custom import
  //  also import from wasi_unstable so it is recognized as wasi
  const minWat = `(module 
    (import "console" "echo" (func $echo (param $char i32)))
    (import "wasi_unstable" "fd_write" (func (param i32 i32 i32 i32) (result i32)))
    (memory (export "memory") 0 32)
    (func $run )
    (export "_start" (func $run)))`;

  // Convert the wat to wasm bytes
  const nopWasmModule = wabt.parseWat('nop.wat', nopWat);
  const minWasmModule = wabt.parseWat('min.wat', minWat);
  const nop = nopWasmModule.toBinary({});
  const min = minWasmModule.toBinary({});

  // Instantiate WASI
  let wasi = new WASI({
    args: [],
    env: {}
  })

  // Async function to run our Wasm module/instance
  const startWasiTask =
    async options => {

      // Get the buffer from options
      const { buffer } = options;

      // Format the wasm bytes
      let wasmBytes = new Uint8Array(buffer);

      // Compile the WebAssembly file into a module
      const module = await WebAssembly.compile(wasmBytes);

      // Build imports object to pass to the module
      const importsProvided = {
        'console': {
          'echo': echo
        }
      }

      // Instantiate the module
      const instance = await wasi.instantiate(module, importsProvided);

      // Start the WASI instance
      const resultCode = wasi.start();

      return {resultCode};
    }

  // Run the minimal import test
  let minResult;
  try {
    minResult = await startWasiTask(min);
    console.log('SUCCESS: minimal import test');
  } catch(err) {
    console.log('ERROR: minimal import test\n', err);
  }

  // Run the nop
  let nopResult;
  try {
    nopResult = await startWasiTask(nop);
    console.log('SUCCESS: nop');
  } catch(err) {
    console.log('ERROR: nop\n', err);
  }

  return {nopResult, minResult};
}

run().then((result)=>{
  console.log('==RESULTS==');
  console.log(result);
  console.log('==DONE==');
}).catch((err)=>{
  console.log(err);
})


// Implement "console"."echo": [I32] -> []
function echo(i) {
  console.log(`${i}`);
}
@mhykes
Copy link
Author

mhykes commented Aug 23, 2022

Can someone at least confirm this issue so I know it isn't just something with my setup?

I tried stepping through it in the vscode debugger, but the errors seem to happen inside some bytecode / minified code. I can't quite follow what is going on.

@syrusakbary
Copy link
Member

Yes, this is an issue in wasmer-js. We worked half in #299 and when it's shipped it will be fully fixed!

@syrusakbary
Copy link
Member

The PR #299 is now fixed and this issue should be resolved by now.
We've published the version 1.1.0 in NPM with the fix.

Closing the issue! (let me know if it persists)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants