From 5c5e1bd099d3d2782e8cebb3c55b8cf8062dec47 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Wed, 19 Nov 2025 04:01:02 +0900 Subject: [PATCH] =?UTF-8?q?fix(mir):=20Hotfix=206+7=20-=20Instance=20metho?= =?UTF-8?q?d=20receiver=E5=AE=8C=E5=85=A8=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 問題箇所1 (Hotfix 6): - setup_method_params が next_value_id() で新規 ValueId 生成 - でも MirFunction::new() で既に予約済み - → パラメータマッピングがずれる(%2,%3 vs %0,%1) 修正1: - 予約済み ValueId(0), ValueId(1), ... を直接使用 - setup_function_params と同じロジックに統一 問題箇所2 (Hotfix 7): - emit_unified_call_impl で Callee::Method の receiver が args に含まれない - finalize_call_operands は receiver を Callee 側に保持 - → VM の exec_function_inner で args = [] → ValueId(0) = Void 修正2: - Callee::Method { receiver: Some(recv), .. } の場合に args_local.insert(0, *recv) で receiver を先頭に追加 - VM のパラメータバインディングが正しく動作するように 検証: - 手動テスト: ng → ok ✅ - 各種環境変数組み合わせでも動作確認済み 既知問題: - userbox_birth_to_string_vm.sh スモークテストは依然失敗 → 別調査が必要(手動では動作するので環境依存の可能性) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/mir/builder/calls/lowering.rs | 41 ++++++++++++++++++------ src/mir/builder/calls/unified_emitter.rs | 8 +++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/mir/builder/calls/lowering.rs b/src/mir/builder/calls/lowering.rs index 12cd7a64..47988373 100644 --- a/src/mir/builder/calls/lowering.rs +++ b/src/mir/builder/calls/lowering.rs @@ -268,21 +268,42 @@ impl MirBuilder { let mut slot_regs: Vec<(String, Option)> = Vec::new(); if let Some(ref mut f) = self.current_function { - // 📦 Hotfix 6: Use pre-reserved ValueIds instead of generating new ones - // MirFunction::new() already reserved ValueIds 0..N for parameters - // First parameter is always 'me' at ValueId(0) - let me_id = ValueId(0); - f.params.push(me_id); + // 📦 Hotfix 6 改訂版: + // MirFunction::new() が既に 0..N の ValueId を params 用に予約しているので、 + // ここではそれを「上書き使用」するだけにして、push で二重定義しないようにするよ。 + // + // params レイアウト: + // index 0: me (box) + // index 1..: 通常パラメータ + if f.params.is_empty() { + // 安全弁: 何らかの理由で pre-populate されていない場合は従来どおり new する + let me_id = ValueId(0); + f.params.push(me_id); + for i in 0..params.len() { + f.params.push(ValueId((i + 1) as u32)); + } + } + + // me + let me_id = f.params[0]; self.variable_map.insert("me".to_string(), me_id); self.value_origin_newbox.insert(me_id, box_name.to_string()); slot_regs.push(("me".to_string(), None)); - // Then regular parameters at ValueId(1), ValueId(2), ... + // 通常パラメータ for (idx, p) in params.iter().enumerate() { - let pid = ValueId((idx + 1) as u32); - f.params.push(pid); - self.variable_map.insert(p.clone(), pid); - slot_regs.push((p.clone(), None)); + let param_idx = idx + 1; + if param_idx < f.params.len() { + let pid = f.params[param_idx]; + self.variable_map.insert(p.clone(), pid); + slot_regs.push((p.clone(), None)); + } else { + // 念のため足りない場合は新規に確保(互換用) + let pid = f.next_value_id(); + f.params.push(pid); + self.variable_map.insert(p.clone(), pid); + slot_regs.push((p.clone(), None)); + } } } diff --git a/src/mir/builder/calls/unified_emitter.rs b/src/mir/builder/calls/unified_emitter.rs index 62368705..dd216961 100644 --- a/src/mir/builder/calls/unified_emitter.rs +++ b/src/mir/builder/calls/unified_emitter.rs @@ -177,6 +177,14 @@ impl UnifiedCallEmitterBox { let mut args_local: Vec = args; crate::mir::builder::emit_guard::finalize_call_operands(builder, &mut callee, &mut args_local); + // 📦 Hotfix 7: Include receiver in args for Callee::Method + // VM's exec_function_inner expects receiver as the first parameter (ValueId(0)) + // but finalize_call_operands keeps receiver in Callee, not in args. + // We must add it to args_local here so VM can bind it correctly. + if let Callee::Method { receiver: Some(recv), .. } = &callee { + args_local.insert(0, *recv); + } + // Create MirCall instruction using the new module (pure data composition) let mir_call = call_unified::create_mir_call(dst, callee.clone(), args_local.clone());