// v1_phi_table.hako — V1PhiTableBox // Responsibility: apply SSA φ at block entry (v1 JSON), using prev_bb to select incoming. using selfhost.vm.hakorune-vm.json_v1_reader as JsonV1ReaderBox using selfhost.shared.json.utils.json_frag as JsonFragBox using selfhost.shared.common.string_ops as StringOps using selfhost.vm.helpers.instruction_scanner as InstructionScannerBox using selfhost.vm.helpers.v1_phi_adapter as V1PhiAdapterBox using selfhost.shared.common.string_helpers as StringHelpers static box V1PhiTableBox { // Apply φ for the given block id using prev_bb. Strict/tolerate are string flags ("1"/"0"). apply_at_entry(json, regs, prev_bb, bb, strict, tolerate, flow_trace) { if prev_bb == null { return 0 } if bb == null { return 0 } json = "" + json local trace = 0 if flow_trace != null { if flow_trace == 1 { trace = 1 } } // find instructions array for the block local start = JsonV1ReaderBox.block_insts_start(json, bb) if start < 0 { return 0 } local endp = JsonFragBox._seek_array_end(json, start) if endp <= start { return 0 } local seg = json.substring(start + 1, endp) local pscan = 0 loop(true) { if pscan >= seg.length() { break } local pt = InstructionScannerBox.next_tuple(seg, pscan) if pt == "" { break } local pc1 = StringOps.index_of_from(pt, ",", 0) local pc2 = StringOps.index_of_from(pt, ",", pc1+1) if pc1 < 0 || pc2 < 0 { break } local ps = JsonFragBox._str_to_int(pt.substring(0, pc1)) local pe = JsonFragBox._str_to_int(pt.substring(pc1+1, pc2)) local pop = pt.substring(pc2+1, pt.length()) if pop == "phi" { local pitem = seg.substring(ps, pe) local dstp = JsonFragBox.get_int(pitem, "dst") if dstp == null { return 0 } local chosen = V1PhiAdapterBox.pick_incoming_value_id(pitem, prev_bb, trace) local write = null if chosen == null { if trace == 1 { print("[phi] dst=" + (""+dstp) + " prev=" + (""+prev_bb) + " chosen=null") } if strict == "1" && tolerate != "1" { return -1 } if tolerate == "1" { write = "0" } } else { local srcv = regs.getField(StringHelpers.int_to_str(chosen)) if srcv == null { if trace == 1 { print("[phi] dst=" + (""+dstp) + " prev=" + (""+prev_bb) + " chosen=" + (""+chosen) + " srcv=null") } if strict == "1" && tolerate != "1" { return -1 } if tolerate == "1" { write = "0" } } else { if trace == 1 { print("[phi] dst=" + (""+dstp) + " prev=" + (""+prev_bb) + " chosen=" + (""+chosen) + " srcv=" + (""+srcv) + " write=" + (""+srcv)) } write = "" + srcv } } if write != null { regs.setField(StringHelpers.int_to_str(dstp), write) } } pscan = pe } return 0 } // Apply φ from a pre-parsed table entry list for a block. // table: ArrayBox of { dst:int, incoming:ArrayBox of [pred:int, val:int] } apply_table_at_entry(table, regs, prev_bb, strict, tolerate, flow_trace) { if table == null { return 0 } local trace = 0 if flow_trace != null { if flow_trace == 1 { trace = 1 } } local n = table.size() local i = 0 loop(i < n) { local ent = table.get(i) i = i + 1 if ent == null { continue } local dstp = ent.get("dst") local inc = ent.get("incoming") if dstp == null || inc == null { continue } local write = null local m = inc.size() local j = 0 loop(j < m) { local pair = inc.get(j) j = j + 1 if pair == null { continue } // pair = [pred, val] local pred = 0; local val = 0 if pair.size() >= 1 { pred = JsonFragBox._str_to_int(""+pair.get(0)) } if pair.size() >= 2 { val = JsonFragBox._str_to_int(""+pair.get(1)) } if pred == prev_bb { local sv = regs.getField(StringHelpers.int_to_str(val)) if sv == null { if trace == 1 { print("[phi] dst=" + (""+dstp) + " prev=" + (""+prev_bb) + " chosen=" + (""+val) + " srcv=null") } if strict == "1" && tolerate != "1" { return -1 } if tolerate == "1" { write = "0" } } else { if trace == 1 { print("[phi] dst=" + (""+dstp) + " prev=" + (""+prev_bb) + " chosen=" + (""+val) + " srcv=" + (""+sv) + " write=" + (""+sv)) } write = "" + sv } break } } if write == null { if trace == 1 { print("[phi] dst=" + (""+dstp) + " prev=" + (""+prev_bb) + " chosen=null") } if strict == "1" && tolerate != "1" { return -1 } if tolerate == "1" { write = "0" } } if write != null { regs.setField(StringHelpers.int_to_str(dstp), write) } } return 0 } } static box V1PhiTableMain { method main(args) { return 0 } }