forked from M-Labs/nac3
core: pass resolver error ids to irrt
This commit is contained in:
parent
8863cd64a9
commit
2f7e75d7cf
@ -11,22 +11,38 @@ struct Str {
|
||||
SizeT length;
|
||||
};
|
||||
|
||||
// A limited set of errors IRRT could use.
|
||||
typedef uint32_t ErrorId;
|
||||
struct ErrorIds {
|
||||
ErrorId index_error;
|
||||
ErrorId value_error;
|
||||
ErrorId assertion_error;
|
||||
ErrorId runtime_error;
|
||||
};
|
||||
|
||||
struct ErrorContext {
|
||||
// Context
|
||||
ErrorIds* error_ids;
|
||||
|
||||
// Error thrown by IRRT
|
||||
ErrorId error_id;
|
||||
const char* message_template; // MUST BE `&'static`
|
||||
uint64_t param1;
|
||||
uint64_t param2;
|
||||
uint64_t param3;
|
||||
|
||||
void initialize() {
|
||||
void initialize(ErrorIds* error_ids) {
|
||||
this->error_ids = error_ids;
|
||||
clear_error();
|
||||
}
|
||||
|
||||
void clear_error() {
|
||||
// Point the message_template to an empty str. Don't set it to nullptr as a sentinel
|
||||
set_error("");
|
||||
this->message_template = "";
|
||||
}
|
||||
|
||||
void set_error(const char* message, uint64_t param1 = 0, uint64_t param2 = 0, uint64_t param3 = 0) {
|
||||
void set_error(ErrorId error_id, const char* message, uint64_t param1 = 0, uint64_t param2 = 0, uint64_t param3 = 0) {
|
||||
this->error_id = error_id;
|
||||
this->message_template = message;
|
||||
this->param1 = param1;
|
||||
this->param2 = param2;
|
||||
@ -47,8 +63,8 @@ struct ErrorContext {
|
||||
|
||||
extern "C" {
|
||||
|
||||
void __nac3_error_context_initialize(ErrorContext* errctx) {
|
||||
errctx->initialize();
|
||||
void __nac3_error_context_initialize(ErrorContext* errctx, ErrorIds* error_ids) {
|
||||
errctx->initialize(error_ids);
|
||||
}
|
||||
|
||||
uint8_t __nac3_error_context_has_no_error(ErrorContext* errctx) {
|
||||
@ -64,6 +80,6 @@ void __nac3_error_context_get_error_str64(ErrorContext* errctx, Str<int64_t> *ds
|
||||
}
|
||||
|
||||
void __nac3_error_dummy_raise(ErrorContext* errctx) {
|
||||
errctx->set_error("THROWN FROM __nac3_error_dummy_raise!!!!!!");
|
||||
errctx->set_error(errctx->error_ids->runtime_error, "THROWN FROM __nac3_error_dummy_raise!!!!!!");
|
||||
}
|
||||
}
|
@ -576,6 +576,21 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||
params: [Option<IntValue<'ctx>>; 3],
|
||||
loc: Location,
|
||||
) {
|
||||
let error_id = self.resolver.get_string_id(name);
|
||||
let error_id = self.ctx.i32_type().const_int(error_id as u64, false);
|
||||
self.raise_exn_impl(generator, error_id, msg, params, loc);
|
||||
}
|
||||
|
||||
pub fn raise_exn_impl<G: CodeGenerator + ?Sized>(
|
||||
&mut self,
|
||||
generator: &mut G,
|
||||
error_id: IntValue<'ctx>,
|
||||
msg: BasicValueEnum<'ctx>,
|
||||
params: [Option<IntValue<'ctx>>; 3],
|
||||
loc: Location,
|
||||
) {
|
||||
assert_eq!(error_id.get_type().get_bit_width(), 32);
|
||||
|
||||
let zelf = if let Some(exception_val) = self.exception_val {
|
||||
exception_val
|
||||
} else {
|
||||
@ -588,8 +603,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||
let zero = int32.const_zero();
|
||||
unsafe {
|
||||
let id_ptr = self.builder.build_in_bounds_gep(zelf, &[zero, zero], "exn.id").unwrap();
|
||||
let id = self.resolver.get_string_id(name);
|
||||
self.builder.build_store(id_ptr, int32.const_int(id as u64, false)).unwrap();
|
||||
self.builder.build_store(id_ptr, error_id).unwrap();
|
||||
let ptr = self
|
||||
.builder
|
||||
.build_in_bounds_gep(zelf, &[zero, int32.const_int(5, false)], "exn.msg")
|
||||
|
@ -93,7 +93,36 @@ impl<'ctx> StructureOptic<'ctx> for IrrtStringLens {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ErrorIdsFields<'ctx> {
|
||||
pub index_error: GepGetter<IntLens<'ctx>>,
|
||||
pub value_error: GepGetter<IntLens<'ctx>>,
|
||||
pub assertion_error: GepGetter<IntLens<'ctx>>,
|
||||
pub runtime_error: GepGetter<IntLens<'ctx>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ErrorIdsLens;
|
||||
|
||||
impl<'ctx> StructureOptic<'ctx> for ErrorIdsLens {
|
||||
type Fields = ErrorIdsFields<'ctx>;
|
||||
|
||||
fn struct_name(&self) -> &'static str {
|
||||
"ErrorIds"
|
||||
}
|
||||
|
||||
fn build_fields(&self, builder: &mut FieldBuilder<'ctx>) -> Self::Fields {
|
||||
let i32_lens = IntLens(builder.ctx.i32_type());
|
||||
ErrorIdsFields {
|
||||
index_error: builder.add_field("index_error", i32_lens),
|
||||
value_error: builder.add_field("value_error", i32_lens),
|
||||
assertion_error: builder.add_field("assertion_error", i32_lens),
|
||||
runtime_error: builder.add_field("runtime_error", i32_lens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ErrorContextFields<'ctx> {
|
||||
pub error_ids: GepGetter<AddressLens<ErrorIdsLens>>,
|
||||
pub message_template: GepGetter<AddressLens<IntLens<'ctx>>>,
|
||||
pub param1: GepGetter<IntLens<'ctx>>,
|
||||
pub param2: GepGetter<IntLens<'ctx>>,
|
||||
@ -115,6 +144,7 @@ impl<'ctx> StructureOptic<'ctx> for ErrorContextLens {
|
||||
builder: &mut crate::codegen::optics::FieldBuilder<'ctx>,
|
||||
) -> Self::Fields {
|
||||
ErrorContextFields {
|
||||
error_ids: builder.add_field("error_ids", AddressLens(ErrorIdsLens)),
|
||||
message_template: builder
|
||||
.add_field("message_template", AddressLens(IntLens(builder.ctx.i8_type()))),
|
||||
param1: builder.add_field("param1", IntLens(builder.ctx.i64_type())),
|
||||
|
@ -3,15 +3,13 @@ use inkwell::{
|
||||
values::{AnyValue, BasicMetadataValueEnum, IntValue},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
codegen::{
|
||||
optics::{Address, AddressLens, IntLens, Optic, OpticValue, Prism},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
util::SizeVariant,
|
||||
use crate::codegen::{
|
||||
optics::{Address, AddressLens, IntLens, Optic, OpticValue, Prism},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
use crate::util::SizeVariant;
|
||||
|
||||
use super::classes::{ErrorContextLens, StrLens};
|
||||
use super::classes::{ErrorContextLens, ErrorIdsLens, StrLens};
|
||||
|
||||
fn get_size_variant(ty: IntType) -> SizeVariant {
|
||||
match ty.get_bit_width() {
|
||||
@ -82,12 +80,34 @@ impl<'ctx, 'a> FunctionBuilder<'ctx, 'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error_ids<'ctx>(ctx: &CodeGenContext<'ctx, '_>) -> Address<'ctx, ErrorIdsLens> {
|
||||
// ErrorIdsLens.get_fields(ctx.ctx).assertion_error.
|
||||
let error_ids = ErrorIdsLens.alloca(ctx, "error_ids");
|
||||
let llvm_i32 = ctx.ctx.i32_type();
|
||||
|
||||
let get_string_id =
|
||||
|string_id| llvm_i32.const_int(ctx.resolver.get_string_id(string_id) as u64, false);
|
||||
|
||||
error_ids.view(ctx, |fields| &fields.index_error).store(ctx, &get_string_id("0:IndexError"));
|
||||
error_ids.view(ctx, |fields| &fields.value_error).store(ctx, &get_string_id("0:ValueError"));
|
||||
error_ids
|
||||
.view(ctx, |fields| &fields.assertion_error)
|
||||
.store(ctx, &get_string_id("0:AssertionError"));
|
||||
error_ids
|
||||
.view(ctx, |fields| &fields.runtime_error)
|
||||
.store(ctx, &get_string_id("0:RuntimeError"));
|
||||
|
||||
error_ids
|
||||
}
|
||||
|
||||
pub fn call_nac3_error_context_initialize<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
errctx: &Address<'ctx, ErrorContextLens>,
|
||||
error_ids: &Address<'ctx, ErrorIdsLens>,
|
||||
) {
|
||||
FunctionBuilder::begin(ctx, "__nac3_error_context_initialize")
|
||||
.arg("errctx", &AddressLens(ErrorContextLens), errctx)
|
||||
.arg("error_ids", &AddressLens(ErrorIdsLens), error_ids)
|
||||
.returning_void();
|
||||
}
|
||||
|
||||
@ -130,9 +150,10 @@ pub fn test_dummy_raise<G: CodeGenerator + ?Sized>(
|
||||
) {
|
||||
let size_type = generator.get_size_type(ctx.ctx);
|
||||
|
||||
let error_ids = build_error_ids(ctx);
|
||||
let errctx_ptr = ErrorContextLens.alloca(ctx, "errctx");
|
||||
|
||||
call_nac3_error_context_initialize(ctx, &errctx_ptr);
|
||||
call_nac3_error_context_initialize(ctx, &errctx_ptr, &error_ids);
|
||||
call_nac3_dummy_raise(ctx, &errctx_ptr);
|
||||
|
||||
let has_error = call_nac3_error_context_has_no_error(ctx, &errctx_ptr);
|
||||
|
@ -172,7 +172,7 @@ impl<'ctx, AddresseeOptic: MemoryGetter<'ctx>> Address<'ctx, AddresseeOptic> {
|
||||
|
||||
// To make [`Address`] convenient to use
|
||||
impl<'ctx, AddresseeOptic: MemorySetter<'ctx>> Address<'ctx, AddresseeOptic> {
|
||||
pub fn set(&self, ctx: &CodeGenContext<'ctx, '_>, value: &AddresseeOptic::Value) {
|
||||
pub fn store(&self, ctx: &CodeGenContext<'ctx, '_>, value: &AddresseeOptic::Value) {
|
||||
self.addressee_optic.set(ctx, self.address, value);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user