Some cleanups.
This commit is contained in:
136
src/backend.rs
136
src/backend.rs
@@ -1,85 +1,74 @@
|
||||
mod error;
|
||||
mod into_crane;
|
||||
mod runtime;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub use self::error::BackendError;
|
||||
pub use self::runtime::{RuntimeFunctionError, RuntimeFunctions};
|
||||
use crate::ir;
|
||||
use codespan_reporting::diagnostic::Diagnostic;
|
||||
use cranelift_codegen::isa::LookupError;
|
||||
use cranelift_codegen::settings::{Configurable, SetError};
|
||||
use cranelift_codegen::{isa, settings, CodegenError};
|
||||
use cranelift_module::{default_libcall_names, FuncId, ModuleError};
|
||||
use cranelift_codegen::settings::{Configurable};
|
||||
use cranelift_codegen::{isa, settings};
|
||||
use cranelift_jit::{JITModule, JITBuilder};
|
||||
use cranelift_module::{default_libcall_names, DataContext, DataId, Module, Linkage, FuncId};
|
||||
use cranelift_object::{object, ObjectBuilder, ObjectModule};
|
||||
use target_lexicon::Triple;
|
||||
use thiserror::Error;
|
||||
|
||||
pub struct Program {
|
||||
_func_id: FuncId,
|
||||
module: ObjectModule,
|
||||
const EMPTY_DATUM: [u8; 8] = [0; 8];
|
||||
|
||||
pub struct Backend<M: Module> {
|
||||
pub module: M,
|
||||
data_ctx: DataContext,
|
||||
runtime_functions: RuntimeFunctions,
|
||||
defined_strings: HashMap<String, DataId>,
|
||||
defined_symbols: HashMap<String, DataId>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
#[error(transparent)]
|
||||
CodegenError(#[from] CodegenError),
|
||||
#[error(transparent)]
|
||||
SetError(#[from] SetError),
|
||||
#[error(transparent)]
|
||||
LookupError(#[from] LookupError),
|
||||
}
|
||||
impl Backend<JITModule> {
|
||||
pub fn jit() -> Result<Self, BackendError> {
|
||||
let platform = Triple::host();
|
||||
let isa_builder = isa::lookup(platform.clone())?;
|
||||
let mut settings_builder = settings::builder();
|
||||
settings_builder.set("use_colocated_libcalls", "false")?;
|
||||
settings_builder.set("is_pic", "false")?;
|
||||
let isa = isa_builder.finish(settings::Flags::new(settings_builder))?;
|
||||
let mut builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
|
||||
|
||||
impl From<BackendError> for Diagnostic<usize> {
|
||||
fn from(value: BackendError) -> Self {
|
||||
match value {
|
||||
BackendError::Cranelift(me) => {
|
||||
Diagnostic::error().with_message(format!("Internal cranelift error: {}", me))
|
||||
}
|
||||
BackendError::BuiltinError(me) => {
|
||||
Diagnostic::error().with_message(format!("Internal runtime function error: {}", me))
|
||||
}
|
||||
BackendError::VariableLookupFailure => {
|
||||
Diagnostic::error().with_message("Internal variable lookup error!")
|
||||
}
|
||||
BackendError::CodegenError(me) => {
|
||||
Diagnostic::error().with_message(format!("Internal codegen error: {}", me))
|
||||
}
|
||||
BackendError::SetError(me) => {
|
||||
Diagnostic::error().with_message(format!("Internal backend setup error: {}", me))
|
||||
}
|
||||
BackendError::LookupError(me) => {
|
||||
Diagnostic::error().with_message(format!("Internal error: {}", me))
|
||||
}
|
||||
}
|
||||
RuntimeFunctions::register_jit_implementations(&mut builder);
|
||||
|
||||
let mut module = JITModule::new(builder);
|
||||
let runtime_functions = RuntimeFunctions::new(&platform, &mut module)?;
|
||||
|
||||
Ok(Backend {
|
||||
module,
|
||||
data_ctx: DataContext::new(),
|
||||
runtime_functions,
|
||||
defined_strings: HashMap::new(),
|
||||
defined_symbols: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bytes(&self, function_id: FuncId) -> *const u8 {
|
||||
self.module.get_finalized_function(function_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Program {
|
||||
pub fn new(platform: Triple, ir: ir::Program) -> Result<Program, BackendError> {
|
||||
impl Backend<ObjectModule> {
|
||||
pub fn object_file(platform: Triple) -> Result<Self, BackendError> {
|
||||
let isa_builder = isa::lookup(platform.clone())?;
|
||||
let mut settings_builder = settings::builder();
|
||||
settings_builder.set("is_pic", "true")?;
|
||||
let isa = isa_builder.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(&platform, &mut object_module)?;
|
||||
let mut module = ObjectModule::new(object_builder);
|
||||
let runtime_functions = RuntimeFunctions::new(&platform, &mut module)?;
|
||||
|
||||
Ok(Program {
|
||||
_func_id: ir.into_cranelift::<BackendError, _>(
|
||||
&mut object_module,
|
||||
"gogogo",
|
||||
&rtfuns,
|
||||
&HashMap::new(),
|
||||
&HashMap::new(),
|
||||
)?,
|
||||
module: object_module,
|
||||
Ok(Backend {
|
||||
module,
|
||||
data_ctx: DataContext::new(),
|
||||
runtime_functions,
|
||||
defined_strings: HashMap::new(),
|
||||
defined_symbols: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -87,3 +76,30 @@ impl Program {
|
||||
self.module.finish().emit()
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Module> Backend<M>
|
||||
{
|
||||
pub fn define_string(&mut self, s: &str) -> Result<DataId, BackendError> {
|
||||
let name = format!("<string_constant>{}", s);
|
||||
let global_id = self
|
||||
.module
|
||||
.declare_data(&name, Linkage::Local, false, false)?;
|
||||
let mut data_context = DataContext::new();
|
||||
data_context.set_align(8);
|
||||
data_context.define(s.to_owned().into_boxed_str().into_boxed_bytes());
|
||||
self.module.define_data(global_id, &data_context)?;
|
||||
self.defined_strings.insert(s.to_owned(), global_id);
|
||||
Ok(global_id)
|
||||
}
|
||||
|
||||
pub fn define_variable(&mut self, name: String) -> Result<DataId, BackendError> {
|
||||
self.data_ctx.define(Box::new(EMPTY_DATUM));
|
||||
let id = self
|
||||
.module
|
||||
.declare_data(&name, Linkage::Export, true, false)?;
|
||||
self.module.define_data(id, &self.data_ctx)?;
|
||||
self.data_ctx.clear();
|
||||
self.defined_symbols.insert(name, id);
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user