vm(hako): dispatcher v1 flow scan (opt-in HAKO_V1_DISPATCHER_FLOW), extend extern_provider stubs, parity canary; share block scan used from Mini-VM; keep Core fallback for unsupported ops

This commit is contained in:
nyash-codex
2025-11-03 23:30:23 +09:00
parent 3bda84b136
commit 70a98ae09b
3 changed files with 110 additions and 0 deletions

View File

@ -38,8 +38,71 @@ static box NyVmDispatcherV1Box {
}
return 0
}
// Internal scanner with simple flow: const/compare/mir_call/branch/jump/ret (phi→fallback)
run_scan_flow(json) {
json = "" + json
local regs = new MiniMap()
local last_cmp_dst = -1
local last_cmp_val = 0
local bb = 0
local steps = 0
local max_steps = 200000
loop(true) {
steps = steps + 1
if steps > max_steps { return 0 }
local start = JsonV1ReaderBox.block_insts_start(json, bb)
if start < 0 { return 0 }
local endp = JsonCursorBox.seek_array_end(json, start)
if endp <= start { return 0 }
local seg = (""+json).substring(start + 1, endp)
local scan = 0
loop(true) {
if scan >= seg.length() { break }
local tup = InstructionScannerBox.next_tuple(seg, scan)
if tup == "" { break }
local c1 = StringOps.index_of_from(tup, ",", 0)
local c2 = StringOps.index_of_from(tup, ",", c1+1)
if c1 < 0 || c2 < 0 { break }
local s = JsonFragBox._str_to_int(tup.substring(0, c1))
local e = JsonFragBox._str_to_int(tup.substring(c1+1, c2))
local op = tup.substring(c2+1, tup.length())
local item = seg.substring(s, e)
if op == "const" { OpHandlersBox.handle_const(item, regs) }
else if op == "compare" {
OpHandlersBox.handle_compare(item, regs)
local dst = JsonFragBox.get_int(item, "dst")
if dst != null {
last_cmp_dst = dst
local sv = regs.getField(""+dst); if sv != null { last_cmp_val = JsonFragBox._str_to_int(""+sv) } else { last_cmp_val = 0 }
}
}
else if op == "mir_call" { MirCallV1HandlerBox.handle(item, regs) }
else if op == "branch" {
local c = JsonFragBox.get_int(item, "cond")
local t = JsonFragBox.get_int(item, "then")
local f = JsonFragBox.get_int(item, "else")
if c != null && t != null && f != null {
local cv = 0
if c == last_cmp_dst { cv = last_cmp_val } else { local sv = regs.getField(""+c); if sv != null { cv = JsonFragBox._str_to_int(""+sv) } }
bb = (cv != 0) ? t : f
break
} else { return MirVmMin.run_min(json) }
}
else if op == "jump" {
local tgt = JsonFragBox.get_int(item, "target"); if tgt == null { return MirVmMin.run_min(json) }
bb = tgt; break
}
else if op == "phi" {
return MirVmMin.run_min(json)
}
else if op == "ret" { return MirVmMin._handle_ret_op(item, regs, last_cmp_dst, last_cmp_val, 0) }
scan = e
}
}
}
// Main entry: Choose internal scanner when enabled; otherwise delegate to MiniVM
run(json) {
if env.get("HAKO_V1_DISPATCHER_FLOW") == "1" { return me.run_scan_flow(json) }
if env.get("HAKO_V1_DISPATCHER_INTERNAL") == "1" { return me.run_scan(json) }
return MirVmMin.run_min(json)
}

View File

@ -17,6 +17,14 @@ static box HakoruneExternProviderBox {
print("" + args)
return 0
}
if name == "env.mirbuilder.emit" {
// Stub only (20.38でCABI接続): return empty string
return ""
}
if name == "env.codegen.emit_object" {
// Stub only: return empty string (path placeholder)
return ""
}
// Unknown: return null for now (caller decides FailFast)
return null
}