diff --git a/boa_engine/src/environments/runtime.rs b/boa_engine/src/environments/runtime.rs index 9136c7ba4d9..ccbe4e60233 100644 --- a/boa_engine/src/environments/runtime.rs +++ b/boa_engine/src/environments/runtime.rs @@ -695,7 +695,7 @@ impl BindingLocator { } /// Creates a binding locator that indicates that the binding is on the global object. - pub(crate) const fn global(name: Identifier) -> Self { + pub(super) const fn global(name: Identifier) -> Self { Self { name, environment_index: 0, diff --git a/boa_engine/src/vm/call_frame/mod.rs b/boa_engine/src/vm/call_frame/mod.rs index ce969a479fd..40f97aa8440 100644 --- a/boa_engine/src/vm/call_frame/mod.rs +++ b/boa_engine/src/vm/call_frame/mod.rs @@ -10,7 +10,6 @@ use crate::{ vm::CodeBlock, }; use boa_gc::{Finalize, Gc, Trace}; -use boa_interner::Sym; use thin_vec::ThinVec; pub(crate) use abrupt_record::AbruptCompletionRecord; @@ -44,8 +43,8 @@ pub struct CallFrame { // Iterators and their `[[Done]]` flags that must be closed when an abrupt completion is thrown. pub(crate) iterators: ThinVec<(JsObject, bool)>, - // The current binding being updated. - pub(crate) current_binding: BindingLocator, + // The stack of bindings being updated. + pub(crate) binding_stack: Vec, } /// ---- `CallFrame` public API ---- @@ -76,7 +75,7 @@ impl CallFrame { promise_capability: None, async_generator: None, iterators: ThinVec::new(), - current_binding: BindingLocator::global(Sym::EMPTY_STRING.into()), + binding_stack: Vec::new(), } } diff --git a/boa_engine/src/vm/opcode/get/name.rs b/boa_engine/src/vm/opcode/get/name.rs index 7dae765ccb7..f3b165d31d3 100644 --- a/boa_engine/src/vm/opcode/get/name.rs +++ b/boa_engine/src/vm/opcode/get/name.rs @@ -49,7 +49,7 @@ impl Operation for GetLocator { let mut binding_locator = context.vm.frame().code_block.bindings[index as usize]; context.find_runtime_binding(&mut binding_locator)?; - context.vm.frame_mut().current_binding = binding_locator; + context.vm.frame_mut().binding_stack.push(binding_locator); Ok(CompletionType::Normal) } @@ -80,7 +80,7 @@ impl Operation for GetNameAndLocator { JsNativeError::reference().with_message(format!("{name} is not defined")) })?; - context.vm.frame_mut().current_binding = binding_locator; + context.vm.frame_mut().binding_stack.push(binding_locator); context.vm.push(value); Ok(CompletionType::Normal) } diff --git a/boa_engine/src/vm/opcode/set/name.rs b/boa_engine/src/vm/opcode/set/name.rs index 4edd314073c..9e0431776cc 100644 --- a/boa_engine/src/vm/opcode/set/name.rs +++ b/boa_engine/src/vm/opcode/set/name.rs @@ -46,7 +46,12 @@ impl Operation for SetNameByLocator { const INSTRUCTION: &'static str = "INST - SetNameByLocator"; fn execute(context: &mut Context<'_>) -> JsResult { - let binding_locator = context.vm.frame().current_binding; + let binding_locator = context + .vm + .frame_mut() + .binding_stack + .pop() + .expect("locator should have been popped before"); let value = context.vm.pop(); if binding_locator.is_silent() { return Ok(CompletionType::Normal);