Skip to content

Commit

Permalink
Extend C API with interfaces needed to use threads (#7940)
Browse files Browse the repository at this point in the history
  • Loading branch information
Milek7 committed Mar 8, 2024
1 parent c0a5a66 commit 55bd797
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 3 deletions.
1 change: 1 addition & 0 deletions crates/c-api/include/wasmtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,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
7 changes: 7 additions & 0 deletions crates/c-api/include/wasmtime/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ typedef uint8_t wasmtime_extern_kind_t;
/// \brief Value of #wasmtime_extern_kind_t meaning that #wasmtime_extern_t is a
/// memory
#define WASMTIME_EXTERN_MEMORY 3
/// \brief Value of #wasmtime_extern_kind_t meaning that #wasmtime_extern_t is a
/// shared memory
#define WASMTIME_EXTERN_SHAREDMEMORY 4

struct wasmtime_sharedmemory;

/**
* \typedef wasmtime_extern_union_t
Expand All @@ -105,6 +110,8 @@ typedef union wasmtime_extern_union {
wasmtime_table_t table;
/// Field used if #wasmtime_extern_t::kind is #WASMTIME_EXTERN_MEMORY
wasmtime_memory_t memory;
/// Field used if #wasmtime_extern_t::kind is #WASMTIME_EXTERN_SHAREDMEMORY
struct wasmtime_sharedmemory *sharedmemory;
} wasmtime_extern_union_t;

/**
Expand Down
9 changes: 9 additions & 0 deletions crates/c-api/include/wasmtime/linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,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
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
115 changes: 115 additions & 0 deletions crates/c-api/include/wasmtime/sharedmemory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* \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 engine engine that created shared memory is associated with
* \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 Clones shared linear memory
*
* \param memory memory to be cloned
*
* This function makes shallow clone, ie. copy of reference counted
* memory handle.
*/
WASM_API_EXTERN wasmtime_sharedmemory_t *
wasmtime_sharedmemory_clone(const wasmtime_sharedmemory_t *memory);

/**
* \brief Moves shared linear memory into wasmtime_extern_t object
*
* \param memory memory to be moved
* \param out where to store resulting `wasmtime_extern_t`
*
* This function moves ownership of `memory` into resulting `wasmtime_extern_t`.
*/
WASM_API_EXTERN void
wasmtime_sharedmemory_into_extern(wasmtime_sharedmemory_t *memory,
wasmtime_extern_t *out);

/**
* \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
24 changes: 21 additions & 3 deletions crates/c-api/src/extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
CStoreContext, StoreRef,
};
use std::mem::ManuallyDrop;
use wasmtime::{Extern, Func, Global, Memory, Table};
use wasmtime::{Extern, Func, Global, Memory, SharedMemory, Table};

#[derive(Clone)]
pub struct wasm_extern_t {
Expand Down Expand Up @@ -82,13 +82,25 @@ pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0;
pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1;
pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2;
pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3;
pub const WASMTIME_EXTERN_SHAREDMEMORY: wasmtime_extern_kind_t = 4;

#[repr(C)]
pub union wasmtime_extern_union {
pub func: Func,
pub table: Table,
pub global: Global,
pub memory: Memory,
pub sharedmemory: ManuallyDrop<Box<SharedMemory>>,
}

impl Drop for wasmtime_extern_t {
fn drop(&mut self) {
if self.kind == WASMTIME_EXTERN_SHAREDMEMORY {
unsafe {
ManuallyDrop::drop(&mut self.of.sharedmemory);
}
}
}
}

impl wasmtime_extern_t {
Expand All @@ -98,7 +110,8 @@ impl wasmtime_extern_t {
WASMTIME_EXTERN_GLOBAL => Extern::Global(self.of.global),
WASMTIME_EXTERN_TABLE => Extern::Table(self.of.table),
WASMTIME_EXTERN_MEMORY => Extern::Memory(self.of.memory),
other => panic!("unknown wasm_extern_kind_t: {}", other),
WASMTIME_EXTERN_SHAREDMEMORY => Extern::SharedMemory((**self.of.sharedmemory).clone()),
other => panic!("unknown wasmtime_extern_kind_t: {}", other),
}
}
}
Expand All @@ -122,7 +135,12 @@ impl From<Extern> for wasmtime_extern_t {
kind: WASMTIME_EXTERN_MEMORY,
of: wasmtime_extern_union { memory },
},
Extern::SharedMemory(_memory) => todo!(),
Extern::SharedMemory(sharedmemory) => wasmtime_extern_t {
kind: WASMTIME_EXTERN_SHAREDMEMORY,
of: wasmtime_extern_union {
sharedmemory: ManuallyDrop::new(Box::new(sharedmemory)),
},
},
}
}
}
Expand Down
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
7 changes: 7 additions & 0 deletions crates/c-api/src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
68 changes: 68 additions & 0 deletions crates/c-api/src/sharedmemory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::{handle_result, wasm_engine_t, wasm_memorytype_t, wasmtime_error_t, wasmtime_extern_t};
use std::cell::UnsafeCell;
use std::mem::MaybeUninit;
use wasmtime::{Extern, 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_clone(
mem: &wasmtime_sharedmemory_t,
) -> Box<wasmtime_sharedmemory_t> {
Box::new(mem.clone())
}

#[no_mangle]
pub extern "C" fn wasmtime_sharedmemory_into_extern(
mem: Box<wasmtime_sharedmemory_t>,
ext: &mut MaybeUninit<wasmtime_extern_t>,
) {
crate::initialize(ext, Extern::from(*mem).into());
}

#[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 55bd797

Please sign in to comment.