Skip to content

Commit

Permalink
Extend C API with interfaces needed to use threads
Browse files Browse the repository at this point in the history
  • Loading branch information
Milek7 committed Feb 14, 2024
1 parent 353dc27 commit 1239efd
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 5 deletions.
2 changes: 2 additions & 0 deletions crates/c-api/include/wasmtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,12 @@
#include <wasmtime/memory.h>
#include <wasmtime/module.h>
#include <wasmtime/profiling.h>
#include <wasmtime/sharedmemory.h>
#include <wasmtime/store.h>
#include <wasmtime/table.h>
#include <wasmtime/trap.h>
#include <wasmtime/val.h>
#include <wasmtime/wasictx.h>
#include <wasmtime/async.h>
// IWYU pragma: end_exports
// clang-format on
Expand Down
32 changes: 32 additions & 0 deletions crates/c-api/include/wasmtime/linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <wasm.h>
#include <wasmtime/error.h>
#include <wasmtime/extern.h>
#include <wasmtime/sharedmemory.h>
#include <wasmtime/store.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -42,6 +43,15 @@ typedef struct wasmtime_linker wasmtime_linker_t;
*/
WASM_API_EXTERN wasmtime_linker_t *wasmtime_linker_new(wasm_engine_t *engine);

/**
* \brief Clones existing linker.
*
* This function does not take ownership of the linker argument, and the caller
* is expected to delete the returned linker.
*/
WASM_API_EXTERN wasmtime_linker_t *
wasmtime_linker_clone(wasmtime_linker_t *linker);

/**
* \brief Deletes a linker
*/
Expand Down Expand Up @@ -78,6 +88,28 @@ wasmtime_linker_define(wasmtime_linker_t *linker, wasmtime_context_t *store,
const char *module, size_t module_len, const char *name,
size_t name_len, const wasmtime_extern_t *item);

/**
* \brief Defines a new shared memory in this linker.
*
* \param linker the linker the name is being defined in.
* \param store the store that the `item` is owned by.
* \param module the module name the item is defined under.
* \param module_len the byte length of `module`
* \param name the field name the item is defined under
* \param name_len the byte length of `name`
* \param memory the shared memory that is being defined in this linker.
*
* \return On success `NULL` is returned, otherwise an error is returned which
* describes why the definition failed.
*
* For more information about name resolution consult the [Rust
* documentation](https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Linker.html#name-resolution).
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_linker_define_sharedmemory(
wasmtime_linker_t *linker, wasmtime_context_t *store, const char *module,
size_t module_len, const char *name, size_t name_len,
const wasmtime_sharedmemory_t *memory);

/**
* \brief Defines a new function in this linker.
*
Expand Down
5 changes: 5 additions & 0 deletions crates/c-api/include/wasmtime/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ WASM_API_EXTERN bool wasmtime_memorytype_maximum(const wasm_memorytype_t *ty,
*/
WASM_API_EXTERN bool wasmtime_memorytype_is64(const wasm_memorytype_t *ty);

/**
* \brief Returns whether this type of memory represents a shared memory.
*/
WASM_API_EXTERN bool wasmtime_memorytype_isshared(const wasm_memorytype_t *ty);

/**
* \brief Creates a new WebAssembly linear memory
*
Expand Down
91 changes: 91 additions & 0 deletions crates/c-api/include/wasmtime/sharedmemory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* \file wasmtime/sharedmemory.h
*
* Wasmtime API for interacting with wasm shared memories.
*/

#ifndef WASMTIME_SHAREDMEMORY_H
#define WASMTIME_SHAREDMEMORY_H

#include <wasm.h>
#include <wasmtime/error.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* \brief Interface for shared memories.
*
* For more information see the Rust documentation at:
* https://docs.wasmtime.dev/api/wasmtime/struct.SharedMemory.html
*/
typedef struct wasmtime_sharedmemory wasmtime_sharedmemory_t;

/**
* \brief Creates a new WebAssembly shared linear memory
*
* \param ty the type of the memory to create
* \param ret where to store the returned memory
*
* If an error happens when creating the memory it's returned and owned by the
* caller. If an error happens then `ret` is not filled in.
*/
WASM_API_EXTERN wasmtime_error_t *
wasmtime_sharedmemory_new(const wasm_engine_t *engine,
const wasm_memorytype_t *ty,
wasmtime_sharedmemory_t **ret);

/**
* \brief Deletes shared linear memory
*
* \param memory memory to be deleted
*/
WASM_API_EXTERN void
wasmtime_sharedmemory_delete(wasmtime_sharedmemory_t *memory);

