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 unscanny::Scanner;
use typst::eval::evaluate;
use typst::loading::MemLoader;
use typst::parse::{TokenMode, Tokens};
use typst::source::SourceId;
@ -88,7 +87,7 @@ fn bench_eval(iai: &mut Iai) {
fn bench_layout(iai: &mut Iai) {
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));
}

View File

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

View File

@ -13,6 +13,8 @@ pub struct Machine<'a> {
pub ctx: &'a mut Context,
/// The route of source ids at which the machine is located.
pub route: Vec<SourceId>,
/// The dependencies of the current evaluation process.
pub deps: Vec<(SourceId, usize)>,
/// The stack of scopes.
pub scopes: Scopes<'a>,
/// A control flow event that is currently happening.
@ -22,7 +24,13 @@ pub struct Machine<'a> {
impl<'a> Machine<'a> {
/// Create a new virtual machine.
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

View File

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

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.
pub struct Context {
/// The context's configuration.
pub config: Config,
/// Stores loaded source files.
pub sources: SourceStore,
/// Stores parsed font faces.
pub fonts: FontStore,
/// Stores decoded images.
pub images: ImageStore,
/// The context's configuration.
pub config: Config,
/// Cached modules.
modules: HashMap<SourceId, Module>,
/// The dependencies of the current evaluation process.
deps: Vec<(SourceId, usize)>,
/// Stores evaluated modules.
pub modules: HashMap<SourceId, Module>,
}
impl Context {
/// Create a new context.
pub fn new(loader: Arc<dyn Loader>, config: Config) -> Self {
Self {
config,
sources: SourceStore::new(Arc::clone(&loader)),
fonts: FontStore::new(Arc::clone(&loader)),
images: ImageStore::new(loader),
config,
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 mut sub = Machine::new(vm.ctx, vec![], scopes);
let result = ast.eval(&mut sub);
assert!(vm.deps.is_empty());
// Handle control 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 typst::diag::{Error, StrResult};
use typst::export;
use typst::font::{FaceInfo, FontStore};
use typst::library::text::THEME;
use typst::loading::FsLoader;
use typst::parse::TokenMode;
use typst::source::SourceStore;
use typst::syntax;
use typst::{Config, Context};
/// What to do.
@ -217,7 +215,7 @@ fn typeset(command: TypesetCommand) -> StrResult<()> {
match typst::typeset(&mut ctx, id) {
// Export the PDF.
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")?;
}
@ -266,7 +264,7 @@ fn highlight(command: HighlightCommand) -> StrResult<()> {
let input = std::fs::read_to_string(&command.input)
.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")?;
Ok(())