From c4c0814fd6ddca3b6827a0a42b72a285eac180bb Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Fri, 5 Dec 2025 17:22:14 +0900 Subject: [PATCH] fix(joinir): Use BTreeMap for MirModule.functions deterministic iteration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HashMap iteration order is non-deterministic due to HashDoS protection. This caused merge_joinir_mir_blocks to sometimes process functions in wrong order, leading to incorrect block remapping. Changed: - MirModule.functions: HashMap → BTreeMap - MirInterpreter.functions: HashMap → BTreeMap - IfLoweringDryRunner.scan_module: HashMap → BTreeMap parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/backend/mir_interpreter/mod.rs | 6 +++--- src/mir/function.rs | 8 ++++---- src/mir/join_ir/lowering/if_dry_runner.rs | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/backend/mir_interpreter/mod.rs b/src/backend/mir_interpreter/mod.rs index 587a6deb..9ffce625 100644 --- a/src/backend/mir_interpreter/mod.rs +++ b/src/backend/mir_interpreter/mod.rs @@ -6,7 +6,7 @@ * Print/Debug (best-effort), Barrier/Safepoint (no-op). */ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use crate::box_trait::NyashBox; @@ -31,7 +31,7 @@ pub struct MirInterpreter { pub(super) mem: HashMap, // Object field storage keyed by stable object identity (Arc ptr addr fallback) pub(super) obj_fields: HashMap>, - pub(super) functions: HashMap, + pub(super) functions: BTreeMap, pub(super) cur_fn: Option, // Trace context (dev-only; enabled with NYASH_VM_TRACE=1) pub(super) last_block: Option, @@ -54,7 +54,7 @@ impl MirInterpreter { regs: HashMap::new(), mem: HashMap::new(), obj_fields: HashMap::new(), - functions: HashMap::new(), + functions: BTreeMap::new(), cur_fn: None, last_block: None, last_inst: None, diff --git a/src/mir/function.rs b/src/mir/function.rs index 2d1faa3d..d37bd904 100644 --- a/src/mir/function.rs +++ b/src/mir/function.rs @@ -5,7 +5,7 @@ */ use super::{BasicBlock, BasicBlockId, EffectMask, MirInstruction, MirType, ValueId}; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt; /// Function signature for MIR functions @@ -381,8 +381,8 @@ pub struct MirModule { /// Module name pub name: String, - /// Functions in this module - pub functions: HashMap, + /// Functions in this module (BTreeMap for deterministic iteration order) + pub functions: BTreeMap, /// Global constants/statics pub globals: HashMap, @@ -416,7 +416,7 @@ impl MirModule { pub fn new(name: String) -> Self { Self { name, - functions: HashMap::new(), + functions: BTreeMap::new(), globals: HashMap::new(), metadata: ModuleMetadata::default(), } diff --git a/src/mir/join_ir/lowering/if_dry_runner.rs b/src/mir/join_ir/lowering/if_dry_runner.rs index 97fcb677..c2d74332 100644 --- a/src/mir/join_ir/lowering/if_dry_runner.rs +++ b/src/mir/join_ir/lowering/if_dry_runner.rs @@ -11,7 +11,7 @@ use crate::mir::join_ir::JoinInst; use crate::mir::{MirFunction, MirInstruction}; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::time::{Duration, Instant}; /// If lowering dry-run スキャナー @@ -42,7 +42,7 @@ impl IfLoweringDryRunner { /// - 各 Branch ブロックで try_lower_if_to_joinir() 試行 /// - パフォーマンス計測(マイクロ秒レベル) /// - 統計情報収集(Select/IfMerge分類) - pub fn scan_module(&self, functions: &HashMap) -> DryRunStats { + pub fn scan_module(&self, functions: &BTreeMap) -> DryRunStats { let mut total_branches = 0; let mut lowered_count = 0; let mut select_count = 0;