hv1: early-exit at main (no plugin init); tokenizer: Stage-3 single-quote + full escapes (\/ \b \f \' \r fix); builder: route BinOp via SSOT emit_binop_to_dst; hv1 verify canary route (builder→Core); docs: phase-20.39 updates

This commit is contained in:
nyash-codex
2025-11-04 20:46:43 +09:00
parent 31ce798341
commit 44a5158a14
53 changed files with 2237 additions and 179 deletions

View File

@ -55,11 +55,12 @@ static box NyVmDispatcher {
local iter = 0
loop (iter < max_iter) {
iter = iter + 1
local bjson = block_map.get("" + current_bb)
if bjson == null { print("[core] block not found: " + ("" + current_bb)) return -1 }
using selfhost.shared.common.string_helpers as StringHelpers
local bjson = block_map.get(StringHelpers.int_to_str(current_bb))
if bjson == null { print("[core] block not found: " + StringHelpers.int_to_str(current_bb)) return -1 }
// Execute instructions in this block
local insts = NyVmJsonV0Reader.block_instructions_json(bjson)
if insts == "" { print("[core] empty instructions at bb" + ("" + current_bb)) return -1 }
if insts == "" { print("[core] empty instructions at bb" + StringHelpers.int_to_str(current_bb)) return -1 }
// First pass: apply phi nodes
{

View File

@ -108,7 +108,8 @@ static box NyVmJsonV0Reader {
local blk = arr.substring(pos, end+1)
local id = me.read_block_id(blk)
if id >= 0 {
out.set("" + id, blk)
using selfhost.shared.common.string_helpers as StringHelpers
out.set(StringHelpers.int_to_str(id), blk)
}
pos = end + 1
}

View File

@ -15,10 +15,22 @@ static box NyVmOpMirCall {
return -1
}
_arr_key(recv_id) { return "arrsize:r" + ("" + recv_id) }
_arr_val_key(recv_id, idx) { return "arrval:r" + ("" + recv_id) + ":" + ("" + idx) }
_map_key(recv_id) { return "maplen:r" + ("" + recv_id) }
_map_entry_slot(recv_id, key) { return "mapentry:r" + ("" + recv_id) + ":" + key }
_arr_key(recv_id) {
using selfhost.shared.common.string_helpers as StringHelpers
return "arrsize:r" + StringHelpers.int_to_str(recv_id)
}
_arr_val_key(recv_id, idx) {
using selfhost.shared.common.string_helpers as StringHelpers
return "arrval:r" + StringHelpers.int_to_str(recv_id) + ":" + StringHelpers.int_to_str(idx)
}
_map_key(recv_id) {
using selfhost.shared.common.string_helpers as StringHelpers
return "maplen:r" + StringHelpers.int_to_str(recv_id)
}
_map_entry_slot(recv_id, key) {
using selfhost.shared.common.string_helpers as StringHelpers
return "mapentry:r" + StringHelpers.int_to_str(recv_id) + ":" + key
}
_extract_mir_call_obj(inst_json) {
local key = "\"mir_call\":"
@ -235,7 +247,8 @@ static box NyVmOpMirCall {
local arg_vid = me._read_arg_vid(m, 0, "[core/mir_call] console missing arg", "[core/mir_call] console bad arg")
if arg_vid == null { return -1 }
local val = NyVmState.get_reg(state, arg_vid)
print("" + val)
using selfhost.vm.hakorune-vm.str_cast as StrCast
print(StrCast.to_str(val))
return 0
}
@ -390,7 +403,8 @@ static box NyVmOpMirCall {
local key_vid = me._read_arg_vid(m, 0, "[core/mir_call] map has missing key", "[core/mir_call] map has bad key")
if key_vid == null { return -1 }
local key_val = NyVmState.get_reg(state, key_vid)
local key = "" + key_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local key = StrCast.to_str(key_val)
local slot = me._map_entry_slot(recv_id, key)
local has_key = mem.get(slot) != null
local result = 0
@ -409,7 +423,8 @@ static box NyVmOpMirCall {
local i = 0
local n = all_keys.length()
loop(i < n) {
local k = "" + all_keys.get(i)
using selfhost.vm.hakorune-vm.str_cast as StrCast
local k = StrCast.to_str(all_keys.get(i))
// startsWith(prefix)
local ok = 0
if k.length() >= prefix.length() {
@ -437,7 +452,8 @@ static box NyVmOpMirCall {
local i = 0
local n = all_keys.length()
loop(i < n) {
local k = "" + all_keys.get(i)
using selfhost.vm.hakorune-vm.str_cast as StrCast
local k = StrCast.to_str(all_keys.get(i))
local ok = 0
if k.length() >= prefix.length() {
if k.substring(0, prefix.length()) == prefix { ok = 1 }
@ -462,7 +478,8 @@ static box NyVmOpMirCall {
local key_vid = me._read_arg_vid(m, 0, "[core/mir_call] map delete missing key", "[core/mir_call] map delete bad key")
if key_vid == null { return -1 }
local key_val = NyVmState.get_reg(state, key_vid)
local key = "" + key_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local key = StrCast.to_str(key_val)
local slot = me._map_entry_slot(recv_id, key)
local deleted = mem.get(slot)
if deleted != null {
@ -482,7 +499,8 @@ static box NyVmOpMirCall {
local i = 0
local n = all_keys.length()
loop(i < n) {
local k = "" + all_keys.get(i)
using selfhost.vm.hakorune-vm.str_cast as StrCast
local k = StrCast.to_str(all_keys.get(i))
local ok = 0
if k.length() >= prefix.length() {
if k.substring(0, prefix.length()) == prefix { ok = 1 }
@ -503,7 +521,8 @@ static box NyVmOpMirCall {
local key_val = NyVmState.get_reg(state, key_vid)
// Validate key: null/void are invalid暗黙変換なし
if key_val == null || key_val == void { return me._fail(state, "[core/map/key_type]") }
local key = "" + key_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local key = StrCast.to_str(key_val)
local slot = me._map_entry_slot(recv_id, key)
local had = mem.get(slot) != null
// Validate value: void は不正。null は許可(値として保存)。
@ -522,7 +541,8 @@ static box NyVmOpMirCall {
local key_vid = me._read_arg_vid(m, 0, "[core/mir_call] map get missing key", "[core/mir_call] map get bad key")
if key_vid == null { return -1 }
local key_val = NyVmState.get_reg(state, key_vid)
local key = "" + key_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local key = StrCast.to_str(key_val)
local slot = me._map_entry_slot(recv_id, key)
local value = mem.get(slot)
local opt = me._read_optionality(m)
@ -584,7 +604,8 @@ static box NyVmOpMirCall {
local dst = me._read_dst(inst_json, "method(size)")
if dst == null { return -1 }
local recv_val = NyVmState.get_reg(state, recv_id)
local s = "" + recv_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(recv_val)
NyVmState.set_reg(state, dst, s.length())
return 0
}
@ -595,9 +616,11 @@ static box NyVmOpMirCall {
local idx_vid = me._read_arg_vid(m, 0, "[core/mir_call] method(indexOf) missing needle", "[core/mir_call] method(indexOf) bad needle")
if idx_vid == null { return -1 }
local recv_val = NyVmState.get_reg(state, recv_id)
local s = "" + recv_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(recv_val)
local needle_val = NyVmState.get_reg(state, idx_vid)
local needle = "" + needle_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local needle = StrCast.to_str(needle_val)
local pos = s.indexOf(needle)
if pos >= 0 {
NyVmState.set_reg(state, dst, pos)
@ -622,9 +645,11 @@ static box NyVmOpMirCall {
local idx_vid = me._read_arg_vid(m, 0, "[core/mir_call] method(lastIndexOf) missing needle", "[core/mir_call] method(lastIndexOf) bad needle")
if idx_vid == null { return -1 }
local recv_val = NyVmState.get_reg(state, recv_id)
local s = "" + recv_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(recv_val)
local needle_val = NyVmState.get_reg(state, idx_vid)
local needle = "" + needle_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local needle = StrCast.to_str(needle_val)
local pos = s.lastIndexOf(needle)
NyVmState.set_reg(state, dst, pos)
return 0
@ -638,7 +663,8 @@ static box NyVmOpMirCall {
local end_vid = me._read_arg_vid(m, 1, "[core/mir_call] method(substring) missing end", "[core/mir_call] method(substring) bad end")
if end_vid == null { return -1 }
local recv_val = NyVmState.get_reg(state, recv_id)
local s = "" + recv_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(recv_val)
local start = NyVmState.get_reg(state, start_vid)
local end = NyVmState.get_reg(state, end_vid)
// Bounds check
@ -656,7 +682,8 @@ static box NyVmOpMirCall {
local idx_vid = me._read_arg_vid(m, 0, "[core/mir_call] method(charAt) missing index", "[core/mir_call] method(charAt) bad index")
if idx_vid == null { return -1 }
local recv_val = NyVmState.get_reg(state, recv_id)
local s = "" + recv_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(recv_val)
local idx = NyVmState.get_reg(state, idx_vid)
// Bounds check
if idx < 0 || idx >= s.length() {
@ -675,11 +702,14 @@ static box NyVmOpMirCall {
local replacement_vid = me._read_arg_vid(m, 1, "[core/mir_call] method(replace) missing replacement", "[core/mir_call] method(replace) bad replacement")
if replacement_vid == null { return -1 }
local recv_val = NyVmState.get_reg(state, recv_id)
local s = "" + recv_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(recv_val)
local pattern_val = NyVmState.get_reg(state, pattern_vid)
local pattern = "" + pattern_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local pattern = StrCast.to_str(pattern_val)
local replacement_val = NyVmState.get_reg(state, replacement_vid)
local replacement = "" + replacement_val
using selfhost.vm.hakorune-vm.str_cast as StrCast
local replacement = StrCast.to_str(replacement_val)
// Simple replace: find first occurrence and replace
local pos = s.indexOf(pattern)
local result = s
@ -737,7 +767,8 @@ static box NyVmOpMirCall {
local arg_vid = me._read_first_arg(m)
if arg_vid == null { return me._fail(state, "[core/mir_call] int_to_str missing arg") }
local v = NyVmState.get_reg(state, arg_vid)
local s = "" + v
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(v)
local dst = me._read_dst(inst_json, "modulefn StringHelpers.int_to_str/1")
if dst == null { return -1 }
NyVmState.set_reg(state, dst, s)
@ -749,12 +780,14 @@ static box NyVmOpMirCall {
local v = NyVmState.get_reg(state, arg_vid)
// Accept already-integer values; else convert numeric strings only
local outv = 0
if ("" + v) == ("" + StringHelpers.to_i64(v)) {
using selfhost.vm.hakorune-vm.str_cast as StrCast
if StrCast.to_str(v) == StrCast.to_str(StringHelpers.to_i64(v)) {
// naive guard: to_i64 roundtrip textual equality — accept v
outv = StringHelpers.to_i64(v)
} else {
// Fallback strict check: only digit strings with optional sign
local s = "" + v
using selfhost.vm.hakorune-vm.str_cast as StrCast
local s = StrCast.to_str(v)
local i = 0
if s.length() > 0 && (s.substring(0,1) == "-" || s.substring(0,1) == "+") { i = 1 }
local ok = (s.length() > i)

View File

@ -7,7 +7,10 @@ static box NyVmState {
s.set("mem", new MapBox())
return s
}
_reg_key(id) { return "r" + ("" + id) }
_reg_key(id) {
using selfhost.shared.common.string_helpers as StringHelpers
return "r" + StringHelpers.int_to_str(id)
}
get_reg(s, id) {
local key = me._reg_key(id)
local regs = s.get("regs")