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

Extend C API with interfaces needed to use threads #7940

Merged
merged 1 commit into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
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