mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
Merge remote-tracking branch 'origin/master' into fix/singlepass-indirect-call
This commit is contained in:
commit
5ca6c22cbf
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -70,15 +70,17 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41b598ce988ade113c05bc970a8c9102b59dfac0b318289971cba3379471cae4"
|
||||
checksum = "100179f909a27ed067ce4fa6db58f7fa0f67070d7a04d38f040886174b85ef6f"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
"crypto-mac",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -95,9 +97,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "c2-chacha"
|
||||
@ -348,6 +350,16 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.1"
|
||||
@ -557,15 +569,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
|
||||
checksum = "76cdda6bf525062a0c9e8f14ee2b37935c86b8efb6c8b69b3c83dfb518a914af"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.3.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc"
|
||||
checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
|
||||
dependencies = [
|
||||
"autocfg 1.0.0",
|
||||
"serde",
|
||||
@ -1409,6 +1421,12 @@ dependencies = [
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
|
2
Makefile
2
Makefile
@ -307,7 +307,7 @@ dep-graph:
|
||||
cargo deps --optional-deps --filter wasmer-wasi wasmer-wasi-tests wasmer-kernel-loader wasmer-dev-utils wasmer-llvm-backend wasmer-emscripten wasmer-emscripten-tests wasmer-runtime-core wasmer-runtime wasmer-middleware-common wasmer-middleware-common-tests wasmer-singlepass-backend wasmer-clif-backend wasmer --manifest-path Cargo.toml | dot -Tpng > wasmer_depgraph.png
|
||||
|
||||
docs:
|
||||
cargo doc --features=backend-singlepass,backend-cranelift,backend-llvm,docs,wasi,managed --all --no-deps
|
||||
cargo doc --features=backend-singlepass,backend-cranelift,backend-llvm,docs,wasi,managed --all --document-private-items --no-deps
|
||||
cd lib/runtime-c-api/ && doxygen doxyfile && cd ..
|
||||
mkdir -p api-docs
|
||||
mkdir -p api-docs/c
|
||||
|
@ -1,11 +1,12 @@
|
||||
//! Read runtime errors.
|
||||
|
||||
use libc::{c_char, c_int};
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
error::Error,
|
||||
fmt::{self, Display, Formatter},
|
||||
ptr, slice,
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
static LAST_ERROR: RefCell<Option<Box<dyn Error>>> = RefCell::new(None);
|
||||
|
@ -107,7 +107,7 @@ pub mod table;
|
||||
pub mod trampoline;
|
||||
pub mod value;
|
||||
|
||||
/// The `wasmer_result_t` struct is a type that represents either a
|
||||
/// The `wasmer_result_t` enum is a type that represents either a
|
||||
/// success, or a failure.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
@ -119,15 +119,26 @@ pub enum wasmer_result_t {
|
||||
WASMER_ERROR = 2,
|
||||
}
|
||||
|
||||
/// The `wasmer_limits_t` struct is a type that describes a memory
|
||||
/// options. See the `wasmer_memory_t` struct or the
|
||||
/// `wasmer_memory_new()` function to get more information.
|
||||
#[repr(C)]
|
||||
pub struct wasmer_limits_t {
|
||||
/// The minimum number of allowed pages.
|
||||
pub min: u32,
|
||||
|
||||
/// The maximum number of allowed pages.
|
||||
pub max: wasmer_limit_option_t,
|
||||
}
|
||||
|
||||
/// The `wasmer_limit_option_t` struct represents an optional limit
|
||||
/// for `wasmer_limits_t`.
|
||||
#[repr(C)]
|
||||
pub struct wasmer_limit_option_t {
|
||||
/// Whether the limit is set.
|
||||
pub has_some: bool,
|
||||
|
||||
/// The limit value.
|
||||
pub some: u32,
|
||||
}
|
||||
|
||||
|
@ -1,26 +1,66 @@
|
||||
//! Create, read, write, grow, destroy memory of an instance.
|
||||
|
||||
use crate::{error::update_last_error, error::CApiError, wasmer_limits_t, wasmer_result_t};
|
||||
use std::cell::Cell;
|
||||
use crate::{
|
||||
error::{update_last_error, CApiError},
|
||||
wasmer_limits_t, wasmer_result_t,
|
||||
};
|
||||
use std::{cell::Cell, ptr};
|
||||
use wasmer_runtime::Memory;
|
||||
use wasmer_runtime_core::{
|
||||
types::MemoryDescriptor,
|
||||
units::{Bytes, Pages},
|
||||
};
|
||||
|
||||
/// Opaque pointer to a `wasmer_runtime::Memory` value in Rust.
|
||||
///
|
||||
/// A `wasmer_runtime::Memory` represents a WebAssembly memory. It is
|
||||
/// possible to create one with `wasmer_memory_new()` and pass it as
|
||||
/// imports of an instance, or to read it from exports of an instance
|
||||
/// with `wasmer_export_to_memory()`.
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
pub struct wasmer_memory_t;
|
||||
|
||||
/// Creates a new Memory for the given descriptor and initializes the given
|
||||
/// pointer to pointer to a pointer to the new memory.
|
||||
/// Creates a new empty WebAssembly memory for the given descriptor.
|
||||
///
|
||||
/// The caller owns the object and should call `wasmer_memory_destroy` to free it.
|
||||
/// The result is stored in the first argument `memory` if successful,
|
||||
/// i.e. when the function returns
|
||||
/// `wasmer_result_t::WASMER_OK`. Otherwise,
|
||||
/// `wasmer_result_t::WASMER_ERROR` is returned, and
|
||||
/// `wasmer_last_error_length()` with `wasmer_last_error_message()`
|
||||
/// must be used to read the error message.
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
/// The caller owns the memory and is responsible to free it with
|
||||
/// `wasmer_memory_destroy()`.
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||
/// and `wasmer_last_error_message` to get an error message.
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// // 1. The memory object.
|
||||
/// wasmer_memory_t *memory = NULL;
|
||||
///
|
||||
/// // 2. The memory descriptor.
|
||||
/// wasmer_limits_t memory_descriptor = {
|
||||
/// .min = 10,
|
||||
/// .max = {
|
||||
/// .has_some = true,
|
||||
/// .some = 15,
|
||||
/// },
|
||||
/// };
|
||||
///
|
||||
/// // 3. Initialize the memory.
|
||||
/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
|
||||
///
|
||||
/// if (result != WASMER_OK) {
|
||||
/// int error_length = wasmer_last_error_length();
|
||||
/// char *error = malloc(error_length);
|
||||
/// wasmer_last_error_message(error, error_length);
|
||||
/// // Do something with `error`…
|
||||
/// }
|
||||
///
|
||||
/// // 4. Free the memory!
|
||||
/// wasmer_memory_destroy(memory);
|
||||
/// ```
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmer_memory_new(
|
||||
memory: *mut *mut wasmer_memory_t,
|
||||
@ -53,53 +93,139 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
||||
wasmer_result_t::WASMER_OK
|
||||
}
|
||||
|
||||
/// Grows a Memory by the given number of pages.
|
||||
/// Grows a memory by the given number of pages (of 65Kb each).
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
/// The functions return `wasmer_result_t::WASMER_OK` upon success,
|
||||
/// `wasmer_result_t::WASMER_ERROR` otherwise. Use
|
||||
/// `wasmer_last_error_length()` with `wasmer_last_error_message()` to
|
||||
/// read the error message.
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||
/// and `wasmer_last_error_message` to get an error message.
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// wasmer_result_t result = wasmer_memory_grow(memory, 10);
|
||||
///
|
||||
/// if (result != WASMER_OK) {
|
||||
/// // …
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -> wasmer_result_t {
|
||||
if memory.is_null() {
|
||||
update_last_error(CApiError {
|
||||
msg: "`memory` is NULL.".to_string(),
|
||||
});
|
||||
|
||||
return wasmer_result_t::WASMER_ERROR;
|
||||
}
|
||||
|
||||
let memory = unsafe { &*(memory as *mut Memory) };
|
||||
let delta_result = memory.grow(Pages(delta));
|
||||
|
||||
match delta_result {
|
||||
Ok(_) => wasmer_result_t::WASMER_OK,
|
||||
Err(grow_error) => {
|
||||
update_last_error(grow_error);
|
||||
|
||||
wasmer_result_t::WASMER_ERROR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current length in pages of the given memory
|
||||
/// Reads the current length (in pages) of the given memory.
|
||||
///
|
||||
/// The function returns zero if `memory` is a null pointer.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// uint32_t memory_length = wasmer_memory_length(memory);
|
||||
///
|
||||
/// printf("Memory pages length: %d\n", memory_length);
|
||||
/// ```
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_memory_length(memory: *const wasmer_memory_t) -> u32 {
|
||||
if memory.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let memory = unsafe { &*(memory as *const Memory) };
|
||||
let Pages(len) = memory.size();
|
||||
len
|
||||
let Pages(length) = memory.size();
|
||||
|
||||
length
|
||||
}
|
||||
|
||||
/// Gets the start pointer to the bytes within a Memory
|
||||
/// Gets a pointer to the beginning of the contiguous memory data
|
||||
/// bytes.
|
||||
///
|
||||
/// The function returns `NULL` if `memory` is a null pointer.
|
||||
///
|
||||
/// Note that when the memory grows, it can be reallocated, and thus
|
||||
/// the returned pointer can be invalidated.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// uint8_t *memory_data = wasmer_memory_data(memory);
|
||||
/// char *str = (char*) malloc(sizeof(char) * 7);
|
||||
///
|
||||
/// for (uint32_t nth = 0; nth < 7; ++nth) {
|
||||
/// str[nth] = (char) memory_data[nth];
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_memory_data(mem: *const wasmer_memory_t) -> *mut u8 {
|
||||
let memory = unsafe { &*(mem as *const Memory) };
|
||||
pub extern "C" fn wasmer_memory_data(memory: *const wasmer_memory_t) -> *mut u8 {
|
||||
if memory.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
let memory = unsafe { &*(memory as *const Memory) };
|
||||
|
||||
memory.view::<u8>()[..].as_ptr() as *mut Cell<u8> as *mut u8
|
||||
}
|
||||
|
||||
/// Gets the size in bytes of a Memory
|
||||
/// Gets the size in bytes of the memory data.
|
||||
///
|
||||
/// This function returns 0 if `memory` is a null pointer.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
||||
/// ```
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_memory_data_length(mem: *mut wasmer_memory_t) -> u32 {
|
||||
let memory = mem as *mut Memory;
|
||||
let Bytes(len) = unsafe { (*memory).size().bytes() };
|
||||
len as u32
|
||||
pub extern "C" fn wasmer_memory_data_length(memory: *mut wasmer_memory_t) -> u32 {
|
||||
if memory.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let memory = unsafe { &*(memory as *const Memory) };
|
||||
let Bytes(length) = memory.size().bytes();
|
||||
|
||||
length as u32
|
||||
}
|
||||
|
||||
/// Frees memory for the given Memory
|
||||
/// Frees memory for the given `wasmer_memory_t`.
|
||||
///
|
||||
/// Check the `wasmer_memory_new()` function to get a complete
|
||||
/// example.
|
||||
///
|
||||
/// If `memory` is a null pointer, this function does nothing.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// // Get a memory.
|
||||
/// wasmer_memory_t *memory = NULL;
|
||||
/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
|
||||
///
|
||||
/// // Destroy the memory.
|
||||
/// wasmer_memory_destroy(memory);
|
||||
/// ```
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_memory_destroy(memory: *mut wasmer_memory_t) {
|
||||
|
Binary file not shown.
@ -7,12 +7,13 @@
|
||||
int main()
|
||||
{
|
||||
wasmer_memory_t *memory = NULL;
|
||||
wasmer_limits_t descriptor;
|
||||
descriptor.min = 10;
|
||||
wasmer_limit_option_t max;
|
||||
max.has_some = true;
|
||||
max.some = 15;
|
||||
descriptor.max = max;
|
||||
wasmer_limits_t descriptor = {
|
||||
.min = 10,
|
||||
.max = {
|
||||
.has_some = true,
|
||||
.some = 15,
|
||||
},
|
||||
};
|
||||
wasmer_result_t memory_result = wasmer_memory_new(&memory, descriptor);
|
||||
printf("Memory result: %d\n", memory_result);
|
||||
assert(memory_result == WASMER_OK);
|
||||
|
@ -86,7 +86,7 @@ enum wasmer_import_export_kind {
|
||||
typedef uint32_t wasmer_import_export_kind;
|
||||
|
||||
/**
|
||||
* The `wasmer_result_t` struct is a type that represents either a
|
||||
* The `wasmer_result_t` enum is a type that represents either a
|
||||
* success, or a failure.
|
||||
*/
|
||||
typedef enum {
|
||||
@ -234,6 +234,14 @@ typedef struct {
|
||||
|
||||
} wasmer_export_t;
|
||||
|
||||
/**
|
||||
* Opaque pointer to a `wasmer_runtime::Memory` value in Rust.
|
||||
*
|
||||
* A `wasmer_runtime::Memory` represents a WebAssembly memory. It is
|
||||
* possible to create one with `wasmer_memory_new()` and pass it as
|
||||
* imports of an instance, or to read it from exports of an instance
|
||||
* with `wasmer_export_to_memory()`.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
} wasmer_memory_t;
|
||||
@ -326,13 +334,34 @@ typedef struct {
|
||||
|
||||
} wasmer_instance_context_t;
|
||||
|
||||
/**
|
||||
* The `wasmer_limit_option_t` struct repreesents an optional limit
|
||||
* for `wasmer_limits_t`.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Whether the limit is set.
|
||||
*/
|
||||
bool has_some;
|
||||
/**
|
||||
* The limit value.
|
||||
*/
|
||||
uint32_t some;
|
||||
} wasmer_limit_option_t;
|
||||
|
||||
/**
|
||||
* The `wasmer_limits_t` struct is a type that describes a memory
|
||||
* options. See the `wasmer_memory_t` struct or the
|
||||
* `wasmer_memory_new()` function to get more information.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* The minimum number of allowed pages.
|
||||
*/
|
||||
uint32_t min;
|
||||
/**
|
||||
* The maximum number of allowed pages.
|
||||
*/
|
||||
wasmer_limit_option_t max;
|
||||
} wasmer_limits_t;
|
||||
|
||||
@ -1110,45 +1139,137 @@ int wasmer_last_error_length(void);
|
||||
int wasmer_last_error_message(char *buffer, int length);
|
||||
|
||||
/**
|
||||
* Gets the start pointer to the bytes within a Memory
|
||||
* Gets a pointer to the beginning of the contiguous memory data
|
||||
* bytes.
|
||||
*
|
||||
* The function returns `NULL` if `memory` is a null pointer.
|
||||
*
|
||||
* Note that when the memory grows, it can be reallocated, and thus
|
||||
* the returned pointer can be invalidated.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* uint8_t *memory_data = wasmer_memory_data(memory);
|
||||
* char *str = (char*) malloc(sizeof(char) * 7);
|
||||
*
|
||||
* for (uint32_t nth = 0; nth < 7; ++nth) {
|
||||
* str[nth] = (char) memory_data[nth];
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
uint8_t *wasmer_memory_data(const wasmer_memory_t *mem);
|
||||
uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
|
||||
|
||||
/**
|
||||
* Gets the size in bytes of a Memory
|
||||
* Gets the size in bytes of the memory data.
|
||||
*
|
||||
* This function returns 0 if `memory` is a null pointer.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
||||
* ```
|
||||
*/
|
||||
uint32_t wasmer_memory_data_length(wasmer_memory_t *mem);
|
||||
uint32_t wasmer_memory_data_length(wasmer_memory_t *memory);
|
||||
|
||||
/**
|
||||
* Frees memory for the given Memory
|
||||
* Frees memory for the given `wasmer_memory_t`.
|
||||
*
|
||||
* Check the `wasmer_memory_new()` function to get a complete
|
||||
* example.
|
||||
*
|
||||
* If `memory` is a null pointer, this function does nothing.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* // Get a memory.
|
||||
* wasmer_memory_t *memory = NULL;
|
||||
* wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
|
||||
*
|
||||
* // Destroy the memory.
|
||||
* wasmer_memory_destroy(memory);
|
||||
* ```
|
||||
*/
|
||||
void wasmer_memory_destroy(wasmer_memory_t *memory);
|
||||
|
||||
/**
|
||||
* Grows a Memory by the given number of pages.
|
||||
* Grows a memory by the given number of pages (of 65Kb each).
|
||||
*
|
||||
* Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
* The functions return `wasmer_result_t::WASMER_OK` upon success,
|
||||
* `wasmer_result_t::WASMER_ERROR` otherwise. Use
|
||||
* `wasmer_last_error_length()` with `wasmer_last_error_message()` to
|
||||
* read the error message.
|
||||
*
|
||||
* Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||
* and `wasmer_last_error_message` to get an error message.
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* wasmer_result_t result = wasmer_memory_grow(memory, 10);
|
||||
*
|
||||
* if (result != WASMER_OK) {
|
||||
* // …
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
wasmer_result_t wasmer_memory_grow(wasmer_memory_t *memory, uint32_t delta);
|
||||
|
||||
/**
|
||||
* Returns the current length in pages of the given memory
|
||||
* Reads the current length (in pages) of the given memory.
|
||||
*
|
||||
* The function returns zero if `memory` is a null pointer.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* uint32_t memory_length = wasmer_memory_length(memory);
|
||||
*
|
||||
* printf("Memory pages length: %d\n", memory_length);
|
||||
* ```
|
||||
*/
|
||||
uint32_t wasmer_memory_length(const wasmer_memory_t *memory);
|
||||
|
||||
/**
|
||||
* Creates a new Memory for the given descriptor and initializes the given
|
||||
* pointer to pointer to a pointer to the new memory.
|
||||
* Creates a new empty WebAssembly memory for the given descriptor.
|
||||
*
|
||||
* The caller owns the object and should call `wasmer_memory_destroy` to free it.
|
||||
* The result is stored in the first argument `memory` if successful,
|
||||
* i.e. when the function returns
|
||||
* `wasmer_result_t::WASMER_OK`. Otherwise,
|
||||
* `wasmer_result_t::WASMER_ERROR` is returned, and
|
||||
* `wasmer_last_error_length()` with `wasmer_last_error_message()`
|
||||
* must be used to read the error message.
|
||||
*
|
||||
* Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
* The caller owns the memory and is responsible to free it with
|
||||
* `wasmer_memory_destroy()`.
|
||||
*
|
||||
* Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||
* and `wasmer_last_error_message` to get an error message.
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* // 1. The memory object.
|
||||
* wasmer_memory_t *memory = NULL;
|
||||
*
|
||||
* // 2. The memory descriptor.
|
||||
* wasmer_limits_t memory_descriptor = {
|
||||
* .min = 10,
|
||||
* .max = {
|
||||
* .has_some = true,
|
||||
* .some = 15,
|
||||
* },
|
||||
* };
|
||||
*
|
||||
* // 3. Initialize the memory.
|
||||
* wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
|
||||
*
|
||||
* if (result != WASMER_OK) {
|
||||
* int error_length = wasmer_last_error_length();
|
||||
* char *error = malloc(error_length);
|
||||
* wasmer_last_error_message(error, error_length);
|
||||
* // Do something with `error`…
|
||||
* }
|
||||
*
|
||||
* // 4. Free the memory!
|
||||
* wasmer_memory_destroy(memory);
|
||||
* ```
|
||||
*/
|
||||
wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits);
|
||||
|
||||
|
@ -65,7 +65,7 @@ enum class wasmer_import_export_kind : uint32_t {
|
||||
WASM_TABLE = 3,
|
||||
};
|
||||
|
||||
/// The `wasmer_result_t` struct is a type that represents either a
|
||||
/// The `wasmer_result_t` enum is a type that represents either a
|
||||
/// success, or a failure.
|
||||
enum class wasmer_result_t {
|
||||
/// Represents a success.
|
||||
@ -177,6 +177,12 @@ struct wasmer_export_t {
|
||||
|
||||
};
|
||||
|
||||
/// Opaque pointer to a `wasmer_runtime::Memory` value in Rust.
|
||||
///
|
||||
/// A `wasmer_runtime::Memory` represents a WebAssembly memory. It is
|
||||
/// possible to create one with `wasmer_memory_new()` and pass it as
|
||||
/// imports of an instance, or to read it from exports of an instance
|
||||
/// with `wasmer_export_to_memory()`.
|
||||
struct wasmer_memory_t {
|
||||
|
||||
};
|
||||
@ -263,13 +269,22 @@ struct wasmer_instance_context_t {
|
||||
|
||||
};
|
||||
|
||||
/// The `wasmer_limit_option_t` struct repreesents an optional limit
|
||||
/// for `wasmer_limits_t`.
|
||||
struct wasmer_limit_option_t {
|
||||
/// Whether the limit is set.
|
||||
bool has_some;
|
||||
/// The limit value.
|
||||
uint32_t some;
|
||||
};
|
||||
|
||||
/// The `wasmer_limits_t` struct is a type that describes a memory
|
||||
/// options. See the `wasmer_memory_t` struct or the
|
||||
/// `wasmer_memory_new()` function to get more information.
|
||||
struct wasmer_limits_t {
|
||||
/// The minimum number of allowed pages.
|
||||
uint32_t min;
|
||||
/// The maximum number of allowed pages.
|
||||
wasmer_limit_option_t max;
|
||||
};
|
||||
|
||||
@ -920,35 +935,127 @@ int wasmer_last_error_length();
|
||||
/// ```
|
||||
int wasmer_last_error_message(char *buffer, int length);
|
||||
|
||||
/// Gets the start pointer to the bytes within a Memory
|
||||
uint8_t *wasmer_memory_data(const wasmer_memory_t *mem);
|
||||
/// Gets a pointer to the beginning of the contiguous memory data
|
||||
/// bytes.
|
||||
///
|
||||
/// The function returns `NULL` if `memory` is a null pointer.
|
||||
///
|
||||
/// Note that when the memory grows, it can be reallocated, and thus
|
||||
/// the returned pointer can be invalidated.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// uint8_t *memory_data = wasmer_memory_data(memory);
|
||||
/// char *str = (char*) malloc(sizeof(char) * 7);
|
||||
///
|
||||
/// for (uint32_t nth = 0; nth < 7; ++nth) {
|
||||
/// str[nth] = (char) memory_data[nth];
|
||||
/// }
|
||||
/// ```
|
||||
uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
|
||||
|
||||
/// Gets the size in bytes of a Memory
|
||||
uint32_t wasmer_memory_data_length(wasmer_memory_t *mem);
|
||||
/// Gets the size in bytes of the memory data.
|
||||
///
|
||||
/// This function returns 0 if `memory` is a null pointer.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
|
||||
/// ```
|
||||
uint32_t wasmer_memory_data_length(wasmer_memory_t *memory);
|
||||
|
||||
/// Frees memory for the given Memory
|
||||
/// Frees memory for the given `wasmer_memory_t`.
|
||||
///
|
||||
/// Check the `wasmer_memory_new()` function to get a complete
|
||||
/// example.
|
||||
///
|
||||
/// If `memory` is a null pointer, this function does nothing.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// // Get a memory.
|
||||
/// wasmer_memory_t *memory = NULL;
|
||||
/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
|
||||
///
|
||||
/// // Destroy the memory.
|
||||
/// wasmer_memory_destroy(memory);
|
||||
/// ```
|
||||
void wasmer_memory_destroy(wasmer_memory_t *memory);
|
||||
|
||||
/// Grows a Memory by the given number of pages.
|
||||
/// Grows a memory by the given number of pages (of 65Kb each).
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
/// The functions return `wasmer_result_t::WASMER_OK` upon success,
|
||||
/// `wasmer_result_t::WASMER_ERROR` otherwise. Use
|
||||
/// `wasmer_last_error_length()` with `wasmer_last_error_message()` to
|
||||
/// read the error message.
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||
/// and `wasmer_last_error_message` to get an error message.
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// wasmer_result_t result = wasmer_memory_grow(memory, 10);
|
||||
///
|
||||
/// if (result != WASMER_OK) {
|
||||
/// // …
|
||||
/// }
|
||||
/// ```
|
||||
wasmer_result_t wasmer_memory_grow(wasmer_memory_t *memory, uint32_t delta);
|
||||
|
||||
/// Returns the current length in pages of the given memory
|
||||
/// Reads the current length (in pages) of the given memory.
|
||||
///
|
||||
/// The function returns zero if `memory` is a null pointer.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// uint32_t memory_length = wasmer_memory_length(memory);
|
||||
///
|
||||
/// printf("Memory pages length: %d\n", memory_length);
|
||||
/// ```
|
||||
uint32_t wasmer_memory_length(const wasmer_memory_t *memory);
|
||||
|
||||
/// Creates a new Memory for the given descriptor and initializes the given
|
||||
/// pointer to pointer to a pointer to the new memory.
|
||||
/// Creates a new empty WebAssembly memory for the given descriptor.
|
||||
///
|
||||
/// The caller owns the object and should call `wasmer_memory_destroy` to free it.
|
||||
/// The result is stored in the first argument `memory` if successful,
|
||||
/// i.e. when the function returns
|
||||
/// `wasmer_result_t::WASMER_OK`. Otherwise,
|
||||
/// `wasmer_result_t::WASMER_ERROR` is returned, and
|
||||
/// `wasmer_last_error_length()` with `wasmer_last_error_message()`
|
||||
/// must be used to read the error message.
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_OK` upon success.
|
||||
/// The caller owns the memory and is responsible to free it with
|
||||
/// `wasmer_memory_destroy()`.
|
||||
///
|
||||
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
|
||||
/// and `wasmer_last_error_message` to get an error message.
|
||||
/// Example:
|
||||
///
|
||||
/// ```c
|
||||
/// // 1. The memory object.
|
||||
/// wasmer_memory_t *memory = NULL;
|
||||
///
|
||||
/// // 2. The memory descriptor.
|
||||
/// wasmer_limits_t memory_descriptor = {
|
||||
/// .min = 10,
|
||||
/// .max = {
|
||||
/// .has_some = true,
|
||||
/// .some = 15,
|
||||
/// },
|
||||
/// };
|
||||
///
|
||||
/// // 3. Initialize the memory.
|
||||
/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
|
||||
///
|
||||
/// if (result != WASMER_OK) {
|
||||
/// int error_length = wasmer_last_error_length();
|
||||
/// char *error = malloc(error_length);
|
||||
/// wasmer_last_error_message(error, error_length);
|
||||
/// // Do something with `error`…
|
||||
/// }
|
||||
///
|
||||
/// // 4. Free the memory!
|
||||
/// wasmer_memory_destroy(memory);
|
||||
/// ```
|
||||
wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits);
|
||||
|
||||
/// Deserialize the given serialized module.
|
||||
|
@ -109,7 +109,7 @@ impl Memory {
|
||||
}
|
||||
|
||||
/// Return a "view" of the currently accessible memory. By
|
||||
/// default, the view is unsyncronized, using regular memory
|
||||
/// default, the view is unsynchronized, using regular memory
|
||||
/// accesses. You can force a memory view to use atomic accesses
|
||||
/// by calling the [`atomically`] method.
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user