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,
|
||||
Encoding(Box<ErrorKind>),
|
||||
PluginModuleError(String, String, PluginModuleError),
|
||||
ProcessExit,
|
||||
}
|
||||
|
||||
#[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};
|
||||
// there is no WASI defined for wasm64, yet, so always use 32bit pointers
|
||||
type MemoryModel = wasmer::Memory32;
|
||||
@ -105,6 +105,8 @@ pub(crate) fn wasi_env_get(
|
||||
_environ: WasmPtr<WasmPtr<u8, MemoryModel>, MemoryModel>,
|
||||
_environ_buf: WasmPtr<u8, MemoryModel>,
|
||||
) -> 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
|
||||
}
|
||||
|
||||
@ -118,14 +120,18 @@ pub(crate) fn wasi_env_sizes_get(
|
||||
let memory = env.data().memory().clone();
|
||||
let store = env.as_store_mut();
|
||||
let mem = memory.view(&store);
|
||||
const NUMBER_OF_ENVIRONMENT_ENTRIES: u32 = 0;
|
||||
const NUMBER_OF_ENVIRONMENT_BYTES: u32 = 0;
|
||||
numptr
|
||||
.write(&mem, 0)
|
||||
.and_then(|()| bytesptr.write(&mem, 0))
|
||||
.map(|()| Errno::Success)
|
||||
.unwrap_or(Errno::Memviolation) as i32
|
||||
.write(&mem, NUMBER_OF_ENVIRONMENT_ENTRIES)
|
||||
.and_then(|()| bytesptr.write(&mem, NUMBER_OF_ENVIRONMENT_BYTES))
|
||||
.map_or(Errno::Memviolation, |()| Errno::Success) as i32
|
||||
}
|
||||
|
||||
// proc_exit(rval: exitcode)
|
||||
pub(crate) fn wasi_proc_exit(env: FunctionEnvMut<HostFunctionEnvironment>, _exitcode: i32) {
|
||||
tracing::warn!("Plugin {} called exit().", env.data().name)
|
||||
pub(crate) fn wasi_proc_exit(
|
||||
_env: FunctionEnvMut<HostFunctionEnvironment>,
|
||||
exitcode: i32,
|
||||
) -> Result<(), HostFunctionException> {
|
||||
Err(HostFunctionException::ProcessExit(exitcode))
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ use self::{
|
||||
errors::PluginError,
|
||||
memory_manager::EcsWorld,
|
||||
module::{PluginModule, PreparedEventQuery},
|
||||
wasm_env::HostFunctionException,
|
||||
};
|
||||
|
||||
use rayon::prelude::*;
|
||||
@ -102,6 +103,24 @@ impl Plugin {
|
||||
.flat_map(|module| {
|
||||
module.try_execute(ecs, event).map(|x| {
|
||||
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(
|
||||
self.data.name.to_owned(),
|
||||
event.get_function_name().to_owned(),
|
||||
@ -111,6 +130,13 @@ impl Plugin {
|
||||
})
|
||||
})
|
||||
.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,
|
||||
#[allow(dead_code)]
|
||||
name: String,
|
||||
pub(crate) exit_code: Option<i32>,
|
||||
}
|
||||
|
||||
impl PluginModule {
|
||||
@ -125,6 +126,7 @@ impl PluginModule {
|
||||
wasm_state: Arc::new(instance),
|
||||
store,
|
||||
name,
|
||||
exit_code: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -151,6 +153,8 @@ impl PluginModule {
|
||||
};
|
||||
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
|
||||
|
@ -26,6 +26,19 @@ pub struct HostFunctionEnvironmentInit {
|
||||
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 {
|
||||
pub fn new(name: String, ecs: Arc<EcsAccessManager>) -> Self {
|
||||
Self {
|
||||
|
Loading…
Reference in New Issue
Block a user