A fairly major refactor / simplification.
This commit is contained in:
@@ -1 +1,81 @@
|
||||
mod into_crane;
|
||||
mod runtime;
|
||||
|
||||
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, ModuleCompiledFunction, ModuleError};
|
||||
use cranelift_object::{ObjectBuilder, ObjectModule, object};
|
||||
use target_lexicon::Triple;
|
||||
use thiserror::Error;
|
||||
|
||||
pub struct Program {
|
||||
_compiled: ModuleCompiledFunction,
|
||||
module: ObjectModule,
|
||||
}
|
||||
|
||||
#[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 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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Program {
|
||||
pub fn new(platform: Triple, ir: ir::Program) -> Result<Program, 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)?;
|
||||
|
||||
Ok(Program {
|
||||
_compiled: ir.into_cranelift(&mut object_module, &rtfuns)?,
|
||||
module: object_module,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bytes(self) -> Result<Vec<u8>, object::write::Error> {
|
||||
self.module.finish().emit()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user