use super::super::super::abi::emit::BlobSlice;
use super::super::blob::{resolve, Segment, SymRef, SymbolBases};
use super::plan::{Cell, LiftPlan};
pub(super) mod char_info;
pub(super) mod enum_info;
pub(super) mod flags_info;
pub(super) mod handle_info;
pub(super) mod record_info;
pub(super) mod tuple_indices;
pub(super) mod variant_info;
use flags_info::FlagsRuntimeFill;
use handle_info::HandleRuntimeFill;
use record_info::RecordRuntimeFill;
use variant_info::VariantRuntimeFill;
#[derive(Clone, Debug)]
pub(crate) enum CellSideData {
None,
Record(Box<RecordRuntimeFill>),
Tuple { source: TupleIdxSource },
Flags(Box<FlagsRuntimeFill>),
Variant(Box<VariantRuntimeFill>),
Char { scratch: CharScratch },
Handle(Box<HandleRuntimeFill>),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum CharScratch {
Static { scratch_addr: i32 },
Prestaged,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum TupleIdxSource {
Static(BlobSlice),
PerIteration { offset_in_elem: u32 },
}
pub(crate) struct CellFillSources<'a> {
pub record_fill: &'a [Option<RecordRuntimeFill>],
pub tuple_indices: &'a [Option<BlobSlice>],
pub flags_fill: &'a [Option<FlagsRuntimeFill>],
pub variant_fill: &'a [Option<VariantRuntimeFill>],
pub char_scratch: &'a [Option<i32>],
pub handle_fill: &'a [Option<HandleRuntimeFill>],
}
pub(crate) fn fold_cell_side_data(
plan: &LiftPlan,
sources: &CellFillSources<'_>,
) -> Vec<CellSideData> {
let n = plan.cells.len();
debug_assert_eq!(sources.record_fill.len(), n);
debug_assert_eq!(sources.tuple_indices.len(), n);
debug_assert_eq!(sources.flags_fill.len(), n);
debug_assert_eq!(sources.variant_fill.len(), n);
debug_assert_eq!(sources.char_scratch.len(), n);
debug_assert_eq!(sources.handle_fill.len(), n);
plan.cells
.iter()
.enumerate()
.map(|(i, cell)| match cell {
Cell::RecordOf { .. } => CellSideData::Record(Box::new(
sources.record_fill[i]
.clone()
.expect("RecordOf cell missing runtime-fill bundle"),
)),
Cell::TupleOf { .. } => CellSideData::Tuple {
source: TupleIdxSource::Static(
sources.tuple_indices[i].expect("TupleOf cell missing tuple-indices slice"),
),
},
Cell::Flags { .. } => CellSideData::Flags(Box::new(
sources.flags_fill[i]
.clone()
.expect("Flags cell missing runtime-fill bundle"),
)),
Cell::Variant { .. } => CellSideData::Variant(Box::new(
sources.variant_fill[i]
.clone()
.expect("Variant cell missing runtime-fill bundle"),
)),
Cell::Char { .. } => CellSideData::Char {
scratch: CharScratch::Static {
scratch_addr: sources.char_scratch[i].expect("Char cell missing scratch addr"),
},
},
Cell::Handle { .. } => CellSideData::Handle(Box::new(
sources.handle_fill[i]
.clone()
.expect("Handle cell missing runtime-fill bundle"),
)),
Cell::Bool { .. }
| Cell::IntegerSignExt { .. }
| Cell::IntegerZeroExt { .. }
| Cell::Integer64 { .. }
| Cell::FloatingF32 { .. }
| Cell::FloatingF64 { .. }
| Cell::Text { .. }
| Cell::Bytes { .. }
| Cell::EnumCase { .. }
| Cell::Option { .. }
| Cell::Result { .. }
| Cell::ListOf { .. } => CellSideData::None,
})
.collect()
}
pub(super) fn back_fill_per_cell<F>(
fill: &mut PerCellIndices<F>,
single_fill: &mut [Option<F>],
mut patch: impl FnMut(&mut F),
) {
for fn_row in fill.per_param.iter_mut() {
for param_row in fn_row.iter_mut() {
for slot in param_row.iter_mut() {
if let Some(f) = slot.as_mut() {
patch(f);
}
}
}
}
for fn_row in fill.per_result.iter_mut() {
for slot in fn_row.iter_mut() {
if let Some(f) = slot.as_mut() {
patch(f);
}
}
}
for slot in single_fill.iter_mut() {
if let Some(f) = slot.as_mut() {
patch(f);
}
}
}
pub(crate) struct PerCellIndices<T> {
pub(super) per_param: Vec<Vec<Vec<Option<T>>>>,
pub(super) per_result: Vec<Vec<Option<T>>>,
}
impl<T> PerCellIndices<T> {
pub(crate) fn for_param(&self, fn_idx: usize, param_idx: usize) -> &[Option<T>] {
&self.per_param[fn_idx][param_idx]
}
pub(crate) fn for_result(&self, fn_idx: usize) -> &[Option<T>] {
&self.per_result[fn_idx]
}
}
impl PerCellIndices<SymRef> {
pub(crate) fn resolve_param(
&self,
fn_idx: usize,
param_idx: usize,
symbols: &SymbolBases,
) -> Vec<Option<BlobSlice>> {
resolve_cell_syms(self.for_param(fn_idx, param_idx), symbols)
}
pub(crate) fn resolve_result(
&self,
fn_idx: usize,
symbols: &SymbolBases,
) -> Vec<Option<BlobSlice>> {
resolve_cell_syms(self.for_result(fn_idx), symbols)
}
}
fn resolve_cell_syms(syms: &[Option<SymRef>], symbols: &SymbolBases) -> Vec<Option<BlobSlice>> {
syms.iter()
.map(|s| s.map(|s| resolve(Some(s), symbols)))
.collect()
}
pub(super) const INFO_TYPE_NAME: &str = "type-name";
pub(crate) struct SideTableBlob {
pub segment: Segment,
pub per_param: Vec<Vec<Option<SymRef>>>,
pub per_result: Vec<Option<SymRef>>,
}