From efcb4e368509e3c7e84b2fc7a43fb9fc26016b67 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Tue, 10 Mar 2026 20:25:04 +0100 Subject: [PATCH] feat: Add stack size to runtime metadata Store the pre-calculated stack size of lambda bodies in the RuntimeMetadata. This allows the VM to directly access this information without recalculating it. --- src/ast/compiler/tco.rs | 13 +++++++++++++ src/ast/vm.rs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ast/compiler/tco.rs b/src/ast/compiler/tco.rs index b362cca..71aac68 100644 --- a/src/ast/compiler/tco.rs +++ b/src/ast/compiler/tco.rs @@ -10,6 +10,7 @@ pub struct RuntimeMetadata { pub is_tail: bool, /// The analyzed node, containing metrics and a link to the original TypedNode. pub original: Rc, + pub stack_size: u32, } impl Debug for RuntimeMetadata { @@ -17,6 +18,7 @@ impl Debug for RuntimeMetadata { f.debug_struct("Metadata") .field("ty", &self.ty) .field("is_tail", &self.is_tail) + .field("stack_size", &self.stack_size) .finish() } } @@ -174,6 +176,16 @@ impl TCO { BoundKind::Error => BoundKind::Error, }; + let stack_size = match &new_kind { + BoundKind::Lambda { .. } => { + // Pre-calculate stack size for the lambda body. + // Note: 'node' here is AnalyzedNode (Node, NodeMetrics>) + // 'calculate_stack_size' works for any T. + node.calculate_stack_size() + } + _ => 0, + }; + Node { identity: node.identity.clone(), kind: new_kind, @@ -181,6 +193,7 @@ impl TCO { ty: node.ty.original.ty.clone(), is_tail: is_tail_position, original: node_rc, + stack_size, }, } } diff --git a/src/ast/vm.rs b/src/ast/vm.rs index 06aab04..30e0f93 100644 --- a/src/ast/vm.rs +++ b/src/ast/vm.rs @@ -508,7 +508,7 @@ impl VM { for addr in upvalues { captured.push(self.capture_upvalue(*addr)?); } - let stack_size = body.calculate_stack_size(); + let stack_size = node.ty.stack_size; let closure = Closure::new( params.ty.original.clone(), body.ty.original.clone(),