Phase 10.7 scaffolding: IRBuilder control-flow APIs; LowerCore prepares block mapping and calls branch/jump hooks (no-op by default).
This commit is contained in:
@ -25,6 +25,17 @@ pub trait IRBuilder {
|
||||
fn emit_return(&mut self);
|
||||
/// Phase 10_d scaffolding: host-call emission (symbolic)
|
||||
fn emit_host_call(&mut self, _symbol: &str, _argc: usize, _has_ret: bool) { }
|
||||
// ==== Phase 10.7 (control-flow wiring, default no-op) ====
|
||||
/// Optional: prepare N basic blocks and return their handles (0..N-1)
|
||||
fn prepare_blocks(&mut self, _count: usize) { }
|
||||
/// Optional: switch current insertion point to a given block index
|
||||
fn switch_to_block(&mut self, _index: usize) { }
|
||||
/// Optional: seal a block after all predecessors are known
|
||||
fn seal_block(&mut self, _index: usize) { }
|
||||
/// Optional: conditional branch, treating the top-of-stack as condition (i64!=0 or b1)
|
||||
fn br_if_top_is_true(&mut self, _then_index: usize, _else_index: usize) { }
|
||||
/// Optional: unconditional jump to target block index
|
||||
fn jump_to(&mut self, _target_index: usize) { }
|
||||
}
|
||||
|
||||
pub struct NoopBuilder {
|
||||
|
||||
@ -24,16 +24,43 @@ impl LowerCore {
|
||||
for (i, v) in func.params.iter().copied().enumerate() {
|
||||
self.param_index.insert(v, i);
|
||||
}
|
||||
// Prepare block mapping (Phase 10.7 stub): deterministic ordering by sorted keys
|
||||
let mut bb_ids: Vec<_> = func.blocks.keys().copied().collect();
|
||||
bb_ids.sort_by_key(|b| b.0);
|
||||
builder.prepare_blocks(bb_ids.len());
|
||||
builder.prepare_signature_i64(func.params.len(), true);
|
||||
builder.begin_function(&func.signature.name);
|
||||
for (_bb_id, bb) in func.blocks.iter() {
|
||||
// Iterate blocks in the sorted order to keep indices stable
|
||||
for (idx, bb_id) in bb_ids.iter().enumerate() {
|
||||
let bb = func.blocks.get(bb_id).unwrap();
|
||||
builder.switch_to_block(idx);
|
||||
for instr in bb.instructions.iter() {
|
||||
self.cover_if_supported(instr);
|
||||
self.try_emit(builder, instr);
|
||||
}
|
||||
if let Some(term) = &bb.terminator {
|
||||
self.cover_if_supported(term);
|
||||
self.try_emit(builder, term);
|
||||
// Branch/Jump need block mapping: pass indices
|
||||
match term {
|
||||
crate::mir::MirInstruction::Branch { condition, then_bb, else_bb } => {
|
||||
// Try to place condition on stack (param/const path); builder will adapt
|
||||
self.push_value_if_known_or_param(builder, condition);
|
||||
// Map BasicBlockId -> index
|
||||
let then_index = bb_ids.iter().position(|x| x == then_bb).unwrap_or(0);
|
||||
let else_index = bb_ids.iter().position(|x| x == else_bb).unwrap_or(0);
|
||||
builder.br_if_top_is_true(then_index, else_index);
|
||||
builder.seal_block(then_index);
|
||||
builder.seal_block(else_index);
|
||||
}
|
||||
crate::mir::MirInstruction::Jump { target } => {
|
||||
let target_index = bb_ids.iter().position(|x| x == target).unwrap_or(0);
|
||||
builder.jump_to(target_index);
|
||||
builder.seal_block(target_index);
|
||||
}
|
||||
_ => {
|
||||
self.try_emit(builder, term);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.end_function();
|
||||
|
||||
Reference in New Issue
Block a user