refactor(mir): Remove ScopeContext legacy fields (Phase 2-4/7)
完全移行→削除の安全順序(Option C)に従い、ScopeContextの
deprecated フィールドと sync helpers を完全削除。
## Changes
- Migrated all access sites to scope_ctx.*
- Removed 7 deprecated fields:
- current_function
- lexical_scope_stack
- function_param_names
- loop_header_stack
- loop_exit_stack
- if_merge_stack
- debug_scope_stack
- Removed 2 sync helpers (sync_scope_ctx_to_legacy, sync_legacy_to_scope_ctx)
- Updated 20+ files with direct field access
## Tests
- cargo build --release: PASS ✅
- Deprecation warnings: 255 → 166 (-89, -35%)
Phase 2 Progress: 4/7 contexts complete (57%)
This commit is contained in:
@ -78,11 +78,6 @@ pub struct MirBuilder {
|
||||
/// Current module being built
|
||||
pub(super) current_module: Option<MirModule>,
|
||||
|
||||
/// [DEPRECATED] Current function being built
|
||||
/// Phase 136: Moved to scope_ctx.current_function (backward compat wrapper)
|
||||
#[deprecated(note = "Use scope_ctx.current_function instead")]
|
||||
pub(super) current_function: Option<MirFunction>,
|
||||
|
||||
/// Current basic block being built
|
||||
pub(super) current_block: Option<BasicBlockId>,
|
||||
|
||||
@ -139,11 +134,6 @@ pub struct MirBuilder {
|
||||
#[deprecated(note = "Use variable_ctx.variable_map instead")]
|
||||
pub(super) variable_map: BTreeMap<String, ValueId>,
|
||||
|
||||
/// [DEPRECATED] Lexical scope stack for block-scoped `local` declarations.
|
||||
/// Phase 136: Moved to scope_ctx.lexical_scope_stack (backward compat wrapper)
|
||||
#[deprecated(note = "Use scope_ctx.lexical_scope_stack instead")]
|
||||
lexical_scope_stack: Vec<vars::lexical_scope::LexicalScopeFrame>,
|
||||
|
||||
/// Pending phi functions to be inserted
|
||||
#[allow(dead_code)]
|
||||
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
|
||||
@ -198,11 +188,6 @@ pub struct MirBuilder {
|
||||
#[deprecated(note = "Use comp_ctx.static_method_index instead")]
|
||||
pub(super) static_method_index: std::collections::HashMap<String, Vec<(String, usize)>>,
|
||||
|
||||
/// [DEPRECATED] Function parameter names (for LoopForm PHI construction)
|
||||
/// Phase 136: Moved to scope_ctx.function_param_names (backward compat wrapper)
|
||||
#[deprecated(note = "Use scope_ctx.function_param_names instead")]
|
||||
pub(super) function_param_names: HashSet<String>,
|
||||
|
||||
/// [DEPRECATED] Fast lookup: method+arity tail → candidate function names (e.g., ".str/0" → ["JsonNode.str/0", ...])
|
||||
/// Phase 136 Step 7/7: Moved to comp_ctx.method_tail_index (backward compat wrapper)
|
||||
#[deprecated(note = "Use comp_ctx.method_tail_index instead")]
|
||||
@ -233,19 +218,6 @@ pub struct MirBuilder {
|
||||
pub binding_map: BTreeMap<String, super::BindingId>,
|
||||
|
||||
// include guards removed
|
||||
/// [DEPRECATED] Loop context stacks for lowering break/continue inside nested control flow
|
||||
/// Phase 136: Moved to scope_ctx.loop_header_stack (backward compat wrapper)
|
||||
#[deprecated(note = "Use scope_ctx.loop_header_stack instead")]
|
||||
pub(super) loop_header_stack: Vec<BasicBlockId>,
|
||||
#[allow(dead_code)]
|
||||
#[deprecated(note = "Use scope_ctx.loop_exit_stack instead")]
|
||||
pub(super) loop_exit_stack: Vec<BasicBlockId>,
|
||||
|
||||
/// [DEPRECATED] If/merge context stack (innermost first)
|
||||
/// Phase 136: Moved to scope_ctx.if_merge_stack (backward compat wrapper)
|
||||
#[deprecated(note = "Use scope_ctx.if_merge_stack instead")]
|
||||
pub(super) if_merge_stack: Vec<BasicBlockId>,
|
||||
|
||||
// フェーズM: no_phi_modeフィールド削除(常にPHI使用)
|
||||
|
||||
// ---- Try/Catch/Cleanup lowering context ----
|
||||
@ -270,10 +242,6 @@ pub struct MirBuilder {
|
||||
// ----------------------
|
||||
// Debug scope context (dev only; zero-cost when unused)
|
||||
// ----------------------
|
||||
/// [DEPRECATED] Stack of region identifiers like "loop#1/header" or "join#3/join".
|
||||
/// Phase 136: Moved to scope_ctx.debug_scope_stack (backward compat wrapper)
|
||||
#[deprecated(note = "Use scope_ctx.debug_scope_stack instead")]
|
||||
debug_scope_stack: Vec<String>,
|
||||
|
||||
/// Local SSA cache: ensure per-block materialization for critical operands (e.g., recv)
|
||||
/// Key: (bb, original ValueId, kind) -> local ValueId
|
||||
@ -323,7 +291,6 @@ impl MirBuilder {
|
||||
#[allow(deprecated)]
|
||||
Self {
|
||||
current_module: None,
|
||||
current_function: None,
|
||||
current_block: None,
|
||||
|
||||
// Phase 136 Step 2/7: Core context (new SSOT)
|
||||
@ -337,7 +304,6 @@ impl MirBuilder {
|
||||
metadata_ctx: metadata_context::MetadataContext::new(), // Phase 136 Step 6/7: Metadata context
|
||||
comp_ctx, // Phase 136 Step 7/7: Compilation context
|
||||
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
||||
lexical_scope_stack: Vec::new(),
|
||||
pending_phis: Vec::new(),
|
||||
user_defined_boxes: HashSet::new(),
|
||||
weak_fields_by_box: HashMap::new(),
|
||||
@ -349,7 +315,6 @@ impl MirBuilder {
|
||||
plugin_method_sigs,
|
||||
current_static_box: None,
|
||||
static_method_index: std::collections::HashMap::new(),
|
||||
function_param_names: HashSet::new(),
|
||||
method_tail_index: std::collections::HashMap::new(),
|
||||
method_tail_index_source_len: 0,
|
||||
|
||||
@ -358,9 +323,6 @@ impl MirBuilder {
|
||||
|
||||
binding_map: BTreeMap::new(), // Phase 74: Initialize BindingId mapping
|
||||
|
||||
loop_header_stack: Vec::new(),
|
||||
loop_exit_stack: Vec::new(),
|
||||
if_merge_stack: Vec::new(),
|
||||
// フェーズM: no_phi_modeフィールド削除
|
||||
return_defer_active: false,
|
||||
return_defer_slot: None,
|
||||
@ -371,9 +333,6 @@ impl MirBuilder {
|
||||
cleanup_allow_throw: false,
|
||||
suppress_pin_entry_copy_next: false,
|
||||
|
||||
// Debug scope context
|
||||
debug_scope_stack: Vec::new(),
|
||||
|
||||
local_ssa_map: HashMap::new(),
|
||||
schedule_mat_map: HashMap::new(),
|
||||
pin_slot_names: HashMap::new(),
|
||||
@ -385,31 +344,6 @@ impl MirBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Phase 136 Step 3/7: ScopeContext synchronization helpers ----
|
||||
/// Sync scope_ctx changes back to legacy fields (backward compatibility)
|
||||
#[allow(deprecated)]
|
||||
fn sync_scope_ctx_to_legacy(&mut self) {
|
||||
self.lexical_scope_stack = self.scope_ctx.lexical_scope_stack.clone();
|
||||
self.loop_header_stack = self.scope_ctx.loop_header_stack.clone();
|
||||
self.loop_exit_stack = self.scope_ctx.loop_exit_stack.clone();
|
||||
self.if_merge_stack = self.scope_ctx.if_merge_stack.clone();
|
||||
self.current_function = self.scope_ctx.current_function.clone();
|
||||
self.function_param_names = self.scope_ctx.function_param_names.clone();
|
||||
self.debug_scope_stack = self.scope_ctx.debug_scope_stack.clone();
|
||||
}
|
||||
|
||||
/// Sync legacy field changes to scope_ctx (backward compatibility)
|
||||
#[allow(deprecated)]
|
||||
fn sync_legacy_to_scope_ctx(&mut self) {
|
||||
self.scope_ctx.lexical_scope_stack = self.lexical_scope_stack.clone();
|
||||
self.scope_ctx.loop_header_stack = self.loop_header_stack.clone();
|
||||
self.scope_ctx.loop_exit_stack = self.loop_exit_stack.clone();
|
||||
self.scope_ctx.if_merge_stack = self.if_merge_stack.clone();
|
||||
self.scope_ctx.current_function = self.current_function.clone();
|
||||
self.scope_ctx.function_param_names = self.function_param_names.clone();
|
||||
self.scope_ctx.debug_scope_stack = self.debug_scope_stack.clone();
|
||||
}
|
||||
|
||||
// ---- Phase 136 Step 4/7: BindingContext synchronization helpers ----
|
||||
/// Sync binding_ctx changes back to legacy fields (backward compatibility)
|
||||
#[allow(deprecated)]
|
||||
|
||||
@ -21,7 +21,7 @@ impl MirBuilder {
|
||||
// Dev trace
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
let cur_fun = self
|
||||
.current_function
|
||||
.scope_ctx.current_function
|
||||
.as_ref()
|
||||
.map(|f| f.signature.name.clone())
|
||||
.unwrap_or_else(|| "<none>".to_string());
|
||||
|
||||
@ -79,9 +79,8 @@ impl MirBuilder {
|
||||
let entry = self.next_block_id();
|
||||
let function = self.new_function_with_metadata(signature, entry);
|
||||
|
||||
// Phase 136 Step 3/7: Save from scope_ctx (SSOT), sync to legacy field
|
||||
// Phase 136 Step 3/7: Save from scope_ctx (SSOT)
|
||||
ctx.saved_function = self.scope_ctx.current_function.take();
|
||||
self.current_function = None;
|
||||
ctx.saved_block = self.current_block.take();
|
||||
|
||||
eprintln!(
|
||||
@ -90,9 +89,8 @@ impl MirBuilder {
|
||||
);
|
||||
eprintln!("[DEBUG/create_function_skeleton] Entry block: {:?}", entry);
|
||||
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
self.scope_ctx.current_function = Some(function.clone());
|
||||
self.current_function = Some(function);
|
||||
// Phase 136 Step 3/7: Use scope_ctx as SSOT
|
||||
self.scope_ctx.current_function = Some(function);
|
||||
self.current_block = Some(entry);
|
||||
// 新しい関数スコープ用の SlotRegistry を準備するよ(観測専用)
|
||||
self.current_slot_registry = Some(FunctionSlotRegistry::new());
|
||||
@ -107,15 +105,14 @@ impl MirBuilder {
|
||||
/// 🎯 箱理論: Step 3 - パラメータ設定
|
||||
#[allow(deprecated)]
|
||||
fn setup_function_params(&mut self, params: &[String]) {
|
||||
// Phase 136 Step 3/7: Clear both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
// Phase 136 Step 3/7: Clear scope_ctx (SSOT)
|
||||
self.scope_ctx.function_param_names.clear();
|
||||
self.function_param_names.clear();
|
||||
// SlotRegistry 更新は borrow 競合を避けるため、まずローカルに集約してから反映するよ。
|
||||
let mut slot_regs: Vec<(String, Option<MirType>)> = Vec::new();
|
||||
// Phase 26-A-3: パラメータ型情報も後で一括登録(借用競合回避)
|
||||
let mut param_kinds: Vec<(ValueId, u32)> = Vec::new();
|
||||
|
||||
if let Some(ref mut f) = self.current_function {
|
||||
if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
// 📦 Hotfix 5: Use pre-populated params from MirFunction::new()
|
||||
// Static methods have implicit receiver at params[0], so actual parameters start at offset
|
||||
let receiver_offset = if f.params.is_empty() {
|
||||
@ -143,9 +140,8 @@ impl MirBuilder {
|
||||
new_pid
|
||||
};
|
||||
self.variable_map.insert(p.clone(), pid);
|
||||
// Phase 136 Step 3/7: Insert into both scope_ctx (SSOT) and legacy field
|
||||
// Phase 136 Step 3/7: Insert into scope_ctx (SSOT)
|
||||
self.scope_ctx.function_param_names.insert(p.clone());
|
||||
self.function_param_names.insert(p.clone());
|
||||
|
||||
// Phase 26-A-3: パラメータ型情報を収集(後で一括登録)
|
||||
// param_idx: receiver offset を考慮した実際のパラメータインデックス
|
||||
@ -183,7 +179,7 @@ impl MirBuilder {
|
||||
fn finalize_function(&mut self, returns_value: bool) -> Result<(), String> {
|
||||
// Void return追加(必要な場合)
|
||||
if !returns_value {
|
||||
if let Some(ref mut f) = self.current_function {
|
||||
if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
if let Some(block) = f.get_block(self.current_block.unwrap()) {
|
||||
if !block.is_terminated() {
|
||||
let void_val = crate::mir::builder::emission::constant::emit_void(self);
|
||||
@ -196,7 +192,7 @@ impl MirBuilder {
|
||||
}
|
||||
|
||||
// 型推論
|
||||
if let Some(ref mut f) = self.current_function {
|
||||
if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
if returns_value && matches!(f.signature.return_type, MirType::Void | MirType::Unknown)
|
||||
{
|
||||
let mut inferred: Option<MirType> = None;
|
||||
@ -223,9 +219,8 @@ impl MirBuilder {
|
||||
}
|
||||
|
||||
// Moduleに追加
|
||||
// Phase 136 Step 3/7: Take from legacy field, sync to scope_ctx
|
||||
let finalized = self.current_function.take().unwrap();
|
||||
self.scope_ctx.current_function = None;
|
||||
// Phase 136 Step 3/7: Take from scope_ctx (SSOT)
|
||||
let finalized = self.scope_ctx.current_function.take().unwrap();
|
||||
if let Some(ref mut module) = self.current_module {
|
||||
module.add_function(finalized);
|
||||
}
|
||||
@ -235,9 +230,8 @@ impl MirBuilder {
|
||||
|
||||
/// 🎯 箱理論: Step 6 - Context復元
|
||||
fn restore_lowering_context(&mut self, ctx: LoweringContext) {
|
||||
// Phase 136 Step 3/7: Restore to scope_ctx (SSOT), sync to legacy field
|
||||
self.scope_ctx.current_function = ctx.saved_function.clone();
|
||||
self.current_function = ctx.saved_function;
|
||||
// Phase 136 Step 3/7: Restore to scope_ctx (SSOT)
|
||||
self.scope_ctx.current_function = ctx.saved_function;
|
||||
self.current_block = ctx.saved_block;
|
||||
|
||||
// モード別にcontext復元
|
||||
@ -272,14 +266,12 @@ impl MirBuilder {
|
||||
let entry = self.next_block_id();
|
||||
let function = self.new_function_with_metadata(signature, entry);
|
||||
|
||||
// Phase 136 Step 3/7: Save from scope_ctx (SSOT), sync to legacy field
|
||||
// Phase 136 Step 3/7: Save from scope_ctx (SSOT)
|
||||
ctx.saved_function = self.scope_ctx.current_function.take();
|
||||
self.current_function = None;
|
||||
ctx.saved_block = self.current_block.take();
|
||||
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
self.scope_ctx.current_function = Some(function.clone());
|
||||
self.current_function = Some(function);
|
||||
// Phase 136 Step 3/7: Use scope_ctx as SSOT
|
||||
self.scope_ctx.current_function = Some(function);
|
||||
self.current_block = Some(entry);
|
||||
// instance method 用の関数スコープ SlotRegistry もここで用意するよ。
|
||||
self.current_slot_registry = Some(FunctionSlotRegistry::new());
|
||||
@ -296,7 +288,7 @@ impl MirBuilder {
|
||||
// SlotRegistry 更新はローカルバッファに集約してから反映するよ。
|
||||
let mut slot_regs: Vec<(String, Option<MirType>)> = Vec::new();
|
||||
|
||||
if let Some(ref mut f) = self.current_function {
|
||||
if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
// 📦 Hotfix 6 改訂版:
|
||||
// MirFunction::new() が既に 0..N の ValueId を params 用に予約しているので、
|
||||
// ここではそれを「上書き使用」するだけにして、push で二重定義しないようにするよ。
|
||||
@ -377,7 +369,7 @@ impl MirBuilder {
|
||||
self.lower_function_body(body)?;
|
||||
|
||||
// Step 5: 関数finalize
|
||||
let returns_value = if let Some(ref f) = self.current_function {
|
||||
let returns_value = if let Some(ref f) = self.scope_ctx.current_function {
|
||||
!matches!(f.signature.return_type, MirType::Void)
|
||||
} else {
|
||||
false
|
||||
@ -427,7 +419,7 @@ impl MirBuilder {
|
||||
self.lower_method_body(body)?;
|
||||
|
||||
// Step 5: 関数finalize
|
||||
let returns_value = if let Some(ref f) = self.current_function {
|
||||
let returns_value = if let Some(ref f) = self.scope_ctx.current_function {
|
||||
!matches!(f.signature.return_type, MirType::Void)
|
||||
} else {
|
||||
false
|
||||
@ -442,7 +434,7 @@ impl MirBuilder {
|
||||
}
|
||||
|
||||
// 型推論(Step 5の一部として)
|
||||
if let Some(ref mut f) = self.current_function {
|
||||
if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
if returns_value && matches!(f.signature.return_type, MirType::Void | MirType::Unknown)
|
||||
{
|
||||
let mut inferred: Option<MirType> = None;
|
||||
@ -469,7 +461,7 @@ impl MirBuilder {
|
||||
}
|
||||
|
||||
// Moduleに追加
|
||||
let finalized_function = self.current_function.take().unwrap();
|
||||
let finalized_function = self.scope_ctx.current_function.take().unwrap();
|
||||
if let Some(ref mut module) = self.current_module {
|
||||
module.add_function(finalized_function);
|
||||
}
|
||||
@ -477,9 +469,8 @@ impl MirBuilder {
|
||||
// FunctionRegion を 1 段ポップして元の関数コンテキストに戻るよ。
|
||||
crate::mir::region::observer::pop_function_region(self);
|
||||
|
||||
// Phase 136 Step 3/7: Restore to scope_ctx (SSOT), sync to legacy field
|
||||
self.scope_ctx.current_function = ctx.saved_function.clone();
|
||||
self.current_function = ctx.saved_function;
|
||||
// Phase 136 Step 3/7: Restore to scope_ctx (SSOT)
|
||||
self.scope_ctx.current_function = ctx.saved_function;
|
||||
self.current_block = ctx.saved_block;
|
||||
if let Some(saved) = ctx.saved_var_map {
|
||||
self.variable_map = saved;
|
||||
|
||||
@ -26,7 +26,7 @@ pub(super) fn build_exit_phi(
|
||||
) -> Result<(Option<ValueId>, BTreeMap<String, ValueId>), String> {
|
||||
let mut carrier_phis: BTreeMap<String, ValueId> = BTreeMap::new();
|
||||
|
||||
let exit_phi_result_id = if let Some(ref mut func) = builder.current_function {
|
||||
let exit_phi_result_id = if let Some(ref mut func) = builder.scope_ctx.current_function {
|
||||
let mut exit_block = BasicBlock::new(exit_block_id);
|
||||
|
||||
// Phase 189-Fix: If we collected return values, create a PHI in exit block
|
||||
|
||||
@ -149,7 +149,7 @@ pub(super) fn merge_and_rewrite(
|
||||
|
||||
// Phase 195 FIX: Reuse existing block if present (preserves PHI from JoinIR Select lowering)
|
||||
// ultrathink "finalizer集約案": Don't overwrite blocks with BasicBlock::new()
|
||||
let mut new_block = if let Some(ref mut current_func) = builder.current_function {
|
||||
let mut new_block = if let Some(ref mut current_func) = builder.scope_ctx.current_function {
|
||||
current_func
|
||||
.blocks
|
||||
.remove(&new_block_id)
|
||||
@ -811,7 +811,7 @@ pub(super) fn merge_and_rewrite(
|
||||
}
|
||||
|
||||
// Add block to current function
|
||||
if let Some(ref mut current_func) = builder.current_function {
|
||||
if let Some(ref mut current_func) = builder.scope_ctx.current_function {
|
||||
current_func.add_block(new_block);
|
||||
}
|
||||
}
|
||||
@ -866,7 +866,7 @@ pub(super) fn merge_and_rewrite(
|
||||
|
||||
// Use BoundaryInjector to inject Copy instructions
|
||||
// Phase 177-3 Option B: Returns reallocations map for condition_bindings with PHI collisions
|
||||
if let Some(ref mut current_func) = builder.current_function {
|
||||
if let Some(ref mut current_func) = builder.scope_ctx.current_function {
|
||||
let _reallocations = BoundaryInjector::inject_boundary_copies(
|
||||
current_func,
|
||||
entry_block_remapped,
|
||||
|
||||
@ -733,7 +733,7 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if let Some(boundary) = boundary {
|
||||
if let Some(ref func) = builder.current_function {
|
||||
if let Some(ref func) = builder.scope_ctx.current_function {
|
||||
verify_joinir_contracts(
|
||||
func,
|
||||
entry_block,
|
||||
|
||||
@ -115,7 +115,7 @@ impl super::MirBuilder {
|
||||
"Loop lowering failed: JoinIR does not support this pattern, and LoopBuilder has been removed.\n\
|
||||
Function: {}\n\
|
||||
Hint: This loop pattern is not supported. All loops must use JoinIR lowering.",
|
||||
self.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("<unknown>")
|
||||
self.scope_ctx.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("<unknown>")
|
||||
)));
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ pub fn emit_conditional(
|
||||
then_bb: BasicBlockId,
|
||||
else_bb: BasicBlockId,
|
||||
) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) {
|
||||
if let (Some(func), Some(cur_bb)) = (b.scope_ctx.current_function.as_mut(), b.current_block) {
|
||||
crate::mir::ssot::cf_common::set_branch(func, cur_bb, cond, then_bb, else_bb);
|
||||
Ok(())
|
||||
} else {
|
||||
@ -24,7 +24,7 @@ pub fn emit_conditional(
|
||||
|
||||
#[inline]
|
||||
pub fn emit_jump(b: &mut MirBuilder, target: BasicBlockId) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) {
|
||||
if let (Some(func), Some(cur_bb)) = (b.scope_ctx.current_function.as_mut(), b.current_block) {
|
||||
crate::mir::ssot::cf_common::set_jump(func, cur_bb, target);
|
||||
Ok(())
|
||||
} else {
|
||||
|
||||
@ -11,7 +11,7 @@ pub fn emit_to(
|
||||
lhs: ValueId,
|
||||
rhs: ValueId,
|
||||
) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) {
|
||||
if let (Some(func), Some(cur_bb)) = (b.scope_ctx.current_function.as_mut(), b.current_block) {
|
||||
crate::mir::ssot::cf_common::emit_compare_func(func, cur_bb, dst, op, lhs, rhs);
|
||||
} else {
|
||||
b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?;
|
||||
|
||||
@ -22,7 +22,7 @@ impl super::MirBuilder {
|
||||
// Jump from current block to dispatch (ensure terminator exists)
|
||||
let need_jump = {
|
||||
let cur = self.current_block;
|
||||
if let (Some(cb), Some(ref func)) = (cur, &self.current_function) {
|
||||
if let (Some(cb), Some(ref func)) = (cur, &self.scope_ctx.current_function) {
|
||||
if let Some(bb) = func.blocks.get(&cb) {
|
||||
!bb.is_terminated()
|
||||
} else {
|
||||
@ -118,7 +118,7 @@ impl super::MirBuilder {
|
||||
// Merge and yield result
|
||||
self.start_new_block(merge_block)?;
|
||||
// フェーズM: PHI はブロック先頭に配置(cf_common 統一)
|
||||
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) {
|
||||
if let (Some(func), Some(cur_bb)) = (self.scope_ctx.current_function.as_mut(), self.current_block) {
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
|
||||
func,
|
||||
cur_bb,
|
||||
|
||||
@ -23,7 +23,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
|
||||
) -> Result<(), String> {
|
||||
// merge ブロックの先頭に PHI を挿入
|
||||
if let (Some(func), Some(_cur_bb)) =
|
||||
(self.0.current_function.as_mut(), self.0.current_block)
|
||||
(self.0.scope_ctx.current_function.as_mut(), self.0.current_block)
|
||||
{
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
|
||||
func,
|
||||
@ -47,7 +47,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
|
||||
}
|
||||
|
||||
fn get_block_predecessors(&self, block: BasicBlockId) -> Vec<BasicBlockId> {
|
||||
if let Some(ref func) = self.0.current_function {
|
||||
if let Some(ref func) = self.0.scope_ctx.current_function {
|
||||
func.blocks
|
||||
.get(&block)
|
||||
.map(|bb| bb.predecessors.iter().copied().collect())
|
||||
@ -72,7 +72,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
|
||||
}
|
||||
|
||||
fn block_exists(&self, block: BasicBlockId) -> bool {
|
||||
if let Some(ref func) = self.0.current_function {
|
||||
if let Some(ref func) = self.0.scope_ctx.current_function {
|
||||
func.blocks.contains_key(&block)
|
||||
} else {
|
||||
false
|
||||
@ -239,7 +239,7 @@ impl MirBuilder {
|
||||
core_mainline || (joinir_enabled && is_target && (joinir_toplevel || joinir_dryrun));
|
||||
|
||||
if should_try_joinir {
|
||||
if let Some(ref func) = self.current_function {
|
||||
if let Some(ref func) = self.scope_ctx.current_function {
|
||||
let context =
|
||||
crate::mir::join_ir::lowering::if_phi_context::IfPhiContext::pure_if();
|
||||
|
||||
|
||||
@ -118,9 +118,8 @@ impl super::MirBuilder {
|
||||
main_function.metadata.is_entry_point = true;
|
||||
|
||||
self.current_module = Some(module);
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
self.scope_ctx.current_function = Some(main_function.clone());
|
||||
self.current_function = Some(main_function);
|
||||
// Phase 136 Step 3/7: Use scope_ctx as SSOT
|
||||
self.scope_ctx.current_function = Some(main_function);
|
||||
self.current_block = Some(entry_block);
|
||||
|
||||
// 関数スコープの SlotRegistry を初期化するよ(観測専用)。
|
||||
@ -293,7 +292,7 @@ impl super::MirBuilder {
|
||||
// Hint: scope leave at function end (id=0 for main)
|
||||
self.hint_scope_leave(0);
|
||||
if let Some(block_id) = self.current_block {
|
||||
if let Some(ref mut function) = self.current_function {
|
||||
if let Some(ref mut function) = self.scope_ctx.current_function {
|
||||
if let Some(block) = function.get_block_mut(block_id) {
|
||||
if !block.is_terminated() {
|
||||
block.add_instruction(MirInstruction::Return {
|
||||
@ -308,9 +307,8 @@ impl super::MirBuilder {
|
||||
}
|
||||
|
||||
let mut module = self.current_module.take().unwrap();
|
||||
// Phase 136 Step 3/7: Take from legacy field, sync to scope_ctx
|
||||
let mut function = self.current_function.take().unwrap();
|
||||
self.scope_ctx.current_function = None;
|
||||
// Phase 136 Step 3/7: Take from scope_ctx (SSOT)
|
||||
let mut function = self.scope_ctx.current_function.take().unwrap();
|
||||
// Phase 84-2: Copy命令型伝播(return型推論の前に実行)
|
||||
//
|
||||
// Loop exit や If merge の edge copy で発生する型欠如を解消する。
|
||||
|
||||
@ -8,42 +8,42 @@ pub(crate) fn push_loop_context(
|
||||
header: BasicBlockId,
|
||||
exit: BasicBlockId,
|
||||
) {
|
||||
builder.loop_header_stack.push(header);
|
||||
builder.loop_exit_stack.push(exit);
|
||||
builder.scope_ctx.loop_header_stack.push(header);
|
||||
builder.scope_ctx.loop_exit_stack.push(exit);
|
||||
}
|
||||
|
||||
/// Pop loop context (header/exit) from the MirBuilder stacks.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn pop_loop_context(builder: &mut super::MirBuilder) {
|
||||
let _ = builder.loop_header_stack.pop();
|
||||
let _ = builder.loop_exit_stack.pop();
|
||||
let _ = builder.scope_ctx.loop_header_stack.pop();
|
||||
let _ = builder.scope_ctx.loop_exit_stack.pop();
|
||||
}
|
||||
|
||||
/// Peek current loop header block id
|
||||
#[allow(dead_code)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn current_header(builder: &super::MirBuilder) -> Option<BasicBlockId> {
|
||||
builder.loop_header_stack.last().copied()
|
||||
builder.scope_ctx.loop_header_stack.last().copied()
|
||||
}
|
||||
|
||||
/// Peek current loop exit block id
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn current_exit(builder: &super::MirBuilder) -> Option<BasicBlockId> {
|
||||
builder.loop_exit_stack.last().copied()
|
||||
builder.scope_ctx.loop_exit_stack.last().copied()
|
||||
}
|
||||
|
||||
/// Returns true if the builder is currently inside at least one loop context.
|
||||
#[allow(dead_code)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn in_loop(builder: &super::MirBuilder) -> bool {
|
||||
!builder.loop_header_stack.is_empty()
|
||||
!builder.scope_ctx.loop_header_stack.is_empty()
|
||||
}
|
||||
|
||||
/// Current loop nesting depth (0 means not in a loop).
|
||||
#[allow(dead_code)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn depth(builder: &super::MirBuilder) -> usize {
|
||||
builder.loop_header_stack.len()
|
||||
builder.scope_ctx.loop_header_stack.len()
|
||||
}
|
||||
|
||||
/// Add predecessor edge metadata to a basic block.
|
||||
@ -55,7 +55,7 @@ pub(crate) fn add_predecessor(
|
||||
block: BasicBlockId,
|
||||
pred: BasicBlockId,
|
||||
) -> Result<(), String> {
|
||||
if let Some(ref mut function) = builder.current_function {
|
||||
if let Some(ref mut function) = builder.scope_ctx.current_function {
|
||||
// 📦 Hotfix 6: Ensure block exists (same as start_new_block logic)
|
||||
// Create block if not present, without changing current_block
|
||||
if !function.blocks.contains_key(&block) {
|
||||
|
||||
@ -136,7 +136,7 @@ impl super::MirBuilder {
|
||||
} else {
|
||||
// guard中は従来のBinOp
|
||||
if let (Some(func), Some(cur_bb)) =
|
||||
(self.current_function.as_mut(), self.current_block)
|
||||
(self.scope_ctx.current_function.as_mut(), self.current_block)
|
||||
{
|
||||
crate::mir::ssot::binop_lower::emit_binop_to_dst(
|
||||
func, cur_bb, dst, op, lhs, rhs,
|
||||
@ -149,7 +149,7 @@ impl super::MirBuilder {
|
||||
} else {
|
||||
// 既存の算術経路
|
||||
if let (Some(func), Some(cur_bb)) =
|
||||
(self.current_function.as_mut(), self.current_block)
|
||||
(self.scope_ctx.current_function.as_mut(), self.current_block)
|
||||
{
|
||||
crate::mir::ssot::binop_lower::emit_binop_to_dst(
|
||||
func, cur_bb, dst, op, lhs, rhs,
|
||||
@ -201,7 +201,7 @@ impl super::MirBuilder {
|
||||
} else {
|
||||
// 既存の算術経路
|
||||
if let (Some(func), Some(cur_bb)) =
|
||||
(self.current_function.as_mut(), self.current_block)
|
||||
(self.scope_ctx.current_function.as_mut(), self.current_block)
|
||||
{
|
||||
crate::mir::ssot::binop_lower::emit_binop_to_dst(
|
||||
func, cur_bb, dst, op, lhs, rhs,
|
||||
@ -392,7 +392,7 @@ impl super::MirBuilder {
|
||||
let rhs_false_exit = self.current_block()?;
|
||||
// join rhs result into a single bool
|
||||
self.start_new_block(rhs_join)?;
|
||||
if let Some(func) = self.current_function.as_mut() {
|
||||
if let Some(func) = self.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
|
||||
@ -446,7 +446,7 @@ impl super::MirBuilder {
|
||||
let rhs_false_exit = self.current_block()?;
|
||||
// join rhs result into a single bool
|
||||
self.start_new_block(rhs_join)?;
|
||||
if let Some(func) = self.current_function.as_mut() {
|
||||
if let Some(func) = self.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
|
||||
@ -476,7 +476,7 @@ impl super::MirBuilder {
|
||||
inputs.push((else_exit_block, else_value_raw));
|
||||
}
|
||||
let result_val = if inputs.len() >= 2 {
|
||||
if let Some(func) = self.current_function.as_mut() {
|
||||
if let Some(func) = self.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
let dst = self.insert_phi(inputs)?;
|
||||
|
||||
@ -12,7 +12,7 @@ pub(crate) fn annotate_me_origin(builder: &mut MirBuilder, me_id: ValueId) {
|
||||
}
|
||||
}
|
||||
if cls.is_none() {
|
||||
if let Some(ref fun) = builder.current_function {
|
||||
if let Some(ref fun) = builder.scope_ctx.current_function {
|
||||
if let Some(dot) = fun.signature.name.find('.') {
|
||||
let c = fun.signature.name[..dot].to_string();
|
||||
if !c.is_empty() {
|
||||
|
||||
@ -67,10 +67,10 @@ impl MirBuilder {
|
||||
self.variable_map.insert(pin_name.clone(), v);
|
||||
}
|
||||
_ => {
|
||||
if let Some(func) = self.current_function.as_mut() {
|
||||
if let Some(func) = self.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
if let (Some(func), Some(cur_bb)) = (&self.current_function, self.current_block)
|
||||
if let (Some(func), Some(cur_bb)) = (&self.scope_ctx.current_function, self.current_block)
|
||||
{
|
||||
crate::mir::phi_core::common::debug_verify_phi_inputs(
|
||||
func, cur_bb, &inputs,
|
||||
@ -78,7 +78,7 @@ impl MirBuilder {
|
||||
}
|
||||
let merged = self.next_value_id();
|
||||
if let (Some(func), Some(cur_bb)) =
|
||||
(self.current_function.as_mut(), self.current_block)
|
||||
(self.scope_ctx.current_function.as_mut(), self.current_block)
|
||||
{
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
|
||||
func,
|
||||
@ -169,10 +169,10 @@ impl MirBuilder {
|
||||
return Ok(inputs[0].1);
|
||||
}
|
||||
_ => {
|
||||
if let Some(func) = self.current_function.as_mut() {
|
||||
if let Some(func) = self.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
if let (Some(func), Some(cur_bb)) = (&self.current_function, self.current_block)
|
||||
if let (Some(func), Some(cur_bb)) = (&self.scope_ctx.current_function, self.current_block)
|
||||
{
|
||||
crate::mir::phi_core::common::debug_verify_phi_inputs(
|
||||
func, cur_bb, &inputs,
|
||||
@ -202,10 +202,10 @@ impl MirBuilder {
|
||||
return Ok(inputs[0].1);
|
||||
}
|
||||
_ => {
|
||||
if let Some(func) = self.current_function.as_mut() {
|
||||
if let Some(func) = self.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
if let (Some(func), Some(cur_bb)) = (&self.current_function, self.current_block)
|
||||
if let (Some(func), Some(cur_bb)) = (&self.scope_ctx.current_function, self.current_block)
|
||||
{
|
||||
crate::mir::phi_core::common::debug_verify_phi_inputs(
|
||||
func, cur_bb, &inputs,
|
||||
|
||||
@ -86,11 +86,11 @@ impl<'a> PhiMergeHelper<'a> {
|
||||
}
|
||||
_ => {
|
||||
// Multiple predecessors - insert PHI
|
||||
if let Some(func) = self.builder.current_function.as_mut() {
|
||||
if let Some(func) = self.builder.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
if let (Some(func), Some(cur_bb)) =
|
||||
(&self.builder.current_function, self.builder.current_block)
|
||||
(&self.builder.scope_ctx.current_function, self.builder.current_block)
|
||||
{
|
||||
crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs);
|
||||
}
|
||||
@ -132,11 +132,11 @@ impl<'a> PhiMergeHelper<'a> {
|
||||
}
|
||||
_ => {
|
||||
// Insert PHI with explicit dst
|
||||
if let Some(func) = self.builder.current_function.as_mut() {
|
||||
if let Some(func) = self.builder.scope_ctx.current_function.as_mut() {
|
||||
func.update_cfg();
|
||||
}
|
||||
if let (Some(func), Some(cur_bb)) =
|
||||
(&self.builder.current_function, self.builder.current_block)
|
||||
(&self.builder.scope_ctx.current_function, self.builder.current_block)
|
||||
{
|
||||
crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ impl BlockScheduleBox {
|
||||
if std::env::var("NYASH_BLOCK_SCHEDULE_VERIFY").ok().as_deref() != Some("1") {
|
||||
return;
|
||||
}
|
||||
let (f_opt, bb_opt) = (builder.current_function.as_ref(), builder.current_block);
|
||||
let (f_opt, bb_opt) = (builder.scope_ctx.current_function.as_ref(), builder.current_block);
|
||||
let (Some(fun), Some(bb_id)) = (f_opt, bb_opt) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@ -181,7 +181,7 @@ impl super::MirBuilder {
|
||||
idx + 1,
|
||||
total,
|
||||
self.current_block,
|
||||
self.current_function
|
||||
self.scope_ctx.current_function
|
||||
.as_ref()
|
||||
.map(|f| f.signature.name.as_str())
|
||||
.unwrap_or("none")
|
||||
|
||||
@ -38,7 +38,7 @@ impl super::MirBuilder {
|
||||
#[allow(deprecated)]
|
||||
pub(crate) fn next_value_id(&mut self) -> super::ValueId {
|
||||
loop {
|
||||
let candidate = if let Some(ref mut f) = self.current_function {
|
||||
let candidate = if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
f.next_value_id() // Function context
|
||||
} else {
|
||||
// Phase 136 Step 2/7 + Phase 2-2: Use core_ctx as SSOT (no sync needed)
|
||||
@ -92,7 +92,7 @@ impl super::MirBuilder {
|
||||
}
|
||||
/// Ensure a basic block exists in the current function
|
||||
pub(crate) fn ensure_block_exists(&mut self, block_id: BasicBlockId) -> Result<(), String> {
|
||||
if let Some(ref mut function) = self.current_function {
|
||||
if let Some(ref mut function) = self.scope_ctx.current_function {
|
||||
if !function.blocks.contains_key(&block_id) {
|
||||
let block = BasicBlock::new(block_id);
|
||||
function.add_block(block);
|
||||
@ -105,7 +105,7 @@ impl super::MirBuilder {
|
||||
|
||||
/// Start a new basic block and set as current
|
||||
pub(crate) fn start_new_block(&mut self, block_id: BasicBlockId) -> Result<(), String> {
|
||||
if let Some(ref mut function) = self.current_function {
|
||||
if let Some(ref mut function) = self.scope_ctx.current_function {
|
||||
if !function.blocks.contains_key(&block_id) {
|
||||
function.add_block(BasicBlock::new(block_id));
|
||||
}
|
||||
@ -440,7 +440,7 @@ impl super::MirBuilder {
|
||||
let slot_id = self.core_ctx.next_temp_slot();
|
||||
let slot_name = format!("__pin${}${}", slot_id, hint);
|
||||
// Phase 25.1b: Use function-local ID allocator to avoid SSA verification failures
|
||||
let dst = if let Some(ref mut f) = self.current_function {
|
||||
let dst = if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
f.next_value_id() // Function context: use local ID
|
||||
} else {
|
||||
self.core_ctx.next_value() // Module context: use core_ctx SSOT
|
||||
@ -471,7 +471,7 @@ impl super::MirBuilder {
|
||||
v: super::ValueId,
|
||||
) -> Result<super::ValueId, String> {
|
||||
// Phase 25.1b: Use function-local ID allocator to avoid SSA verification failures
|
||||
let dst = if let Some(ref mut f) = self.current_function {
|
||||
let dst = if let Some(ref mut f) = self.scope_ctx.current_function {
|
||||
f.next_value_id() // Function context: use local ID
|
||||
} else {
|
||||
self.core_ctx.next_value() // Module context: use core_ctx SSOT
|
||||
@ -489,7 +489,7 @@ impl super::MirBuilder {
|
||||
dst: super::ValueId,
|
||||
src: super::ValueId,
|
||||
) -> Result<(), String> {
|
||||
if let (Some(ref mut function), Some(bb)) = (&mut self.current_function, self.current_block)
|
||||
if let (Some(ref mut function), Some(bb)) = (&mut self.scope_ctx.current_function, self.current_block)
|
||||
{
|
||||
if std::env::var("NYASH_SCHEDULE_TRACE").ok().as_deref() == Some("1") {
|
||||
eprintln!(
|
||||
|
||||
@ -116,9 +116,6 @@ impl super::super::MirBuilder {
|
||||
self.binding_ctx.insert(name.to_string(), binding_id);
|
||||
self.sync_binding_ctx_to_legacy();
|
||||
|
||||
// Sync to legacy field
|
||||
self.sync_scope_ctx_to_legacy();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user