/**
* \brief Returns the type of the shared memory specified
*/
WASM_API_EXTERN wasm_memorytype_t *
wasmtime_sharedmemory_type(const wasmtime_sharedmemory_t *memory);

/**
* \brief Returns the base pointer in memory where
the shared linear memory starts.
*/
WASM_API_EXTERN uint8_t *
wasmtime_sharedmemory_data(const wasmtime_sharedmemory_t *memory);

/**
* \brief Returns the byte length of this shared linear memory.
*/
WASM_API_EXTERN size_t
wasmtime_sharedmemory_data_size(const wasmtime_sharedmemory_t *memory);

/**
* \brief Returns the length, in WebAssembly pages, of this shared linear memory
*/
WASM_API_EXTERN uint64_t
wasmtime_sharedmemory_size(const wasmtime_sharedmemory_t *memory);

/**
* \brief Attempts to grow the specified shared memory by `delta` pages.
*
* \param memory the memory to grow
* \param delta the number of pages to grow by
* \param prev_size where to store the previous size of memory
*
* If memory cannot be grown then `prev_size` is left unchanged and an error is
* returned. Otherwise `prev_size` is set to the previous size of the memory, in
* WebAssembly pages, and `NULL` is returned.
*/
WASM_API_EXTERN wasmtime_error_t *
wasmtime_sharedmemory_grow(const wasmtime_sharedmemory_t *memory,
uint64_t delta, uint64_t *prev_size);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // WASMTIME_SHAREDMEMORY_H
18 changes: 15 additions & 3 deletions crates/c-api/include/wasmtime/store.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <wasi.h>
#include <wasm.h>
#include <wasmtime/error.h>
#include <wasmtime/wasictx.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -176,11 +177,11 @@ WASM_API_EXTERN wasmtime_error_t *
wasmtime_context_get_fuel(const wasmtime_context_t *context, uint64_t *fuel);

/**
* \brief Configures WASI state within the specified store.
* \brief Creates and attaches WASI context to the specified store.
*
* This function is required if #wasmtime_linker_define_wasi is called. This
* will configure the WASI state for instances defined within this store to the
* configuration specified.
* will create WASI context with the specified configuration and attach it
* to this store.
*
* This function does not take ownership of `context` but it does take ownership
* of `wasi`. The caller should no longer use `wasi` after calling this function
Expand All @@ -189,6 +190,17 @@ wasmtime_context_get_fuel(const wasmtime_context_t *context, uint64_t *fuel);
WASM_API_EXTERN wasmtime_error_t *
wasmtime_context_set_wasi(wasmtime_context_t *context, wasi_config_t *wasi);

/**
* \brief Attaches manually created WASI context to the specified store.
*
* Compared to `wasmtime_context_set_wasi`, this interface allows to attach
* one manually created WASI context object to multiple stores.
*
* This function does not take ownership of passed arguments.
*/
void wasmtime_context_set_wasictx(wasmtime_context_t *context,
wasmtime_wasictx_t *wasi);

/**
* \brief Configures the relative deadline at which point WebAssembly code will
* trap or invoke the callback function.
Expand Down
44 changes: 44 additions & 0 deletions crates/c-api/include/wasmtime/wasictx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* \file wasmtime/wasictx.h
*
* Wasmtime API for creating WASI context object.
*/

#ifndef WASMTIME_WASICTX_H
#define WASMTIME_WASICTX_H

#include <wasi.h>
#include <wasm.h>
#include <wasmtime/error.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* \brief Manually created WASI context object.
*/
typedef struct wasmtime_wasictx wasmtime_wasictx_t;

/**
* \brief Deletes WASI context object.
*/
WASM_API_EXTERN void wasmtime_wasictx_delete(wasmtime_wasictx_t *wasictx);

/**
* \brief Creates WASI context object from provided config.
*
* \param wasi WASI config to be used to configure created context
* \param ret pointer to where created `wasmtime_wasictx_t*` will be written
*
* This function does take ownership of `wasi`, even when returning with error.
* Space pointed to by `ret` is only written when returning without error.
*/
WASM_API_EXTERN wasmtime_error_t *
wasmtime_wasictx_new(wasi_config_t *wasi, wasmtime_wasictx_t **ret);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // WASMTIME_WASICTX_H
5 changes: 5 additions & 0 deletions crates/c-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mod module;
#[cfg(feature = "profiling")]
mod profiling;
mod r#ref;
mod sharedmemory;
mod store;
mod table;
mod trap;
Expand Down Expand Up @@ -63,6 +64,10 @@ pub use crate::r#async::*;
mod wasi;
#[cfg(feature = "wasi")]
pub use crate::wasi::*;
#[cfg(feature = "wasi")]
mod wasictx;
#[cfg(feature = "wasi")]
pub use crate::wasictx::*;

