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:
@ -38,8 +38,71 @@ static box NyVmDispatcherV1Box {
|
|||||||
}
|
}
|
||||||
return 0
|
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 Mini‑VM
|
// Main entry: Choose internal scanner when enabled; otherwise delegate to Mini‑VM
|
||||||
run(json) {
|
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) }
|
if env.get("HAKO_V1_DISPATCHER_INTERNAL") == "1" { return me.run_scan(json) }
|
||||||
return MirVmMin.run_min(json)
|
return MirVmMin.run_min(json)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,14 @@ static box HakoruneExternProviderBox {
|
|||||||
print("" + args)
|
print("" + args)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
if name == "env.mirbuilder.emit" {
|
||||||
|
// Stub only (20.38でC‑ABI接続): 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 Fail‑Fast)
|
// Unknown: return null for now (caller decides Fail‑Fast)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Parity: MirCallV1Handler used by Mini‑VM and Hakovm dispatcher produce same rc
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"; if ROOT_GIT=$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null); then ROOT="$ROOT_GIT"; else ROOT="$(cd "$SCRIPT_DIR/../../../../../../../../.." && pwd)"; fi
|
||||||
|
source "$ROOT/tools/smokes/v2/lib/test_runner.sh"; require_env || exit 2
|
||||||
|
|
||||||
|
tmp_json="/tmp/mir_v1_parity_mircall_$$.json"
|
||||||
|
cat > "$tmp_json" <<'JSON'
|
||||||
|
{
|
||||||
|
"schema_version": "1.0",
|
||||||
|
"functions": [
|
||||||
|
{"name":"main","blocks":[{"id":0,"instructions":[
|
||||||
|
{"op":"mir_call","dst":0, "callee":{"type":"Constructor","box_type":"ArrayBox"}, "args":[], "effects":[]},
|
||||||
|
{"op":"const","dst":1, "value": {"type": "i64", "value": 10}},
|
||||||
|
{"op":"const","dst":2, "value": {"type": "i64", "value": 20}},
|
||||||
|
{"op":"mir_call", "callee":{"type":"Method","box_name":"ArrayBox","method":"push","receiver":0}, "args":[1], "effects":[]},
|
||||||
|
{"op":"mir_call", "callee":{"type":"Method","box_name":"ArrayBox","method":"push","receiver":0}, "args":[2], "effects":[]},
|
||||||
|
{"op":"mir_call","dst":3, "callee":{"type":"Method","box_name":"ArrayBox","method":"size","receiver":0}, "args":[], "effects":[]},
|
||||||
|
{"op":"ret","value":3}
|
||||||
|
]}]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
|
||||||
|
set +e
|
||||||
|
# Mini‑VM path
|
||||||
|
rc_min=0; HAKO_VERIFY_PRIMARY=hakovm HAKO_V1_DISPATCHER_INTERNAL=0 HAKO_V1_DISPATCHER_FLOW=0 verify_mir_rc "$tmp_json" >/dev/null 2>&1; rc_min=$?
|
||||||
|
# Hakovm internal flow path
|
||||||
|
rc_hv1=0; HAKO_VERIFY_PRIMARY=hakovm HAKO_V1_DISPATCHER_FLOW=1 verify_mir_rc "$tmp_json" >/dev/null 2>&1; rc_hv1=$?
|
||||||
|
set -e
|
||||||
|
rm -f "$tmp_json" || true
|
||||||
|
|
||||||
|
if [ "$rc_min" -eq "$rc_hv1" ]; then
|
||||||
|
echo "[PASS] v1_mircall_parity_hakovm_minivm_vm (rc=$rc_hv1)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "[FAIL] v1_mircall_parity_hakovm_minivm_vm (mini=$rc_min, hv1=$rc_hv1)" >&2; exit 1
|
||||||
|
|
||||||
Reference in New Issue
Block a user