Extract calculate_stack_size to a standalone function
The `calculate_stack_size` method was duplicated in `bound_nodes.rs` and `tco.rs`. This commit extracts it into a single standalone function in `tco.rs` to avoid duplication. The stack size is now calculated and stored in the `ExecNode`'s `ty` field during the TCO optimization phase.
This commit is contained in:
+7
-14
@@ -144,8 +144,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
let exec_ast = TCO::optimize(Analyzer::analyze(&typed_ast, &HashMap::new())); // Minimal analysis for macro eval
|
||||
|
||||
let mut vm = VM::new(self.global_values.clone());
|
||||
let stack_size = exec_ast.calculate_stack_size();
|
||||
vm.run(&exec_ast, stack_size)
|
||||
vm.run(&exec_ast)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,7 +600,7 @@ impl Environment {
|
||||
} = &node.kind
|
||||
&& upvalues.is_empty()
|
||||
{
|
||||
let stack_size = node.calculate_stack_size();
|
||||
let stack_size = node.ty.stack_size;
|
||||
let closure = Rc::new(crate::ast::vm::Closure::new(
|
||||
params.ty.original.clone(),
|
||||
body.ty.original.clone(),
|
||||
@@ -629,7 +628,7 @@ impl Environment {
|
||||
purity: Purity::Impure,
|
||||
func: Rc::new(move |args| {
|
||||
let mut vm = VM::new(global_values.clone());
|
||||
let res = match vm.run(&exec_node, 0) { // Root call, use 0 if node is not a lambda
|
||||
let res = match vm.run(&exec_node) {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("Myc Runtime Error: {}", e),
|
||||
};
|
||||
@@ -708,8 +707,7 @@ impl Environment {
|
||||
|
||||
let tco_ast = TCO::optimize(optimized_ast);
|
||||
let mut vm = VM::new(global_values.clone());
|
||||
let stack_size = tco_ast.calculate_stack_size();
|
||||
let compiled_val = match vm.run(&tco_ast, stack_size) {
|
||||
let compiled_val = match vm.run(&tco_ast) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(format!("VM Error during specialization: {}", e)),
|
||||
};
|
||||
@@ -746,7 +744,6 @@ impl Environment {
|
||||
|
||||
pub fn run_script_compiled(&self, compiled: TypedNode) -> Result<Value, String> {
|
||||
let linked = self.link(compiled);
|
||||
let _stack_size = linked.calculate_stack_size();
|
||||
let func = self.instantiate(linked);
|
||||
let res = (func.func)(&[]);
|
||||
self.run_pipeline();
|
||||
@@ -757,16 +754,12 @@ impl Environment {
|
||||
self.preload_dependencies(source, None)?;
|
||||
let compiled = self.compile(source).into_result()?;
|
||||
let linked = self.link(compiled);
|
||||
|
||||
// Late Counting: Determine stack size after all optimizations are finished.
|
||||
// This keeps AST nodes clean and ensures the VM always has enough space.
|
||||
let stack_size = linked.calculate_stack_size();
|
||||
|
||||
let mut vm = VM::new(self.global_values.clone());
|
||||
let mut observer = TracingObserver::new();
|
||||
|
||||
// 1. Run the script wrapper (returns a closure representing the script)
|
||||
let result = vm.run_with_observer(&mut observer, &linked, stack_size);
|
||||
|
||||
// 1. Run the script wrapper (returns a closure representing the script)
|
||||
let result = vm.run_with_observer(&mut observer, &linked);
|
||||
// 2. Execute the root closure immediately to get the actual script result.
|
||||
// All Myc scripts are wrapped in a parameterless lambda for consistency.
|
||||
let mut final_result = result;
|
||||
|
||||
Reference in New Issue
Block a user