Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Replace eval with bytecode-based VM #3307

Closed
wants to merge 103 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
4907717
Initial work
Dherse Jan 23, 2024
1ca3c63
Before rewrite
Dherse Jan 27, 2024
f2d0508
Initial new VM
Dherse Jan 30, 2024
370d5bd
Fixed instruction decoding & rules
Dherse Jan 30, 2024
c00cfeb
Fixed jumps in scopes
Dherse Jan 30, 2024
41fab3e
Lots of fixes for compile, iter, etc.
Dherse Jan 30, 2024
c3a51db
Fixed writable access
Dherse Jan 30, 2024
82f6a29
cargo fmt
Dherse Jan 30, 2024
a2d9ba3
Fixed loops
Dherse Jan 30, 2024
e64ddad
Fixed loop (again)
Dherse Jan 30, 2024
d99fe29
Fixed condition & loops
Dherse Jan 31, 2024
798327a
cargo fmt
Dherse Jan 31, 2024
d04bf41
Fixed control flow
Dherse Jan 31, 2024
6b998f3
Cheaper `Opcode::Flow` (no span)
Dherse Jan 31, 2024
6fdf9ee
Fixed export & capturing duplicates
Dherse Jan 31, 2024
9ec4037
Fixed recursive module call weirdness
Dherse Jan 31, 2024
00cd913
Fixed label attachment
Dherse Jan 31, 2024
355b843
Fix show rule, fixed set and show (join), fixed break
Dherse Jan 31, 2024
c18933e
Removed logging
Dherse Jan 31, 2024
d5da17b
Fix pattern capture fail, fix no display in markup
Dherse Feb 1, 2024
748d236
Fixed messy decoding-encoding
Dherse Feb 2, 2024
8217c44
Fixed jumps, duplicate consts, etc.
Dherse Feb 3, 2024
5bcaeb3
Fixed jumps once and for all!
Dherse Feb 3, 2024
116f4e4
Variable # of registers, reuse regs
Dherse Feb 3, 2024
33350e4
cargo fmt
Dherse Feb 3, 2024
762235a
Simplify & speed
Dherse Feb 3, 2024
7e24092
Smallvec & stacker
Dherse Feb 3, 2024
1a406d1
Improved looping performance
Dherse Feb 3, 2024
82c5046
Improved opcode caching (yes really)
Dherse Feb 3, 2024
6c74666
Fixed small error
Dherse Feb 3, 2024
a9ec993
Removed `eval` module
Dherse Feb 3, 2024
79e7dd6
Starting fixing removal of eval
Dherse Feb 3, 2024
62d6d76
Add a few manual Debug impls to elements
laurmaedje Jan 17, 2024
edcafa9
Fix emptyness check in `into_par_items`
laurmaedje Jan 17, 2024
69466e9
Handle metadata application where styles are managed
laurmaedje Jan 17, 2024
1b1587c
Add `Page` struct
laurmaedje Jan 17, 2024
680f725
Cleaner separation between single and multi-region layout
laurmaedje Jan 18, 2024
170f4ad
Renamed `diff` symbol to `partial` (#3211)
Andrew15-5 Jan 18, 2024
f94864d
Add `gt.approx`, `gt.napprox`, `lt.approx`, `lt.napprox` and `colon.d…
MDLC01 Jan 24, 2024
4a78163
Handle `Finalize` alongside `Synthesize`
laurmaedje Jan 24, 2024
b6f0624
Remove guards for built-in elements
laurmaedje Jan 24, 2024
cc57fec
More efficient guard storage
laurmaedje Jan 24, 2024
d25842f
Implement bitwise operations on integers (#3130)
PgBiel Jan 25, 2024
8402e31
Add explanation of show rule scope in footnote (#3187)
mkpoli Jan 25, 2024
b0170ee
Add symbol name for narrow non-breaking space (#3217)
t-rapp Jan 25, 2024
3db3e57
Fix PDF export of grayscale image (#3219)
LaurenzV Jan 25, 2024
5f72abe
Make `math.class` affect the limit configuration (#3231)
MDLC01 Jan 25, 2024
d704c42
Make typst's advanced color public (#3234)
Myriad-Dreamin Jan 25, 2024
e68679a
doc: remove inaccurate statement in eval (#3250)
Enter-tainer Jan 25, 2024
d3e1d2a
Include units in top-level SVG element (#3233)
artemist Jan 25, 2024
93b36fc
Merging cells: Colspans [More Flexible Tables Pt.3a] (#3239)
PgBiel Jan 25, 2024
986f5c9
Bump resvg + svg2pdf and add support for filters (#3254)
LaurenzV Jan 25, 2024
fc63590
Add missing Chinese counting symbols to documentation (#3264)
zica87 Jan 26, 2024
302c6ed
Refactor math styling to bring it closer to normal styling (#3262)
laurmaedje Jan 26, 2024
e60e061
Configure ureq to use sytem-native TLS (#3258)
laurmaedje Jan 26, 2024
55e3fb7
Do not parse special spaces to Space Token (#3267)
peng1999 Jan 29, 2024
7a02c0b
Link to `datetime` from `datetime.display` docs (#3270)
tertsdiepraam Jan 29, 2024
29bdcba
Add `openssl` to dependencies in `flake.nix` (#3285)
s-cerevisiae Jan 29, 2024
98bf4f7
Merge `Fields` and `ElementFields` traits
laurmaedje Jan 29, 2024
26ace35
Refactor capability helpers
laurmaedje Jan 29, 2024
5491531
Raise Rust version to 1.74
laurmaedje Jan 29, 2024
4a175cd
Remove an unnecessary clone in loop evaluation (#3297)
Leedehai Jan 30, 2024
0aad47e
Fix an error of uncastable dict input (#3247)
Leedehai Jan 30, 2024
3f5c6b2
Refactor folding (#3294)
laurmaedje Jan 30, 2024
5bc5059
Refactor `#[elem]` macro (#3303)
laurmaedje Jan 30, 2024
82f34ea
Respect set rules in where selectors (#3290)
laurmaedje Jan 30, 2024
84dedb8
Document how to cite sources with special characters. (#3261)
01mf02 Jan 30, 2024
e304c76
nix: bump nixpkgs (#3305)
cmoog Jan 30, 2024
de518c2
Adjust for-loop's pattern matching rules (#3308)
Leedehai Jan 31, 2024
192644b
Use alternate screen and refactor terminal output. (#2665)
frozolotl Jan 31, 2024
252ea9b
Ensure synthesized field access never panics (#3310)
laurmaedje Jan 31, 2024
bf00314
Fix show-set semantics (#3311)
laurmaedje Feb 1, 2024
050bb03
Introduce override list to FontInfo (#3228)
peng1999 Feb 1, 2024
8788938
Allow for-loop to iterate over bytes (#3317)
Leedehai Feb 2, 2024
fbc7757
Let for-loop iterate Dict with an iterator (#3318)
Leedehai Feb 2, 2024
e9cd05c
Fix style issue for Latin Modern (#3315)
peng1999 Feb 2, 2024
9be1c47
Use heading's own location for numbering (#3322)
laurmaedje Feb 2, 2024
2dc9c9c
font-exceptions: override weight of Arial Black (#3321)
mkroening Feb 2, 2024
4cea772
Support for and/or selectors in show rules (#3326)
laurmaedje Feb 2, 2024
8786b38
Before rewrite
Dherse Jan 27, 2024
3e6ded3
Initial new VM
Dherse Jan 30, 2024
eec8560
Fixed label attachment
Dherse Jan 31, 2024
747c46d
Fix show rule, fixed set and show (join), fixed break
Dherse Jan 31, 2024
6eb4fa3
Merge remote-tracking branch 'upstream/main' into bytecode-vm
Dherse Feb 4, 2024
c7658fe
Fix merge & fmt
Dherse Feb 4, 2024
3f8216f
Fixed module import
Dherse Feb 5, 2024
a3425d2
Fixed cyclic import
Dherse Feb 5, 2024
7ec3a13
Fix performance
Dherse Feb 5, 2024
5ec67c3
Optimizations
Dherse Feb 5, 2024
2d46781
Simplification & opt
Dherse Feb 5, 2024
6b7a5bc
Various attempts at optimization
Dherse Feb 6, 2024
7709042
Removed unsafe
Dherse Feb 6, 2024
66c81a1
Optimization bonanza
Dherse Feb 6, 2024
9099196
Haha optimizations goes brrrrrrrrrrrrrrr
Dherse Feb 7, 2024
072ab62
`PicoStr` goes brrr & simplification
Dherse Feb 8, 2024
e8cf94b
Fixed arg span
Dherse Feb 8, 2024
67e0fdd
Massive compiler cleanup & simplification
Dherse Feb 8, 2024
ef55cca
Further cleanup
Dherse Feb 8, 2024
4dc43e7
Cleanup `Call` opcode
Dherse Feb 8, 2024
f829d3f
Fixed state
Dherse Feb 8, 2024
7cff984
Improved efficiency
Dherse Feb 9, 2024
6994b6a
Working on things
Dherse Feb 18, 2024
4808ad3
Missing file
Dherse Feb 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[target.x86_64-unknown-linux-gnu]
26 changes: 26 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ typst-timing = { path = "crates/typst-timing" }
az = "1.2"
base64 = "0.21.2"
bitflags = { version = "2", features = ["serde"] }
bytemuck = "1"
bytemuck = { version = "1.14", features = [ "derive" ] }
chinese-number = { version = "0.7.2", default-features = false, features = ["number-to-chinese"] }
chrono = { version = "0.4.24", default-features = false, features = ["clock", "std"] }
ciborium = "0.2.1"
Expand Down Expand Up @@ -121,16 +121,18 @@ xmp-writer = "0.2"
xz2 = "0.1"
yaml-front-matter = "0.1"
zip = { version = "0.6", default-features = false, features = ["deflate"] }
atomic = "0.6.0"

[profile.dev.package."*"]
opt-level = 2

[profile.release]
lto = "thin"
codegen-units = 1
debug = true

[profile.release.package."typst-cli"]
strip = true
strip = false

[workspace.lints.clippy]
uninlined_format_args = "warn"
Expand Down
9 changes: 7 additions & 2 deletions crates/typst-cli/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ use ecow::{eco_format, EcoString};
use parking_lot::RwLock;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use typst::diag::{bail, At, Severity, SourceDiagnostic, StrResult};
use typst::eval::Tracer;
use typst::foundations::Datetime;
use typst::layout::Frame;
use typst::model::Document;
use typst::syntax::{FileId, Source, Span};
use typst::util::{HITS, MISSES};
use typst::visualize::Color;
use typst::vm::Tracer;
use typst::{World, WorldExt};

use crate::args::{CompileCommand, DiagnosticFormat, OutputFormat};
Expand Down Expand Up @@ -68,7 +69,7 @@ pub fn compile(mut timer: Timer, mut command: CompileCommand) -> StrResult<()> {
/// Compile a single time.
///
/// Returns whether it compiled without errors.
#[typst_macros::time(name = "compile once")]
#[typst_macros::time(name = "compile document once")]
pub fn compile_once(
world: &mut SystemWorld,
command: &mut CompileCommand,
Expand Down Expand Up @@ -136,6 +137,10 @@ pub fn compile_once(
}
}

let hits = HITS.load(std::sync::atomic::Ordering::SeqCst);
let misses = MISSES.load(std::sync::atomic::Ordering::SeqCst);
eprintln!("Hit rate: {}% ({} / {})", hits as f64 * 100.0 / (hits as f64 + misses as f64), hits, hits + misses);

Ok(())
}

Expand Down
3 changes: 1 addition & 2 deletions crates/typst-cli/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use comemo::Track;
use ecow::{eco_format, EcoString};
use serde::Serialize;
use typst::diag::{bail, StrResult};
use typst::eval::{eval_string, EvalMode, Tracer};
use typst::foundations::{Content, IntoValue, LocatableSelector, Scope};
use typst::model::Document;
use typst::syntax::Span;
use typst::vm::{eval_string, EvalMode, Tracer};
use typst::World;

use crate::args::{QueryCommand, SerializationFormat};
Expand Down Expand Up @@ -77,7 +77,6 @@ fn retrieve(
.introspector
.query(&selector.0)
.into_iter()
.map(|x| x.into_inner())
.collect::<Vec<_>>())
}

Expand Down
2 changes: 1 addition & 1 deletion crates/typst-docs/src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use pulldown_cmark as md;
use serde::{Deserialize, Serialize};
use typed_arena::Arena;
use typst::diag::{FileResult, StrResult};
use typst::eval::Tracer;
use typst::foundations::{Bytes, Datetime};
use typst::layout::{Abs, Point, Size};
use typst::syntax::{FileId, Source, VirtualPath};
use typst::text::{Font, FontBook};
use typst::vm::Tracer;
use typst::{Library, World};
use unscanny::Scanner;
use yaml_front_matter::YamlFrontMatter;
Expand Down
16 changes: 9 additions & 7 deletions crates/typst-docs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use typst::loading::DATA_LOADING;
use typst::math::MATH;
use typst::model::Document;
use typst::model::MODEL;
use typst::pico;
use typst::symbols::SYMBOLS;
use typst::text::{Font, FontBook, TEXT};
use typst::visualize::VISUALIZE;
Expand All @@ -48,7 +49,7 @@ static GROUPS: Lazy<Vec<GroupData>> = Lazy::new(|| {
.scope()
.iter()
.filter(|(_, v)| matches!(v, Value::Func(_)))
.map(|(k, _)| k.clone())
.map(|(k, _)| k.to_owned())
.collect();
}
}
Expand Down Expand Up @@ -241,19 +242,20 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {

// Add functions.
let scope = module.scope();
for (name, value) in scope.iter() {
for (name, value) in scope.iter_pico() {
if scope.get_category(name) != Some(category) {
continue;
}

if category == MATH {
// Skip grouped functions.
if GROUPS.iter().flat_map(|group| &group.filter).any(|f| f == name) {
let resolved = name.resolve();
if GROUPS.iter().flat_map(|group| &group.filter).any(|f| *f == resolved) {
continue;
}

// Already documented in the text category.
if name == "text" {
if name == pico!("text") {
continue;
}
}
Expand Down Expand Up @@ -532,7 +534,7 @@ fn group_page(

let mut outline_items = vec![];
for name in &group.filter {
let value = group.module().scope().get(name).unwrap();
let value = group.module().scope().get(name as &str).unwrap();
let Value::Func(func) = value else { panic!("not a function") };
let func = func_model(resolver, func, &path, true);
let id_base = urlify(&eco_format!("functions-{}", func.name));
Expand Down Expand Up @@ -644,7 +646,7 @@ fn symbols_model(resolver: &dyn Resolver, group: &GroupData) -> SymbolsModel {
let Value::Symbol(symbol) = value else { continue };
let complete = |variant: &str| {
if variant.is_empty() {
name.clone()
EcoString::from(name)
} else {
eco_format!("{}.{}", name, variant)
}
Expand Down Expand Up @@ -760,7 +762,7 @@ struct GroupData {
#[serde(default)]
path: Vec<EcoString>,
#[serde(default)]
filter: Vec<EcoString>,
filter: Vec<String>,
details: EcoString,
}

Expand Down
4 changes: 2 additions & 2 deletions crates/typst-docs/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn resolve_definition(head: &str) -> StrResult<String> {

while let Some(name) = parts.peek() {
if category.is_none() {
category = focus.scope().get_category(name);
category = focus.scope().get_category(*name);
}
let Ok(module) = get_module(focus, name) else { break };
focus = module;
Expand All @@ -73,7 +73,7 @@ fn resolve_definition(head: &str) -> StrResult<String> {

// Handle grouped functions.
if let Some(group) = GROUPS.iter().find(|group| {
group.category == category.name() && group.filter.iter().any(|func| func == name)
group.category == category.name() && group.filter.iter().any(|func| *func == name)
}) {
let mut route = format!(
"/docs/reference/{}/{}/#functions-{}",
Expand Down
9 changes: 5 additions & 4 deletions crates/typst-ide/src/analyze.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use comemo::Track;
use ecow::{eco_vec, EcoString, EcoVec};
use typst::engine::{Engine, Route};
use typst::eval::{Tracer, Vm};
use typst::foundations::{Label, Scopes, Value};
use typst::introspection::{Introspector, Locator};
use typst::model::{BibliographyElem, Document};
use typst::syntax::{ast, LinkedNode, Span, SyntaxKind};
use typst::vm::Tracer;
use typst::World;

/// Try to determine a set of possible values for an expression.
Expand All @@ -23,7 +23,7 @@ pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<Value> {
let Some(child) = node.children().next() else { return eco_vec![] };
analyze_expr(world, &child)
.into_iter()
.filter_map(|target| target.field(&access.field()).ok())
.filter_map(|target| target.field(access.field().get()).ok())
.collect()
}

Expand Down Expand Up @@ -62,10 +62,11 @@ pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option<Value> {
tracer: tracer.track_mut(),
};

let mut vm = Vm::new(engine, Scopes::new(Some(world.library())), Span::detached());
/*let mut vm = Vm::new(engine, Scopes::new(Some(world.library())), Span::detached());
typst::eval::import(&mut vm, source, Span::detached(), true)
.ok()
.map(Value::Module)
.map(Value::Module)*/
todo!()
}

/// Find all labels and details for them.
Expand Down
18 changes: 9 additions & 9 deletions crates/typst-ide/src/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,12 @@ fn complete_field_accesses(ctx: &mut CompletionContext) -> bool {
/// Add completions for all fields on a value.
fn field_access_completions(ctx: &mut CompletionContext, value: &Value) {
for (name, value) in value.ty().scope().iter() {
ctx.value_completion(Some(name.clone()), value, true, None);
ctx.value_completion(Some(name.into()), value, true, None);
}

if let Some(scope) = value.scope() {
for (name, value) in scope.iter() {
ctx.value_completion(Some(name.clone()), value, true, None);
ctx.value_completion(Some(name.into()), value, true, None);
}
}

Expand Down Expand Up @@ -517,7 +517,7 @@ fn import_item_completions<'a>(

for (name, value) in scope.iter() {
if existing.iter().all(|item| item.original_name().as_str() != name) {
ctx.value_completion(Some(name.clone()), value, false, None);
ctx.value_completion(Some(name.into()), value, false, None);
}
}
}
Expand Down Expand Up @@ -760,11 +760,11 @@ fn resolve_global_callee<'a>(
callee: ast::Expr<'a>,
) -> Option<&'a Func> {
let value = match callee {
ast::Expr::Ident(ident) => ctx.global.get(&ident)?,
ast::Expr::Ident(ident) => ctx.global.get(ident.get())?,
ast::Expr::FieldAccess(access) => match access.target() {
ast::Expr::Ident(target) => match ctx.global.get(&target)? {
Value::Module(module) => module.field(&access.field()).ok()?,
Value::Func(func) => func.field(&access.field()).ok()?,
ast::Expr::Ident(target) => match ctx.global.get(target.get())? {
Value::Module(module) => module.field(access.field().get()).ok()?,
Value::Func(func) => func.field(access.field().get()).ok()?,
_ => return None,
},
_ => return None,
Expand Down Expand Up @@ -1303,7 +1303,7 @@ impl<'a> CompletionContext<'a> {
defined.extend(value.name().map(Into::into));
} else if let Some(scope) = value.scope() {
for (name, _) in scope.iter() {
defined.insert(name.clone());
defined.insert(name.into());
}
}
}
Expand Down Expand Up @@ -1347,7 +1347,7 @@ impl<'a> CompletionContext<'a> {
let scope = if in_math { self.math } else { self.global };
for (name, value) in scope.iter() {
if filter(value) && !defined.contains(name) {
self.value_completion(Some(name.clone()), value, parens, None);
self.value_completion(Some(name.into()), value, parens, None);
}
}

Expand Down
9 changes: 5 additions & 4 deletions crates/typst-ide/src/tooltip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use std::fmt::Write;

use ecow::{eco_format, EcoString};
use if_chain::if_chain;
use typst::eval::{CapturesVisitor, Tracer};
use typst::foundations::{repr, CastInfo, Repr, Value};
use typst::layout::Length;
use typst::model::Document;
use typst::syntax::{ast, LinkedNode, Source, SyntaxKind};
use typst::util::{round_2, Numeric};
use typst::vm::Tracer;
use typst::World;

use crate::analyze::{analyze_expr, analyze_labels};
Expand Down Expand Up @@ -119,7 +119,7 @@ fn closure_tooltip(leaf: &LinkedNode) -> Option<Tooltip> {
return None;
}

// Analyze the closure's captures.
/*// Analyze the closure's captures.
let mut visitor = CapturesVisitor::new(None);
visitor.visit(parent);

Expand All @@ -133,7 +133,8 @@ fn closure_tooltip(leaf: &LinkedNode) -> Option<Tooltip> {
names.sort();

let tooltip = repr::separated_list(&names, "and");
Some(Tooltip::Text(eco_format!("This closure captures {tooltip}.")))
Some(Tooltip::Text(eco_format!("This closure captures {tooltip}.")))*/
None
}

/// Tooltip text for a hovered length.
Expand Down Expand Up @@ -184,7 +185,7 @@ fn named_param_tooltip(world: &dyn World, leaf: &LinkedNode) -> Option<Tooltip>
};

// Find metadata about the function.
if let Some(Value::Func(func)) = world.library().global.scope().get(&callee);
if let Some(Value::Func(func)) = world.library().global.scope().get(callee.get());
then { (func, named) }
else { return None; }
};
Expand Down