Files
hakorune/lang/src/vm/hakorune-vm/method_call_handler.hako
nyash-codex 6a452b2dca fix(mir): PHI検証panic修正 - update_cfg()を検証前に呼び出し
A案実装: debug_verify_phi_inputs呼び出し前にCFG predecessorを更新

修正箇所(7箇所):
- src/mir/builder/phi.rs:50, 73, 132, 143
- src/mir/builder/ops.rs:273, 328, 351

根本原因:
- Branch/Jump命令でsuccessorは即座に更新
- predecessorはupdate_cfg()で遅延再構築
- PHI検証が先に実行されてpredecessor未更新でpanic

解決策:
- 各debug_verify_phi_inputs呼び出し前に
  if let Some(func) = self.current_function.as_mut() {
      func.update_cfg();
  }
  を挿入してCFGを同期

影響: if/else文、論理演算子(&&/||)のPHI生成が正常動作
2025-11-01 13:28:56 +09:00

78 lines
3.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MethodCallHandlerBox - Handle Method calls (MirCall with Method callee)
// Single Responsibility: Execute instance methods (e.g., array.length(), string.substring())
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox
using "lang/src/vm/hakorune-vm/callee_parser.hako" as CalleeParserBox
using "lang/src/vm/hakorune-vm/args_extractor.hako" as ArgsExtractorBox
using "lang/src/vm/hakorune-vm/args_guard.hako" as ArgsGuardBox
using "lang/src/vm/hakorune-vm/receiver_guard.hako" as ReceiverGuardBox
using "lang/src/vm/hakorune-vm/json_field_extractor.hako" as JsonFieldExtractor
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/shared/host_bridge/host_bridge_box.hako" as HostBridge
using "lang/src/vm/hakorune-vm/core_bridge_ops.hako" as CoreBridgeOps
static box MethodCallHandlerBox {
// TTL: Delegation policy (Phase 20.17 — P1 audit complete)
// - Delegated via CoreBridgeOps: Array(size/push/pop/get/set), Map(len/iterator/set/get)
// - Local/HostBridge: string instance methodssubstring/indexOf/lastIndexOf/dirname/join…
// 文字列意味論の完全移行まで HostBridge に留める20.18+ で段階移行予定)。
// 正規化は最小限length→size のみ)として drift を抑制する。
// Handle Method call
// mir_call_json: {"callee":{"type":"Method","receiver":X,"method":"name"},"args":[...]}
// dst_reg: destination register (null if no return value)
// regs: register MapBox
// Returns: Result.Ok(0) or Result.Err(message)
handle(mir_call_json, dst_reg, regs) {
// Extract receiver ValueId from callee.receiver field
local receiver_id = CalleeParserBox.extract_receiver(mir_call_json)
if receiver_id == null {
return Result.Err("method: receiver not found in callee")
}
// Extract method name from callee.method field
local method_name = CalleeParserBox.extract_method(mir_call_json)
if method_name == null {
return Result.Err("method: method name not found in callee")
}
// Extract arguments from mir_call.args
local args_array = ArgsExtractorBox.extract_and_load(mir_call_json, regs)
local _g = ArgsGuardBox.ensure_no_nulls(args_array, method_name + "/" + StringHelpers.int_to_str(args_array.length()))
if _g.is_Err() { return _g }
// Build signature and guard
local arg_count = args_array.length()
local method_sig = method_name + "/" + StringHelpers.int_to_str(arg_count)
// Load receiver and guard
local receiver = ValueManagerBox.get(regs, receiver_id)
local guard = ReceiverGuardBox.ensure_valid(receiver, method_sig, receiver_id)
if guard.is_Err() { return guard }
// Unified dispatch via HostBridge (Phase B):
// Normalize a few well-known aliases to SSOT names (e.g., length -> size).
local method_canon = method_name
if method_canon == "length" { method_canon = "size" }
// Core bridge handles collection metadata + semantics directly (Phase 20.16).
// Delegate to CoreBridgeOps for Array/Map shortcuts to avoid drift.
// TODO: Remove fallback once Core mir_call covers every method variant (size/push/pop/len/set/get).
local core_shortcut = CoreBridgeOps.try_method_collection(method_canon, mir_call_json, args_array, dst_reg, regs, receiver_id)
if core_shortcut != null {
return core_shortcut
}
// Forward to HostBridge. PluginResolver performs the final resolution.
local result_val = HostBridge.box_call(receiver, method_canon, args_array)
// Store result in destination register
if dst_reg != null {
ValueManagerBox.set(regs, dst_reg, result_val)
}
return Result.Ok(0)
}
}