ComponentizeJS icon indicating copy to clipboard operation
ComponentizeJS copied to clipboard

Question - Can we optionally enable `cli` and `fs` worlds.

Open karthik2804 opened this issue 1 year ago • 3 comments

Could we optionally enable the cli and fs worlds. This would enable building compatibility layers such that more libraries would work and also improve the variety of applications that can be built.

Are there any concerns with this? if not, I am happy to create a PR.

karthik2804 avatar May 13 '24 12:05 karthik2804

It's possible to build against cli and fs by having a WIT file that imports them and then using the interfaces directly.

For higher-level interfaces it might make sense to use the Node.js standard library design for these instead, effectively implementing builtins in StarlingMonkey under the builtins/node folder for Node.js standard functions to support eg import { readFileSync } from 'node:fs' from within the binary wrapping WASI fs underneath.

I'm not sure which approach you're referring to here though, so let me know your thoughts further.

guybedford avatar May 14 '24 16:05 guybedford

It is the first approach that I am interested in. I have the following minimal example.

The wit file is defined as the follows along with the deps folder.

// hello.wit
package local:hello;

world hello {
  import wasi:cli/[email protected];
  export hello: func(name: string) -> string;
}

The hello.js file

import { getEnvironment } from "wasi:cli/[email protected]";

export function hello(name) {
  console.log(getEnvironment())
  return `Hello ${name}`;
}

The component builds successfully but when trying to execute it, I am running into the following error.

cargo run --release 
    Finished release [optimized] target(s) in 0.12s
     Running `target/release/wasmtime-test`
Error: error while executing at wasm backtrace:
    0: 0x76e0e5 - <unknown>!<wasm function 12125>
    1: 0x7537fc - <unknown>!<wasm function 9529>
    2: 0x33361d - <unknown>!<wasm function 436>
    3: 0xc4f67 - <unknown>!<wasm function 25>
    4: 0x330de1 - <unknown>!<wasm function 432>
    5: 0x333478 - <unknown>!<wasm function 436>
    6: 0x67c0eb - <unknown>!<wasm function 4567>
    7: 0x4db9be - <unknown>!<wasm function 1541>
    8: 0x3beb31 - <unknown>!<wasm function 682>
    9: 0x769ed5 - <unknown>!hello

Caused by:
    wasm trap: wasm `unreachable` instruction executed

I am able to work around this by building componentize-js locally by commenting out the following line https://github.com/bytecodealliance/ComponentizeJS/blob/519256f5632f48e42cfea54bfd588f383eccb855/crates/spidermonkey-embedding-splicer/src/stub_wasi.rs#L60 which if I understand correctly stubs the import in the component as unreachable which is the above trap.

karthik2804 avatar May 14 '24 17:05 karthik2804

Okay, yes this is definitely a bug then - we should never stub features which are part of the the target world.

Perhaps we can:

  • Update the stub_wasi API to also take the target wit-path, wit-world and world-name, just like the main splice function (https://github.com/bytecodealliance/ComponentizeJS/blob/main/crates/spidermonkey-embedding-splicer/wit/spidermonkey-embedding-splicer.wit#L34)
  • Inside of stub_wasi, reparse the target world, and then never stub out an import name that is defined in the target world.

Later on, we could possibly make filesystem, cli and sockets explicit features, but I think that only makes sense if StarlingMonkey has implementations for these like I discussed in (2). That is, for now never stubbing the target world seems the stronger constraint overall to maintain, even if features offer a global opt-out in future.

guybedford avatar May 14 '24 18:05 guybedford