mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
address more of zesterer's proposals and implement process exit removing the binary
This commit is contained in:
parent
43f7bb7ddc
commit
65966294a0
@ -9,6 +9,7 @@ pub enum PluginError {
|
|||||||
NoSuchModule,
|
NoSuchModule,
|
||||||
Encoding(Box<ErrorKind>),
|
Encoding(Box<ErrorKind>),
|
||||||
PluginModuleError(String, String, PluginModuleError),
|
PluginModuleError(String, String, PluginModuleError),
|
||||||
|
ProcessExit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::plugin::wasm_env::HostFunctionEnvironment;
|
use crate::plugin::wasm_env::{HostFunctionEnvironment, HostFunctionException};
|
||||||
use wasmer::{AsStoreMut, AsStoreRef, FunctionEnvMut, Memory32, Memory64, MemorySize, WasmPtr};
|
use wasmer::{AsStoreMut, AsStoreRef, FunctionEnvMut, Memory32, Memory64, MemorySize, WasmPtr};
|
||||||
// there is no WASI defined for wasm64, yet, so always use 32bit pointers
|
// there is no WASI defined for wasm64, yet, so always use 32bit pointers
|
||||||
type MemoryModel = wasmer::Memory32;
|
type MemoryModel = wasmer::Memory32;
|
||||||
@ -105,6 +105,8 @@ pub(crate) fn wasi_env_get(
|
|||||||
_environ: WasmPtr<WasmPtr<u8, MemoryModel>, MemoryModel>,
|
_environ: WasmPtr<WasmPtr<u8, MemoryModel>, MemoryModel>,
|
||||||
_environ_buf: WasmPtr<u8, MemoryModel>,
|
_environ_buf: WasmPtr<u8, MemoryModel>,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
|
// as the environment is always empty (0 bytes, 0 entries) this function will
|
||||||
|
// just unconditionally return Success.
|
||||||
wasmer_wasix_types::wasi::Errno::Success as i32
|
wasmer_wasix_types::wasi::Errno::Success as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,14 +120,18 @@ pub(crate) fn wasi_env_sizes_get(
|
|||||||
let memory = env.data().memory().clone();
|
let memory = env.data().memory().clone();
|
||||||
let store = env.as_store_mut();
|
let store = env.as_store_mut();
|
||||||
let mem = memory.view(&store);
|
let mem = memory.view(&store);
|
||||||
|
const NUMBER_OF_ENVIRONMENT_ENTRIES: u32 = 0;
|
||||||
|
const NUMBER_OF_ENVIRONMENT_BYTES: u32 = 0;
|
||||||
numptr
|
numptr
|
||||||
.write(&mem, 0)
|
.write(&mem, NUMBER_OF_ENVIRONMENT_ENTRIES)
|
||||||
.and_then(|()| bytesptr.write(&mem, 0))
|
.and_then(|()| bytesptr.write(&mem, NUMBER_OF_ENVIRONMENT_BYTES))
|
||||||
.map(|()| Errno::Success)
|
.map_or(Errno::Memviolation, |()| Errno::Success) as i32
|
||||||
.unwrap_or(Errno::Memviolation) as i32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// proc_exit(rval: exitcode)
|
// proc_exit(rval: exitcode)
|
||||||
pub(crate) fn wasi_proc_exit(env: FunctionEnvMut<HostFunctionEnvironment>, _exitcode: i32) {
|
pub(crate) fn wasi_proc_exit(
|
||||||
tracing::warn!("Plugin {} called exit().", env.data().name)
|
_env: FunctionEnvMut<HostFunctionEnvironment>,
|
||||||
|
exitcode: i32,
|
||||||
|
) -> Result<(), HostFunctionException> {
|
||||||
|
Err(HostFunctionException::ProcessExit(exitcode))
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use self::{
|
|||||||
errors::PluginError,
|
errors::PluginError,
|
||||||
memory_manager::EcsWorld,
|
memory_manager::EcsWorld,
|
||||||
module::{PluginModule, PreparedEventQuery},
|
module::{PluginModule, PreparedEventQuery},
|
||||||
|
wasm_env::HostFunctionException,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
@ -102,6 +103,24 @@ impl Plugin {
|
|||||||
.flat_map(|module| {
|
.flat_map(|module| {
|
||||||
module.try_execute(ecs, event).map(|x| {
|
module.try_execute(ecs, event).map(|x| {
|
||||||
x.map_err(|e| {
|
x.map_err(|e| {
|
||||||
|
if let errors::PluginModuleError::RunFunction(runtime_err) = &e {
|
||||||
|
if let Some(host_except) =
|
||||||
|
runtime_err.downcast_ref::<HostFunctionException>()
|
||||||
|
{
|
||||||
|
match host_except {
|
||||||
|
HostFunctionException::ProcessExit(code) => {
|
||||||
|
module.exit_code = Some(*code);
|
||||||
|
tracing::warn!(
|
||||||
|
"Module {} binary {} exited with {}",
|
||||||
|
self.data.name,
|
||||||
|
module.name(),
|
||||||
|
*code
|
||||||
|
);
|
||||||
|
return PluginError::ProcessExit;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
PluginError::PluginModuleError(
|
PluginError::PluginModuleError(
|
||||||
self.data.name.to_owned(),
|
self.data.name.to_owned(),
|
||||||
event.get_function_name().to_owned(),
|
event.get_function_name().to_owned(),
|
||||||
@ -111,6 +130,13 @@ impl Plugin {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map_err(|e| {
|
||||||
|
if matches!(e, PluginError::ProcessExit) {
|
||||||
|
// remove the executable from the module which called process exit
|
||||||
|
self.modules.retain(|m| m.exit_code.is_none())
|
||||||
|
}
|
||||||
|
e
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ pub struct PluginModule {
|
|||||||
store: Store,
|
store: Store,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
name: String,
|
name: String,
|
||||||
|
pub(crate) exit_code: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PluginModule {
|
impl PluginModule {
|
||||||
@ -125,6 +126,7 @@ impl PluginModule {
|
|||||||
wasm_state: Arc::new(instance),
|
wasm_state: Arc::new(instance),
|
||||||
store,
|
store,
|
||||||
name,
|
name,
|
||||||
|
exit_code: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +153,8 @@ impl PluginModule {
|
|||||||
};
|
};
|
||||||
Some(bincode::deserialize(&bytes).map_err(PluginModuleError::Encoding))
|
Some(bincode::deserialize(&bytes).map_err(PluginModuleError::Encoding))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str { &self.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This structure represent a Pre-encoded event object (Useful to avoid
|
/// This structure represent a Pre-encoded event object (Useful to avoid
|
||||||
|
@ -26,6 +26,19 @@ pub struct HostFunctionEnvironmentInit {
|
|||||||
memory: Memory,
|
memory: Memory,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
// Exception thrown from a native wasm callback
|
||||||
|
pub enum HostFunctionException {
|
||||||
|
ProcessExit(i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
// needed for `std::error::Error`
|
||||||
|
impl core::fmt::Display for HostFunctionException {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{:?}", self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for HostFunctionException {}
|
||||||
|
|
||||||
impl HostFunctionEnvironment {
|
impl HostFunctionEnvironment {
|
||||||
pub fn new(name: String, ecs: Arc<EcsAccessManager>) -> Self {
|
pub fn new(name: String, ecs: Arc<EcsAccessManager>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user