feat(joinir): S-5.2-improved - VM完全意味論統合完了
Phase 27-shortterm S-5.2-improved 実装完了: ## 実装内容 1. **execute_box_call() ラッパー追加**: - src/backend/mir_interpreter/mod.rs に公開 API 実装 - 1_000_000 番台レジスタで一時値管理 - 適切なクリーンアップ処理実装 2. **handle_box_call 可視性変更**: - src/backend/mir_interpreter/handlers/boxes.rs を pub に変更 - JoinIR Runner からアクセス可能に 3. **JoinIR Runner BoxCall 統合**: - src/mir/join_ir_runner.rs の BoxCall 処理を書き換え - StringBox 直接呼び出し削除 - VM の execute_box_call 経由に変更 - JoinValue ↔ VMValue 変換で統合 4. **不要な関数削除**: - expect_str(), expect_int(), box_to_join_value() 削除 - VMValue 変換に一本化 5. **テスト更新**: - joinir_runner_standalone.rs: VM インスタンス追加 - joinir_runner_min.rs: VM 再利用 ## 期待される効果 ✅ Void guards 完全対応 (Void.length() → 0) ✅ PluginBox/InstanceBox 将来対応可能 ✅ VM の完全な BoxCall 意味論統一 ✅ VM 2号機回避(ガードレール設計成功) ## テスト結果 ✅ joinir_runner_standalone_skip_ws ... ok ✅ joinir_runner_standalone_trim ... ok ✅ ビルド成功(0エラー) ## 完了タスク - [x] MirInterpreter::execute_box_call() 実装 - [x] 1_000_000 レジスタ帯域割り当て - [x] regs クリーンアップ実装 - [x] JoinIR Runner BoxCall 書き換え - [x] テスト更新&PASS確認 🎉 VM 完全意味論統合完了!
This commit is contained in:
@ -79,6 +79,71 @@ impl MirInterpreter {
|
||||
self.static_box_decls.insert(name, decl);
|
||||
}
|
||||
|
||||
/// Execute a BoxCall with VM's complete semantics (Phase 27-shortterm S-5.2-improved)
|
||||
///
|
||||
/// This wrapper allows external modules (e.g., JoinIR Runner) to invoke BoxCall
|
||||
/// with the VM's complete semantics including:
|
||||
/// - Void guards (e.g., Void.length() → 0)
|
||||
/// - PluginBox support (FileBox, NetBox, etc.)
|
||||
/// - InstanceBox policy checks
|
||||
/// - object_fields handling
|
||||
/// - Method re-routing (toString→str)
|
||||
///
|
||||
/// # Implementation Notes
|
||||
/// - Uses 1_000_000 register range for scratch registers (避ける ID 衝突)
|
||||
/// - Properly cleans up temporary registers after use
|
||||
/// - Delegates to `handle_box_call` for complete VM semantics
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `receiver`: The box instance (VMValue::BoxRef or primitive)
|
||||
/// - `method`: Method name to invoke
|
||||
/// - `args`: Method arguments as VMValue
|
||||
///
|
||||
/// # Returns
|
||||
/// Result value as VMValue (may be Void, Int, String, BoxRef, etc.)
|
||||
pub fn execute_box_call(
|
||||
&mut self,
|
||||
receiver: VMValue,
|
||||
method: &str,
|
||||
args: Vec<VMValue>,
|
||||
) -> Result<VMValue, VMError> {
|
||||
// Allocate temporary register IDs in the 1_000_000 range (not 1000!)
|
||||
// This avoids conflicts with user code and future extensions
|
||||
let base = ValueId(1_000_000);
|
||||
let recv_id = base;
|
||||
|
||||
// Place receiver in register
|
||||
self.regs.insert(recv_id, receiver);
|
||||
|
||||
// Place arguments in consecutive registers
|
||||
let arg_ids: Vec<ValueId> = args
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, v)| {
|
||||
let id = ValueId(base.0 + 1 + i as u32);
|
||||
self.regs.insert(id, v);
|
||||
id
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Allocate destination register
|
||||
let dst_id = ValueId(base.0 + 1000);
|
||||
|
||||
// Invoke handle_box_call for complete VM semantics
|
||||
self.handle_box_call(Some(dst_id), recv_id, method, &arg_ids)?;
|
||||
|
||||
// Read result (may be Void if method returns nothing)
|
||||
let result = self.regs.remove(&dst_id).unwrap_or(VMValue::Void);
|
||||
|
||||
// Cleanup temporary registers (important to avoid stale values!)
|
||||
self.regs.remove(&recv_id);
|
||||
for id in arg_ids {
|
||||
self.regs.remove(&id);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Ensure static box singleton instance exists, create if not
|
||||
/// Returns mutable reference to the singleton instance
|
||||
fn ensure_static_box_instance(
|
||||
|
||||
Reference in New Issue
Block a user