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

provide wasi api style like FFI interface exmaple #215

Open
HerrCai0907 opened this issue Jun 18, 2024 · 8 comments
Open

provide wasi api style like FFI interface exmaple #215

HerrCai0907 opened this issue Jun 18, 2024 · 8 comments

Comments

@HerrCai0907
Copy link

Is the WASI style API supported by moonbit? for example provide a raw linear memory view via FFI.

@HerrCai0907 HerrCai0907 changed the title provide wasi api style like FFI interface provide wasi api style like FFI interface exmaple Jun 18, 2024
@bobzhang
Copy link
Collaborator

@HerrCai0907 Does your host support https://github.com/WebAssembly/multi-memory, can you elaborate a little bit what APIs would you like to use?

@HerrCai0907
Copy link
Author

For example wasi: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/witx/wasi_snapshot_preview1.witx

It provide an series API to operate file / socket ...

The API looks like:

  (@interface func (export "fd_readdir")
    (param $fd $fd)
    ;;; The buffer where directory entries are stored
    (param $buf (@witx pointer u8))
    (param $buf_len $size)
    ;;; The location within the directory to start reading
    (param $cookie $dircookie)
    ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
    (result $error (expected $size (error $errno)))
  )

It means moonbit should provide a raw linear memory offset to low level runtime and let low level runtime can read / write data from/to this linear memeory.

@peter-jerry-ye
Copy link
Collaborator

If you can run wasm-gc then you can embed wat instructions: https://github.com/peter-jerry-ye/wasi

@yamajik
Copy link

yamajik commented Jul 4, 2024

My wish is WASIX support. And WebGPU support would be much better.

@HerrCai0907
Copy link
Author

If you can run wasm-gc then you can embed wat instructions: https://github.com/peter-jerry-ye/wasi

But it is an incompatible solution. If I want to import several thing together, then I need to do integrate, extract the heap related code and reuse it.

@yamajik
Copy link

yamajik commented Jul 22, 2024

@HerrCai0907 Here are some approaches for your wish (tips: for now, all the following options have no wasm-gc support)

  • Option 1: extism framework, seems extism team has started a new PDK project for Moonbit
  • Option 2: wasmer runtime, a possible way that I have successfully injected wasm func in Moonbit by wasmer-go-sdk
  • Option 3: wasmtime runtime, a possible way as wasmer, but not tested
  • Option 4: wasmedge runtime, a possible way as wasmer, but not tested

@yamajik
Copy link

yamajik commented Jul 29, 2024

I do successfully call some wasi methods over WasmEdge runtime, but unfortunately, only partly supported. Because there's no way to get the address of a pointer/object in MoonBit.

  • Basic stub types are supported: Int, Uint, Float...
  • Unsupported types: String, Array, Struct...

How to pass a string to wasi methods, "wasi:logging/logging" "log" as an example

#[allow(unused_unsafe, clippy::all)]
/// Emit a log message.
///
/// A log message has a `level` describing what kind of message is being
/// sent, a context, which is an uninterpreted string meant to help
/// consumers group similar messages, and a string containing the message
/// text.
pub fn log(level: Level, context: &str, message: &str) {
    unsafe {
        let vec0 = context;
        let ptr0 = vec0.as_ptr().cast::<u8>();
        let len0 = vec0.len();
        let vec1 = message;
        let ptr1 = vec1.as_ptr().cast::<u8>();
        let len1 = vec1.len();
        #[cfg(not(target_arch = "wasm32"))]
        fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8, _: usize) {
            ::core::panicking::panic("internal error: entered unreachable code")
        }
        wit_import(
            level.clone() as i32,
            ptr0.cast_mut(t,
            len0,
            ptr1.cast_mut(),
            len1,
        );
    }
}
  • But in MoonBit, it doesn't work for missing pointer/address features
// ffi definitions for wasi logging - https://github.com/WebAssembly/wasi-logging/blob/main/wit/logging.wit#L34
fn wasi_log(level : Int, context_ptr: Int, context_offset: Int, message_ptr: Int, message_offset: Int) = "wasi:logging/logging" "log"

pub fn log(level : Level, context : Context, message : String) -> Unit {
  let context_bytes = context.0.to_bytes()
  let message_bytes = message.to_bytes()
  wasi_log(
    level.0,
    context_bytes.as_ptr(), // Error here, no such method in MoonBit `as_ptr`
    context_bytes.length(),
    message_bytes.as_ptr(), // Error here, no such method in MoonBit `as_ptr`
    message_bytes.length(),
  )
}

@peter-jerry-ye
Copy link
Collaborator

@yamajik We have inline wasm supported, which allows you to manipulate pointer/address. We will provide wit-bindgen very soon.

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

4 participants