From d7c90ce4096ef6c1b8a16250a2471b2c15707a49 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 4 Jul 2024 20:46:11 -0500 Subject: [PATCH 1/4] working on data layout trying to get ir with objmaker to work --- e2e/src/main.rs | 10 ++++---- ir/src/lib.rs | 8 +++--- object/src/lib.rs | 62 ++++++++++++++++++++++++++++++--------------- objmaker/src/lib.rs | 28 ++++++++++---------- types/src/lib.rs | 19 ++++++++++++++ 5 files changed, 83 insertions(+), 44 deletions(-) diff --git a/e2e/src/main.rs b/e2e/src/main.rs index a4d42c5..058efa3 100644 --- a/e2e/src/main.rs +++ b/e2e/src/main.rs @@ -4,7 +4,6 @@ use linter::LintSource; use parser::Parser; use std::fs::File; use std::io::Read; -use typetable::TypeTable; use std::path::Path; use std::process::Command; @@ -12,10 +11,11 @@ use std::process::Command; fn main() { println!("[run] simple exe"); objmaker::from_buffer( - "pub const main = fn() usize { - const m = 7 - const x = 5 - return x + m + "const z = 2\n + pub const main = fn() usize {\n + const m = 7\n + const x = 3\n + return x + m + z }", Path::new("main.ty"), ); diff --git a/ir/src/lib.rs b/ir/src/lib.rs index 0509eda..aa9ef2a 100644 --- a/ir/src/lib.rs +++ b/ir/src/lib.rs @@ -15,7 +15,7 @@ use symtable::*; use types::*; use typetable::*; -pub struct IRSource<'tt> { +pub struct IRFunc<'tt> { package: u32, fname: u32, variables: u32, @@ -23,9 +23,9 @@ pub struct IRSource<'tt> { t_scope: &'tt TypeTable, } -impl<'tt> IRSource<'tt> { +impl<'tt> IRFunc<'tt> { pub fn new(package: u32, scope: SymTable, t_scope: &'tt TypeTable) -> Self { - IRSource { + IRFunc { package, fname: 0, variables: 0, @@ -267,7 +267,7 @@ mod tests { let mut scp = vec![]; let mut linter = LintSource::new("test", &mut scp, &mut tt); let linter_result = linter.check_func_decl(&func_def).unwrap(); - let mut fir = IRSource::new(0, SymTable::new(), &linter.ttbls.get(0).unwrap()); + let mut fir = IRFunc::new(0, SymTable::new(), &linter.ttbls.get(0).unwrap()); let result = fir.begin(linter_result.0); /* * function u0:0() -> i64 system_v diff --git a/object/src/lib.rs b/object/src/lib.rs index 3b6c0a3..8c3f574 100644 --- a/object/src/lib.rs +++ b/object/src/lib.rs @@ -1,31 +1,51 @@ use cranelift_codegen::ir::Function; use cranelift_codegen::settings::*; use cranelift_codegen::Context; -use cranelift_module::{Linkage, Module}; +use cranelift_module::{DataDescription, Linkage, Module}; use cranelift_object::{ObjectBuilder, ObjectModule}; -pub fn new_obj_handler(obj_name: &str) -> ObjectModule { - let settings = builder(); - let flags = Flags::new(settings); - let isa_builder = cranelift_native::builder().unwrap(); - let isa = isa_builder.finish(flags).unwrap(); - - let obj_builder = - ObjectBuilder::new(isa, obj_name, cranelift_module::default_libcall_names()).unwrap(); - ObjectModule::new(obj_builder) +pub struct ObjectSource { + pub obj_mod: ObjectModule, + pub data: DataDescription, + pub name: String, } -pub fn build_std_fn(om: &mut ObjectModule, func: Function, obj_name: &str) -> () { - let func_id = om - .declare_function(obj_name, Linkage::Export, &func.signature) - .unwrap(); +impl ObjectSource { + pub fn new(obj_name: &str) -> ObjectSource { + let settings = builder(); + let flags = Flags::new(settings); + let isa_builder = cranelift_native::builder().unwrap(); + let isa = isa_builder.finish(flags).unwrap(); - let mut ctx = Context::for_function(func); - om.define_function(func_id, &mut ctx).unwrap(); -} + let obj_builder = + ObjectBuilder::new(isa, obj_name, cranelift_module::default_libcall_names()).unwrap(); + ObjectSource { + obj_mod: ObjectModule::new(obj_builder), + data: DataDescription::new(), + name: obj_name.to_string(), + } + } + pub fn add_const_data(&mut self, contents: Vec) -> () { + self.data.define(contents.into_boxed_slice()); + let id = self + .obj_mod + .declare_data(&self.name, Linkage::Export, false, false) + .unwrap(); + self.obj_mod.define_data(id, &self.data).unwrap(); + self.data.clear(); + } + pub fn add_fn(&mut self, func: Function) -> () { + let func_id = self + .obj_mod + .declare_function(&self.name, Linkage::Export, &func.signature) + .unwrap(); -pub fn flush_obj(om: ObjectModule) -> Vec { - let object_product = om.finish(); - let bytes = object_product.emit().unwrap(); - return bytes; + let mut ctx = Context::for_function(func); + self.obj_mod.define_function(func_id, &mut ctx).unwrap(); + } + pub fn flush_self(self) -> Vec { + let object_product = self.obj_mod.finish(); + let bytes = object_product.emit().unwrap(); + return bytes; + } } diff --git a/objmaker/src/lib.rs b/objmaker/src/lib.rs index 5ca8856..eebbc43 100644 --- a/objmaker/src/lib.rs +++ b/objmaker/src/lib.rs @@ -1,9 +1,7 @@ -use ir::IRSource; +use ir::IRFunc; use lexer::TLexer; use linter::LintSource; -use object::build_std_fn; -use object::flush_obj; -use object::new_obj_handler; +use object::*; use parser::Parser; use std::fs::create_dir; use std::fs::write; @@ -12,7 +10,6 @@ use std::io::Read; use std::path::Path; use std::path::PathBuf; use symtable::SymTable; -use typetable::TypeTable; pub fn from_buffer(contents: &str, path: &Path) -> () { let lex = TLexer::new(&contents); @@ -22,14 +19,17 @@ pub fn from_buffer(contents: &str, path: &Path) -> () { let mut scopes = vec![]; let mut linter = LintSource::new(path.to_str().unwrap(), &mut scopes, &mut type_tables); let lint_res = linter.lint_check(&ast_parsed); - let mut ir = IRSource::new(0, SymTable::new(), linter.ttbls.get(0).unwrap()); + let mut ir = IRFunc::new(0, SymTable::new(), linter.ttbls.get(0).unwrap()); if linter.issues.len() > 0 { for x in linter.issues { println!("{}", x); } panic!("linter issues exist"); } - let rc_thing = lint_res.first().unwrap().to_owned(); + let mut om = ObjectSource::new(path.to_str().unwrap()); + println!("lint res {:?}", lint_res); + om.add_const_data(lint_res.get(0).unwrap().into_init().right.into_data()); + let rc_thing = lint_res.get(1).unwrap().to_owned(); let result = ir.begin(rc_thing); if !Path::new(".ty-cache").is_dir() { create_dir(".ty-cache").unwrap(); @@ -40,9 +40,9 @@ pub fn from_buffer(contents: &str, path: &Path) -> () { output.push(".ty-cache"); output.push(filename); output.set_extension("o"); - let mut om = new_obj_handler(filename); - build_std_fn(&mut om, result, filename); - write(output, flush_obj(om)).unwrap(); + let mut om = ObjectSource::new(filename); + om.add_fn(result); + write(output, om.flush_self()).unwrap(); } pub fn from_file(input_path: &PathBuf) -> () { @@ -56,7 +56,7 @@ pub fn from_file(input_path: &PathBuf) -> () { let mut scopes = vec![]; let mut linter = LintSource::new(input_path.to_str().unwrap(), &mut scopes, &mut type_tables); let lint_res = linter.lint_check(&ast_parsed); - let mut ir = IRSource::new(0, SymTable::new(), linter.ttbls.get(0).unwrap()); + let mut ir = IRFunc::new(0, SymTable::new(), linter.ttbls.get(0).unwrap()); if linter.issues.len() > 0 { panic!("linter issues exist"); } @@ -71,7 +71,7 @@ pub fn from_file(input_path: &PathBuf) -> () { output.push(".ty-cache"); output.push(filename); output.set_extension("o"); - let mut om = new_obj_handler(filename); - build_std_fn(&mut om, result, filename); - write(output, flush_obj(om)).unwrap(); + let mut om = ObjectSource::new(filename); + om.add_fn(result); + write(output, om.flush_self()).unwrap(); } diff --git a/types/src/lib.rs b/types/src/lib.rs index 7b7bb6d..8084fa2 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -301,6 +301,25 @@ impl TypeTree { TypeTree::SymbolInit(x) => x.curried.clone(), } } + pub fn into_init(&self) -> &Initialization { + match self { + TypeTree::ConstInit(x) => x, + _ => panic!("type lang issue, failed into init"), + } + } + pub fn into_data(&self) -> Vec { + let mut v = vec![]; + match self { + TypeTree::U64(x) => { + v.extend_from_slice(&u64::to_ne_bytes(x.clone())); + } + TypeTree::I64(x) => { + v.extend_from_slice(&i64::to_ne_bytes(x.clone())); + } + _ => panic!("type lang issue, failed into data"), + } + return v; + } pub fn into_declarator(&self) -> &DeclaratorInfo { match self { TypeTree::DeclaratorInfo(x) => x, From 9f1fe277e604d0711f734600390db75ef2fe693a Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 21 Jul 2024 14:57:25 -0500 Subject: [PATCH 2/4] Data Incorporated in obj files Simple data incorporated into the .rodata section. Next focus will be on refactoring and intertwining with the cache context, and passing obj_module to IR builder. --- e2e/src/main.rs | 6 +++--- object/src/lib.rs | 9 ++++----- objmaker/src/lib.rs | 40 ++++++++-------------------------------- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/e2e/src/main.rs b/e2e/src/main.rs index 058efa3..2c953a5 100644 --- a/e2e/src/main.rs +++ b/e2e/src/main.rs @@ -11,11 +11,11 @@ use std::process::Command; fn main() { println!("[run] simple exe"); objmaker::from_buffer( - "const z = 2\n + "const z = 1\n pub const main = fn() usize {\n const m = 7\n - const x = 3\n - return x + m + z + const x = 5\n + return x + m }", Path::new("main.ty"), ); diff --git a/object/src/lib.rs b/object/src/lib.rs index 8c3f574..7e05374 100644 --- a/object/src/lib.rs +++ b/object/src/lib.rs @@ -25,19 +25,18 @@ impl ObjectSource { name: obj_name.to_string(), } } - pub fn add_const_data(&mut self, contents: Vec) -> () { + pub fn add_const_data(&mut self, name: &str, contents: Vec) -> () { self.data.define(contents.into_boxed_slice()); let id = self .obj_mod - .declare_data(&self.name, Linkage::Export, false, false) + .declare_data(name, Linkage::Export, false, false) .unwrap(); self.obj_mod.define_data(id, &self.data).unwrap(); - self.data.clear(); } - pub fn add_fn(&mut self, func: Function) -> () { + pub fn add_fn(&mut self, name: &str, func: Function) -> () { let func_id = self .obj_mod - .declare_function(&self.name, Linkage::Export, &func.signature) + .declare_function(name, Linkage::Export, &func.signature) .unwrap(); let mut ctx = Context::for_function(func); diff --git a/objmaker/src/lib.rs b/objmaker/src/lib.rs index eebbc43..a960f18 100644 --- a/objmaker/src/lib.rs +++ b/objmaker/src/lib.rs @@ -26,11 +26,6 @@ pub fn from_buffer(contents: &str, path: &Path) -> () { } panic!("linter issues exist"); } - let mut om = ObjectSource::new(path.to_str().unwrap()); - println!("lint res {:?}", lint_res); - om.add_const_data(lint_res.get(0).unwrap().into_init().right.into_data()); - let rc_thing = lint_res.get(1).unwrap().to_owned(); - let result = ir.begin(rc_thing); if !Path::new(".ty-cache").is_dir() { create_dir(".ty-cache").unwrap(); } @@ -40,8 +35,13 @@ pub fn from_buffer(contents: &str, path: &Path) -> () { output.push(".ty-cache"); output.push(filename); output.set_extension("o"); - let mut om = ObjectSource::new(filename); - om.add_fn(result); + let mut om = ObjectSource::new(&output.to_string_lossy()); + let res = lint_res.get(0).unwrap().into_init(); + om.add_const_data(&res.left, res.right.into_data()); + let rc_thing = lint_res.get(1).unwrap().to_owned(); + let result = ir.begin(rc_thing); + println!("result {:?}", result); + om.add_fn("main", result); write(output, om.flush_self()).unwrap(); } @@ -49,29 +49,5 @@ pub fn from_file(input_path: &PathBuf) -> () { let mut file = File::open(input_path.clone()).unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); - let lex = TLexer::new(&contents); - let mut parse = Parser::new(lex); - let ast_parsed = parse.all().unwrap(); - let mut type_tables = vec![]; - let mut scopes = vec![]; - let mut linter = LintSource::new(input_path.to_str().unwrap(), &mut scopes, &mut type_tables); - let lint_res = linter.lint_check(&ast_parsed); - let mut ir = IRFunc::new(0, SymTable::new(), linter.ttbls.get(0).unwrap()); - if linter.issues.len() > 0 { - panic!("linter issues exist"); - } - let rc_thing = lint_res.first().unwrap().to_owned(); - let result = ir.begin(rc_thing); - if !Path::new(".ty-cache").is_dir() { - create_dir(".ty-cache").unwrap(); - } - let wo_extension = input_path.with_extension(""); - let filename = wo_extension.file_name().unwrap().to_str().unwrap(); - let mut output = PathBuf::new(); - output.push(".ty-cache"); - output.push(filename); - output.set_extension("o"); - let mut om = ObjectSource::new(filename); - om.add_fn(result); - write(output, om.flush_self()).unwrap(); + from_buffer(&contents, input_path); } From b71b5c4e883a07703bd8773707bef1fd9a3b83b8 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 8 Sep 2024 12:24:29 -0500 Subject: [PATCH 3/4] adding a compiler step to manage top level items --- Cargo.toml | 2 +- compiler/Cargo.toml | 10 ++++++++++ compiler/src/lib.rs | 29 +++++++++++++++++++++++++++++ e2e/src/main.rs | 4 ++-- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 compiler/Cargo.toml create mode 100644 compiler/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 7d7edfa..ac17b41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,6 @@ members = [ "cachectx", "typetable", "scopetable" -] +, "compiler"] resolver = "2" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml new file mode 100644 index 0000000..8c9208d --- /dev/null +++ b/compiler/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "compiler" +version = "0.1.0" +edition = "2021" + +[dependencies] +typetable = { path="../typetable" } +types = { path="../types" } +object = { path="../object" } +cranelift-codegen = "0" diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs new file mode 100644 index 0000000..7afe8bb --- /dev/null +++ b/compiler/src/lib.rs @@ -0,0 +1,29 @@ +use cranelift_codegen::ir::Function; +use object::ObjectSource; +use std::rc::Rc; +use types::TypeTree; + +// right now is just looping on lint source to generate multiple ir and data +pub struct Compiler { + pub lintres: Vec>>, + pub firs: Vec, + pub obj: ObjectSource, +} + +impl<'table> Compiler { + pub fn new(lintres: Vec>>, obj: ObjectSource) -> Self { + Compiler { + lintres, + firs: vec![], + obj, + } + } + + pub fn loopf(self) -> () { + self.lintres.into_iter().for_each(|x| match x { + TypeTree::ConstInit(y) => { self.obj.add_const_data(y.right.into_data()) }, + TypeTree::FuncInit(y) => { self.firs.push( + + }); + } +} diff --git a/e2e/src/main.rs b/e2e/src/main.rs index 2c953a5..1af6ace 100644 --- a/e2e/src/main.rs +++ b/e2e/src/main.rs @@ -14,8 +14,8 @@ fn main() { "const z = 1\n pub const main = fn() usize {\n const m = 7\n - const x = 5\n - return x + m + const x = 4\n + return x + m + z }", Path::new("main.ty"), ); From 13c28378fefed95cded588bed1d48879f3b10b71 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 29 Nov 2024 11:39:26 -0600 Subject: [PATCH 4/4] this is going to be a rough merge --- compiler/Cargo.toml | 3 +++ compiler/src/lib.rs | 38 ++++++++++++++++++++++++++++++-------- ir/Cargo.toml | 2 ++ ir/src/lib.rs | 42 +++++++++++++++++++++++++----------------- object/src/lib.rs | 4 +++- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 8c9208d..39dba85 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -5,6 +5,9 @@ edition = "2021" [dependencies] typetable = { path="../typetable" } +symtable = { path="../symtable" } types = { path="../types" } object = { path="../object" } +ir = { path="../ir" } cranelift-codegen = "0" +cranelift-module = "0" diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 7afe8bb..1e903fb 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,29 +1,51 @@ use cranelift_codegen::ir::Function; +use cranelift_module::DataId; +use ir::IRFunc; use object::ObjectSource; use std::rc::Rc; -use types::TypeTree; +use symtable::SymTable; +use types::{FunctionInitialize, TypeTree}; +use typetable::TypeTable; // right now is just looping on lint source to generate multiple ir and data pub struct Compiler { pub lintres: Vec>>, + pub fncnt: usize, pub firs: Vec, pub obj: ObjectSource, + pub typtbl: Vec, + pub gbl: Vec<(DataId, String)>, } impl<'table> Compiler { - pub fn new(lintres: Vec>>, obj: ObjectSource) -> Self { + pub fn new(lintres: Vec>>, obj: ObjectSource, typtbl: Vec) -> Self { Compiler { lintres, firs: vec![], + fncnt: 0, obj, + typtbl, + gbl: vec![], } } - pub fn loopf(self) -> () { - self.lintres.into_iter().for_each(|x| match x { - TypeTree::ConstInit(y) => { self.obj.add_const_data(y.right.into_data()) }, - TypeTree::FuncInit(y) => { self.firs.push( - - }); + pub fn loopf(&mut self) -> () { + for item in &self.lintres { + match item.as_ref().as_ref() { + TypeTree::ConstInit(y) => { + let id = self.obj.add_const_data("x", y.right.into_data()); + self.gbl.push((id, "x".to_string())); + } + TypeTree::FuncInit(y) => { + let func = self.make_ir(&y); + self.firs.push(func); + } + _ => panic!("developer error, unhandled loopfval, {:?}", item.clone()), + } + } + } + fn make_ir(&self, fi: &FunctionInitialize) -> Function { + let mut ir = IRFunc::new(0, SymTable::new()); + return ir.begin(fi, &self.gbl); } } diff --git a/ir/Cargo.toml b/ir/Cargo.toml index 1bd0b3b..c952ce0 100644 --- a/ir/Cargo.toml +++ b/ir/Cargo.toml @@ -16,3 +16,5 @@ linter = { path="../linter" } types = { path="../types" } cranelift-frontend = "0" cranelift-codegen = "0" +cranelift-module = "0" +cranelift-object = "0" diff --git a/ir/src/lib.rs b/ir/src/lib.rs index aa9ef2a..a80c064 100644 --- a/ir/src/lib.rs +++ b/ir/src/lib.rs @@ -9,28 +9,29 @@ use cranelift_codegen::settings; use cranelift_codegen::verifier::verify_function; use cranelift_frontend::*; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; +use cranelift_module::{DataId, Module}; +use cranelift_object::ObjectModule; use perror::*; -use std::rc::Rc; use symtable::*; use types::*; -use typetable::*; -pub struct IRFunc<'tt> { +pub struct IRFunc<'gbl, 'md> { package: u32, fname: u32, variables: u32, scope: SymTable, - t_scope: &'tt TypeTable, + global: Option<&'gbl Vec<(DataId, String)>>, + obj_mod: Option<&'md mut ObjectModule>, } -impl<'tt> IRFunc<'tt> { - pub fn new(package: u32, scope: SymTable, t_scope: &'tt TypeTable) -> Self { +impl<'gbl, 'md> IRFunc<'gbl, 'md> { + pub fn new(package: u32, scope: SymTable) -> Self { IRFunc { package, fname: 0, variables: 0, scope, - t_scope, + global: None, } } pub fn handle_const_init( @@ -96,10 +97,12 @@ impl<'tt> IRFunc<'tt> { builder.ins().return_(&[arg]); Ok(temp) } - pub fn handle_sym(&self, op: &SymbolAccess) -> ResultFir { - Ok(Variable::from_u32( - *self.scope.table.get(&op.ident).unwrap(), - )) + pub fn handle_sym(&self, op: &SymbolAccess, builder: &mut FunctionBuilder) -> ResultFir { + if let Some(val) = self.scope.table.get(&op.ident) { + return Ok(Variable::from_u32(*val)); + } + let data = self.obj_mod.unwrap().declare_data_in_func(self.global.builder. + return Ok(Variable::from_u32(2)); } pub fn handle_u64(&mut self, num: u64, builder: &mut FunctionBuilder) -> ResultFir { let result = self.add_var(); @@ -166,13 +169,17 @@ impl<'tt> IRFunc<'tt> { _ => panic!("developer error unexpected expression {:?}", expr), } } - pub fn begin(&mut self, func_def: Rc>) -> Function { + pub fn begin( + &mut self, + func_def: &FunctionInitialize, + gbl: &'gbl Vec<(DataId, String)>, + ) -> Function { + self.global = Some(gbl); let mut ctx = FunctionBuilderContext::new(); let mut sig = Signature::new(CallConv::SystemV); let name = UserFuncName::user(self.package, self.fname); - let func_init = func_def.into_func_init(); // todo:: types need to be worked out, params and returns defined - func_init + func_def .args .iter() .for_each(|_x| sig.params.push(AbiParam::new(I64))); @@ -183,7 +190,7 @@ impl<'tt> IRFunc<'tt> { let root_block = builder.create_block(); builder.append_block_params_for_function_params(root_block); builder.switch_to_block(root_block); - let _result = self.recurse(&func_init.block, &mut builder); + let _result = self.recurse(&func_def.block, &mut builder); builder.seal_block(root_block); builder.finalize(); func @@ -266,9 +273,10 @@ mod tests { let mut tt = vec![]; let mut scp = vec![]; let mut linter = LintSource::new("test", &mut scp, &mut tt); + let global: Vec<(DataId, String)> = vec![]; let linter_result = linter.check_func_decl(&func_def).unwrap(); - let mut fir = IRFunc::new(0, SymTable::new(), &linter.ttbls.get(0).unwrap()); - let result = fir.begin(linter_result.0); + let mut fir = IRFunc::new(0, SymTable::new()); + let result = fir.begin(&linter_result.0.into_func_init(), &global); /* * function u0:0() -> i64 system_v * { diff --git a/object/src/lib.rs b/object/src/lib.rs index 7e05374..de4a1b0 100644 --- a/object/src/lib.rs +++ b/object/src/lib.rs @@ -1,6 +1,7 @@ use cranelift_codegen::ir::Function; use cranelift_codegen::settings::*; use cranelift_codegen::Context; +use cranelift_module::DataId; use cranelift_module::{DataDescription, Linkage, Module}; use cranelift_object::{ObjectBuilder, ObjectModule}; @@ -25,13 +26,14 @@ impl ObjectSource { name: obj_name.to_string(), } } - pub fn add_const_data(&mut self, name: &str, contents: Vec) -> () { + pub fn add_const_data(&mut self, name: &str, contents: Vec) -> DataId { self.data.define(contents.into_boxed_slice()); let id = self .obj_mod .declare_data(name, Linkage::Export, false, false) .unwrap(); self.obj_mod.define_data(id, &self.data).unwrap(); + return id; } pub fn add_fn(&mut self, name: &str, func: Function) -> () { let func_id = self