#[cfg(feature = "wat")]
mod wat2wasm;
Expand Down
26 changes: 25 additions & 1 deletion crates/c-api/src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use std::ffi::c_void;
use std::mem::MaybeUninit;
use std::str;
use wasmtime::{Func, Instance, Linker};
use wasmtime::{Func, Instance, Linker, SharedMemory};

#[repr(C)]
pub struct wasmtime_linker_t {
Expand All @@ -21,6 +21,13 @@ pub extern "C" fn wasmtime_linker_new(engine: &wasm_engine_t) -> Box<wasmtime_li
})
}

#[no_mangle]
pub extern "C" fn wasmtime_linker_clone(linker: &wasmtime_linker_t) -> Box<wasmtime_linker_t> {
Box::new(wasmtime_linker_t {
linker: linker.linker.clone(),
})
}

#[no_mangle]
pub extern "C" fn wasmtime_linker_allow_shadowing(
linker: &mut wasmtime_linker_t,
Expand Down Expand Up @@ -57,6 +64,23 @@ pub unsafe extern "C" fn wasmtime_linker_define(
handle_result(linker.define(&store, module, name, item), |_linker| ())
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_linker_define_sharedmemory(
linker: &mut wasmtime_linker_t,
store: CStoreContext<'_>,
module: *const u8,
module_len: usize,
name: *const u8,
name_len: usize,
item: &SharedMemory,
) -> Option<Box<wasmtime_error_t>> {
let linker = &mut linker.linker;
let module = to_str!(module, module_len);
let name = to_str!(name, name_len);
let item = item.clone();
handle_result(linker.define(&store, module, name, item), |_linker| ())
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_linker_define_func(
linker: &mut wasmtime_linker_t,
Expand Down
52 changes: 52 additions & 0 deletions crates/c-api/src/sharedmemory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::{handle_result, wasm_engine_t, wasm_memorytype_t, wasmtime_error_t};
use std::cell::UnsafeCell;
use wasmtime::SharedMemory;

type wasmtime_sharedmemory_t = SharedMemory;

wasmtime_c_api_macros::declare_own!(wasmtime_sharedmemory_t);

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_new(
engine: &wasm_engine_t,
ty: &wasm_memorytype_t,
ret: &mut *mut wasmtime_sharedmemory_t,
) -> Option<Box<wasmtime_error_t>> {
handle_result(
SharedMemory::new(&engine.engine, ty.ty().ty.clone()),
|mem| *ret = Box::<wasmtime_sharedmemory_t>::into_raw(Box::new(mem)),
)
}

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_type(
mem: &wasmtime_sharedmemory_t,
) -> Box<wasm_memorytype_t> {
Box::new(wasm_memorytype_t::new(mem.ty()))
}

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_data(
mem: &wasmtime_sharedmemory_t,
) -> *const UnsafeCell<u8> {
mem.data().as_ptr()
}

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_data_size(mem: &wasmtime_sharedmemory_t) -> usize {
mem.data().len()
}

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_size(mem: &wasmtime_sharedmemory_t) -> u64 {
mem.size()
}

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_grow(
mem: &wasmtime_sharedmemory_t,
delta: u64,
prev_size: &mut u64,
) -> Option<Box<wasmtime_error_t>> {
handle_result(mem.grow(delta), |prev| *prev_size = prev)
}
11 changes: 10 additions & 1 deletion crates/c-api/src/store.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{wasm_engine_t, wasmtime_error_t, wasmtime_val_t, ForeignData};
use crate::{wasm_engine_t, wasmtime_error_t, wasmtime_val_t, wasmtime_wasictx_t, ForeignData};
use std::cell::UnsafeCell;
use std::ffi::c_void;
use std::sync::Arc;
Expand Down Expand Up @@ -202,6 +202,15 @@ pub extern "C" fn wasmtime_context_set_wasi(
})
}

#[cfg(feature = "wasi")]
#[no_mangle]
pub extern "C" fn wasmtime_context_set_wasictx(
mut context: CStoreContextMut<'_>,
wasi: &wasmtime_wasictx_t,
) {
context.data_mut().wasi = Some(wasi.clone());
}

#[no_mangle]
pub extern "C" fn wasmtime_context_gc(mut context: CStoreContextMut<'_>) {
context.gc();
Expand Down

0 comments on commit 1239efd

Please sign in to comment.