78 lines
3.6 KiB
Plaintext
78 lines
3.6 KiB
Plaintext
// MethodCallHandlerBox - Handle Method calls (MirCall with Method callee)
|
||
// Single Responsibility: Execute instance methods (e.g., array.length(), string.substring())
|
||
|
||
using selfhost.vm.boxes.result_box as Result
|
||
using selfhost.shared.common.string_helpers as StringHelpers
|
||
using selfhost.vm.hakorune-vm.value_manager as ValueManagerBox
|
||
using selfhost.vm.hakorune-vm.callee_parser as CalleeParserBox
|
||
using selfhost.vm.hakorune-vm.args_extractor as ArgsExtractorBox
|
||
using selfhost.vm.hakorune-vm.args_guard as ArgsGuardBox
|
||
using selfhost.vm.hakorune-vm.receiver_guard as ReceiverGuardBox
|
||
using selfhost.vm.hakorune-vm.json_field_extractor as JsonFieldExtractor
|
||
using selfhost.shared.json.core.json_cursor as JsonCursorBox
|
||
using selfhost.shared.host_bridge.host_bridge as HostBridge
|
||
using selfhost.vm.hakorune-vm.core_bridge_ops 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 methods(substring/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)
|
||
}
|
||
}
|