From bb1cbf9962bc20b7131a7da0b05dd23e0dc9a6ca Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Thu, 29 Dec 2022 14:30:30 -0800 Subject: [PATCH] something worked --- Cargo.toml | 1 + src/backend.rs | 1 + src/bin.rs | 41 +++++++++++------------ src/errors.rs | 2 +- src/passes.rs | 4 ++- src/passes/into_crane.rs | 72 ++++++++++++++++++++++++++++++++-------- src/runtime.rs | 40 +++++++++++++++------- 7 files changed, 112 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cb15903..78d6ccb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ lalrpop-util = "^0.19.7" lazy_static = "^1.4.0" logos = "^0.12.0" pretty = { version = "^0.11.2", features = ["termcolor"] } +target-lexicon = "^0.12.5" thiserror = "^1.0.30" [build-dependencies] diff --git a/src/backend.rs b/src/backend.rs index e69de29..8b13789 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -0,0 +1 @@ + diff --git a/src/bin.rs b/src/bin.rs index ae5d6e9..5c2a9e7 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -3,15 +3,17 @@ use codespan_reporting::diagnostic::Diagnostic; use codespan_reporting::files::SimpleFiles; use codespan_reporting::term; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; -use cranelift_codegen::ir::{AbiParam, types, Signature}; +use cranelift_codegen::ir::{types, AbiParam, Signature}; use cranelift_codegen::isa::CallConv; use cranelift_codegen::{isa, settings, CodegenError}; -use cranelift_module::{default_libcall_names, ModuleError, Linkage, Module}; -use cranelift_object::{ObjectBuilder, ObjectModule, object}; +use cranelift_module::{default_libcall_names, Linkage, Module, ModuleError}; +use cranelift_object::{object, ObjectBuilder, ObjectModule}; use ngr::asts::lil; -use ngr::passes::run_front_end; +use ngr::passes::{run_front_end, BackendError}; +use ngr::runtime::RuntimeFunctions; use pretty::Arena; use std::io; +use target_lexicon::Triple; use thiserror::Error; #[derive(Parser, Debug)] @@ -41,6 +43,9 @@ enum MainError { #[error("Object write error: {0}")] Object(#[from] object::write::Error), + + #[error(transparent)] + Backend(#[from] BackendError), } fn main() -> Result<(), MainError> { @@ -74,19 +79,13 @@ fn main() -> Result<(), MainError> { if let Some((hil_tree, variable_map)) = hil_conversion_result.result { //let arena = Arena::new(); let lil_tree = lil::Program::convert(hil_tree, variable_map.clone()); - - let isa = isa::lookup_by_name("aarch64-apple-darwin")?.finish(settings::Flags::new(settings::builder()))?; - let object_builder = ObjectBuilder::new(isa, "example", default_libcall_names())?; - let mut object_module = ObjectModule::new(object_builder); - - let print_signature = Signature { - params: vec![AbiParam::new(types::I64)], - returns: vec![], - call_conv: CallConv::SystemV, - }; - let print_func_id = object_module.declare_function("print", Linkage::Import, &print_signature)?; - let _compiled = lil_tree.into_cranelift(&mut object_module, print_func_id)?; + let isa = isa::lookup(Triple::host())?.finish(settings::Flags::new(settings::builder()))?; + let object_builder = ObjectBuilder::new(isa, "example", default_libcall_names())?; + let mut object_module = ObjectModule::new(object_builder); + let rtfuns = RuntimeFunctions::new(&mut object_module)?; + + let _compiled = lil_tree.into_cranelift(&mut object_module, &rtfuns)?; // something? @@ -94,11 +93,11 @@ fn main() -> Result<(), MainError> { std::fs::write("output.o", bytes)?; -// lil_tree -// .pretty(&variable_map, &arena) -// .into_doc() -// .render_colored(72, StandardStream::stdout(ColorChoice::Auto)) -// .unwrap() + // lil_tree + // .pretty(&variable_map, &arena) + // .into_doc() + // .render_colored(72, StandardStream::stdout(ColorChoice::Auto)) + // .unwrap() } Ok(()) diff --git a/src/errors.rs b/src/errors.rs index 3c51c78..ff4cd03 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -181,7 +181,7 @@ impl From for Diagnostic { Label::primary(*file_id, *offset..*offset).with_message("this is related") ]) .with_message(format!("Internal error: {}", string)), - } + }, } } } diff --git a/src/passes.rs b/src/passes.rs index 299babd..011956f 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -7,9 +7,11 @@ use crate::warnings::Warning; use codespan_reporting::files::SimpleFiles; use std::fs; +pub use crate::passes::into_crane::BackendError; + mod hil_to_lil; -mod syntax_to_hil; mod into_crane; +mod syntax_to_hil; pub struct PassResult { pub result: T, diff --git a/src/passes/into_crane.rs b/src/passes/into_crane.rs index a06c6aa..4c8c1fa 100644 --- a/src/passes/into_crane.rs +++ b/src/passes/into_crane.rs @@ -1,13 +1,31 @@ -use crate::asts::lil::{Program, Statement, Primitive, SimpleExpression, Value}; +use std::collections::HashMap; + +use crate::asts::lil::{Primitive, Program, SimpleExpression, Statement, Value}; +use crate::runtime::{RuntimeFunctionError, RuntimeFunctions}; use cranelift_codegen::entity::EntityRef; -use cranelift_codegen::ir::{Function, UserFuncName, Signature, types, InstBuilder, entities}; +use cranelift_codegen::ir::{entities, types, Function, InstBuilder, Signature, UserFuncName}; use cranelift_codegen::isa::CallConv; -use cranelift_codegen::{Context}; -use cranelift_frontend::{FunctionBuilderContext, FunctionBuilder, Variable}; -use cranelift_module::{FuncId, Module, Linkage, ModuleError, ModuleCompiledFunction}; +use cranelift_codegen::Context; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; +use cranelift_module::{FuncId, Linkage, Module, ModuleCompiledFunction, ModuleError, DataContext}; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum BackendError { + #[error("Cranelift module error: {0}")] + Cranelift(#[from] ModuleError), + #[error("Builtin function error: {0}")] + BuiltinError(#[from] RuntimeFunctionError), + #[error("Internal variable lookup error")] + VariableLookupFailure, +} impl Program { - pub fn into_cranelift(&self, module: &mut M, print_func_id: FuncId) -> Result { + pub fn into_cranelift( + &self, + module: &mut M, + rtfuns: &RuntimeFunctions, + ) -> Result { let basic_signature = Signature { params: vec![], returns: vec![], @@ -16,9 +34,33 @@ impl Program { let func_id = module.declare_function("gogogo", Linkage::Export, &basic_signature)?; let mut ctx = Context::new(); - ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature); + ctx.func = + Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature); + let mut variable_name_global_values = HashMap::new(); - let print_func_ref = module.declare_func_in_func(print_func_id, &mut ctx.func); + for stmt in self.statements.iter() { + if let Statement::Print(_ann, var) = stmt { + let name = self + .variable_info + .get_name(*var) + .ok_or(BackendError::VariableLookupFailure)?; + let global_id = module.declare_data( + &format!("local-{}", name), + Linkage::Local, + false, + false, + )?; + let mut data_context = DataContext::new(); + data_context.set_align(8); + let zero_termed = format!("{}\0", name); + data_context.define(zero_termed.into_boxed_str().into_boxed_bytes()); + module.define_data(global_id, &data_context)?; + let local_data = module.declare_data_in_func(global_id, &mut ctx.func); + variable_name_global_values.insert(*var, local_data); + } + } + + let print_func_ref = rtfuns.include_runtime_function("print", module, &mut ctx.func)?; let mut fctx = FunctionBuilderContext::new(); let mut builder = FunctionBuilder::new(&mut ctx.func, &mut fctx); @@ -28,8 +70,10 @@ impl Program { for stmt in self.statements.iter() { match stmt { Statement::Print(_ann, var) => { - let var = builder.use_var(Variable::new(*var)); - builder.ins().call(print_func_ref, &[var]); + let local_data = *variable_name_global_values.get(var).unwrap(); + let var_name = builder.ins().symbol_value(types::I64, local_data); + let val = builder.use_var(Variable::new(*var)); + builder.ins().call(print_func_ref, &[var_name, val]); } Statement::ResultBinding(_, varnum, value) => { @@ -63,7 +107,7 @@ impl Program { }; builder.def_var(var, val); } - + Statement::VariableBinding(_, varnum, exp) => { let var = Variable::new(*varnum); builder.declare_var(var, types::I64); @@ -77,7 +121,7 @@ impl Program { builder.seal_block(main_block); builder.finalize(); - module.define_function(func_id, &mut ctx) + Ok(module.define_function(func_id, &mut ctx)?) } } @@ -86,9 +130,9 @@ impl SimpleExpression { match self { SimpleExpression::Constant(_, value) => match value { Value::Number(_base, numval) => builder.ins().iconst(types::I64, *numval as i64), - } + }, SimpleExpression::Reference(_, num) => builder.use_var(Variable::new(*num)), } } -} \ No newline at end of file +} diff --git a/src/runtime.rs b/src/runtime.rs index 5768969..f0eff4e 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -1,6 +1,8 @@ -use cranelift_codegen::ir::{Signature, AbiParam, types, ArgumentPurpose, ArgumentExtension, Function, FuncRef}; +use cranelift_codegen::ir::{ + types, AbiParam, ArgumentExtension, ArgumentPurpose, FuncRef, Function, Signature, +}; use cranelift_codegen::isa::CallConv; -use cranelift_module::{Module, ModuleResult, Linkage, FuncId}; +use cranelift_module::{FuncId, Linkage, Module, ModuleResult}; use std::collections::HashMap; use thiserror::Error; @@ -20,23 +22,37 @@ impl RuntimeFunctions { let mut builtin_functions = HashMap::new(); let _referenced_functions = Vec::new(); - let string_param = AbiParam::new(types::R64); + let string_param = AbiParam::new(types::I64); let int64_param = AbiParam::new(types::I64); - let print_id = module.declare_function("print", Linkage::Import, &Signature { - params: vec![string_param, int64_param], - returns: vec![], - call_conv: CallConv::AppleAarch64 - })?; + let print_id = module.declare_function( + "print", + Linkage::Import, + &Signature { + params: vec![string_param, int64_param], + returns: vec![], + call_conv: CallConv::AppleAarch64, + }, + )?; builtin_functions.insert("print".to_string(), print_id); - Ok(RuntimeFunctions { builtin_functions, _referenced_functions }) + Ok(RuntimeFunctions { + builtin_functions, + _referenced_functions, + }) } - pub fn include_runtime_function(&self, name: &str, module: &mut M, func: &mut Function) -> Result { + pub fn include_runtime_function( + &self, + name: &str, + module: &mut M, + func: &mut Function, + ) -> Result { match self.builtin_functions.get(name) { - None => Err(RuntimeFunctionError::CannotFindRuntimeFunction(name.to_string())), + None => Err(RuntimeFunctionError::CannotFindRuntimeFunction( + name.to_string(), + )), Some(func_id) => Ok(module.declare_func_in_func(*func_id, func)), } } -} \ No newline at end of file +}