bytecodealliance / jco

JavaScript toolchain for working with WebAssembly Components
https://bytecodealliance.github.io/jco/
Apache License 2.0
642 stars 63 forks source link

Resource transferring seems not working with wasi-virt #431

Closed kateinoigakukun closed 6 months ago

kateinoigakukun commented 6 months ago

I guess resource transferring between the adapter module and wasi-virt does not work

Reproducer

#include <stdio.h>
#include <dirent.h>

int main(int argc, char *argv[]) {
    DIR *dir;
    struct dirent *ent;

    if (argc != 2) {
        printf("Usage: %s <directory>\n", argv[0]);
        return 1;
    }

    char *path = argv[1];
    printf("Listing directory: %s\n", path);
    dir = opendir(path);
    if (dir != NULL) {
        while ((ent = readdir(dir)) != NULL) {
            printf(" - %s\n", ent->d_name);
        }
        closedir(dir);
    } else {
        perror("Could not open directory");
        return 1;
    }

    return 0;
}
$ $WASI_SDK_PATH/bin/clang main.c -target wasm32-unknonwn-wasi -o main.core.wasm
$ wasm-tools component new main.core.wasm -o main.wasm --adapt wasi_snapshot_preview1.command.wasm
$ wasi-virt --allow-stdio --allow-exit --allow-all --mount /foo=foo --debug --out main.virt.wasm main.wasm
Virtualized files from local filesystem:

  - /foo/bar : foo/bar
  - /foo/bar/hello.txt : foo/bar/hello.txt

# It works with wasmtime
$ wasmtime main.virt.wasm /foo/bar
Listing directory: /foo/bar
 - ..
 - hello.txt

# It it doesn't with jco
$ npx jco run main.virt.wasm /foo/bar
CALL wasi:cli/stdin#get-stdin
CALL wasi:cli/stdout#get-stdout
CALL wasi:cli/stderr#get-stderr
CALL wasi:filesystem/preopens#get-directories
CALL wasi:filesystem/types#descriptor.get-type FD=Static(StaticIndexEntry { name: 0x0, ty: ActiveFile, data: STATIC [0, 0] })
CALL wasi:cli/terminal-stdout#get-terminal-stdout
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null
CALL wasi:filesystem/types#descriptor.get-flags FD=Static(StaticIndexEntry { name: 0x0, ty: ActiveFile, data: STATIC [0, 0] })
CALL wasi:filesystem/types#descriptor.get-type FD=Static(StaticIndexEntry { name: 0x0, ty: ActiveFile, data: STATIC [0, 0] })
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null
CALL wasi:io/streams#output-stream.blocking-write-and-flush SID=Null

main.virt.wasm.zip

The line CALL wasi:filesystem/types#descriptor.get-type FD=Static(StaticIndexEntry { name: 0x0, ty: ActiveFile, data: STATIC [0, 0] }) implies the file descriptor is broken at this point. Based on my debugging, it seems like resourceTransferBorrow returns a handle 0x1, but the callee side (wasi-virt) expects it to be a pointer.

kateinoigakukun commented 6 months ago

Thanks! I'll check later on my project