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

refactor: runner code for better error messages. #584

Merged
merged 1 commit into from
Jun 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions kclvm/runner/benches/bench_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ criterion_main!(benches);
fn exec(file: &str) -> Result<String, String> {
let mut args = ExecProgramArgs::default();
args.k_filename_list.push(file.to_string());
let plugin_agent = 0;
let opts = args.get_load_program_options();
let sess = Arc::new(ParseSession::default());
// Load AST program
let program = load_program(sess.clone(), &[file], Some(opts)).unwrap();
// Resolve ATS, generate libs, link libs and execute.
execute(sess, program, plugin_agent, &args)
execute(sess, program, &args)
}

/// Get kcl files from path.
Expand Down
70 changes: 41 additions & 29 deletions kclvm/runner/src/assembler.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Result;
use compiler_base_macros::bug;
use indexmap::IndexMap;
use kclvm_ast::ast::{self, Program};
Expand Down Expand Up @@ -59,12 +60,13 @@ pub(crate) trait LibAssembler {
import_names: IndexMap<String, IndexMap<String, String>>,
code_file: &str,
code_file_path: &str,
) -> String;
) -> Result<String>;

/// Clean cache lock files.
#[inline]
fn clean_lock_file(&self, path: &str) {
fn clean_lock_file(&self, path: &str) -> Result<()> {
let lock_path = &format!("{}.lock", self.add_code_file_suffix(path));
clean_path(lock_path);
clean_path(lock_path)
}
}

Expand All @@ -88,7 +90,7 @@ impl LibAssembler for KclvmLibAssembler {
import_names: IndexMap<String, IndexMap<String, String>>,
code_file: &str,
object_file_path: &str,
) -> String {
) -> Result<String> {
match &self {
KclvmLibAssembler::LLVM => LlvmLibAssembler::default().assemble(
compile_prog,
Expand Down Expand Up @@ -143,9 +145,9 @@ impl LibAssembler for LlvmLibAssembler {
import_names: IndexMap<String, IndexMap<String, String>>,
code_file: &str,
object_file_path: &str,
) -> String {
) -> Result<String> {
// Clean the existed "*.o" object file.
clean_path(object_file_path);
clean_path(object_file_path)?;

// Compile KCL code into ".o" object file.
emit_code(
Expand All @@ -157,9 +159,14 @@ impl LibAssembler for LlvmLibAssembler {
no_link: true,
},
)
.expect("Compile KCL to LLVM error");
.map_err(|e| {
anyhow::anyhow!(
"Internal error: compile KCL to LLVM error {}",
e.to_string()
)
})?;

object_file_path.to_string()
Ok(object_file_path.to_string())
}

#[inline]
Expand Down Expand Up @@ -215,32 +222,33 @@ impl KclvmAssembler {
/// Clean up the path of the dynamic link libraries generated.
/// It will remove the file in "file_path" and all the files in file_path end with ir code file suffix.
#[inline]
pub(crate) fn clean_path_for_genlibs(&self, file_path: &str, suffix: &str) {
pub(crate) fn clean_path_for_genlibs(&self, file_path: &str, suffix: &str) -> Result<()> {
let path = std::path::Path::new(file_path);
if path.exists() {
std::fs::remove_file(path).unwrap();
std::fs::remove_file(path)?;
}
for entry in glob::glob(&format!("{}*{}", file_path, suffix)).unwrap() {
for entry in glob::glob(&format!("{}*{}", file_path, suffix))? {
match entry {
Ok(path) => {
if path.exists() {
std::fs::remove_file(path).unwrap();
std::fs::remove_file(path)?;
}
}
Err(e) => bug!("{:?}", e),
};
}
Ok(())
}

/// Generate cache dir from the program root path.
/// Create cache dir if it doesn't exist.
#[inline]
pub(crate) fn load_cache_dir(&self, prog_root_name: &str) -> PathBuf {
pub(crate) fn load_cache_dir(&self, prog_root_name: &str) -> Result<PathBuf> {
let cache_dir = self.construct_cache_dir(prog_root_name);
if !cache_dir.exists() {
std::fs::create_dir_all(&cache_dir).unwrap();
std::fs::create_dir_all(&cache_dir)?;
}
cache_dir
Ok(cache_dir)
}

#[inline]
Expand All @@ -262,12 +270,12 @@ impl KclvmAssembler {
///
/// `gen_libs` will create multiple threads and call the method provided by [KclvmLibAssembler] in each thread
/// to generate the dynamic link library in parallel.
pub(crate) fn gen_libs(self) -> Vec<String> {
pub(crate) fn gen_libs(self) -> Result<Vec<String>> {
self.clean_path_for_genlibs(
DEFAULT_IR_FILE,
&self.single_file_assembler.get_code_file_suffix(),
);
let cache_dir = self.load_cache_dir(&self.program.root);
)?;
let cache_dir = self.load_cache_dir(&self.program.root)?;
let mut compile_progs: IndexMap<
String,
(
Expand Down Expand Up @@ -307,15 +315,17 @@ impl KclvmAssembler {
// The path to the generated files(*.o or *.lock) when the non-main package is compiled.
cache_dir.join(&pkgpath)
};
let code_file = file.to_str().unwrap().to_string();
let code_file = file
.to_str()
.ok_or(anyhow::anyhow!("Internal error: get cache file failed"))?
.to_string();
let code_file_path = assembler.add_code_file_suffix(&code_file);
let lock_file_path = format!("{}.lock", code_file_path);
let target = self.target.clone();
{
// Locking file for parallel code generation.
let mut file_lock = fslock::LockFile::open(&lock_file_path)
.unwrap_or_else(|_| panic!("{} not found", lock_file_path));
file_lock.lock().unwrap();
let mut file_lock = fslock::LockFile::open(&lock_file_path)?;
file_lock.lock()?;

let root = &compile_prog.root;
// The main package does not perform cache reading and writing,
Expand All @@ -326,7 +336,7 @@ impl KclvmAssembler {
// written.
let file_path = if is_main_pkg {
// generate dynamic link library for single file kcl program
assembler.assemble(&compile_prog, import_names, &code_file, &code_file_path)
assembler.assemble(&compile_prog, import_names, &code_file, &code_file_path)?
} else {
// Read the lib path cache
let file_relative_path: Option<String> = load_pkg_cache(
Expand Down Expand Up @@ -360,7 +370,7 @@ impl KclvmAssembler {
import_names,
&code_file,
&code_file_path,
);
)?;
let lib_relative_path = file_path.replacen(root, ".", 1);
save_pkg_cache(
root,
Expand All @@ -373,18 +383,20 @@ impl KclvmAssembler {
}
}
};
file_lock.unlock().unwrap();
file_lock.unlock()?;
lib_paths.push(file_path);
};
}
self.single_file_assembler.clean_lock_file(&self.entry_file);
lib_paths
self.single_file_assembler
.clean_lock_file(&self.entry_file)?;
Ok(lib_paths)
}
}

#[inline]
pub(crate) fn clean_path(path: &str) {
pub(crate) fn clean_path(path: &str) -> Result<()> {
if Path::new(path).exists() {
std::fs::remove_file(path).unwrap();
std::fs::remove_file(path)?;
}
Ok(())
}
Loading
Loading