diff --git a/kclvm/evaluator/src/module.rs b/kclvm/evaluator/src/module.rs index 108a1947f..61c24ca15 100644 --- a/kclvm/evaluator/src/module.rs +++ b/kclvm/evaluator/src/module.rs @@ -83,7 +83,7 @@ impl<'ctx> Evaluator<'_> { /// 1. scan all possible global variables and allocate undefined values to global pointers. /// 2. build all user-defined schema/rule types. /// 3. evaluate all codes for the third time. - pub(crate) fn compile_ast_modules(&self, modules: &Vec>>) -> ValueRef { + pub(crate) fn compile_ast_modules(&self, modules: &[Arc>]) -> ValueRef { // Scan global variables for ast_module in modules { let ast_module = ast_module.read().expect("Failed to acquire module lock"); diff --git a/kclvm/evaluator/src/scope.rs b/kclvm/evaluator/src/scope.rs index 1e44f12bf..27ff2f13f 100644 --- a/kclvm/evaluator/src/scope.rs +++ b/kclvm/evaluator/src/scope.rs @@ -1,10 +1,12 @@ +use std::sync::{Arc, RwLock}; + use crate::func::ClosureMap; use crate::lazy::merge_setters; use crate::{ error as kcl_error, lazy::LazyEvalScope, rule::RuleEvalContextRef, schema::SchemaEvalContextRef, }; use indexmap::{IndexMap, IndexSet}; -use kclvm_ast::ast::{self, Module}; +use kclvm_ast::ast; use kclvm_ast::walker::TypedResultWalker; use kclvm_runtime::{ValueRef, _kclvm_get_fn_ptr_by_name, MAIN_PKG_PATH}; use kclvm_sema::{builtin, plugin}; @@ -37,45 +39,20 @@ impl<'ctx> Evaluator<'ctx> { let scopes = vec![Scope::default()]; pkg_scopes.insert(String::from(pkgpath), scopes); } - let msg = format!("pkgpath {} is not found", pkgpath); // Get the AST module list in the package path. - let module_list: Vec = if self.program.pkgs.contains_key(pkgpath) { - let modules = self.program.pkgs.get(pkgpath).expect(&msg); - let modules: Vec = modules - .iter() - .map(|m| { - self.program - .get_module(m) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", m)) - .clone() - }) - .collect(); - modules + let module_list: Vec>> = if self.program.pkgs.contains_key(pkgpath) + { + self.program.get_modules_for_pkg(pkgpath) } else if pkgpath.starts_with(kclvm_runtime::PKG_PATH_PREFIX) && self.program.pkgs.contains_key(&pkgpath[1..]) { - let modules = self - .program - .pkgs - .get(&pkgpath[1..]) - .expect(kcl_error::INTERNAL_ERROR_MSG); - let modules: Vec = modules - .iter() - .map(|m| { - self.program - .get_module(m) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", m)) - .clone() - }) - .collect(); - modules + self.program.get_modules_for_pkg(&pkgpath[1..]) } else { panic!("pkgpath {} not found", pkgpath); }; // Init all global types including schema and rule. for module in &module_list { + let module = module.read().expect("Failed to acquire module lock"); for stmt in &module.body { let name = match &stmt.node { ast::Stmt::Schema(schema_stmt) => schema_stmt.name.node.clone(), @@ -100,6 +77,7 @@ impl<'ctx> Evaluator<'ctx> { let mut setters = IndexMap::new(); for (index, module) in module_list.iter().enumerate() { let index = self.add_global_body(index); + let module = module.read().expect("Failed to acquire module lock"); merge_setters(&mut setters, &self.emit_setters(&module.body, Some(index))) } if !lazy_scopes.contains_key(pkgpath) { diff --git a/kclvm/sema/src/advanced_resolver/mod.rs b/kclvm/sema/src/advanced_resolver/mod.rs index 66773fecf..b38be6dec 100644 --- a/kclvm/sema/src/advanced_resolver/mod.rs +++ b/kclvm/sema/src/advanced_resolver/mod.rs @@ -139,11 +139,9 @@ impl<'ctx> AdvancedResolver<'ctx> { pkg_info.kfile_paths.clone(), ); + let modules = advanced_resolver.ctx.program.get_modules_for_pkg(name); for module in modules.iter() { - let module = program - .get_module(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); + let module = module.read().expect("Failed to acquire module lock"); advanced_resolver.ctx.current_filename = Some(module.filename.clone()); advanced_resolver.walk_module_schemas(&module)?; } @@ -171,11 +169,9 @@ impl<'ctx> AdvancedResolver<'ctx> { .unwrap(); advanced_resolver.ctx.scopes.push(scope_ref); + let modules = advanced_resolver.ctx.program.get_modules_for_pkg(name); for module in modules.iter() { - let module = program - .get_module(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); + let module = module.read().expect("Failed to acquire module lock"); advanced_resolver.ctx.current_filename = Some(module.filename.clone()); advanced_resolver.walk_module(&module)?; } diff --git a/kclvm/sema/src/namer/mod.rs b/kclvm/sema/src/namer/mod.rs index c45f88e36..2303fd663 100644 --- a/kclvm/sema/src/namer/mod.rs +++ b/kclvm/sema/src/namer/mod.rs @@ -153,12 +153,9 @@ impl<'ctx> Namer<'ctx> { Some(PackageInfo::new(name.to_string(), real_path, false)); } + let modules = namer.ctx.program.get_modules_for_pkg(name); for module in modules.iter() { - let module = program - .get_module(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); - + let module = module.read().expect("Failed to acquire module lock"); namer .ctx .current_package_info diff --git a/kclvm/sema/src/pre_process/config.rs b/kclvm/sema/src/pre_process/config.rs index e43eb283a..ad4c7c6cf 100644 --- a/kclvm/sema/src/pre_process/config.rs +++ b/kclvm/sema/src/pre_process/config.rs @@ -125,75 +125,66 @@ impl ConfigMergeTransformer { Vec<(String, usize, usize, ConfigMergeKind)>, > = IndexMap::default(); // 1. Collect merged config - if let Some(modules) = program.pkgs.get(kclvm_ast::MAIN_PKG) { - for (module_id, module) in modules.iter().enumerate() { - let mut module = program - .get_module_mut(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); - let filename = module.filename.to_string(); - for (i, stmt) in module.body.iter_mut().enumerate() { - match &mut stmt.node { - ast::Stmt::Unification(unification_stmt) - if !unification_stmt.target.node.names.is_empty() => - { - let name = &unification_stmt.target.node.names[0].node; - match name_declaration_mapping.get_mut(name) { - Some(declarations) => declarations.push(( - filename.clone(), - module_id, - i, - ConfigMergeKind::Union, - )), - None => { - name_declaration_mapping.insert( - name.to_string(), - vec![( - filename.clone(), - module_id, - i, - ConfigMergeKind::Union, - )], - ); - } + let modules = program.get_modules_for_pkg(kclvm_ast::MAIN_PKG); + for (module_id, module) in modules.iter().enumerate() { + let mut module = module.write().expect("Failed to acquire module lock"); + let filename = module.filename.to_string(); + for (i, stmt) in module.body.iter_mut().enumerate() { + match &mut stmt.node { + ast::Stmt::Unification(unification_stmt) + if !unification_stmt.target.node.names.is_empty() => + { + let name = &unification_stmt.target.node.names[0].node; + match name_declaration_mapping.get_mut(name) { + Some(declarations) => declarations.push(( + filename.clone(), + module_id, + i, + ConfigMergeKind::Union, + )), + None => { + name_declaration_mapping.insert( + name.to_string(), + vec![(filename.clone(), module_id, i, ConfigMergeKind::Union)], + ); } } - ast::Stmt::Assign(assign_stmt) => { - if let ast::Expr::Schema(_) = assign_stmt.value.node { - for target in &assign_stmt.targets { - if target.node.paths.is_empty() { - let name = &target.node.name.node; - match name_declaration_mapping.get_mut(name) { - Some(declarations) => { - // A hidden var is mutable. - if is_private_field(name) { - declarations.clear(); - declarations.push(( - filename.clone(), - module_id, - i, - ConfigMergeKind::Override, - )) - } - } - None => { - name_declaration_mapping.insert( - name.to_string(), - vec![( - filename.clone(), - module_id, - i, - ConfigMergeKind::Override, - )], - ); + } + ast::Stmt::Assign(assign_stmt) => { + if let ast::Expr::Schema(_) = assign_stmt.value.node { + for target in &assign_stmt.targets { + if target.node.paths.is_empty() { + let name = &target.node.name.node; + match name_declaration_mapping.get_mut(name) { + Some(declarations) => { + // A hidden var is mutable. + if is_private_field(name) { + declarations.clear(); + declarations.push(( + filename.clone(), + module_id, + i, + ConfigMergeKind::Override, + )) } } + None => { + name_declaration_mapping.insert( + name.to_string(), + vec![( + filename.clone(), + module_id, + i, + ConfigMergeKind::Override, + )], + ); + } } } } } - _ => {} } + _ => {} } } } @@ -204,118 +195,104 @@ impl ConfigMergeTransformer { let (filename, merged_id, merged_index, merged_kind) = index_list.last().unwrap(); let mut items: Vec> = vec![]; for (merged_filename, merged_id, index, kind) in index_list { - if let Some(modules) = program.pkgs.get(kclvm_ast::MAIN_PKG) { - for (module_id, module) in modules.iter().enumerate() { - let mut module = program - .get_module_mut(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); - if &module.filename == merged_filename && module_id == *merged_id { - let stmt = module.body.get_mut(*index).unwrap(); - match &mut stmt.node { - ast::Stmt::Unification(unification_stmt) - if matches!(kind, ConfigMergeKind::Union) => + let modules = program.get_modules_for_pkg(kclvm_ast::MAIN_PKG); + for (module_id, module) in modules.iter().enumerate() { + let mut module = module.write().expect("Failed to acquire module lock"); + if &module.filename == merged_filename && module_id == *merged_id { + let stmt = module.body.get_mut(*index).unwrap(); + match &mut stmt.node { + ast::Stmt::Unification(unification_stmt) + if matches!(kind, ConfigMergeKind::Union) => + { + if let ast::Expr::Config(config_expr) = + &mut unification_stmt.value.node.config.node + { + let mut config_items = config_expr.items.clone(); + items.append(&mut config_items); + } + } + ast::Stmt::Assign(assign_stmt) + if matches!(kind, ConfigMergeKind::Override) => + { + if let ast::Expr::Schema(schema_expr) = + &mut assign_stmt.value.node { if let ast::Expr::Config(config_expr) = - &mut unification_stmt.value.node.config.node + &mut schema_expr.config.node { let mut config_items = config_expr.items.clone(); items.append(&mut config_items); } } - ast::Stmt::Assign(assign_stmt) - if matches!(kind, ConfigMergeKind::Override) => - { - if let ast::Expr::Schema(schema_expr) = - &mut assign_stmt.value.node - { - if let ast::Expr::Config(config_expr) = - &mut schema_expr.config.node - { - let mut config_items = config_expr.items.clone(); - items.append(&mut config_items); - } - } - } - _ => { - bug!("mismatch ast node and config merge kind: {:?}", kind) - } + } + _ => { + bug!("mismatch ast node and config merge kind: {:?}", kind) } } } } } - if let Some(modules) = program.pkgs.get(kclvm_ast::MAIN_PKG) { - for (module_id, module) in modules.iter().enumerate() { - let mut module = program - .get_module_mut(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); - if &module.filename == filename && module_id == *merged_id { - if let Some(stmt) = module.body.get_mut(*merged_index) { - match &mut stmt.node { - ast::Stmt::Unification(unification_stmt) - if matches!(merged_kind, ConfigMergeKind::Union) => + for (module_id, module) in modules.iter().enumerate() { + let mut module = module.write().expect("Failed to acquire module lock"); + if &module.filename == filename && module_id == *merged_id { + if let Some(stmt) = module.body.get_mut(*merged_index) { + match &mut stmt.node { + ast::Stmt::Unification(unification_stmt) + if matches!(merged_kind, ConfigMergeKind::Union) => + { + if let ast::Expr::Config(config_expr) = + &mut unification_stmt.value.node.config.node { - if let ast::Expr::Config(config_expr) = - &mut unification_stmt.value.node.config.node - { - config_expr.items = unify_config_entries(&items); - } + config_expr.items = unify_config_entries(&items); } - ast::Stmt::Assign(assign_stmt) - if matches!(merged_kind, ConfigMergeKind::Override) => + } + ast::Stmt::Assign(assign_stmt) + if matches!(merged_kind, ConfigMergeKind::Override) => + { + if let ast::Expr::Schema(schema_expr) = + &mut assign_stmt.value.node { - if let ast::Expr::Schema(schema_expr) = - &mut assign_stmt.value.node + if let ast::Expr::Config(config_expr) = + &mut schema_expr.config.node { - if let ast::Expr::Config(config_expr) = - &mut schema_expr.config.node - { - config_expr.items = unify_config_entries(&items); - } + config_expr.items = unify_config_entries(&items); } } - _ => bug!( - "mismatch ast node and config merge kind: {:?}", - merged_kind - ), } + _ => bug!( + "mismatch ast node and config merge kind: {:?}", + merged_kind + ), } - break; } + break; } } } } // 3. Delete redundant config. - if let Some(modules) = program.pkgs.get(kclvm_ast::MAIN_PKG) { - for (i, module) in modules.iter().enumerate() { - let mut module = program - .get_module_mut(module) - .expect("Failed to acquire module lock") - .expect(&format!("module {:?} not found in program", module)); - let mut delete_index_set: IndexSet = IndexSet::default(); - for (_, index_list) in &name_declaration_mapping { - let index_len = index_list.len(); - if index_len > 1 { - for (filename, module_id, index, _) in &index_list[..index_len - 1] { - // Use module filename and index to prevent the same compile filenames - // in the main package. - if &module.filename == filename && i == *module_id { - delete_index_set.insert(*index); - } + for (i, module) in modules.iter().enumerate() { + let mut module = module.write().expect("Failed to acquire module lock"); + let mut delete_index_set: IndexSet = IndexSet::default(); + for (_, index_list) in &name_declaration_mapping { + let index_len = index_list.len(); + if index_len > 1 { + for (filename, module_id, index, _) in &index_list[..index_len - 1] { + // Use module filename and index to prevent the same compile filenames + // in the main package. + if &module.filename == filename && i == *module_id { + delete_index_set.insert(*index); } } } - let mut body: Vec<(usize, &ast::NodeRef)> = - module.body.iter().enumerate().collect(); - body.retain(|(idx, _)| !delete_index_set.contains(idx)); - module.body = body - .iter() - .map(|(_, stmt)| (*stmt).clone()) - .collect::>>(); } + let mut body: Vec<(usize, &ast::NodeRef)> = + module.body.iter().enumerate().collect(); + body.retain(|(idx, _)| !delete_index_set.contains(idx)); + module.body = body + .iter() + .map(|(_, stmt)| (*stmt).clone()) + .collect::>>(); } } }