//! 🎯 箱理論: Call命令発行専用モジュール //! //! 責務: MIR Call命令の発行のみ //! - emit_unified_call: 統一Call発行(Phase 3対応) //! - emit_legacy_call: レガシーCall発行(既存互換) //! - emit_global_call/emit_method_call/emit_constructor_call: 便利ラッパー use super::super::{EffectMask, MirBuilder, MirInstruction, ValueId}; use super::CallTarget; use crate::mir::definitions::call_unified::Callee; impl MirBuilder { /// Unified call emission - delegates to UnifiedCallEmitterBox /// 箱理論: 統一Call発行ロジックを unified_emitter.rs に集約 pub fn emit_unified_call( &mut self, dst: Option, target: CallTarget, args: Vec, ) -> Result<(), String> { super::unified_emitter::UnifiedCallEmitterBox::emit_unified_call(self, dst, target, args) } /// Legacy call fallback - preserves existing behavior pub fn emit_legacy_call( &mut self, dst: Option, target: CallTarget, args: Vec, ) -> Result<(), String> { match target { CallTarget::Method { receiver, method, box_type: _, } => { // LEGACY PATH (after unified migration): // Instance→Function rewrite is centralized in unified call path. // Legacy path no longer functionizes; always use Box/Plugin call here. // CRITICAL FIX: Prevent bouncing back to emit_unified_call // Set flag to prevent emit_box_or_plugin_call from calling emit_unified_call let prev_flag = self.in_unified_boxcall_fallback; self.in_unified_boxcall_fallback = true; let result = self.emit_box_or_plugin_call(dst, receiver, method, None, args, EffectMask::IO); self.in_unified_boxcall_fallback = prev_flag; result } CallTarget::Constructor(box_type) => { // Use existing NewBox let dst = dst.ok_or("Constructor must have destination")?; self.emit_instruction(MirInstruction::NewBox { dst, box_type, args, }) } CallTarget::Extern(name) => { // Use existing ExternCall let mut args = args; crate::mir::builder::ssa::local::finalize_args(self, &mut args); let parts: Vec<&str> = name.splitn(2, '.').collect(); let (iface, method) = if parts.len() == 2 { (parts[0].to_string(), parts[1].to_string()) } else { ("nyash".to_string(), name) }; self.emit_instruction(MirInstruction::ExternCall { dst, iface_name: iface, method_name: method, args, effects: EffectMask::IO, }) } CallTarget::Global(name) => { super::unified_emitter::UnifiedCallEmitterBox::emit_global_unified( self, dst, name, args, ) } CallTarget::Value(func_val) => { super::unified_emitter::UnifiedCallEmitterBox::emit_value_unified( self, dst, func_val, args, ) } CallTarget::Closure { params, captures, me_capture, } => { let dst = dst.ok_or("Closure creation must have destination")?; self.emit_instruction(MirInstruction::NewClosure { dst, params, body: vec![], // Empty body for now captures, me: me_capture, }) } } } // Phase 2 Migration: Convenience methods that use emit_unified_call /// Emit a global function call (print, panic, etc.) pub fn emit_global_call( &mut self, dst: Option, name: String, args: Vec, ) -> Result<(), String> { self.emit_unified_call(dst, CallTarget::Global(name), args) } /// Emit a method call (box.method) pub fn emit_method_call( &mut self, dst: Option, receiver: ValueId, method: String, args: Vec, ) -> Result<(), String> { self.emit_unified_call( dst, CallTarget::Method { box_type: None, // Auto-infer method, receiver, }, args, ) } /// Emit a constructor call (new BoxType) pub fn emit_constructor_call( &mut self, dst: ValueId, box_type: String, args: Vec, ) -> Result<(), String> { self.emit_unified_call(Some(dst), CallTarget::Constructor(box_type), args) } // ======================================== // Private helper methods (small functions) // ======================================== /// Try fallback handlers for global functions (delegates to CallMaterializerBox) #[allow(dead_code)] pub(super) fn try_global_fallback_handlers( &mut self, dst: Option, name: &str, args: &[ValueId], ) -> Result, String> { super::materializer::CallMaterializerBox::try_global_fallback_handlers( self, dst, name, args, ) } /// Ensure receiver is materialized in Callee::Method (delegates to CallMaterializerBox) #[allow(dead_code)] pub(super) fn materialize_receiver_in_callee( &mut self, callee: Callee, ) -> Result { super::materializer::CallMaterializerBox::materialize_receiver_in_callee(self, callee) } // ✅ 箱化完了: // - emit_unified_call_impl → UnifiedCallEmitterBox::emit_unified_call_impl (unified_emitter.rs) // - emit_global_unified → UnifiedCallEmitterBox::emit_global_unified (unified_emitter.rs) // - emit_value_unified → UnifiedCallEmitterBox::emit_value_unified (unified_emitter.rs) // - apply_static_runtime_guard → CalleeGuardBox::apply_static_runtime_guard (guard.rs) }