mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
simplify the interface and make the functions more explicit
This commit is contained in:
parent
01223d7174
commit
c9ff9e9841
@ -110,7 +110,7 @@ impl EcsAccessManager {
|
|||||||
/// buffer calling the `wasm_prepare_buffer` function Note: There is
|
/// buffer calling the `wasm_prepare_buffer` function Note: There is
|
||||||
/// probably optimizations that can be done using less restrictive
|
/// probably optimizations that can be done using less restrictive
|
||||||
/// ordering
|
/// ordering
|
||||||
pub fn get_pointer(
|
fn get_pointer(
|
||||||
store: &mut StoreMut,
|
store: &mut StoreMut,
|
||||||
object_length: <MemoryModel as wasmer::MemorySize>::Offset,
|
object_length: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||||
allocator: &TypedFunction<
|
allocator: &TypedFunction<
|
||||||
@ -123,45 +123,17 @@ pub fn get_pointer(
|
|||||||
.map_err(MemoryAllocationError::CantAllocate)
|
.map_err(MemoryAllocationError::CantAllocate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function writes an object to WASM memory returning a pointer and a
|
|
||||||
/// length. Will realloc the buffer is not wide enough
|
|
||||||
pub fn write_data<T: Serialize>(
|
|
||||||
store: &mut StoreMut,
|
|
||||||
memory: &Memory,
|
|
||||||
allocator: &TypedFunction<
|
|
||||||
<MemoryModel as wasmer::MemorySize>::Offset,
|
|
||||||
WasmPtr<u8, MemoryModel>,
|
|
||||||
>,
|
|
||||||
object: &T,
|
|
||||||
) -> Result<
|
|
||||||
(
|
|
||||||
WasmPtr<u8, MemoryModel>,
|
|
||||||
<MemoryModel as wasmer::MemorySize>::Offset,
|
|
||||||
),
|
|
||||||
PluginModuleError,
|
|
||||||
> {
|
|
||||||
write_bytes(
|
|
||||||
store,
|
|
||||||
memory,
|
|
||||||
allocator,
|
|
||||||
(
|
|
||||||
&bincode::serialize(object).map_err(PluginModuleError::Encoding)?,
|
|
||||||
&[],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This functions wraps the serialization process
|
/// This functions wraps the serialization process
|
||||||
pub fn serialize_data<T: Serialize>(object: &T) -> Result<Vec<u8>, PluginModuleError> {
|
fn serialize_data<T: Serialize>(object: &T) -> Result<Vec<u8>, PluginModuleError> {
|
||||||
bincode::serialize(object).map_err(PluginModuleError::Encoding)
|
bincode::serialize(object).map_err(PluginModuleError::Encoding)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function writes an object to the wasm memory using the allocator if
|
/// This function writes an object to the wasm memory using the allocator if
|
||||||
/// necessary using length padding.
|
/// necessary using length padding.
|
||||||
///
|
///
|
||||||
/// With length padding the first 8 bytes written are the length of the the
|
/// With length padding the first bytes written are the length of the the
|
||||||
/// following slice (The object serialized).
|
/// following slice (The object serialized).
|
||||||
pub fn write_data_as_pointer<T: Serialize>(
|
pub(crate) fn write_serialized_with_length<T: Serialize>(
|
||||||
store: &mut StoreMut,
|
store: &mut StoreMut,
|
||||||
memory: &Memory,
|
memory: &Memory,
|
||||||
allocator: &TypedFunction<
|
allocator: &TypedFunction<
|
||||||
@ -170,7 +142,7 @@ pub fn write_data_as_pointer<T: Serialize>(
|
|||||||
>,
|
>,
|
||||||
object: &T,
|
object: &T,
|
||||||
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
|
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
|
||||||
write_bytes_as_pointer(store, memory, allocator, &serialize_data(object)?)
|
write_length_and_bytes(store, memory, allocator, &serialize_data(object)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function writes an raw bytes to WASM memory returning a pointer and
|
/// This function writes an raw bytes to WASM memory returning a pointer and
|
||||||
@ -179,7 +151,7 @@ pub fn write_data_as_pointer<T: Serialize>(
|
|||||||
/// As this function is often called after prepending a length to an existing
|
/// As this function is often called after prepending a length to an existing
|
||||||
/// object it accepts two slices and concatenates them to cut down copying in
|
/// object it accepts two slices and concatenates them to cut down copying in
|
||||||
/// the caller.
|
/// the caller.
|
||||||
pub fn write_bytes(
|
pub(crate) fn write_bytes(
|
||||||
store: &mut StoreMut,
|
store: &mut StoreMut,
|
||||||
memory: &Memory,
|
memory: &Memory,
|
||||||
allocator: &TypedFunction<
|
allocator: &TypedFunction<
|
||||||
@ -211,9 +183,9 @@ pub fn write_bytes(
|
|||||||
/// This function writes bytes to the wasm memory using the allocator if
|
/// This function writes bytes to the wasm memory using the allocator if
|
||||||
/// necessary using length padding.
|
/// necessary using length padding.
|
||||||
///
|
///
|
||||||
/// With length padding the first 8 bytes written are the length of the the
|
/// With length padding the first bytes written are the length of the the
|
||||||
/// following slice.
|
/// following slice.
|
||||||
pub fn write_bytes_as_pointer(
|
pub(crate) fn write_length_and_bytes(
|
||||||
store: &mut StoreMut,
|
store: &mut StoreMut,
|
||||||
memory: &Memory,
|
memory: &Memory,
|
||||||
allocator: &TypedFunction<
|
allocator: &TypedFunction<
|
||||||
@ -228,7 +200,7 @@ pub fn write_bytes_as_pointer(
|
|||||||
|
|
||||||
/// This function reads data from memory at a position with the array length and
|
/// This function reads data from memory at a position with the array length and
|
||||||
/// converts it to an object using bincode
|
/// converts it to an object using bincode
|
||||||
pub fn read_data<'a, T: for<'b> Deserialize<'b>>(
|
pub(crate) fn read_serialized<'a, T: for<'b> Deserialize<'b>>(
|
||||||
memory: &'a Memory,
|
memory: &'a Memory,
|
||||||
store: &StoreRef,
|
store: &StoreRef,
|
||||||
ptr: WasmPtr<u8, MemoryModel>,
|
ptr: WasmPtr<u8, MemoryModel>,
|
||||||
@ -241,7 +213,7 @@ pub fn read_data<'a, T: for<'b> Deserialize<'b>>(
|
|||||||
|
|
||||||
/// This function reads raw bytes from memory at a position with the array
|
/// This function reads raw bytes from memory at a position with the array
|
||||||
/// length
|
/// length
|
||||||
pub fn read_bytes(
|
pub(crate) fn read_bytes(
|
||||||
memory: &Memory,
|
memory: &Memory,
|
||||||
store: &StoreRef,
|
store: &StoreRef,
|
||||||
ptr: WasmPtr<u8, MemoryModel>,
|
ptr: WasmPtr<u8, MemoryModel>,
|
||||||
@ -253,7 +225,7 @@ pub fn read_bytes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This function reads a constant amount of raw bytes from memory
|
/// This function reads a constant amount of raw bytes from memory
|
||||||
pub fn read_exact_bytes<const N: usize>(
|
pub(crate) fn read_exact_bytes<const N: usize>(
|
||||||
memory: &Memory,
|
memory: &Memory,
|
||||||
store: &StoreRef,
|
store: &StoreRef,
|
||||||
ptr: WasmPtr<u8, MemoryModel>,
|
ptr: WasmPtr<u8, MemoryModel>,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use std::{convert::TryInto, marker::PhantomData, sync::Arc};
|
use std::{marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
imports, AsStoreMut, AsStoreRef, Function, FunctionEnv, FunctionEnvMut, Instance, Memory,
|
imports, AsStoreMut, AsStoreRef, Function, FunctionEnv, FunctionEnvMut, Instance, Memory,
|
||||||
@ -47,13 +47,15 @@ impl PluginModule {
|
|||||||
ptr: WasmPtr<u8, MemoryModel>,
|
ptr: WasmPtr<u8, MemoryModel>,
|
||||||
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||||
) {
|
) {
|
||||||
handle_actions(match env.data().read_data(&env.as_store_ref(), ptr, len) {
|
handle_actions(
|
||||||
Ok(e) => e,
|
match env.data().read_serialized(&env.as_store_ref(), ptr, len) {
|
||||||
Err(e) => {
|
Ok(e) => e,
|
||||||
tracing::error!(?e, "Can't decode action");
|
Err(e) => {
|
||||||
return;
|
tracing::error!(?e, "Can't decode action");
|
||||||
|
return;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_retrieve_action(
|
fn raw_retrieve_action(
|
||||||
@ -62,16 +64,16 @@ impl PluginModule {
|
|||||||
ptr: WasmPtr<u8, MemoryModel>,
|
ptr: WasmPtr<u8, MemoryModel>,
|
||||||
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||||
) -> <MemoryModel as wasmer::MemorySize>::Offset {
|
) -> <MemoryModel as wasmer::MemorySize>::Offset {
|
||||||
let out = match env.data().read_data(&env.as_store_ref(), ptr, len) {
|
let out = match env.data().read_serialized(&env.as_store_ref(), ptr, len) {
|
||||||
Ok(data) => retrieve_action(&env.data().ecs, data),
|
Ok(data) => retrieve_action(&env.data().ecs, data),
|
||||||
Err(e) => Err(RetrieveError::BincodeError(e.to_string())),
|
Err(e) => Err(RetrieveError::BincodeError(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = env.data().clone();
|
let data = env.data().clone();
|
||||||
// If an error happen set the i64 to 0 so the WASM side can tell an error
|
data.write_serialized_with_length(&mut env.as_store_mut(), &out)
|
||||||
// occured
|
.unwrap_or_else(|_e|
|
||||||
data.write_data_as_pointer(&mut env.as_store_mut(), &out)
|
// return a null pointer so the WASM side can tell an error occured
|
||||||
.unwrap_or_else(|_e| WasmPtr::null())
|
WasmPtr::null())
|
||||||
.offset()
|
.offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,28 +185,6 @@ impl<T: Event> PreparedEventQuery<T> {
|
|||||||
pub fn get_function_name(&self) -> &str { &self.function_name }
|
pub fn get_function_name(&self) -> &str { &self.function_name }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function split a u128 in two u64 encoding them as le bytes
|
|
||||||
pub fn from_u128(i: u128) -> (u64, u64) {
|
|
||||||
let i = i.to_le_bytes();
|
|
||||||
(
|
|
||||||
u64::from_le_bytes(i[0..8].try_into().unwrap()),
|
|
||||||
u64::from_le_bytes(i[8..16].try_into().unwrap()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function merge two u64 encoded as le in one u128
|
|
||||||
pub fn to_u128(a: u64, b: u64) -> u128 {
|
|
||||||
let a = a.to_le_bytes();
|
|
||||||
let b = b.to_le_bytes();
|
|
||||||
u128::from_le_bytes([a, b].concat().try_into().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function encode a u64 into a i64 using le bytes
|
|
||||||
pub fn to_i64(i: u64) -> i64 { i64::from_le_bytes(i.to_le_bytes()) }
|
|
||||||
|
|
||||||
/// This function decode a i64 into a u64 using le bytes
|
|
||||||
pub fn from_i64(i: i64) -> u64 { u64::from_le_bytes(i.to_le_bytes()) }
|
|
||||||
|
|
||||||
// This function is not public because this function should not be used without
|
// This function is not public because this function should not be used without
|
||||||
// an interface to limit unsafe behaviours
|
// an interface to limit unsafe behaviours
|
||||||
fn execute_raw(
|
fn execute_raw(
|
||||||
|
@ -65,41 +65,25 @@ impl HostFunctionEnvironment {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn name(&self) -> &str { &self.name }
|
pub fn name(&self) -> &str { &self.name }
|
||||||
|
|
||||||
/// This function is a safe interface to WASM memory that writes data to the
|
/// This function is a safe interface to WASM memory that serializes and
|
||||||
/// memory returning a pointer and length
|
/// writes an object to linear memory returning a pointer
|
||||||
pub fn write_data<T: Serialize>(
|
pub fn write_serialized_with_length<T: Serialize>(
|
||||||
&self,
|
|
||||||
store: &mut StoreMut,
|
|
||||||
object: &T,
|
|
||||||
) -> Result<
|
|
||||||
(
|
|
||||||
WasmPtr<u8, MemoryModel>,
|
|
||||||
<MemoryModel as wasmer::MemorySize>::Offset,
|
|
||||||
),
|
|
||||||
PluginModuleError,
|
|
||||||
> {
|
|
||||||
memory_manager::write_data(store, self.memory(), self.allocator(), object)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function is a safe interface to WASM memory that writes data to the
|
|
||||||
/// memory returning a pointer and length
|
|
||||||
pub fn write_data_as_pointer<T: Serialize>(
|
|
||||||
&self,
|
&self,
|
||||||
store: &mut StoreMut,
|
store: &mut StoreMut,
|
||||||
object: &T,
|
object: &T,
|
||||||
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
|
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
|
||||||
memory_manager::write_data_as_pointer(store, self.memory(), self.allocator(), object)
|
memory_manager::write_serialized_with_length(store, self.memory(), self.allocator(), object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is a safe interface to WASM memory that reads memory from
|
/// This function is a safe interface to WASM memory that reads memory from
|
||||||
/// pointer and length returning an object
|
/// pointer and length returning an object
|
||||||
pub fn read_data<T: DeserializeOwned>(
|
pub fn read_serialized<T: DeserializeOwned>(
|
||||||
&self,
|
&self,
|
||||||
store: &StoreRef,
|
store: &StoreRef,
|
||||||
position: WasmPtr<u8, MemoryModel>,
|
position: WasmPtr<u8, MemoryModel>,
|
||||||
length: <MemoryModel as wasmer::MemorySize>::Offset,
|
length: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||||
) -> Result<T, bincode::Error> {
|
) -> Result<T, bincode::Error> {
|
||||||
memory_manager::read_data(self.memory(), store, position, length)
|
memory_manager::read_serialized(self.memory(), store, position, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is a safe interface to WASM memory that reads memory from
|
/// This function is a safe interface to WASM memory that reads memory from
|
||||||
@ -110,10 +94,7 @@ impl HostFunctionEnvironment {
|
|||||||
ptr: WasmPtr<u8, MemoryModel>,
|
ptr: WasmPtr<u8, MemoryModel>,
|
||||||
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||||
) -> Result<Vec<u8>, PluginModuleError> {
|
) -> Result<Vec<u8>, PluginModuleError> {
|
||||||
self.memory.as_ref().map_or_else(
|
memory_manager::read_bytes(self.memory(), store, ptr, len)
|
||||||
|| Err(PluginModuleError::InvalidPointer),
|
|
||||||
|m| memory_manager::read_bytes(m, store, ptr, len),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn args_from_instance(
|
pub fn args_from_instance(
|
||||||
|
Loading…
Reference in New Issue
Block a user