Fix compiler bomb
@@ -448,8 +448,18 @@ pub fn return_from_block(ctx: &mut Context, arity: u32, is_function_end: bool) {
}
pub fn start_block(ctx: &mut Context) -> BlockState {
- // free_return_register(ctx, arity);
- let current_state = ctx.block_state.clone();
+ use std::mem;
+
+ // OPTIMISATION: We cannot use the parent's stack values (it is disallowed by the spec)
+ // so we start a new stack, using `mem::replace` to ensure that we never
+ // clone or deallocate anything.
+ //
+ // I believe that it would be possible to cause a compiler bomb if we did
+ // not do this, since cloning iterates over the whole `Vec`.
+ let out_stack = mem::replace(&mut ctx.block_state.stack, vec![]);
+ let mut current_state = ctx.block_state.clone();
+ current_state.stack = out_stack;
+
ctx.block_state.parent_locals = ctx.block_state.locals.clone();
ctx.block_state.return_register = None;
current_state
