diff --git a/src/ast/vm.rs b/src/ast/vm.rs index 30e0f93..249d82d 100644 --- a/src/ast/vm.rs +++ b/src/ast/vm.rs @@ -168,6 +168,13 @@ impl VM { } else { self.unpack(&closure.parameter_node, &next_args, &mut 0)?; } + + // PRE-ALLOCATION + let current_stack = self.stack.len() as u32; + if closure.stack_size > current_stack { + self.stack.resize(closure.stack_size as usize, Value::Void); + } + result = self.eval_observed(observer, &closure.exec_node); self.frames.pop(); } else if let Some(series) = next_obj.as_series() { @@ -239,9 +246,7 @@ impl VM { // Fill remaining stack slots with Void let current_stack = self.stack.len() as u32; if closure.stack_size > current_stack { - for _ in 0..(closure.stack_size - current_stack) { - self.stack.push(Value::Void); - } + self.stack.resize(closure.stack_size as usize, Value::Void); } self.frames.push(CallFrame { @@ -263,9 +268,7 @@ impl VM { self.stack.clear(); self.frames.clear(); - for _ in 0..stack_size { - self.stack.push(Value::Void); - } + self.stack.resize(stack_size as usize, Value::Void); self.frames.push(CallFrame { stack_base: 0, @@ -697,7 +700,14 @@ impl VM { }; let res = match unpack_res { - Ok(_) => self.eval_internal(obs, &closure.exec_node), + Ok(_) => { + // PRE-ALLOCATION + let current_stack = (self.stack.len() - base) as u32; + if closure.stack_size > current_stack { + self.stack.resize(base + closure.stack_size as usize, Value::Void); + } + self.eval_internal(obs, &closure.exec_node) + } Err(e) => Err(e), };