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生成が正常動作
This commit is contained in:
@ -7,8 +7,8 @@ static box LLVMAotFacadeBox {
|
||||
_route(){
|
||||
// Decide route by env (read-only). Default = lib (via AotBox)
|
||||
// HAKO_AOT_USE_FFI=1 → ffi, HAKO_AOT_USE_PLUGIN=1 → plugin, else lib
|
||||
local ffi = call("env.local.get/1", "HAKO_AOT_USE_FFI"); if LLVMAotFacadeBox._truthy(ffi) { return "ffi" }
|
||||
local plug = call("env.local.get/1", "HAKO_AOT_USE_PLUGIN"); if LLVMAotFacadeBox._truthy(plug) { return "plugin" }
|
||||
local ffi = env.get("HAKO_AOT_USE_FFI"); if LLVMAotFacadeBox._truthy(ffi) { return "ffi" }
|
||||
local plug = env.get("HAKO_AOT_USE_PLUGIN"); if LLVMAotFacadeBox._truthy(plug) { return "plugin" }
|
||||
return "lib"
|
||||
}
|
||||
_q(s){ return "\"" + s + "\"" }
|
||||
@ -52,7 +52,7 @@ static box LLVMAotFacadeBox {
|
||||
|
||||
// Convenience wrappers (delegate to LLVMBuilderBox when gate=on; else inline JSON)
|
||||
compile_link_ret0(obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) {
|
||||
local json = LLVMBuilderBox.program_ret0()
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
@ -63,7 +63,7 @@ static box LLVMAotFacadeBox {
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
}
|
||||
compile_link_ret_i64(v, obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) {
|
||||
local json = LLVMBuilderBox.program_ret_i64(v)
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
@ -73,7 +73,7 @@ static box LLVMAotFacadeBox {
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
}
|
||||
compile_link_binop_i64(lhs, rhs, opk, obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) {
|
||||
local json = LLVMBuilderBox.program_binop_i64(lhs, rhs, opk)
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
@ -143,7 +143,7 @@ static box LLVMAotFacadeBox {
|
||||
|
||||
// extern call convenience wrappers (console.*) — build via Builder and link
|
||||
compile_link_call_console_log(obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_console_log_ret0() }
|
||||
else {
|
||||
@ -156,7 +156,7 @@ static box LLVMAotFacadeBox {
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
}
|
||||
compile_link_call_console_warn(obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_console_warn_ret0() }
|
||||
else {
|
||||
@ -169,7 +169,7 @@ static box LLVMAotFacadeBox {
|
||||
return LLVMAotFacadeBox.compile_link_json(json, obj_out, exe_out, flags)
|
||||
}
|
||||
compile_link_call_console_error(obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_console_error_ret0() }
|
||||
else {
|
||||
@ -193,7 +193,7 @@ static box LLVMAotFacadeBox {
|
||||
}
|
||||
// time.now_ms — build via Builder when gate, else inline JSON; ret 0
|
||||
compile_link_call_time_now_ms(obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_time_now_ms_ret0() }
|
||||
else {
|
||||
@ -206,7 +206,7 @@ static box LLVMAotFacadeBox {
|
||||
}
|
||||
// JSON.stringify(any) — via nyash.json.stringify_h; ret 0
|
||||
compile_link_call_json_stringify(obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_json_stringify_ret0() }
|
||||
else {
|
||||
@ -220,7 +220,7 @@ static box LLVMAotFacadeBox {
|
||||
}
|
||||
// env.mem.alloc/free wrapper — ret 0
|
||||
compile_link_call_mem_alloc_free(sz, obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_mem_alloc_free_ret0(sz) }
|
||||
else {
|
||||
@ -236,7 +236,7 @@ static box LLVMAotFacadeBox {
|
||||
}
|
||||
// env.local.get wrapper — ret 0 (value ignored)
|
||||
compile_link_call_env_local_get(key, obj_out, exe_out, flags){
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local json
|
||||
if on && (LLVMAotFacadeBox._truthy(on)) { json = LLVMBuilderBox.program_call_env_local_get_ret0(key) }
|
||||
else {
|
||||
|
||||
@ -50,7 +50,7 @@ static box AotPrepBox {
|
||||
if ls < 0 { return [-1, -1] }
|
||||
local depth = 0
|
||||
local i = ls
|
||||
local L = s.size()
|
||||
local L = s.length()
|
||||
local rs = -1
|
||||
loop(i < L) {
|
||||
local ch = s.substring(i, i+1)
|
||||
@ -75,7 +75,7 @@ static box AotPrepBox {
|
||||
local k = "\"dst\":"
|
||||
local i = ss.indexOf(k, pos)
|
||||
if i < 0 { return -1 }
|
||||
i = i + k.size()
|
||||
i = i + k.length()
|
||||
local digs = StringHelpers.read_digits(ss, i)
|
||||
if digs == "" { return -1 }
|
||||
return StringHelpers.to_i64(digs)
|
||||
@ -84,7 +84,7 @@ static box AotPrepBox {
|
||||
local k = "\"value\":{\"type\":\"i64\",\"value\":"
|
||||
local i = ss.indexOf(k, pos)
|
||||
if i < 0 { return null }
|
||||
i = i + k.size()
|
||||
i = i + k.length()
|
||||
local digs = StringHelpers.read_digits(ss, i)
|
||||
if digs == "" { return null }
|
||||
return StringHelpers.to_i64(digs)
|
||||
@ -98,7 +98,7 @@ static box AotPrepBox {
|
||||
local k = key
|
||||
local i = ss.indexOf(k, pos)
|
||||
if i < 0 { return -1 }
|
||||
i = i + k.size()
|
||||
i = i + k.length()
|
||||
local digs = StringHelpers.read_digits(ss, i)
|
||||
if digs == "" { return -1 }
|
||||
return StringHelpers.to_i64(digs)
|
||||
@ -107,7 +107,7 @@ static box AotPrepBox {
|
||||
local k = "\"operation\":\""
|
||||
local i = ss.indexOf(k, pos)
|
||||
if i < 0 { return "" }
|
||||
i = i + k.size()
|
||||
i = i + k.length()
|
||||
local j = ss.indexOf("\"", i)
|
||||
if j < 0 { return "" }
|
||||
return ss.substring(i, j)
|
||||
@ -127,7 +127,7 @@ static box AotPrepBox {
|
||||
"{\\\"op\\\":\\\"const\\\",\\\"dst\\\":" + StringHelpers.int_to_str(d1) + ",\\\"value\\\":{\\\"type\\\":\\\"i64\\\",\\\"value\\\":" + StringHelpers.int_to_str(res) + "}}," +
|
||||
"{\\\"op\\\":\\\"ret\\\",\\\"value\\\":" + StringHelpers.int_to_str(d1) + "}]"
|
||||
local head = s.substring(0, arr_start)
|
||||
local tail = s.substring(arr_end + 1, s.size())
|
||||
local tail = s.substring(arr_end + 1, s.length())
|
||||
return head + new_insts + tail
|
||||
}
|
||||
// Pass 1: prefer name:"main"
|
||||
|
||||
@ -28,17 +28,17 @@ static box LLVMBuilderBox {
|
||||
"{\\\"op\\\":\\\"ret\\\",\\\"value\\\":1}] } ] } ] }"
|
||||
}
|
||||
const_i64(fn_handle, value){
|
||||
local strict = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER_STRICT");
|
||||
local strict = env.get("HAKO_LLVM_SCRIPT_BUILDER_STRICT");
|
||||
if strict && strict != "0" && strict != "false" { print("UNSUPPORTED: const_i64 (stub)"); return -1 }
|
||||
return 0
|
||||
}
|
||||
binop_add(fn_handle, lhs, rhs){
|
||||
local strict = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER_STRICT");
|
||||
local strict = env.get("HAKO_LLVM_SCRIPT_BUILDER_STRICT");
|
||||
if strict && strict != "0" && strict != "false" { print("UNSUPPORTED: binop_add (stub)"); return -1 }
|
||||
return 0
|
||||
}
|
||||
ret(fn_handle, val){
|
||||
local strict = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER_STRICT");
|
||||
local strict = env.get("HAKO_LLVM_SCRIPT_BUILDER_STRICT");
|
||||
if strict && strict != "0" && strict != "false" { print("UNSUPPORTED: ret (stub)"); return -1 }
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
static box LLVMModuleBox {
|
||||
new(name, triple, dl){
|
||||
// Gate: opt‑in のみ
|
||||
local on = call("env.local.get/1", "HAKO_LLVM_SCRIPT_BUILDER");
|
||||
local on = env.get("HAKO_LLVM_SCRIPT_BUILDER");
|
||||
if !on || on == "0" || on == "false" { return -1 }
|
||||
// For MVP, just return a dummy handle (=1)
|
||||
return 1
|
||||
|
||||
@ -37,7 +37,7 @@ static box V0Demo {
|
||||
static box Main {
|
||||
// デモエントリ: ret 0 の exe を生成
|
||||
main(){
|
||||
local tmp = call("env.local.get/1", "NYASH_ROOT")
|
||||
local tmp = env.get("NYASH_ROOT")
|
||||
if !tmp { tmp = "." }
|
||||
local obj = tmp + "/tmp/v0_min.o"
|
||||
local exe = tmp + "/tmp/v0_min_exe"
|
||||
|
||||
@ -36,7 +36,7 @@ static box LLVMBranchInstructionBox {
|
||||
batch_branch(branch_list) {
|
||||
local results = []
|
||||
local i = 0
|
||||
while i < branch_list.size() {
|
||||
while i < branch_list.length() {
|
||||
local branch = branch_list[i]
|
||||
local json = me.lower_branch(branch.cond, branch.then_block, branch.else_block)
|
||||
results.push(json)
|
||||
|
||||
@ -60,7 +60,7 @@ static box LLVMCompareInstructionBox {
|
||||
batch_compare(compare_list) {
|
||||
local results = []
|
||||
local i = 0
|
||||
while i < compare_list.size() {
|
||||
while i < compare_list.length() {
|
||||
local cmp = compare_list[i]
|
||||
local json = me.lower_compare(cmp.op, cmp.lhs, cmp.rhs, cmp.dst)
|
||||
results.push(json)
|
||||
|
||||
@ -40,7 +40,7 @@ static box LLVMCopyInstructionBox {
|
||||
batch_copy(copy_list) {
|
||||
local results = []
|
||||
local i = 0
|
||||
while i < copy_list.size() {
|
||||
while i < copy_list.length() {
|
||||
local copy = copy_list[i]
|
||||
local json = me.lower_copy(copy.dst, copy.src)
|
||||
results.push(json)
|
||||
|
||||
@ -45,7 +45,7 @@ static box LLVMJumpInstructionBox {
|
||||
batch_jump(jump_list) {
|
||||
local results = []
|
||||
local i = 0
|
||||
while i < jump_list.size() {
|
||||
while i < jump_list.length() {
|
||||
local jump = jump_list[i]
|
||||
local json = me.lower_jump(jump.target)
|
||||
results.push(json)
|
||||
|
||||
Reference in New Issue
Block a user