ffi issue-0050: monomorphizeFunction isolates pack-fn mono state
Adds the same save+null+defer-restore block at the top of `monomorphizeFunction` that landed in `lazyLowerFunction` for issue-0048. The outer pack-fn's `pack_arg_nodes` / `pack_param_count` / `pack_arg_types` / `inline_return_target` are now suppressed for the duration of the generic mono's body lowering and restored on exit. `examples/175-generic-fn-pack-state-leak.sx` flips green (len=0/1/2/4 across the four pack shapes); suite stays at 215/215.
This commit is contained in:
@@ -8730,6 +8730,29 @@ pub const Lowering = struct {
|
|||||||
const saved_defer_base = self.func_defer_base;
|
const saved_defer_base = self.func_defer_base;
|
||||||
const saved_block_terminated = self.block_terminated;
|
const saved_block_terminated = self.block_terminated;
|
||||||
const saved_target = self.target_type;
|
const saved_target = self.target_type;
|
||||||
|
// Pack-fn mono state is lexical to the pack-fn body. A generic
|
||||||
|
// function called from inside a pack-fn mono (e.g.
|
||||||
|
// `build(args: []Type, $ret: Type)` invoked from
|
||||||
|
// `probe(..$args) { build($args, void) }`) must not inherit the
|
||||||
|
// caller's pack maps — `lowerFieldAccess`'s `<pack_name>.len`
|
||||||
|
// intercept would otherwise constant-fold the callee's
|
||||||
|
// same-named param to whichever shape triggered the first mono
|
||||||
|
// and bake the wrong arity into the cached IR. Same shape of
|
||||||
|
// fix as `lazyLowerFunction` (issue-0048, commit 0ede097).
|
||||||
|
const saved_pan = self.pack_arg_nodes;
|
||||||
|
const saved_ppc = self.pack_param_count;
|
||||||
|
const saved_pat = self.pack_arg_types;
|
||||||
|
const saved_iri = self.inline_return_target;
|
||||||
|
self.pack_arg_nodes = null;
|
||||||
|
self.pack_param_count = null;
|
||||||
|
self.pack_arg_types = null;
|
||||||
|
self.inline_return_target = null;
|
||||||
|
defer {
|
||||||
|
self.pack_arg_nodes = saved_pan;
|
||||||
|
self.pack_param_count = saved_ppc;
|
||||||
|
self.pack_arg_types = saved_pat;
|
||||||
|
self.inline_return_target = saved_iri;
|
||||||
|
}
|
||||||
self.func_defer_base = self.defer_stack.items.len;
|
self.func_defer_base = self.defer_stack.items.len;
|
||||||
self.block_terminated = false;
|
self.block_terminated = false;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user