Compare commits

...

1 Commits

Author SHA1 Message Date
495727d617 hacky shit
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-05 13:05:04 -07:00
6 changed files with 125 additions and 43 deletions

View File

@ -460,7 +460,7 @@ impl ExecutorContext {
Ok(last_expr) Ok(last_expr)
} }
pub(super) async fn open_module( pub async fn open_module(
&self, &self,
path: &ImportPath, path: &ImportPath,
attrs: &[Node<Annotation>], attrs: &[Node<Annotation>],
@ -468,6 +468,7 @@ impl ExecutorContext {
source_range: SourceRange, source_range: SourceRange,
) -> Result<ModuleId, KclError> { ) -> Result<ModuleId, KclError> {
let resolved_path = ModulePath::from_import_path(path, &self.settings.project_directory); let resolved_path = ModulePath::from_import_path(path, &self.settings.project_directory);
match path { match path {
ImportPath::Kcl { .. } => { ImportPath::Kcl { .. } => {
exec_state.global.mod_loader.cycle_check(&resolved_path, source_range)?; exec_state.global.mod_loader.cycle_check(&resolved_path, source_range)?;
@ -597,7 +598,7 @@ impl ExecutorContext {
result result
} }
async fn exec_module_from_ast( pub async fn exec_module_from_ast(
&self, &self,
program: &Node<Program>, program: &Node<Program>,
module_id: ModuleId, module_id: ModuleId,
@ -605,6 +606,7 @@ impl ExecutorContext {
exec_state: &mut ExecState, exec_state: &mut ExecState,
source_range: SourceRange, source_range: SourceRange,
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> { ) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
println!("exec_module_from_ast {path}");
exec_state.global.mod_loader.enter_module(path); exec_state.global.mod_loader.enter_module(path);
let result = self.exec_module_body(program, exec_state, false, module_id, path).await; let result = self.exec_module_body(program, exec_state, false, module_id, path).await;
exec_state.global.mod_loader.leave_module(path); exec_state.global.mod_loader.leave_module(path);
@ -2658,6 +2660,7 @@ d = b + c
original_file_contents: "".to_owned(), original_file_contents: "".to_owned(),
}, },
&mut exec_state, &mut exec_state,
false,
) )
.await .await
.unwrap(); .unwrap();

View File

@ -31,14 +31,14 @@ use tokio::task::JoinSet;
use crate::{ use crate::{
engine::EngineManager, engine::EngineManager,
errors::KclError, errors::{KclError, KclErrorDetails},
execution::{ execution::{
artifact::build_artifact_graph, artifact::build_artifact_graph,
cache::{CacheInformation, CacheResult}, cache::{CacheInformation, CacheResult},
types::{UnitAngle, UnitLen}, types::{UnitAngle, UnitLen},
}, },
fs::FileManager, fs::FileManager,
modules::{ModuleId, ModulePath}, modules::{ModuleId, ModulePath, ModuleRepr},
parsing::ast::types::{Expr, ImportPath, NodeRef}, parsing::ast::types::{Expr, ImportPath, NodeRef},
source_range::SourceRange, source_range::SourceRange,
std::StdLib, std::StdLib,
@ -671,7 +671,7 @@ impl ExecutorContext {
(program, exec_state, false) (program, exec_state, false)
}; };
let result = self.inner_run(&program, &mut exec_state, preserve_mem).await; let result = self.run_concurrent(&program, &mut exec_state, preserve_mem).await;
if result.is_err() { if result.is_err() {
cache::bust_cache().await; cache::bust_cache().await;
@ -704,7 +704,7 @@ impl ExecutorContext {
program: &crate::Program, program: &crate::Program,
exec_state: &mut ExecState, exec_state: &mut ExecState,
) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> { ) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> {
self.run_concurrent(program, exec_state).await self.run_concurrent(program, exec_state, false).await
} }
/// Perform the execution of a program using an (experimental!) concurrent /// Perform the execution of a program using an (experimental!) concurrent
@ -721,46 +721,107 @@ impl ExecutorContext {
&self, &self,
program: &crate::Program, program: &crate::Program,
exec_state: &mut ExecState, exec_state: &mut ExecState,
preserve_mem: bool,
) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> { ) -> Result<(EnvironmentRef, Option<ModelingSessionData>), KclErrorWithOutputs> {
self.prepare_mem(exec_state).await.unwrap(); self.prepare_mem(exec_state).await.unwrap();
let mut universe = std::collections::HashMap::new(); let mut universe = std::collections::HashMap::new();
let mut out_id_map = std::collections::HashMap::new();
crate::walk::import_universe(self, &program.ast, &mut universe) crate::walk::import_universe(self, &program.ast, &mut universe, &mut out_id_map, exec_state)
.await .await
.unwrap(); .unwrap();
for modules in crate::walk::import_graph(&universe).unwrap().into_iter() { for modules in crate::walk::import_graph(&universe).unwrap().into_iter() {
let mut set = JoinSet::new(); println!("Running module {modules:?}");
//let mut set = JoinSet::new();
println!("AFTER Running module {modules:?}");
let (results_tx, mut results_rx): (
tokio::sync::mpsc::Sender<(
String,
Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError>,
)>,
tokio::sync::mpsc::Receiver<_>,
) = tokio::sync::mpsc::channel(1);
for module in modules { for module in modules {
let program = universe.get(&module).unwrap().clone(); let program = universe.get(&module).unwrap().clone();
let Some(module_id) = out_id_map.get(&module) else {
panic!("Module {module} not found in exec_state");
};
let module_id = module_id.clone();
let module_path = {
let module_info = exec_state.get_module(module_id).unwrap();
let module_path = module_info.path.clone();
module_path
};
let exec_state = exec_state.clone(); let exec_state = exec_state.clone();
let exec_ctxt = self.clone(); let exec_ctxt = self.clone();
let results_tx = results_tx.clone();
set.spawn(async move { println!("before spawn");
#[cfg(target_arch = "wasm32")]
{
wasm_bindgen_futures::spawn_local(async move {
//set.spawn(async move {
println!("Running module {module} from run_concurrent"); println!("Running module {module} from run_concurrent");
let mut exec_state = exec_state; let mut exec_state = exec_state;
let exec_ctxt = exec_ctxt; let exec_ctxt = exec_ctxt;
let program = program; let program = program;
exec_ctxt let result = exec_ctxt
.inner_run( .exec_module_from_ast(
&crate::Program { &program,
ast: program.clone(), module_id,
original_file_contents: "".to_owned(), &module_path,
},
&mut exec_state, &mut exec_state,
false, Default::default(),
) )
.await .await;
results_tx.send((module, result)).await.unwrap();
}); });
} }
set.join_all().await;
} }
self.inner_run(program, exec_state, false).await drop(results_tx);
while let Some((module, result)) = results_rx.recv().await {
match result {
Ok((env_ref, session_data, variables)) => {
println!("{module} {:?}", variables);
let Some(module_id) = out_id_map.get(&module) else {
//let snapshot_png_bytes = self.prepare_snapshot().await.unwrap().contents.0;
// Save to a file.
//tokio::fs::write("snapshot.png", snapshot_png_bytes).await.unwrap();
return Err(KclErrorWithOutputs::no_outputs(KclError::Internal(KclErrorDetails {
message: format!("Module {module} not found in exec_state"),
source_ranges: Default::default(),
})));
};
let path = exec_state.global.module_infos[module_id].path.clone();
let mut repr = exec_state.global.module_infos[module_id].take_repr();
let ModuleRepr::Kcl(program, cache) = &mut repr else {
continue;
};
*cache = Some((session_data, variables.clone()));
exec_state.global.module_infos[module_id].restore_repr(repr);
}
Err(e) => {
//let snapshot_png_bytes = self.prepare_snapshot().await.unwrap().contents.0;
// Save to a file.
//tokio::fs::write("snapshot.png", snapshot_png_bytes).await.unwrap();
return Err(KclErrorWithOutputs::no_outputs(e));
}
}
}
}
self.inner_run(program, exec_state, preserve_mem).await
} }
/// Perform the execution of a program. Accept all possible parameters and /// Perform the execution of a program. Accept all possible parameters and

View File

@ -228,7 +228,7 @@ impl ExecState {
self.global.module_infos.insert(id, module_info); self.global.module_infos.insert(id, module_info);
} }
pub(super) fn get_module(&mut self, id: ModuleId) -> Option<&ModuleInfo> { pub fn get_module(&mut self, id: ModuleId) -> Option<&ModuleInfo> {
self.global.module_infos.get(&id) self.global.module_infos.get(&id)
} }

View File

@ -6,10 +6,10 @@ use std::{
use anyhow::Result; use anyhow::Result;
use crate::{ use crate::{
fs::FileSystem, modules::ModuleRepr,
parsing::ast::types::{ImportPath, Node as AstNode, NodeRef, Program}, parsing::ast::types::{ImportPath, Node as AstNode, NodeRef, Program},
walk::{Node, Visitable}, walk::{Node, Visitable},
ExecutorContext, SourceRange, ExecState, ExecutorContext, ModuleId,
}; };
/// Specific dependency between two modules. The 0th element of this tuple /// Specific dependency between two modules. The 0th element of this tuple
@ -43,6 +43,9 @@ pub fn import_graph(progs: &HashMap<String, AstNode<Program>>) -> Result<Vec<Vec
#[allow(clippy::iter_over_hash_type)] #[allow(clippy::iter_over_hash_type)]
fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> { fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
if all_modules.is_empty() {
return Ok(vec![]);
}
let mut dep_map = HashMap::<String, Vec<String>>::new(); let mut dep_map = HashMap::<String, Vec<String>>::new();
for (dependent, dependency) in graph.iter() { for (dependent, dependency) in graph.iter() {
@ -59,6 +62,7 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
let mut order = vec![]; let mut order = vec![];
loop { loop {
println!("waiting_modules: {:?}", waiting_modules);
// Each pass through we need to find any modules which have nothing // Each pass through we need to find any modules which have nothing
// "pointing at it" -- so-called reverse dependencies. This is an entry // "pointing at it" -- so-called reverse dependencies. This is an entry
// that is either not in the dep_map OR an empty list. // that is either not in the dep_map OR an empty list.
@ -131,30 +135,42 @@ pub(crate) async fn import_universe<'prog>(
ctx: &ExecutorContext, ctx: &ExecutorContext,
prog: NodeRef<'prog, Program>, prog: NodeRef<'prog, Program>,
out: &mut HashMap<String, AstNode<Program>>, out: &mut HashMap<String, AstNode<Program>>,
out_id_map: &mut HashMap<String, ModuleId>,
exec_state: &mut ExecState,
) -> Result<()> { ) -> Result<()> {
for module in import_dependencies(prog)? { let modules = import_dependencies(prog)?;
for module in modules {
eprintln!("{:?}", module); eprintln!("{:?}", module);
if out.contains_key(&module) { if out.contains_key(&module) {
continue; continue;
} }
// TODO: use open_module and find a way to pass attrs cleanly let module_id = ctx
let kcl = ctx .open_module(
.fs &ImportPath::Kcl {
.read_to_string( filename: module.to_string(),
ctx.settings },
.project_directory &[],
.clone() exec_state,
.unwrap_or("".into()) Default::default(),
.join(&module),
SourceRange::default(),
) )
.await?; .await?;
let program = crate::parsing::parse_str(&kcl, crate::ModuleId::default()).parse_errs_as_err()?; out_id_map.insert(module.clone(), module_id);
let program = {
let Some(module_info) = exec_state.get_module(module_id) else {
// We should never get here we just fucking added it.
anyhow::bail!("Module {} not found", module);
};
let ModuleRepr::Kcl(program, _) = &module_info.repr else {
anyhow::bail!("Module {} is not a KCL program", module);
};
program.clone()
};
out.insert(module.clone(), program.clone()); out.insert(module.clone(), program.clone());
Box::pin(import_universe(ctx, &program, out)).await?; Box::pin(import_universe(ctx, &program, out, out_id_map, exec_state)).await?;
} }
Ok(()) Ok(())

View File

@ -77,7 +77,8 @@ impl Context {
let program: Program = serde_json::from_str(program_ast_json).map_err(|e| e.to_string())?; let program: Program = serde_json::from_str(program_ast_json).map_err(|e| e.to_string())?;
let ctx = self.create_executor_ctx(settings, path, false)?; let ctx = self.create_executor_ctx(settings, path, false)?;
match ctx.run_with_caching(program).await { let mut exec_state = kcl_lib::ExecState::new(&ctx);
match ctx.run(&program, &mut exec_state).await {
// The serde-wasm-bindgen does not work here because of weird HashMap issues. // The serde-wasm-bindgen does not work here because of weird HashMap issues.
// DO NOT USE serde_wasm_bindgen::to_value it will break the frontend. // DO NOT USE serde_wasm_bindgen::to_value it will break the frontend.
Ok(outcome) => JsValue::from_serde(&outcome).map_err(|e| e.to_string()), Ok(outcome) => JsValue::from_serde(&outcome).map_err(|e| e.to_string()),

View File

@ -1965,6 +1965,7 @@ export class EngineCommandManager extends EventTarget {
range, range,
idToRangeMap, idToRangeMap,
}) })
console.log("responose to wasm", resp)
return BSON.serialize(resp[0]) return BSON.serialize(resp[0])
} }
/** /**