mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 17:32:42 -06:00
Plug-ins: a call with nothing to make it fails the run
vc_call returning -11 (from the start function, or in a run that can't make calls) now fails the run like every other code, so a plug-in that ignores it can't report success for a call that never ran. Calls are allowed once the module has loaded, so a start-function call gets -11 instead of trapping.
This commit is contained in:
@@ -122,7 +122,7 @@ pub const CALL_LIMIT: i32 = -9;
|
||||
/// What `vc_call_result` returns: no call has a result yet.
|
||||
pub const CALL_NO_RESULT: i32 = -10;
|
||||
/// What `vc_call` returns: nothing can be called now (while the module is being loaded, or in a
|
||||
/// run that isn't a filter's run on a document).
|
||||
/// run that isn't a filter's run on a document). In a run, this fails it too.
|
||||
pub const CALL_NO_CONTEXT: i32 = -11;
|
||||
|
||||
/// Most `vc_call` calls one run makes.
|
||||
@@ -370,8 +370,8 @@ pub(crate) struct Run {
|
||||
storage: Option<Arc<dyn Storage>>,
|
||||
storage_calls: usize,
|
||||
storage_bytes: usize,
|
||||
/// The commands `vc_call` may run (the manifest's `commandAllowlist`), when the run has
|
||||
/// something to run them ([`Run::with_calls`]); `None` otherwise.
|
||||
/// The commands `vc_call` may run (the manifest's `commandAllowlist`), once the module has
|
||||
/// loaded and when the run has something to run them ([`Run::allow_calls`]); `None` otherwise.
|
||||
allowed: Option<Vec<String>>,
|
||||
/// How many `vc_call` calls the run made, and the bytes of arguments and results they moved.
|
||||
calls: usize,
|
||||
@@ -416,10 +416,9 @@ impl Run {
|
||||
self
|
||||
}
|
||||
|
||||
/// The run, with `vc_call` running the commands in `allowed`.
|
||||
pub(crate) fn with_calls(mut self, allowed: Vec<String>) -> Self {
|
||||
/// From now on, `vc_call` runs the commands in `allowed`.
|
||||
pub(crate) fn allow_calls(&mut self, allowed: Vec<String>) {
|
||||
self.allowed = Some(allowed);
|
||||
self
|
||||
}
|
||||
|
||||
/// Records the run's first failed call, `e`, and returns `code`.
|
||||
@@ -434,7 +433,8 @@ impl Run {
|
||||
fn call_request(&mut self, memory: &[u8], id: (usize, usize), args: (usize, usize)) -> std::result::Result<(), i32> {
|
||||
self.call_result = None;
|
||||
if self.allowed.is_none() {
|
||||
return Err(CALL_NO_CONTEXT);
|
||||
let why = "vc_call: no command can be called here (while the module loads, or in a run that can't make calls)";
|
||||
return Err(self.fail(CALL_NO_CONTEXT, Error::Abi(why.into())));
|
||||
}
|
||||
let shown = || {
|
||||
id.0.checked_add(id.1)
|
||||
|
||||
@@ -372,11 +372,12 @@ impl Plugin {
|
||||
total.ok_or_else(|| Error::Limit(SELECTION_TOO_LARGE.into()))?;
|
||||
let deadline = Deadline::new(limits.wall_time_ms);
|
||||
let m = &self.manifest;
|
||||
let mut run = Run::new(&m.id, m.kind != Kind::Effect, true, deadline).with_storage(crate::registry::storage(&m.id));
|
||||
if bridge.is_some() {
|
||||
run = run.with_calls(m.command_allowlist.clone());
|
||||
}
|
||||
let run = Run::new(&m.id, m.kind != Kind::Effect, true, deadline).with_storage(crate::registry::storage(&m.id));
|
||||
let mut live = self.instantiate(run, &m.permissions(), report)?;
|
||||
// Calls can be made from `vc_run` on, not from the start function.
|
||||
if bridge.is_some() {
|
||||
live.store.data_mut().run.allow_calls(m.command_allowlist.clone());
|
||||
}
|
||||
let out = self.run_live(&mut live, input, params, limits, &deadline, bridge);
|
||||
let state = &mut live.store.data_mut().run;
|
||||
*report = std::mem::take(&mut state.report);
|
||||
|
||||
Reference in New Issue
Block a user