mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Move deps from context to VM
This commit is contained in:
parent
c010cbc17d
commit
30fdba4356
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/lib.rs
13
src/lib.rs
@ -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![],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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(())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user