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:
@ -41,14 +41,14 @@ static box AotPrepBox {
|
||||
local k1 = "\"value\":{\"type\":\"i64\",\"value\":"
|
||||
local a_pos = body.indexOf(k1, p0)
|
||||
if a_pos < 0 { return "" }
|
||||
a_pos = a_pos + k1.size()
|
||||
a_pos = a_pos + k1.length()
|
||||
local a_s = JsonCursorBox.digits_from(body, a_pos)
|
||||
if a_s == null || a_s == "" { return "" }
|
||||
local p1 = body.indexOf("\"op\":\"const\"", a_pos)
|
||||
if p1 < 0 { return "" }
|
||||
local b_pos = body.indexOf(k1, p1)
|
||||
if b_pos < 0 { return "" }
|
||||
b_pos = b_pos + k1.size()
|
||||
b_pos = b_pos + k1.length()
|
||||
local b_s = JsonCursorBox.digits_from(body, b_pos)
|
||||
if b_s == null || b_s == "" { return "" }
|
||||
// operation symbol
|
||||
@ -69,15 +69,15 @@ static box AotPrepBox {
|
||||
// Build folded instruction array: [const rv -> dst:1, ret 1]
|
||||
local folded = "[{\"op\":\"const\",\"dst\":1,\"value\":{\"type\":\"i64\",\"value\":" + (""+rv) + "}},{\"op\":\"ret\",\"value\":1}]"
|
||||
// Splice back into whole JSON and return
|
||||
return json.substring(0, start+1) + folded + json.substring(end, json.size())
|
||||
return json.substring(0, start+1) + folded + json.substring(end, json.length())
|
||||
}
|
||||
|
||||
_to_i64(s) {
|
||||
// crude but sufficient for our immediate range
|
||||
local i = 0; local neg = 0
|
||||
if s.size() > 0 && s.substring(0,1) == "-" { neg = 1; i = 1 }
|
||||
if s.length() > 0 && s.substring(0,1) == "-" { neg = 1; i = 1 }
|
||||
local out = 0
|
||||
loop (i < s.size()) {
|
||||
loop (i < s.length()) {
|
||||
local ch = s.substring(i, i+1)
|
||||
if ch < "0" || ch > "9" { break }
|
||||
out = out * 10 + (ch - "0")
|
||||
@ -99,7 +99,7 @@ static box AotPrepBox {
|
||||
local p = json.indexOf(pat, i)
|
||||
if p < 0 { break }
|
||||
// Parse dst number
|
||||
local pnum = p + pat.size()
|
||||
local pnum = p + pat.length()
|
||||
local digits = JsonCursorBox.digits_from(json, pnum)
|
||||
if digits == null || digits == "" { i = p + 1; continue }
|
||||
local dst_s = digits
|
||||
@ -114,7 +114,7 @@ static box AotPrepBox {
|
||||
local obj_end = me._seek_object_end(json, obj_start)
|
||||
if obj_end < 0 { i = p + 1; continue }
|
||||
// Validate dst is unused after this object
|
||||
local tail = json.substring(obj_end+1, json.size())
|
||||
local tail = json.substring(obj_end+1, json.length())
|
||||
// Search common reference patterns: ":<dst>" after a key
|
||||
local ref = ":" + dst_s
|
||||
if tail.indexOf(ref) >= 0 {
|
||||
@ -124,11 +124,11 @@ static box AotPrepBox {
|
||||
local cut_left = obj_start
|
||||
local cut_right = obj_end + 1
|
||||
// Trim a single trailing comma to keep JSON valid in arrays
|
||||
if cut_right < json.size() {
|
||||
if cut_right < json.length() {
|
||||
local ch = json.substring(cut_right, cut_right+1)
|
||||
if ch == "," { cut_right = cut_right + 1 }
|
||||
}
|
||||
json = json.substring(0, cut_left) + json.substring(cut_right, json.size())
|
||||
json = json.substring(0, cut_left) + json.substring(cut_right, json.length())
|
||||
changed = 1
|
||||
i = cut_left
|
||||
}
|
||||
@ -140,13 +140,13 @@ static box AotPrepBox {
|
||||
// Handles nested objects and string literals with escapes.
|
||||
_seek_object_end(s, start) {
|
||||
if s == null { return -1 }
|
||||
if start < 0 || start >= s.size() { return -1 }
|
||||
if start < 0 || start >= s.length() { return -1 }
|
||||
if s.substring(start, start+1) != "{" { return -1 }
|
||||
local i = start
|
||||
local depth = 0
|
||||
local in_str = 0
|
||||
local esc = 0
|
||||
loop (i < s.size()) {
|
||||
loop (i < s.length()) {
|
||||
local ch = s.substring(i, i+1)
|
||||
if in_str == 1 {
|
||||
if esc == 1 { esc = 0 }
|
||||
|
||||
Reference in New Issue
Block a user