closure get type back inference

This commit is contained in:
2026-02-20 20:51:21 -06:00
parent 6cac591dc9
commit 3e4f3dff11

View File

@@ -457,6 +457,19 @@ var streamline = function(ir, log) {
i = i + 1
continue
}
if (op == "get" && func._closure_slot_types != null) {
slot = instr[1]
typ = T_UNKNOWN
src_typ = func._closure_slot_types[text(instr[2]) + "_" + text(instr[3])]
if (src_typ != null) {
typ = src_typ
}
if (slot > 0 && slot > nr_args) {
merge_backward(write_types, slot, typ)
}
i = i + 1
continue
}
rule = write_rules[op]
if (rule != null) {
@@ -1966,6 +1979,71 @@ var streamline = function(ir, log) {
}
fi = fi + 1
}
ir._parent_of = parent_of
ir._parent_fc = fc
return null
}
// =========================================================
// Resolve closure slot types from parent write_types.
// For each `get` in func, walk the parent chain and look up
// the ancestor's inferred write type for that closure slot.
// =========================================================
var resolve_closure_types = function(func, fi, ir) {
var parent_of = ir._parent_of
var fc = ir._parent_fc
var instructions = func.instructions
var num_instr = 0
var closure_types = null
var i = 0
var instr = null
var slot = 0
var depth = 0
var anc = 0
var j = 0
var target = null
var typ = null
var key = null
if (instructions == null || parent_of == null) {
return null
}
num_instr = length(instructions)
closure_types = {}
i = 0
while (i < num_instr) {
instr = instructions[i]
if (is_array(instr) && instr[0] == "get") {
slot = instr[2]
depth = instr[3]
key = text(slot) + "_" + text(depth)
if (closure_types[key] == null) {
anc = fi
j = 0
while (j < depth && anc >= 0) {
anc = parent_of[anc]
j = j + 1
}
if (anc >= 0) {
if (anc == fc) {
target = ir.main
} else {
target = ir.functions[anc]
}
if (target != null && target._write_types != null) {
typ = target._write_types[slot]
if (typ != null) {
closure_types[key] = typ
}
}
}
}
}
i = i + 1
}
func._closure_slot_types = closure_types
return null
}
@@ -2284,6 +2362,7 @@ var streamline = function(ir, log) {
run_cycle("")
run_cycle("_2")
func._write_types = write_types
if (ir._warn) {
diagnose_function(func, {param_types: param_types, write_types: write_types}, ir)
}
@@ -2305,11 +2384,12 @@ var streamline = function(ir, log) {
optimize_function(ir.main, log)
}
// Process all sub-functions
// Process all sub-functions (resolve closure types from parent first)
var fi = 0
if (ir.functions != null) {
fi = 0
while (fi < length(ir.functions)) {
resolve_closure_types(ir.functions[fi], fi, ir)
optimize_function(ir.functions[fi], log)
fi = fi + 1
}