diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-24 17:39:08 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-24 17:41:41 +0100 |
| commit | 8d3c68a1deb28dce2b80ed61f85141180ce6a951 (patch) | |
| tree | de007203d448d6b6a2df7838e802f85d23ccd1a6 /src/model | |
| parent | 5ae81971f299688b05d77af208d7bb44ffce5e2d (diff) | |
Protect Vm
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/array.rs | 12 | ||||
| -rw-r--r-- | src/model/content.rs | 2 | ||||
| -rw-r--r-- | src/model/dict.rs | 2 | ||||
| -rw-r--r-- | src/model/eval.rs | 2 | ||||
| -rw-r--r-- | src/model/func.rs | 12 | ||||
| -rw-r--r-- | src/model/methods.rs | 2 | ||||
| -rw-r--r-- | src/model/scope.rs | 2 | ||||
| -rw-r--r-- | src/model/vm.rs | 20 |
8 files changed, 31 insertions, 23 deletions
diff --git a/src/model/array.rs b/src/model/array.rs index 40b063e2..5a2f8672 100644 --- a/src/model/array.rs +++ b/src/model/array.rs @@ -128,7 +128,7 @@ impl Array { } /// Return the first matching element. - pub fn find(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<Option<Value>> { + pub fn find(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<Option<Value>> { for item in self.iter() { let args = Args::new(f.span, [item.clone()]); if f.v.call(vm, args)?.cast::<bool>().at(f.span)? { @@ -140,7 +140,7 @@ impl Array { } /// Return the index of the first matching element. - pub fn position(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<Option<i64>> { + pub fn position(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<Option<i64>> { for (i, item) in self.iter().enumerate() { let args = Args::new(f.span, [item.clone()]); if f.v.call(vm, args)?.cast::<bool>().at(f.span)? { @@ -153,7 +153,7 @@ impl Array { /// Return a new array with only those elements for which the function /// returns true. - pub fn filter(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<Self> { + pub fn filter(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<Self> { let mut kept = vec![]; for item in self.iter() { let args = Args::new(f.span, [item.clone()]); @@ -165,7 +165,7 @@ impl Array { } /// Transform each item in the array with a function. - pub fn map(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<Self> { + pub fn map(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<Self> { let enumerate = f.v.argc() == Some(2); self.iter() .enumerate() @@ -181,7 +181,7 @@ impl Array { } /// Whether any element matches. - pub fn any(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<bool> { + pub fn any(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<bool> { for item in self.iter() { let args = Args::new(f.span, [item.clone()]); if f.v.call(vm, args)?.cast::<bool>().at(f.span)? { @@ -193,7 +193,7 @@ impl Array { } /// Whether all elements match. - pub fn all(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<bool> { + pub fn all(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<bool> { for item in self.iter() { let args = Args::new(f.span, [item.clone()]); if !f.v.call(vm, args)?.cast::<bool>().at(f.span)? { diff --git a/src/model/content.rs b/src/model/content.rs index 9d78020c..90df5a4e 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -362,7 +362,7 @@ pub trait Node: 'static + Capable { /// /// This is passed only the arguments that remain after execution of the /// node's set rule. - fn construct(vm: &mut Vm, args: &mut Args) -> SourceResult<Content> + fn construct(vm: &Vm, args: &mut Args) -> SourceResult<Content> where Self: Sized; diff --git a/src/model/dict.rs b/src/model/dict.rs index 49e50aa0..270c2c9c 100644 --- a/src/model/dict.rs +++ b/src/model/dict.rs @@ -105,7 +105,7 @@ impl Dict { } /// Transform each pair in the array with a function. - pub fn map(&self, vm: &mut Vm, f: Spanned<Func>) -> SourceResult<Array> { + pub fn map(&self, vm: &Vm, f: Spanned<Func>) -> SourceResult<Array> { self.iter() .map(|(key, value)| { let args = Args::new(f.span, [Value::Str(key.clone()), value.clone()]); diff --git a/src/model/eval.rs b/src/model/eval.rs index fb1bd121..e68f6e7a 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -1030,7 +1030,7 @@ impl Eval for ast::ModuleInclude { } /// Process an import of a module relative to the current location. -fn import(vm: &mut Vm, path: &str, span: Span) -> SourceResult<Module> { +fn import(vm: &Vm, path: &str, span: Span) -> SourceResult<Module> { // Load the source file. let full = vm.locate(path).at(span)?; let id = vm.world.resolve(&full).at(span)?; diff --git a/src/model/func.rs b/src/model/func.rs index d84a8170..c0431ac6 100644 --- a/src/model/func.rs +++ b/src/model/func.rs @@ -32,7 +32,7 @@ impl Func { /// Create a new function from a native rust function. pub fn from_fn( name: &'static str, - func: fn(&mut Vm, &mut Args) -> SourceResult<Value>, + func: fn(&Vm, &mut Args) -> SourceResult<Value>, ) -> Self { Self(Arc::new(Repr::Native(Native { name, func, set: None, node: None }))) } @@ -77,7 +77,7 @@ impl Func { } /// Call the function with the given arguments. - pub fn call(&self, vm: &mut Vm, mut args: Args) -> SourceResult<Value> { + pub fn call(&self, vm: &Vm, mut args: Args) -> SourceResult<Value> { let value = match self.0.as_ref() { Repr::Native(native) => (native.func)(vm, &mut args)?, Repr::Closure(closure) => closure.call(vm, &mut args)?, @@ -99,8 +99,8 @@ impl Func { let route = Route::default(); let id = SourceId::detached(); let scopes = Scopes::new(None); - let mut vm = Vm::new(world, route.track(), id, scopes); - self.call(&mut vm, args) + let vm = Vm::new(world, route.track(), id, scopes); + self.call(&vm, args) } /// Apply the given arguments to the function. @@ -160,7 +160,7 @@ struct Native { /// The name of the function. pub name: &'static str, /// The function pointer. - pub func: fn(&mut Vm, &mut Args) -> SourceResult<Value>, + pub func: fn(&Vm, &mut Args) -> SourceResult<Value>, /// The set rule. pub set: Option<fn(&mut Args) -> SourceResult<StyleMap>>, /// The id of the node to customize with this function's show rule. @@ -196,7 +196,7 @@ pub struct Closure { impl Closure { /// Call the function in the context with the arguments. - pub fn call(&self, vm: &mut Vm, args: &mut Args) -> SourceResult<Value> { + pub fn call(&self, vm: &Vm, args: &mut Args) -> SourceResult<Value> { // Don't leak the scopes from the call site. Instead, we use the scope // of captured variables we collected earlier. let mut scopes = Scopes::new(None); diff --git a/src/model/methods.rs b/src/model/methods.rs index 5f879eeb..c5c12ed2 100644 --- a/src/model/methods.rs +++ b/src/model/methods.rs @@ -7,7 +7,7 @@ use crate::util::EcoString; /// Call a method on a value. pub fn call( - vm: &mut Vm, + vm: &Vm, value: Value, method: &str, mut args: Args, diff --git a/src/model/scope.rs b/src/model/scope.rs index 1ab7032c..d21d0587 100644 --- a/src/model/scope.rs +++ b/src/model/scope.rs @@ -78,7 +78,7 @@ impl Scope { pub fn def_fn( &mut self, name: &'static str, - func: fn(&mut Vm, &mut Args) -> SourceResult<Value>, + func: fn(&Vm, &mut Args) -> SourceResult<Value>, ) { self.define(name, Func::from_fn(name, func)); } diff --git a/src/model/vm.rs b/src/model/vm.rs index d13be29c..d3509eae 100644 --- a/src/model/vm.rs +++ b/src/model/vm.rs @@ -9,19 +9,22 @@ use crate::util::PathExt; use crate::World; /// A virtual machine. +/// +/// Holds the state needed to evaluate Typst sources. A new virtual machine is +/// created for each module evaluation and function call. pub struct Vm<'a> { /// The core context. - pub world: Tracked<'a, dyn World>, + pub(crate) world: Tracked<'a, dyn World>, /// The route of source ids the VM took to reach its current location. - pub route: Tracked<'a, Route>, + pub(crate) route: Tracked<'a, Route>, /// The current location. - pub location: SourceId, + pub(crate) location: SourceId, /// The stack of scopes. - pub scopes: Scopes<'a>, + pub(crate) scopes: Scopes<'a>, /// A control flow event that is currently happening. - pub flow: Option<Flow>, + pub(crate) flow: Option<Flow>, /// The language items. - pub items: LangItems, + pub(crate) items: LangItems, } impl<'a> Vm<'a> { @@ -42,6 +45,11 @@ impl<'a> Vm<'a> { } } + /// Access the underlying world. + pub fn world(&self) -> Tracked<dyn World> { + self.world + } + /// Resolve a user-entered path to be relative to the compilation /// environment's root. pub fn locate(&self, path: &str) -> StrResult<PathBuf> { |
