shorten frames to closure vars only on gc

This commit is contained in:
2026-02-19 01:55:35 -06:00
parent e7fec94e38
commit bab4d50b2a
3 changed files with 77 additions and 22 deletions

View File

@@ -951,6 +951,7 @@ var mcode = function(ast) {
}
// Scan scope record for variable declarations
// Closure locals are assigned first so returned frames can be shortened
var scan_scope = function() {
var scope = find_scope_record(s_function_nr)
if (scope == null) {
@@ -963,6 +964,9 @@ var mcode = function(ast) {
var make = null
var is_const = false
var slot = 0
// Pass 1: closure locals first
_i = 0
while (_i < length(keys)) {
name = keys[_i]
if (name == "function_nr" || name == "nr_close_slots") {
@@ -975,14 +979,36 @@ var mcode = function(ast) {
_i = _i + 1
continue
}
if (find_var(name) < 0) {
if (v.closure == true && find_var(name) < 0) {
is_const = (make == "def" || make == "function")
slot = 1 + s_nr_args + s_nr_local_slots
s_nr_local_slots = s_nr_local_slots + 1
s_nr_close_slots = s_nr_close_slots + 1
add_var(name, slot, is_const)
s_vars[length(s_vars) - 1].is_closure = true
}
_i = _i + 1
}
// Pass 2: non-closure locals
_i = 0
while (_i < length(keys)) {
name = keys[_i]
if (name == "function_nr" || name == "nr_close_slots") {
_i = _i + 1
continue
}
v = scope[name]
make = v.make
if (make == null || make == "input") {
_i = _i + 1
continue
}
if (v.closure != true && find_var(name) < 0) {
is_const = (make == "def" || make == "function")
slot = 1 + s_nr_args + s_nr_local_slots
s_nr_local_slots = s_nr_local_slots + 1
add_var(name, slot, is_const)
if (v.closure == true) {
s_vars[length(s_vars) - 1].is_closure = true
}
}
_i = _i + 1
}
@@ -2738,8 +2764,6 @@ var mcode = function(ast) {
var disrupt_clause = func_node.disruption
var null_slot2 = null
var fn_name = func_node.name
var fn_scope = null
var nr_cs = 0
var result = null
var saved_label = 0
var saved_func = 0
@@ -2880,15 +2904,10 @@ var mcode = function(ast) {
fn_name = "<anonymous>"
}
fn_scope = find_scope_record(s_function_nr)
if (fn_scope != null && fn_scope.nr_close_slots != null) {
nr_cs = fn_scope.nr_close_slots
}
result = {
name: fn_name,
nr_args: nr_params,
nr_close_slots: nr_cs,
nr_close_slots: s_nr_close_slots,
nr_slots: s_max_slot + 1,
disruption_pc: disruption_start,
instructions: s_instructions