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 15, 2024
1 parent 353dc27 commit dc86ba5
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/c-api/include/wasmtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
#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>
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
1 change: 1 addition & 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
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)
}
5 changes: 5 additions & 0 deletions crates/c-api/src/types/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ pub extern "C" fn wasmtime_memorytype_is64(mt: &wasm_memorytype_t) -> bool {
mt.ty().ty.is_64()
}

#[no_mangle]
pub extern "C" fn wasmtime_memorytype_isshared(mt: &wasm_memorytype_t) -> bool {
mt.ty().ty.is_shared()
}

#[no_mangle]
pub extern "C" fn wasm_memorytype_as_externtype(ty: &wasm_memorytype_t) -> &wasm_externtype_t {
&ty.ext
Expand Down

0 comments on commit dc86ba5

Please sign in to comment.