Move deps from context to VM

This commit is contained in:
Laurenz 2022-05-25 14:13:01 +02:00
parent c010cbc17d
commit 30fdba4356
7 changed files with 29 additions and 26 deletions

View File

@ -4,7 +4,6 @@ use std::sync::Arc;
use iai::{black_box, main, Iai}; use iai::{black_box, main, Iai};
use unscanny::Scanner; use unscanny::Scanner;
use typst::eval::evaluate;
use typst::loading::MemLoader; use typst::loading::MemLoader;
use typst::parse::{TokenMode, Tokens}; use typst::parse::{TokenMode, Tokens};
use typst::source::SourceId; use typst::source::SourceId;
@ -88,7 +87,7 @@ fn bench_eval(iai: &mut Iai) {
fn bench_layout(iai: &mut Iai) { fn bench_layout(iai: &mut Iai) {
let (mut ctx, id) = context(); let (mut ctx, id) = context();
let module = evaluate(&mut ctx, id, vec![]).unwrap(); let module = typst::eval::evaluate(&mut ctx, id, vec![]).unwrap();
iai.run(|| typst::model::layout(&mut ctx, &module.content)); iai.run(|| typst::model::layout(&mut ctx, &module.content));
} }

View File

@ -230,6 +230,7 @@ impl Closure {
// Evaluate the body. // Evaluate the body.
let mut sub = Machine::new(vm.ctx, route, scopes); let mut sub = Machine::new(vm.ctx, route, scopes);
let result = self.body.eval(&mut sub); let result = self.body.eval(&mut sub);
vm.deps.extend(sub.deps);
// Handle control flow. // Handle control flow.
match sub.flow { match sub.flow {

View File

@ -13,6 +13,8 @@ pub struct Machine<'a> {
pub ctx: &'a mut Context, pub ctx: &'a mut Context,
/// The route of source ids at which the machine is located. /// The route of source ids at which the machine is located.
pub route: Vec<SourceId>, pub route: Vec<SourceId>,
/// The dependencies of the current evaluation process.
pub deps: Vec<(SourceId, usize)>,
/// The stack of scopes. /// The stack of scopes.
pub scopes: Scopes<'a>, pub scopes: Scopes<'a>,
/// A control flow event that is currently happening. /// A control flow event that is currently happening.
@ -22,7 +24,13 @@ pub struct Machine<'a> {
impl<'a> Machine<'a> { impl<'a> Machine<'a> {
/// Create a new virtual machine. /// Create a new virtual machine.
pub fn new(ctx: &'a mut Context, route: Vec<SourceId>, scopes: Scopes<'a>) -> Self { pub fn new(ctx: &'a mut Context, route: Vec<SourceId>, scopes: Scopes<'a>) -> Self {
Self { ctx, route, scopes, flow: None } Self {
ctx,
route,
deps: vec![],
scopes,
flow: None,
}
} }
/// Resolve a user-entered path to be relative to the compilation /// Resolve a user-entered path to be relative to the compilation

View File

@ -73,28 +73,26 @@ pub fn evaluate(
// Parse the file. // Parse the file.
let source = ctx.sources.get(id); let source = ctx.sources.get(id);
let ast = source.ast()?; let ast = source.ast()?;
let rev = source.rev();
// Save the old dependencies.
let prev_deps = std::mem::replace(&mut ctx.deps, vec![(id, source.rev())]);
// Evaluate the module. // Evaluate the module.
let std = ctx.config.std.clone(); let std = ctx.config.std.clone();
let scopes = Scopes::new(Some(&std)); let scopes = Scopes::new(Some(&std));
let mut vm = Machine::new(ctx, route, scopes); let mut vm = Machine::new(ctx, route, scopes);
let result = ast.eval(&mut vm); let result = ast.eval(&mut vm);
let scope = vm.scopes.top; vm.deps.push((id, rev));
let flow = vm.flow;
// Restore the and dependencies.
let deps = std::mem::replace(&mut ctx.deps, prev_deps);
// Handle control flow. // Handle control flow.
if let Some(flow) = flow { if let Some(flow) = vm.flow {
return Err(flow.forbidden()); return Err(flow.forbidden());
} }
// Assemble the module. // Assemble the module.
let module = Module { scope, content: result?, deps }; let module = Module {
scope: vm.scopes.top,
content: result?,
deps: vm.deps,
};
// Save the evaluated module. // Save the evaluated module.
ctx.modules.insert(id, module.clone()); ctx.modules.insert(id, module.clone());
@ -987,7 +985,8 @@ fn import(vm: &mut Machine, path: &str, span: Span) -> TypResult<Module> {
// Evaluate the file. // Evaluate the file.
let route = vm.route.clone(); let route = vm.route.clone();
let module = evaluate(vm.ctx, id, route).trace(|| Tracepoint::Import, span)?; let module = evaluate(vm.ctx, id, route).trace(|| Tracepoint::Import, span)?;
vm.ctx.deps.extend(module.deps.iter().cloned()); vm.deps.extend(module.deps.iter().cloned());
Ok(module) Ok(module)
} }

View File

@ -76,30 +76,27 @@ pub fn typeset(ctx: &mut Context, id: SourceId) -> TypResult<Vec<Arc<Frame>>> {
/// The core context which holds the configuration and stores. /// The core context which holds the configuration and stores.
pub struct Context { pub struct Context {
/// The context's configuration.
pub config: Config,
/// Stores loaded source files. /// Stores loaded source files.
pub sources: SourceStore, pub sources: SourceStore,
/// Stores parsed font faces. /// Stores parsed font faces.
pub fonts: FontStore, pub fonts: FontStore,
/// Stores decoded images. /// Stores decoded images.
pub images: ImageStore, pub images: ImageStore,
/// The context's configuration. /// Stores evaluated modules.
pub config: Config, pub modules: HashMap<SourceId, Module>,
/// Cached modules.
modules: HashMap<SourceId, Module>,
/// The dependencies of the current evaluation process.
deps: Vec<(SourceId, usize)>,
} }
impl Context { impl Context {
/// Create a new context. /// Create a new context.
pub fn new(loader: Arc<dyn Loader>, config: Config) -> Self { pub fn new(loader: Arc<dyn Loader>, config: Config) -> Self {
Self { Self {
config,
sources: SourceStore::new(Arc::clone(&loader)), sources: SourceStore::new(Arc::clone(&loader)),
fonts: FontStore::new(Arc::clone(&loader)), fonts: FontStore::new(Arc::clone(&loader)),
images: ImageStore::new(loader), images: ImageStore::new(loader),
config,
modules: HashMap::new(), modules: HashMap::new(),
deps: vec![],
} }
} }
} }

View File

@ -39,6 +39,7 @@ pub fn eval(vm: &mut Machine, args: &mut Args) -> TypResult<Value> {
let scopes = Scopes::new(Some(&std)); let scopes = Scopes::new(Some(&std));
let mut sub = Machine::new(vm.ctx, vec![], scopes); let mut sub = Machine::new(vm.ctx, vec![], scopes);
let result = ast.eval(&mut sub); let result = ast.eval(&mut sub);
assert!(vm.deps.is_empty());
// Handle control flow. // Handle control flow.
if let Some(flow) = sub.flow { if let Some(flow) = sub.flow {

View File

@ -11,13 +11,11 @@ use same_file::is_same_file;
use termcolor::{ColorChoice, StandardStream, WriteColor}; use termcolor::{ColorChoice, StandardStream, WriteColor};
use typst::diag::{Error, StrResult}; use typst::diag::{Error, StrResult};
use typst::export;
use typst::font::{FaceInfo, FontStore}; use typst::font::{FaceInfo, FontStore};
use typst::library::text::THEME; use typst::library::text::THEME;
use typst::loading::FsLoader; use typst::loading::FsLoader;
use typst::parse::TokenMode; use typst::parse::TokenMode;
use typst::source::SourceStore; use typst::source::SourceStore;
use typst::syntax;
use typst::{Config, Context}; use typst::{Config, Context};
/// What to do. /// What to do.
@ -217,7 +215,7 @@ fn typeset(command: TypesetCommand) -> StrResult<()> {
match typst::typeset(&mut ctx, id) { match typst::typeset(&mut ctx, id) {
// Export the PDF. // Export the PDF.
Ok(frames) => { Ok(frames) => {
let buffer = export::pdf(&ctx, &frames); let buffer = typst::export::pdf(&ctx, &frames);
fs::write(&command.output, buffer).map_err(|_| "failed to write PDF file")?; fs::write(&command.output, buffer).map_err(|_| "failed to write PDF file")?;
} }
@ -266,7 +264,7 @@ fn highlight(command: HighlightCommand) -> StrResult<()> {
let input = std::fs::read_to_string(&command.input) let input = std::fs::read_to_string(&command.input)
.map_err(|_| "failed to load source file")?; .map_err(|_| "failed to load source file")?;
let html = syntax::highlight_html(&input, TokenMode::Markup, &THEME); let html = typst::syntax::highlight_html(&input, TokenMode::Markup, &THEME);
fs::write(&command.output, html).map_err(|_| "failed to write HTML file")?; fs::write(&command.output, html).map_err(|_| "failed to write HTML file")?;
Ok(()) Ok(())