hibana 0.4.1

Const-projected Affine Multiparty Session Types for choreography-first Rust protocols
Documentation
use super::super::images::program::{
    CompiledProgramFacts, CompiledProgramSection, DynamicPolicySite,
};
use super::LoweringSummary;
use super::program_lowering::{
    compiled_program_emit_atom_into_slices, compiled_program_emit_route_controls,
    compiled_program_push_dynamic_policy_site,
};
use super::program_tail_storage::CompiledProgramTailStorage;
use crate::control::cluster::effects::ResourceDescriptor;
use crate::eff::{EffIndex, EffKind};
use crate::global::const_dsl::PolicyMode;
use core::ptr;

pub(crate) unsafe fn init_compiled_program_image_from_summary(
    dst: *mut CompiledProgramFacts,
    summary: &LoweringSummary,
) {
    let counts = summary.compiled_program_counts();
    let storage = unsafe { CompiledProgramTailStorage::from_image_ptr(dst, counts) };
    let base = dst.cast::<u8>().cast_const();
    let resources_section = unsafe {
        CompiledProgramSection::from_ptr(
            base,
            storage.resources.cast_const(),
            storage.resources_len,
        )
    };
    let dynamic_policy_sites_section = unsafe {
        CompiledProgramSection::from_ptr(base, storage.sites.cast_const(), storage.sites_len)
    };
    let route_controls_section = unsafe {
        CompiledProgramSection::from_ptr(
            base,
            storage.route_controls.cast_const(),
            storage.route_controls_len,
        )
    };
    unsafe {
        ptr::addr_of_mut!((*dst).resources).write(resources_section);
        ptr::addr_of_mut!((*dst).dynamic_policy_sites).write(dynamic_policy_sites_section);
        ptr::addr_of_mut!((*dst).route_controls).write(route_controls_section);
        ptr::addr_of_mut!((*dst).role_count).write(summary.compiled_program_role_count() as u8);
        ptr::addr_of_mut!((*dst).control_scope_mask).write(0);
    }

    let resources =
        unsafe { core::slice::from_raw_parts_mut(storage.resources, storage.resources_len) };
    let mut resources_len = 0usize;
    let dynamic_policy_sites =
        unsafe { core::slice::from_raw_parts_mut(storage.sites, storage.sites_len) };
    let mut dynamic_policy_sites_len = 0usize;
    let route_controls = unsafe {
        core::slice::from_raw_parts_mut(storage.route_controls, storage.route_controls_len)
    };
    let mut route_controls_len = 0usize;

    let view = summary.view();
    let mut segment_idx = 0usize;
    while segment_idx < view.segment_count() {
        let segment = view.segment_at(segment_idx);
        let mut local = 0usize;
        while local < segment.len() {
            let offset = segment.start() + local;
            let node = segment.node_at_local(local);
            if matches!(node.kind, EffKind::Atom) {
                let policy = match segment.policy_at_local(local) {
                    Some(policy) => policy,
                    None => PolicyMode::Static,
                };
                let atom = node.atom_data();
                let control_desc = segment.control_desc_at_local(local);
                let resource_policy_site = if policy.is_dynamic() {
                    compiled_program_push_dynamic_policy_site(
                        dynamic_policy_sites,
                        &mut dynamic_policy_sites_len,
                        DynamicPolicySite::new(
                            EffIndex::from_dense_ordinal(offset),
                            atom.label,
                            atom.resource,
                            control_desc.map(crate::global::ControlDesc::op),
                            policy,
                        ),
                    )
                } else {
                    ResourceDescriptor::STATIC_POLICY_SITE
                };
                compiled_program_emit_atom_into_slices(
                    resources,
                    &mut resources_len,
                    atom,
                    offset,
                    policy,
                    resource_policy_site,
                    control_desc,
                );
            }
            local += 1;
        }
        segment_idx += 1;
    }

    unsafe {
        ptr::addr_of_mut!((*dst).resources).write(resources_section.with_len(resources_len));
        ptr::addr_of_mut!((*dst).dynamic_policy_sites)
            .write(dynamic_policy_sites_section.with_len(dynamic_policy_sites_len));
        compiled_program_emit_route_controls(route_controls, &mut route_controls_len, summary);
        ptr::addr_of_mut!((*dst).route_controls)
            .write(route_controls_section.with_len(route_controls_len));
        ptr::addr_of_mut!((*dst).control_scope_mask)
            .write(summary.compiled_program_control_scope_mask());
    }
}