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
|
||||
/// probably optimizations that can be done using less restrictive
|
||||
/// ordering
|
||||
pub fn get_pointer(
|
||||
fn get_pointer(
|
||||
store: &mut StoreMut,
|
||||
object_length: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||
allocator: &TypedFunction<
|
||||
@ -123,45 +123,17 @@ pub fn get_pointer(
|
||||
.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
|
||||
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)
|
||||
}
|
||||
|
||||
/// This function writes an object to the wasm memory using the allocator if
|
||||
/// 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).
|
||||
pub fn write_data_as_pointer<T: Serialize>(
|
||||
pub(crate) fn write_serialized_with_length<T: Serialize>(
|
||||
store: &mut StoreMut,
|
||||
memory: &Memory,
|
||||
allocator: &TypedFunction<
|
||||
@ -170,7 +142,7 @@ pub fn write_data_as_pointer<T: Serialize>(
|
||||
>,
|
||||
object: &T,
|
||||
) -> 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
|
||||
@ -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
|
||||
/// object it accepts two slices and concatenates them to cut down copying in
|
||||
/// the caller.
|
||||
pub fn write_bytes(
|
||||
pub(crate) fn write_bytes(
|
||||
store: &mut StoreMut,
|
||||
memory: &Memory,
|
||||
allocator: &TypedFunction<
|
||||
@ -211,9 +183,9 @@ pub fn write_bytes(
|
||||
/// This function writes bytes to the wasm memory using the allocator if
|
||||
/// 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.
|
||||
pub fn write_bytes_as_pointer(
|
||||
pub(crate) fn write_length_and_bytes(
|
||||
store: &mut StoreMut,
|
||||
memory: &Memory,
|
||||
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
|
||||
/// 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,
|
||||
store: &StoreRef,
|
||||
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
|
||||
/// length
|
||||
pub fn read_bytes(
|
||||
pub(crate) fn read_bytes(
|
||||
memory: &Memory,
|
||||
store: &StoreRef,
|
||||
ptr: WasmPtr<u8, MemoryModel>,
|
||||
@ -253,7 +225,7 @@ pub fn read_bytes(
|
||||
}
|
||||
|
||||
/// 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,
|
||||
store: &StoreRef,
|
||||
ptr: WasmPtr<u8, MemoryModel>,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use hashbrown::HashSet;
|
||||
use std::{convert::TryInto, marker::PhantomData, sync::Arc};
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
use wasmer::{
|
||||
imports, AsStoreMut, AsStoreRef, Function, FunctionEnv, FunctionEnvMut, Instance, Memory,
|
||||
@ -47,13 +47,15 @@ impl PluginModule {
|
||||
ptr: WasmPtr<u8, MemoryModel>,
|
||||
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||
) {
|
||||
handle_actions(match env.data().read_data(&env.as_store_ref(), ptr, len) {
|
||||
Ok(e) => e,
|
||||
Err(e) => {
|
||||
tracing::error!(?e, "Can't decode action");
|
||||
return;
|
||||
handle_actions(
|
||||
match env.data().read_serialized(&env.as_store_ref(), ptr, len) {
|
||||
Ok(e) => e,
|
||||
Err(e) => {
|
||||
tracing::error!(?e, "Can't decode action");
|
||||
return;
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
fn raw_retrieve_action(
|
||||
@ -62,16 +64,16 @@ impl PluginModule {
|
||||
ptr: WasmPtr<u8, MemoryModel>,
|
||||
len: <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),
|
||||
Err(e) => Err(RetrieveError::BincodeError(e.to_string())),
|
||||
};
|
||||
|
||||
let data = env.data().clone();
|
||||
// If an error happen set the i64 to 0 so the WASM side can tell an error
|
||||
// occured
|
||||
data.write_data_as_pointer(&mut env.as_store_mut(), &out)
|
||||
.unwrap_or_else(|_e| WasmPtr::null())
|
||||
data.write_serialized_with_length(&mut env.as_store_mut(), &out)
|
||||
.unwrap_or_else(|_e|
|
||||
// return a null pointer so the WASM side can tell an error occured
|
||||
WasmPtr::null())
|
||||
.offset()
|
||||
}
|
||||
|
||||
@ -183,28 +185,6 @@ impl<T: Event> PreparedEventQuery<T> {
|
||||
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
|
||||
// an interface to limit unsafe behaviours
|
||||
fn execute_raw(
|
||||
|
@ -65,41 +65,25 @@ impl HostFunctionEnvironment {
|
||||
#[inline]
|
||||
pub fn name(&self) -> &str { &self.name }
|
||||
|
||||
/// This function is a safe interface to WASM memory that writes data to the
|
||||
/// memory returning a pointer and length
|
||||
pub fn write_data<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>(
|
||||
/// This function is a safe interface to WASM memory that serializes and
|
||||
/// writes an object to linear memory returning a pointer
|
||||
pub fn write_serialized_with_length<T: Serialize>(
|
||||
&self,
|
||||
store: &mut StoreMut,
|
||||
object: &T,
|
||||
) -> 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
|
||||
/// pointer and length returning an object
|
||||
pub fn read_data<T: DeserializeOwned>(
|
||||
pub fn read_serialized<T: DeserializeOwned>(
|
||||
&self,
|
||||
store: &StoreRef,
|
||||
position: WasmPtr<u8, MemoryModel>,
|
||||
length: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||
) -> 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
|
||||
@ -110,10 +94,7 @@ impl HostFunctionEnvironment {
|
||||
ptr: WasmPtr<u8, MemoryModel>,
|
||||
len: <MemoryModel as wasmer::MemorySize>::Offset,
|
||||
) -> Result<Vec<u8>, PluginModuleError> {
|
||||
self.memory.as_ref().map_or_else(
|
||||
|| Err(PluginModuleError::InvalidPointer),
|
||||
|m| memory_manager::read_bytes(m, store, ptr, len),
|
||||
)
|
||||
memory_manager::read_bytes(self.memory(), store, ptr, len)
|
||||
}
|
||||
|
||||
pub fn args_from_instance(
|
||||
|
Loading…
Reference in New Issue
Block a user