support multiple cells

This commit is contained in:
Sébastien Bourdeauducq 2024-09-11 15:22:50 +08:00
parent b7916cda8a
commit dbb88ad79d
2 changed files with 17 additions and 10 deletions

View File

@ -1,5 +1,5 @@
[target.x86_64-unknown-openbsd] [target.x86_64-unknown-openbsd]
rustflags = [ "-C", "link-args=-Wl,--export-dynamic-symbol=__nac3_personality", "-C", "link-args=-Wl,-z,nobtcfi" ] rustflags = [ "-C", "link-args=-Wl,--export-dynamic-symbol=__nac3_*", "-C", "link-args=-Wl,-z,nobtcfi" ]
[target.x86_64-unknown-linux-gnu] [target.x86_64-unknown-linux-gnu]
rustflags = [ "-C", "link-args=-Wl,--export-dynamic-symbol=__nac3_personality" ] rustflags = [ "-C", "link-args=-Wl,--export-dynamic-symbol=__nac3_*" ]

View File

@ -18,7 +18,7 @@ use nac3core::typecheck::{type_inferencer, typedef};
mod basic_symbol_resolver; mod basic_symbol_resolver;
use basic_symbol_resolver::{Resolver, ResolverInternal}; use basic_symbol_resolver::{Resolver, ResolverInternal};
fn compile(code: &String, output_filename: &Path) -> Result<(), String> { fn compile(code: &String, run_symbol: &String, output_filename: &Path) -> Result<(), String> {
let mut target_machine_options = codegen::CodeGenTargetMachineOptions::from_host(); let mut target_machine_options = codegen::CodeGenTargetMachineOptions::from_host();
target_machine_options.reloc_mode = inkwell::targets::RelocMode::PIC; target_machine_options.reloc_mode = inkwell::targets::RelocMode::PIC;
let llvm_options = codegen::CodeGenLLVMOptions { let llvm_options = codegen::CodeGenLLVMOptions {
@ -59,7 +59,12 @@ fn compile(code: &String, output_filename: &Path) -> Result<(), String> {
return Err(format!("parse error: {}", err)); return Err(format!("parse error: {}", err));
} }
}; };
for stmt in parser_result { for mut stmt in parser_result {
if let nac3parser::ast::StmtKind::FunctionDef { name, .. } = &mut stmt.node {
if *name == "run".into() {
*name = run_symbol.as_str().into();
}
}
match composer.register_top_level(stmt, Some(resolver.clone()), "__main__", true) { match composer.register_top_level(stmt, Some(resolver.clone()), "__main__", true) {
Ok((name, def_id, ty)) => { Ok((name, def_id, ty)) => {
internal_resolver.add_id_def(name, def_id); internal_resolver.add_id_def(name, def_id);
@ -98,7 +103,7 @@ fn compile(code: &String, output_filename: &Path) -> Result<(), String> {
let top_level = Arc::new(composer.make_top_level_context()); let top_level = Arc::new(composer.make_top_level_context());
let run_id_def = match resolver.get_identifier_def("run".into()) { let run_id_def = match resolver.get_identifier_def(run_symbol.as_str().into()) {
Ok(run_id_def) => run_id_def, Ok(run_id_def) => run_id_def,
Err(_) => { Err(_) => {
return Err(format!("no run() entry point")); return Err(format!("no run() entry point"));
@ -115,13 +120,13 @@ fn compile(code: &String, output_filename: &Path) -> Result<(), String> {
else { else {
unreachable!() unreachable!()
}; };
instance_to_symbol.insert(String::new(), "run".to_string()); instance_to_symbol.insert(String::new(), run_symbol.clone());
instance_to_stmt[""].clone() instance_to_stmt[""].clone()
}; };
let task = codegen::CodeGenTask { let task = codegen::CodeGenTask {
subst: Vec::default(), subst: Vec::default(),
symbol_name: "run".to_string(), symbol_name: run_symbol.clone(),
body: instance.body, body: instance.body,
signature, signature,
resolver, resolver,
@ -180,7 +185,8 @@ fn compile(code: &String, output_filename: &Path) -> Result<(), String> {
// Private all functions except "run" // Private all functions except "run"
let mut function_iter = main.get_first_function(); let mut function_iter = main.get_first_function();
while let Some(func) = function_iter { while let Some(func) = function_iter {
if func.count_basic_blocks() > 0 && func.get_name().to_str().unwrap() != "run" { println!("{}", func.get_name().to_str().unwrap());
if func.count_basic_blocks() > 0 && func.get_name().to_str().unwrap() != run_symbol {
func.set_linkage(inkwell::module::Linkage::Private); func.set_linkage(inkwell::module::Linkage::Private);
} }
function_iter = func.get_next_function(); function_iter = func.get_next_function();
@ -244,7 +250,8 @@ impl CellBin {
assert!(self.library.is_none()); assert!(self.library.is_none());
let object = self.directory.path().join("module.o"); let object = self.directory.path().join("module.o");
let library = self.directory.path().join("module.so"); let library = self.directory.path().join("module.so");
compile(code, &object)?; let run_symbol = format!("__cells_run_{}", self.cell_id);
compile(code, &run_symbol, &object)?;
link_with_lld(&library, &object)?; link_with_lld(&library, &object)?;
unsafe { unsafe {
self.library = Some(libloading::Library::new(library).or_else(|e| Err(e.to_string()))?); self.library = Some(libloading::Library::new(library).or_else(|e| Err(e.to_string()))?);
@ -252,7 +259,7 @@ impl CellBin {
.library .library
.as_ref() .as_ref()
.unwrap() .unwrap()
.get::<RunFn>(b"run") .get::<RunFn>(run_symbol.as_bytes())
.unwrap() .unwrap()
.try_as_raw_ptr() .try_as_raw_ptr()
.unwrap(); .unwrap();