feat: initial parallel impl

This commit is contained in:
2025-06-08 17:27:43 +08:00
parent 3797544fc2
commit 7293cb9f75
18 changed files with 529 additions and 934 deletions

View File

@@ -7,13 +7,14 @@ use rnix::ast::HasEntry;
use rnix::ast::{self, Expr};
use crate::builtins::ir_env;
use crate::engine::Engine;
use crate::env::VmEnv;
use crate::error::*;
use crate::ty::public::Symbol;
use crate::eval::Evaluate;
use crate::eval::jit::{JITCompile, JITContext};
use crate::ty::common as c;
use crate::ty::internal::Value;
use crate::eval::jit::{JITContext, JITCompile};
use crate::eval::Evaluate;
use crate::engine::Engine;
use crate::ty::public::Symbol;
mod utils;
use utils::*;
@@ -26,8 +27,12 @@ pub fn downgrade(expr: Expr) -> Result<Downgraded> {
let ir = ir.resolve(&mut ctx, &env)?;
Ok(Downgraded {
top_level: ir,
thunks: ctx.thunks.into(),
funcs: ctx.funcs.into(),
func_offset: ctx.thunks.len(),
thunks: ctx
.thunks
.into_iter()
.chain(ctx.funcs.into_iter().map(|Func { body, .. }| *body))
.collect(),
})
}
@@ -42,7 +47,7 @@ macro_rules! ir {
,*$(,)?
) => {
#[derive(Clone, Debug, IsVariant, Unwrap)]
pub enum Ir {
pub enum Ir {
$(
$ty($ty),
)*
@@ -63,16 +68,6 @@ macro_rules! ir {
}
impl Ir {
#[inline]
fn boxed(self) -> Box<Self> {
Box::new(self)
}
#[inline]
fn ok(self) -> Result<Self> {
Ok(self)
}
#[inline]
fn as_ref(&self) -> IrRef {
match self {
@@ -104,9 +99,9 @@ macro_rules! ir {
}
impl Evaluate for Ir {
fn eval<'a>(self, engine: &'a Engine) -> Result<Value<'a>> {
fn eval(self, engine: &Engine, env: &VmEnv) -> Result<Value> {
match self {
$(Ir::$ty(ir) => ir.eval(engine),)*
$(Ir::$ty(ir) => ir.eval(engine, env),)*
}
}
}
@@ -158,6 +153,18 @@ ir! {
Path => { expr: Box<Ir> },
}
impl Ir {
#[inline]
fn boxed(self) -> Box<Self> {
Box::new(self)
}
#[inline]
fn ok(self) -> Result<Self> {
Ok(self)
}
}
impl<T: Into<c::Const>> From<T> for Const {
fn from(value: T) -> Self {
Const { val: value.into() }
@@ -215,7 +222,11 @@ impl<'a, 'env> Env<'a, 'env> {
}
}
fn enter_multi_arg(&'env self, map: HashMap<EcoString, Option<Ir>>, alias: Option<EcoString>) -> Self {
fn enter_multi_arg(
&'env self,
map: HashMap<EcoString, Option<Ir>>,
alias: Option<EcoString>,
) -> Self {
Self {
env: EnvNode::MultiArg(map, alias),
prev: Some(self),
@@ -301,7 +312,7 @@ impl DowngradeContext {
pub struct Downgraded {
pub top_level: Ir,
pub thunks: Box<[Ir]>,
pub funcs: Box<[Func]>,
pub func_offset: usize,
}
impl DowngradeContext {
@@ -362,10 +373,13 @@ impl Attrs {
.get_mut(&ident)
.unwrap()
.as_mut()
.try_unwrap_attrs().map_err(|_| Error::DowngradeError(format!(
.try_unwrap_attrs()
.map_err(|_| {
Error::DowngradeError(format!(
r#"attribute '{}' already defined"#,
Symbol::from(ident)
)))
))
})
.and_then(|attrs: &mut Attrs| attrs._insert(path, name, value, ctx))
} else {
let mut attrs = Attrs {
@@ -641,7 +655,11 @@ impl Downgrade for ast::Path {
let parts = self
.parts()
.map(|part| match part {
ast::InterpolPart::Literal(lit) => String { val: lit.to_string().into() }.ir().ok(),
ast::InterpolPart::Literal(lit) => String {
val: lit.to_string().into(),
}
.ir()
.ok(),
ast::InterpolPart::Interpolation(interpol) => {
interpol.expr().unwrap().downgrade(ctx)
}
@@ -706,11 +724,14 @@ impl ConcatStrings {
}
impl Downgrade for ast::Literal {
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
fn downgrade(self, _: &mut DowngradeContext) -> Result<Ir> {
match self.kind() {
ast::LiteralKind::Integer(int) => Const::from(int.value().unwrap()).ir(),
ast::LiteralKind::Float(float) => Const::from(float.value().unwrap()).ir(),
ast::LiteralKind::Uri(uri) => String { val: uri.to_string().into() }.ir()
ast::LiteralKind::Uri(uri) => String {
val: uri.to_string().into(),
}
.ir(),
}
.ok()
}
@@ -729,17 +750,20 @@ impl String {
}
impl Downgrade for ast::Ident {
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
fn downgrade(self, _: &mut DowngradeContext) -> Result<Ir> {
let sym = self.ident_token().unwrap().to_string().into();
Var { sym }.ir().ok()
}
}
impl Var {
fn resolve<'a, 'env>(self, ctx: &mut DowngradeContext, env: &Env<'a, 'env>) -> Result<Ir> {
fn resolve<'a, 'env>(self, _: &mut DowngradeContext, env: &Env<'a, 'env>) -> Result<Ir> {
use LookupResult::*;
let Ok(res) = env.lookup(&self.sym) else {
return Err(Error::DowngradeError(format!("{} not found", Symbol::from(self.sym))))
return Err(Error::DowngradeError(format!(
"{} not found",
Symbol::from(self.sym)
)));
};
match res {
Builtin(ir) => ir,
@@ -1021,14 +1045,22 @@ impl Downgrade for ast::LetIn {
}
}
}
let bindings = bindings.into_iter().sorted_by(|(a, _), (b, _)| a.cmp(b)).collect();
let bindings = bindings
.into_iter()
.sorted_by(|(a, _), (b, _)| a.cmp(b))
.collect();
Let { bindings, expr }.ir().ok()
}
}
impl Let {
fn resolve<'a, 'env>(self, ctx: &mut DowngradeContext, env: &Env<'a, 'env>) -> Result<Ir> {
let map = self.bindings.iter().map(|(sym, _)| sym.clone()).sorted().collect();
let map = self
.bindings
.iter()
.map(|(sym, _)| sym.clone())
.sorted()
.collect();
let env = env.enter_let(&map);
let bindings = self
.bindings