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 model;
|
||||||
pub mod numpy;
|
pub mod numpy;
|
||||||
pub mod stmt;
|
pub mod stmt;
|
||||||
|
pub mod structs;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod 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