forked from M-Labs/nac3
core/model: add CSlice & Exception models
This commit is contained in:
parent
afab0a997c
commit
679315acad
|
@ -44,6 +44,7 @@ pub mod llvm_intrinsics;
|
|||
pub mod model;
|
||||
pub mod numpy;
|
||||
pub mod stmt;
|
||||
pub mod structs;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
use crate::codegen::{model::*, CodeGenContext};
|
||||
|
||||
/// Fields of [`CSlice<'ctx>`].
|
||||
pub struct CSliceFields<'ctx> {
|
||||
/// Pointer to the data.
|
||||
pub base: Field<PointerModel<ByteModel>>,
|
||||
/// Number of bytes of the data.
|
||||
pub len: Field<SizeTModel<'ctx>>,
|
||||
}
|
||||
|
||||
/// See <https://crates.io/crates/cslice>.
|
||||
///
|
||||
/// Additionally, see <https://github.com/m-labs/artiq/blob/b0d2705c385f64b6e6711c1726cd9178f40b598e/artiq/firmware/libeh/eh_artiq.rs>)
|
||||
/// for ARTIQ-specific notes.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct CSlice<'ctx> {
|
||||
pub sizet: SizeTModel<'ctx>,
|
||||
}
|
||||
|
||||
impl<'ctx> StructKind<'ctx> for CSlice<'ctx> {
|
||||
type Fields = CSliceFields<'ctx>;
|
||||
|
||||
fn struct_name(&self) -> &'static str {
|
||||
"CSlice"
|
||||
}
|
||||
|
||||
fn build_fields(&self, builder: &mut FieldBuilder<'ctx>) -> Self::Fields {
|
||||
Self::Fields {
|
||||
base: builder.add_field_auto("content"),
|
||||
len: builder.add_field("length", self.sizet),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructModel<CSlice<'ctx>> {
|
||||
/// Create a [`CSlice`].
|
||||
///
|
||||
/// `base` and `len` must be LLVM global constants.
|
||||
pub fn create_const(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
base: Pointer<'ctx, ByteModel>,
|
||||
len: SizeT<'ctx>,
|
||||
) -> Struct<'ctx, CSlice<'ctx>> {
|
||||
let value = self
|
||||
.get_struct_type(ctx.ctx)
|
||||
.const_named_struct(&[base.value.into(), len.value.into()]);
|
||||
self.believe_value(value)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
use crate::codegen::model::*;
|
||||
|
||||
use super::cslice::CSlice;
|
||||
|
||||
/// The LLVM int type of an Exception ID.
|
||||
pub type ExceptionId = Int32;
|
||||
|
||||
/// Fields of [`Exception<'ctx>`]
|
||||
///
|
||||
/// The definition came from `pub struct Exception<'a>` in
|
||||
/// <https://github.com/m-labs/artiq/blob/master/artiq/firmware/libeh/eh_artiq.rs>.
|
||||
pub struct ExceptionFields<'ctx> {
|
||||
/// nac3core's ID of the exception
|
||||
pub exception_id: Field<NIntModel<ExceptionId>>,
|
||||
/// The name of the file this `Exception` was raised in.
|
||||
pub filename: Field<StructModel<CSlice<'ctx>>>,
|
||||
/// The line number in the file this `Exception` was raised in.
|
||||
pub line: Field<NIntModel<Int32>>,
|
||||
/// The column number in the file this `Exception` was raised in.
|
||||
pub column: Field<NIntModel<Int32>>,
|
||||
/// The name of the Python function this `Exception` was raised in.
|
||||
pub function_name: Field<StructModel<CSlice<'ctx>>>,
|
||||
/// The message of this Exception.
|
||||
///
|
||||
/// The message can optionally contain integer parameters `{0}`, `{1}`, and `{2}` in its string,
|
||||
/// where they will be substituted by `params[0]`, `params[1]`, and `params[2]` respectively (as `int64_t`s).
|
||||
/// Here is an example:
|
||||
///
|
||||
/// ```ignore
|
||||
/// "Index {0} is out of bounds! List only has {1} element(s)."
|
||||
/// ```
|
||||
///
|
||||
/// In this case, `params[0]` and `params[1]` must be specified, and `params[2]` is ***unused***.
|
||||
/// Having only 3 parameters is a constraint in ARTIQ.
|
||||
pub message: Field<StructModel<CSlice<'ctx>>>,
|
||||
pub params: [Field<NIntModel<Int64>>; 3],
|
||||
}
|
||||
|
||||
/// nac3core & ARTIQ's Exception
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Exception<'ctx> {
|
||||
/// The `SizeT` type of this string.
|
||||
pub sizet: SizeTModel<'ctx>,
|
||||
}
|
||||
|
||||
impl<'ctx> StructKind<'ctx> for Exception<'ctx> {
|
||||
type Fields = ExceptionFields<'ctx>;
|
||||
|
||||
fn struct_name(&self) -> &'static str {
|
||||
"Exception"
|
||||
}
|
||||
|
||||
fn build_fields(&self, builder: &mut FieldBuilder<'ctx>) -> Self::Fields {
|
||||
let str = StructModel(CSlice { sizet: self.sizet });
|
||||
|
||||
let exception_id = builder.add_field_auto("exception_id");
|
||||
let file_name = builder.add_field("file_name", str);
|
||||
let line = builder.add_field_auto("line");
|
||||
let column = builder.add_field_auto("column");
|
||||
let function_name = builder.add_field("function_name", str);
|
||||
let message = builder.add_field("message", str);
|
||||
let params = [
|
||||
builder.add_field_auto("param0"),
|
||||
builder.add_field_auto("param1"),
|
||||
builder.add_field_auto("param2"),
|
||||
];
|
||||
|
||||
Self::Fields {
|
||||
exception_id,
|
||||
filename: file_name,
|
||||
line,
|
||||
column,
|
||||
function_name,
|
||||
message,
|
||||
params,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod cslice;
|
||||
pub mod exception;
|
Loading…
Reference in New Issue