From 498b424578252944cbbfae90753e73f8c15149ae Mon Sep 17 00:00:00 2001 From: Hans Larsen Date: Wed, 18 Mar 2026 21:31:07 -0700 Subject: [PATCH] refactor(engine): encapsulate Context VM field access behind wrapper methods Add `context/vm_access.rs` with 45 wrapper methods that delegate to `Context`'s internal `Vm` field, then replace all ~600 direct `context.vm.*` accesses across 78 files with calls to these wrappers. This is the first step toward extracting Context into its own crate (boa_context). By routing all external access through methods, the internal structure of Context can be changed without touching call sites. Co-Authored-By: Claude Opus 4.6 (1M context) --- core/engine/src/builtins/error/mod.rs | 2 +- core/engine/src/builtins/eval/mod.rs | 24 +- core/engine/src/builtins/function/bound.rs | 4 +- core/engine/src/builtins/function/mod.rs | 61 ++-- core/engine/src/builtins/generator/mod.rs | 20 +- .../src/builtins/intl/date_time_format/mod.rs | 2 +- .../src/builtins/intl/number_format/mod.rs | 2 +- core/engine/src/builtins/is_html_dda.rs | 6 +- core/engine/src/builtins/json/mod.rs | 10 +- core/engine/src/builtins/proxy/mod.rs | 22 +- core/engine/src/builtins/weak/weak_ref.rs | 4 +- core/engine/src/bytecompiler/declarations.rs | 2 +- core/engine/src/context/mod.rs | 1 + core/engine/src/context/vm_access.rs | 296 ++++++++++++++++++ core/engine/src/module/source.rs | 12 +- core/engine/src/module/synthetic.rs | 11 +- core/engine/src/native_function/mod.rs | 46 ++- core/engine/src/object/builtins/jspromise.rs | 32 +- core/engine/src/object/operations.rs | 46 +-- core/engine/src/script.rs | 8 +- core/engine/src/vm/code_block.rs | 4 +- core/engine/src/vm/mod.rs | 4 +- core/engine/src/vm/opcode/arguments.rs | 16 +- core/engine/src/vm/opcode/await/mod.rs | 6 +- .../src/vm/opcode/binary_ops/logical.rs | 12 +- .../src/vm/opcode/binary_ops/macro_defined.rs | 8 +- core/engine/src/vm/opcode/binary_ops/mod.rs | 22 +- core/engine/src/vm/opcode/call/mod.rs | 38 +-- core/engine/src/vm/opcode/concat/mod.rs | 4 +- .../engine/src/vm/opcode/control_flow/jump.rs | 60 ++-- .../src/vm/opcode/control_flow/return.rs | 36 +-- .../src/vm/opcode/control_flow/throw.rs | 38 +-- core/engine/src/vm/opcode/copy/mod.rs | 6 +- .../src/vm/opcode/define/class/getter.rs | 20 +- .../src/vm/opcode/define/class/method.rs | 20 +- .../src/vm/opcode/define/class/setter.rs | 20 +- core/engine/src/vm/opcode/define/mod.rs | 14 +- .../src/vm/opcode/define/own_property.rs | 10 +- core/engine/src/vm/opcode/delete/mod.rs | 15 +- core/engine/src/vm/opcode/environment/mod.rs | 68 ++-- core/engine/src/vm/opcode/function.rs | 14 +- core/engine/src/vm/opcode/generator/mod.rs | 15 +- .../src/vm/opcode/generator/yield_stm.rs | 16 +- core/engine/src/vm/opcode/get/argument.rs | 4 +- core/engine/src/vm/opcode/get/function.rs | 2 +- core/engine/src/vm/opcode/get/name.rs | 35 +-- core/engine/src/vm/opcode/get/private.rs | 4 +- core/engine/src/vm/opcode/get/property.rs | 40 +-- core/engine/src/vm/opcode/iteration/for_in.rs | 2 +- core/engine/src/vm/opcode/iteration/get.rs | 8 +- .../src/vm/opcode/iteration/iterator.rs | 52 +-- .../src/vm/opcode/iteration/loop_ops.rs | 4 +- core/engine/src/vm/opcode/meta/mod.rs | 6 +- core/engine/src/vm/opcode/mod.rs | 8 +- core/engine/src/vm/opcode/new/mod.rs | 10 +- core/engine/src/vm/opcode/object.rs | 6 +- core/engine/src/vm/opcode/pop/mod.rs | 4 +- core/engine/src/vm/opcode/push/array.rs | 8 +- core/engine/src/vm/opcode/push/class/field.rs | 10 +- core/engine/src/vm/opcode/push/class/mod.rs | 6 +- .../src/vm/opcode/push/class/private.rs | 14 +- core/engine/src/vm/opcode/push/environment.rs | 12 +- core/engine/src/vm/opcode/push/literal.rs | 8 +- core/engine/src/vm/opcode/push/mod.rs | 2 +- core/engine/src/vm/opcode/push/numbers.rs | 4 +- core/engine/src/vm/opcode/push/object.rs | 2 +- .../src/vm/opcode/rest_parameter/mod.rs | 12 +- .../src/vm/opcode/set/class_prototype.rs | 6 +- core/engine/src/vm/opcode/set/name.rs | 10 +- core/engine/src/vm/opcode/set/private.rs | 20 +- core/engine/src/vm/opcode/set/property.rs | 48 +-- core/engine/src/vm/opcode/switch/mod.rs | 6 +- core/engine/src/vm/opcode/templates/mod.rs | 10 +- core/engine/src/vm/opcode/to/mod.rs | 4 +- .../src/vm/opcode/unary_ops/decrement.rs | 6 +- .../src/vm/opcode/unary_ops/increment.rs | 6 +- .../engine/src/vm/opcode/unary_ops/logical.rs | 4 +- core/engine/src/vm/opcode/unary_ops/mod.rs | 8 +- core/engine/src/vm/opcode/value/mod.rs | 6 +- 79 files changed, 856 insertions(+), 618 deletions(-) create mode 100644 core/engine/src/context/vm_access.rs diff --git a/core/engine/src/builtins/error/mod.rs b/core/engine/src/builtins/error/mod.rs index 65fd7415aa3..639560894b9 100644 --- a/core/engine/src/builtins/error/mod.rs +++ b/core/engine/src/builtins/error/mod.rs @@ -170,7 +170,7 @@ impl Error { pub(crate) fn with_caller_position(tag: ErrorKind, context: &Context) -> Self { Self { tag, - position: IgnoreEq(context.vm.shadow_stack.caller_position()), + position: IgnoreEq(context.shadow_stack().caller_position()), backtrace: IgnoreEq(None), } } diff --git a/core/engine/src/builtins/eval/mod.rs b/core/engine/src/builtins/eval/mod.rs index f8fc8f458f0..219bc83afdb 100644 --- a/core/engine/src/builtins/eval/mod.rs +++ b/core/engine/src/builtins/eval/mod.rs @@ -137,7 +137,7 @@ impl Eval { // 9. Let inClassFieldInitializer be false. // a. Let thisEnvRec be GetThisEnvironment(). let flags = match { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -212,14 +212,14 @@ impl Eval { // Poison the last parent function environment, because it may contain new declarations after/during eval. if !strict { { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.poison_until_last_function(global); } } // Set the compile time environment to the current running environment and save the number of current environments. - let environments_len = context.vm.frame().environments.len(); + let environments_len = context.frame().environments.len(); // Pop any added runtime environments that were not removed during the eval execution. EnvStackAction::Truncate(environments_len) @@ -227,7 +227,7 @@ impl Eval { // If the call to eval is indirect, the code is executed in the global environment. // Pop all environments before the eval execution. - let saved = context.vm.frame_mut().environments.pop_to_global(); + let saved = context.frame_mut().environments.pop_to_global(); // Restore all environments to the state from before the eval execution. EnvStackAction::Restore(saved) @@ -242,7 +242,7 @@ impl Eval { }); let (var_environment, mut variable_scope) = - if let Some(e) = context.vm.frame().environments.outer_function_environment() { + if let Some(e) = context.frame().environments.outer_function_environment() { (e.0, e.1) } else { ( @@ -269,7 +269,7 @@ impl Eval { context, )?; - let in_with = context.vm.frame().environments.has_object_environment(); + let in_with = context.frame().environments.has_object_environment(); let source_text = SourceText::new(source); let spanned_source_text = SpannedSourceText::new_source_only(source_text); @@ -328,10 +328,10 @@ impl Eval { var_environment.extend_from_compile(); } - let env_fp = context.vm.frame().environments.len() as u32; - let environments = context.vm.frame().environments.clone(); + let env_fp = context.frame().environments.len() as u32; + let environments = context.frame().environments.clone(); let realm = context.realm().clone(); - context.vm.push_frame_with_stack( + context.push_frame_with_stack( CallFrame::new(code_block.clone(), None, environments, realm) .with_env_fp(env_fp) .with_flags(CallFrameFlags::EXIT_EARLY), @@ -345,7 +345,7 @@ impl Eval { // in `eval_declaration_instantiation` get their proper // environment stack. { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame .environments @@ -355,11 +355,11 @@ impl Eval { context .eval_declaration_instantiation(&code_block) .inspect_err(|_| { - context.vm.pop_frame(); + context.pop_frame(); })?; let record = context.run(); - context.vm.pop_frame(); + context.pop_frame(); record.consume() } diff --git a/core/engine/src/builtins/function/bound.rs b/core/engine/src/builtins/function/bound.rs index f0331bb209b..98c5f9b9847 100644 --- a/core/engine/src/builtins/function/bound.rs +++ b/core/engine/src/builtins/function/bound.rs @@ -151,7 +151,7 @@ fn bound_function_exotic_construct( argument_count: usize, context: &mut InternalMethodCallContext<'_>, ) -> JsResult { - let new_target = context.vm.stack.pop(); + let new_target = context.stack_pop(); debug_assert!(new_target.is_object(), "new.target should be an object"); @@ -182,6 +182,6 @@ fn bound_function_exotic_construct( }; // 6. Return ? Construct(target, args, newTarget). - context.vm.stack.push(new_target); + context.stack_push(new_target); Ok(target.__construct__(bound_args.len() + argument_count)) } diff --git a/core/engine/src/builtins/function/mod.rs b/core/engine/src/builtins/function/mod.rs index bb04263a469..f38b47002b7 100644 --- a/core/engine/src/builtins/function/mod.rs +++ b/core/engine/src/builtins/function/mod.rs @@ -653,7 +653,7 @@ impl BuiltInFunctionObject { return Err(js_error!(SyntaxError: "failed to analyze function scope: {}", reason)); } - let in_with = context.vm.frame().environments.has_object_environment(); + let in_with = context.frame().environments.has_object_environment(); let spanned_source_text = SpannedSourceText::new_empty(); let code = FunctionCompiler::new(spanned_source_text) @@ -672,7 +672,7 @@ impl BuiltInFunctionObject { context.interner_mut(), ); - let saved = context.vm.frame_mut().environments.pop_to_global(); + let saved = context.frame_mut().environments.pop_to_global(); let function_object = crate::vm::create_function_object(code, prototype, context); context .vm @@ -1027,48 +1027,42 @@ pub(crate) fn function_call( .patch_last_native(native_source_info); } - context.vm.push_frame(frame); - context.vm.set_return_value(JsValue::undefined()); + context.push_frame(frame); + context.set_return_value(JsValue::undefined()); let context = context.context(); - let lexical_this_mode = context.vm.frame().code_block.this_mode == ThisMode::Lexical; + let lexical_this_mode = context.frame().code_block.this_mode == ThisMode::Lexical; let this = if lexical_this_mode { ThisBindingStatus::Lexical } else { - let this = context.vm.stack.get_this(context.vm.frame()); - if context.vm.frame().code_block.strict() { - context.vm.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; + let this = context.stack_get_this(); + if context.frame().code_block.strict() { + context.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; ThisBindingStatus::Initialized(this) } else if this.is_null_or_undefined() { - context.vm.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; + context.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; let this: JsValue = context.realm().global_this().clone().into(); - context.vm.stack.set_this( - context.vm.frames.last().js_expect("frame must exist")?, - this.clone(), - ); + context.stack_set_this(this.clone()); ThisBindingStatus::Initialized(this) } else { let this: JsValue = this .to_object(context) .js_expect("conversion cannot fail")? .into(); - context.vm.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; - context.vm.stack.set_this( - context.vm.frames.last().js_expect("frame must exist")?, - this.clone(), - ); + context.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; + context.stack_set_this(this.clone()); ThisBindingStatus::Initialized(this) } }; let mut last_env = 0; - let has_binding_identifier = context.vm.frame().code_block().has_binding_identifier(); - let has_function_scope = context.vm.frame().code_block().has_function_scope(); + let has_binding_identifier = context.frame().code_block().has_binding_identifier(); + let has_function_scope = context.frame().code_block().has_function_scope(); if has_binding_identifier { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); let index = frame.environments.push_lexical(1, global); frame.environments.put_lexical_value( @@ -1081,8 +1075,8 @@ pub(crate) fn function_call( } if has_function_scope { - let scope = context.vm.frame().code_block().constant_scope(last_env); - let frame = context.vm.frame_mut(); + let scope = context.frame().code_block().constant_scope(last_env); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.push_function( scope, @@ -1124,7 +1118,7 @@ fn function_construct( let env_fp = environments.len() as u32; - let new_target = context.vm.stack.pop(); + let new_target = context.stack_pop(); let this = if code.is_derived_constructor() { None @@ -1167,16 +1161,16 @@ fn function_construct( .patch_last_native(native_source_info); } - context.vm.push_frame(frame); - context.vm.set_return_value(JsValue::undefined()); + context.push_frame(frame); + context.set_return_value(JsValue::undefined()); let mut last_env = 0; - let has_binding_identifier = context.vm.frame().code_block().has_binding_identifier(); - let has_function_scope = context.vm.frame().code_block().has_function_scope(); + let has_binding_identifier = context.frame().code_block().has_binding_identifier(); + let has_function_scope = context.frame().code_block().has_function_scope(); if has_binding_identifier { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); let index = frame.environments.push_lexical(1, global); frame.environments.put_lexical_value( @@ -1189,8 +1183,8 @@ fn function_construct( } if has_function_scope { - let scope = context.vm.frame().code_block().constant_scope(last_env); - let frame = context.vm.frame_mut(); + let scope = context.frame().code_block().constant_scope(last_env); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.push_function( scope, @@ -1211,10 +1205,7 @@ fn function_construct( } let context = context.context(); - context.vm.stack.set_this( - context.vm.frames.last().js_expect("frame must exist")?, - this.map(JsValue::new).unwrap_or_default(), - ); + context.stack_set_this(this.map(JsValue::new).unwrap_or_default()); Ok(CallValue::Ready) } diff --git a/core/engine/src/builtins/generator/mod.rs b/core/engine/src/builtins/generator/mod.rs index 74ad7a0feec..d5138807c58 100644 --- a/core/engine/src/builtins/generator/mod.rs +++ b/core/engine/src/builtins/generator/mod.rs @@ -66,13 +66,13 @@ pub(crate) struct GeneratorContext { impl GeneratorContext { /// Creates a new `GeneratorContext` from the current `Context` state. pub(crate) fn from_current(context: &mut Context, async_generator: Option) -> Self { - let mut frame = context.vm.frame().clone(); - frame.environments = context.vm.frame().environments.clone(); + let mut frame = context.frame().clone(); + frame.environments = context.frame().environments.clone(); frame.realm = context.realm().clone(); // Split the stack at fp. The split-off portion starts at what was fp, // so adjust rp and fp to be relative to the new base. - let mut stack = context.vm.stack.split_off_frame(&frame); + let mut stack = context.stack_split_off_at(&frame); frame.rp -= frame.fp; frame.fp = 0; @@ -101,28 +101,28 @@ impl GeneratorContext { resume_kind: GeneratorResumeKind, context: &mut Context, ) -> CompletionRecord { - std::mem::swap(&mut context.vm.stack, &mut self.stack); + context.stack_swap(&mut self.stack); let Some(frame) = self.call_frame.take() else { return CompletionRecord::Throw(PanicError::new("should have a call frame").into()); }; let fp = frame.fp; let rp = frame.rp; - context.vm.push_frame(frame); + context.push_frame(frame); - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); frame.fp = fp; frame.rp = rp; frame.set_exit_early(true); if let Some(value) = value { - context.vm.stack.push(value); + context.stack_push(value); } - context.vm.stack.push(resume_kind); + context.stack_push(resume_kind); let result = context.run(); - std::mem::swap(&mut context.vm.stack, &mut self.stack); - self.call_frame = context.vm.pop_frame(); + context.stack_swap(&mut self.stack); + self.call_frame = context.pop_frame(); assert!(self.call_frame.is_some()); result } diff --git a/core/engine/src/builtins/intl/date_time_format/mod.rs b/core/engine/src/builtins/intl/date_time_format/mod.rs index f562da44529..f2dcee1a369 100644 --- a/core/engine/src/builtins/intl/date_time_format/mod.rs +++ b/core/engine/src/builtins/intl/date_time_format/mod.rs @@ -192,7 +192,7 @@ impl BuiltInConstructor for DateTimeFormat { // ChainDateTimeFormat ( dateTimeFormat, newTarget, this ) // - let this = context.vm.stack.get_this(context.vm.frame()); + let this = context.stack_get_this(); let Some(this_obj) = this.as_object() else { return Ok(date_time_format.into()); }; diff --git a/core/engine/src/builtins/intl/number_format/mod.rs b/core/engine/src/builtins/intl/number_format/mod.rs index af27d458157..13f2c3d0e7f 100644 --- a/core/engine/src/builtins/intl/number_format/mod.rs +++ b/core/engine/src/builtins/intl/number_format/mod.rs @@ -178,7 +178,7 @@ impl BuiltInConstructor for NumberFormat { // ChainNumberFormat ( numberFormat, newTarget, this ) // - let this = context.vm.stack.get_this(context.vm.frame()); + let this = context.stack_get_this(); let Some(this_obj) = this.as_object() else { return Ok(number_format.into()); }; diff --git a/core/engine/src/builtins/is_html_dda.rs b/core/engine/src/builtins/is_html_dda.rs index 8652e9b6de1..1ec25d96633 100644 --- a/core/engine/src/builtins/is_html_dda.rs +++ b/core/engine/src/builtins/is_html_dda.rs @@ -56,11 +56,11 @@ fn is_html_dda_call( .vm .stack .calling_convention_pop_arguments(argument_count); - let _func = context.vm.stack.pop(); - let _this = context.vm.stack.pop(); + let _func = context.stack_pop(); + let _this = context.stack_pop(); // Push undefined as the return value. - context.vm.stack.push(JsValue::undefined()); + context.stack_push(JsValue::undefined()); Ok(CallValue::Complete) } diff --git a/core/engine/src/builtins/json/mod.rs b/core/engine/src/builtins/json/mod.rs index 7b4d9aafed3..dfe5bd0ba4c 100644 --- a/core/engine/src/builtins/json/mod.rs +++ b/core/engine/src/builtins/json/mod.rs @@ -287,7 +287,7 @@ impl Json { }; let code_block = { - let in_with = context.vm.frame().environments.has_object_environment(); + let in_with = context.frame().environments.has_object_environment(); let spanned_source_text = SpannedSourceText::new_source_only( crate::spanned_source_text::SourceText::new(source_text), ); @@ -310,12 +310,12 @@ impl Json { let realm = context.realm().clone(); - let env_fp = context.vm.frame().environments.len() as u32; - context.vm.push_frame_with_stack( + let env_fp = context.frame().environments.len() as u32; + context.push_frame_with_stack( CallFrame::new( code_block, None, - context.vm.frame().environments.clone(), + context.frame().environments.clone(), realm, ) .with_env_fp(env_fp) @@ -326,7 +326,7 @@ impl Json { context.realm().resize_global_env(); let record = context.run(); - context.vm.pop_frame(); + context.pop_frame(); let unfiltered = record.consume()?; diff --git a/core/engine/src/builtins/proxy/mod.rs b/core/engine/src/builtins/proxy/mod.rs index a86155e2421..695566e8a68 100644 --- a/core/engine/src/builtins/proxy/mod.rs +++ b/core/engine/src/builtins/proxy/mod.rs @@ -1174,15 +1174,15 @@ fn proxy_exotic_call( let arg_array = array::Array::create_array_from_list(args, context); // 8. Return ? Call(trap, handler, « target, thisArgument, argArray »). - let _func = context.vm.stack.pop(); - let this = context.vm.stack.pop(); + let _func = context.stack_pop(); + let this = context.stack_pop(); - context.vm.stack.push(handler); // This - context.vm.stack.push(trap.clone()); // Function + context.stack_push(handler); // This + context.stack_push(trap.clone()); // Function - context.vm.stack.push(target); - context.vm.stack.push(this); - context.vm.stack.push(arg_array); + context.stack_push(target); + context.stack_push(this); + context.stack_push(arg_array); Ok(trap.__call__(3)) } @@ -1216,13 +1216,13 @@ fn proxy_exotic_construct( return Ok(target.__construct__(argument_count)); }; - let new_target = context.vm.stack.pop(); + let new_target = context.stack_pop(); let args = context .vm .stack .calling_convention_pop_arguments(argument_count); - let _func = context.vm.stack.pop(); - let _this = context.vm.stack.pop(); + let _func = context.stack_pop(); + let _this = context.stack_pop(); // 8. Let argArray be ! CreateArrayFromList(argumentsList). let arg_array = array::Array::create_array_from_list(args, context); @@ -1240,7 +1240,7 @@ fn proxy_exotic_construct( })?; // 11. Return newObj. - context.vm.stack.push(new_obj); + context.stack_push(new_obj); Ok(CallValue::Complete) } diff --git a/core/engine/src/builtins/weak/weak_ref.rs b/core/engine/src/builtins/weak/weak_ref.rs index a2bd0c4cde2..eb96632ec93 100644 --- a/core/engine/src/builtins/weak/weak_ref.rs +++ b/core/engine/src/builtins/weak/weak_ref.rs @@ -91,7 +91,7 @@ impl BuiltInConstructor for WeakRef { ); // 4. Perform AddToKeptObjects(target). - context.kept_alive.push(target.clone()); + context.add_kept_alive(target.clone()); // 6. Return weakRef. Ok(weak_ref.into()) @@ -128,7 +128,7 @@ impl WeakRef { let object = JsObject::from(object); // a. Perform AddToKeptObjects(target). - context.kept_alive.push(object.clone()); + context.add_kept_alive(object.clone()); // b. Return target. Ok(object.into()) diff --git a/core/engine/src/bytecompiler/declarations.rs b/core/engine/src/bytecompiler/declarations.rs index 8f27206ac0b..98ffb38105f 100644 --- a/core/engine/src/bytecompiler/declarations.rs +++ b/core/engine/src/bytecompiler/declarations.rs @@ -212,7 +212,7 @@ pub(crate) fn prepare_eval_declaration_instantiation( // i. If privateIdentifiers does not contain binding.[[Description]], // append binding.[[Description]] to privateIdentifiers. // b. Set pointer to pointer.[[OuterPrivateEnvironment]]. - let private_identifiers = context.vm.frame().environments.private_name_descriptions(); + let private_identifiers = context.frame().environments.private_name_descriptions(); let private_identifiers = private_identifiers .into_iter() .map(|ident| { diff --git a/core/engine/src/context/mod.rs b/core/engine/src/context/mod.rs index b9791334283..ce88e9d2f96 100644 --- a/core/engine/src/context/mod.rs +++ b/core/engine/src/context/mod.rs @@ -43,6 +43,7 @@ mod hooks; #[cfg(feature = "intl")] pub(crate) mod icu; pub mod intrinsics; +mod vm_access; thread_local! { static CANNOT_BLOCK_COUNTER: Cell = const { Cell::new(0) }; diff --git a/core/engine/src/context/vm_access.rs b/core/engine/src/context/vm_access.rs new file mode 100644 index 00000000000..9db91eaf06d --- /dev/null +++ b/core/engine/src/context/vm_access.rs @@ -0,0 +1,296 @@ +//! Wrapper methods on [`Context`] for VM access. +//! +//! These methods encapsulate access to `Context`'s internal `Vm` field, +//! ensuring external code doesn't depend on Context's internal structure. + +use crate::{ + JsError, JsResult, JsValue, + builtins::promise::PromiseCapability, + object::JsObject, + vm::{CallFrame, Stack, shadow_stack::ShadowStack}, +}; + +use super::Context; + +// === Register Access === + +impl Context { + /// Get a register value by index. + #[track_caller] + #[inline] + pub(crate) fn get_register(&self, index: usize) -> &JsValue { + self.vm.get_register(index) + } + + /// Set a register value by index. + #[track_caller] + #[inline] + pub(crate) fn set_register(&mut self, index: usize, value: JsValue) { + self.vm.set_register(index, value); + } + + /// Take the value from a register, replacing it with `undefined`. + #[track_caller] + #[inline] + pub(crate) fn take_register(&mut self, index: usize) -> JsValue { + self.vm.take_register(index) + } +} + +// === Frame Access === + +impl Context { + /// Retrieves the current VM call frame. + #[track_caller] + #[inline] + pub(crate) fn frame(&self) -> &CallFrame { + self.vm.frame() + } + + /// Retrieves the current VM call frame mutably. + #[track_caller] + #[inline] + pub(crate) fn frame_mut(&mut self) -> &mut CallFrame { + self.vm.frame_mut() + } + + /// Returns a slice of all call frames. + pub(crate) fn frames(&self) -> &[CallFrame] { + &self.vm.frames + } + + /// Returns a mutable slice of all call frames. + pub(crate) fn frames_mut(&mut self) -> &mut [CallFrame] { + &mut self.vm.frames + } + + /// Push a call frame onto the VM. + pub(crate) fn push_frame(&mut self, frame: CallFrame) { + self.vm.push_frame(frame); + } + + /// Push a call frame with this/function values onto the stack. + pub(crate) fn push_frame_with_stack( + &mut self, + frame: CallFrame, + this: JsValue, + function: JsValue, + ) { + self.vm.push_frame_with_stack(frame, this, function); + } + + /// Pop the current call frame. + pub(crate) fn pop_frame(&mut self) -> Option { + self.vm.pop_frame() + } +} + +// === Return Value === + +impl Context { + /// Get the return value (cloned). + pub(crate) fn get_return_value(&self) -> JsValue { + self.vm.get_return_value() + } + + /// Set the return value. + pub(crate) fn set_return_value(&mut self, value: JsValue) { + self.vm.set_return_value(value); + } + + /// Take the return value, replacing it with undefined. + pub(crate) fn take_return_value(&mut self) -> JsValue { + self.vm.take_return_value() + } +} + +// === Exception Handling === + +impl Context { + /// Set the pending exception. + pub(crate) fn set_pending_exception(&mut self, exception: JsError) { + self.vm.pending_exception = Some(exception); + } + + /// Take the pending exception, leaving None. + pub(crate) fn take_pending_exception(&mut self) -> Option { + self.vm.pending_exception.take() + } + + /// Check if there's a pending exception. + pub(crate) fn has_pending_exception(&self) -> bool { + self.vm.pending_exception.is_some() + } + + /// Handle an exception at the given PC. Returns true if handled. + #[inline] + pub(crate) fn handle_exception_at(&mut self, pc: u32) -> bool { + self.vm.handle_exception_at(pc) + } +} + +// === Promise Capability === + +impl Context { + /// Set the promise capability for the current frame. + #[track_caller] + pub(crate) fn set_promise_capability( + &mut self, + promise_capability: PromiseCapability, + ) -> JsResult<()> { + self.vm.set_promise_capability(promise_capability) + } + + /// Get the async generator object for the current frame. + #[track_caller] + pub(crate) fn async_generator_object(&self) -> Option { + self.vm.async_generator_object() + } +} + +// === Native Function === + +impl Context { + /// Set the native active function object. + pub(crate) fn set_native_active_function(&mut self, function: Option) { + self.vm.native_active_function = function; + } +} + +// === Host Call Depth === + +impl Context { + /// Increment the host call depth. + pub(crate) fn inc_host_call_depth(&mut self) { + self.vm.host_call_depth += 1; + } + + /// Decrement the host call depth (saturating). + pub(crate) fn dec_host_call_depth(&mut self) { + self.vm.host_call_depth = self.vm.host_call_depth.saturating_sub(1); + } +} + +// === Shadow Stack === + +impl Context { + /// Get a reference to the shadow stack. + pub(crate) fn shadow_stack(&self) -> &ShadowStack { + &self.vm.shadow_stack + } + + /// Get a mutable reference to the shadow stack. + pub(crate) fn shadow_stack_mut(&mut self) -> &mut ShadowStack { + &mut self.vm.shadow_stack + } +} + +// === Stack Operations === + +impl Context { + /// Push a value onto the VM stack. + pub(crate) fn stack_push>(&mut self, value: T) { + self.vm.stack.push(value); + } + + /// Pop a value from the VM stack. + #[track_caller] + pub(crate) fn stack_pop(&mut self) -> JsValue { + self.vm.stack.pop() + } + + /// Clone the VM stack. + #[cfg(feature = "experimental")] + pub(crate) fn stack_clone(&self) -> Stack { + self.vm.stack.clone() + } + + /// Replace the VM stack. + #[cfg(feature = "experimental")] + pub(crate) fn stack_replace(&mut self, stack: Stack) { + self.vm.stack = stack; + } + + /// Swap the VM stack with another stack. + pub(crate) fn stack_swap(&mut self, stack: &mut Stack) { + std::mem::swap(&mut self.vm.stack, stack); + } + + /// Truncate the stack to an arbitrary frame's frame pointer. + pub(crate) fn stack_truncate_to(&mut self, frame: &CallFrame) { + self.vm.stack.truncate_to_frame(frame); + } + + /// Split the stack at an arbitrary frame. + pub(crate) fn stack_split_off_at(&mut self, frame: &CallFrame) -> Stack { + self.vm.stack.split_off_frame(frame) + } + + /// Get the `this` value of the current frame. + pub(crate) fn stack_get_this(&self) -> JsValue { + self.vm.stack.get_this(self.vm.frame()) + } + + /// Set the `this` value of the current frame. + pub(crate) fn stack_set_this(&mut self, this: JsValue) { + let frame = self.vm.frames.last().expect("frame must exist"); + self.vm.stack.set_this(frame, this); + } + + /// Get the function object of the current frame. + pub(crate) fn stack_get_function(&self) -> Option { + self.vm.stack.get_function(self.vm.frame()) + } + + /// Get the function arguments of the current frame. + pub(crate) fn stack_get_arguments(&self) -> &[JsValue] { + self.vm.stack.get_arguments(self.vm.frame()) + } + + /// Pop rest arguments from the current frame. + pub(crate) fn stack_pop_rest_arguments(&mut self) -> Option> { + let frame = self.vm.frames.last().expect("frame must exist"); + self.vm.stack.pop_rest_arguments(frame) + } + + /// Pop function arguments according to the calling convention. + pub(crate) fn stack_calling_convention_pop_arguments( + &mut self, + argument_count: usize, + ) -> Vec { + self.vm + .stack + .calling_convention_pop_arguments(argument_count) + } + + /// Push function arguments according to the calling convention. + pub(crate) fn stack_calling_convention_push_arguments(&mut self, values: &[JsValue]) { + self.vm.stack.calling_convention_push_arguments(values); + } + + /// Get the function object at the top of the stack according to the calling convention. + #[track_caller] + pub(crate) fn stack_calling_convention_get_function(&self, argument_count: usize) -> &JsValue { + self.vm + .stack + .calling_convention_get_function(argument_count) + } +} + +// === Runtime Limits === + +impl Context { + /// Get the loop iteration limit. + pub(crate) fn loop_iteration_limit(&self) -> u64 { + self.vm.runtime_limits.loop_iteration_limit() + } +} + +// === Kept Alive === + +impl Context { + /// Add an object to the kept-alive list (prevents GC collection). + pub(crate) fn add_kept_alive(&mut self, object: JsObject) { + self.kept_alive.push(object); + } +} diff --git a/core/engine/src/module/source.rs b/core/engine/src/module/source.rs index c8827ee284b..ea7700fb3a7 100644 --- a/core/engine/src/module/source.rs +++ b/core/engine/src/module/source.rs @@ -1832,7 +1832,7 @@ impl SourceTextModule { // i. Let namespace be GetModuleNamespace(importedModule). let namespace = module.namespace(context); { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.put_lexical_value( locator.scope(), @@ -1847,7 +1847,7 @@ impl SourceTextModule { export_locator, } => match export_locator.binding_name() { BindingName::Name(name) => { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .current_declarative_ref(frame.realm.environment()) @@ -1863,7 +1863,7 @@ impl SourceTextModule { } BindingName::Namespace => { let namespace = export_locator.module.namespace(context); - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.put_lexical_value( locator.scope(), @@ -1883,7 +1883,7 @@ impl SourceTextModule { let function = create_function_object_fast(code, context); { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.put_lexical_value( locator.scope(), @@ -1968,7 +1968,7 @@ impl SourceTextModule { .push_frame_with_stack(callframe, JsValue::undefined(), JsValue::null()); if let Some(capability) = capability { - context.vm.set_promise_capability(capability)?; + context.set_promise_capability(capability)?; } // 9. If module.[[HasTLA]] is false, then @@ -1982,7 +1982,7 @@ impl SourceTextModule { // b. Perform AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext). let result = context.run(); - context.vm.pop_frame(); + context.pop_frame(); // f. If result is an abrupt completion, then if let CompletionRecord::Throw(err) = result { diff --git a/core/engine/src/module/synthetic.rs b/core/engine/src/module/synthetic.rs index 3dd783fb21a..f8e4c659d63 100644 --- a/core/engine/src/module/synthetic.rs +++ b/core/engine/src/module/synthetic.rs @@ -411,9 +411,7 @@ impl SyntheticModule { // 2. Set the Function of moduleContext to null. // 7. Suspend the currently running execution context. // 8. Push moduleContext on to the execution context stack; moduleContext is now the running execution context. - context - .vm - .push_frame_with_stack(callframe, JsValue::undefined(), JsValue::null()); + context.push_frame_with_stack(callframe, JsValue::undefined(), JsValue::null()); // 9. Let steps be module.[[EvaluationSteps]]. // 10. Let result be Completion(steps(module)). @@ -421,11 +419,8 @@ impl SyntheticModule { // 11. Suspend moduleContext and remove it from the execution context stack. // 12. Resume the context that is now on the top of the execution context stack as the running execution context. - let frame = context - .vm - .pop_frame() - .js_expect("there should be a frame")?; - context.vm.stack.truncate_to_frame(&frame); + let frame = context.pop_frame().js_expect("there should be a frame")?; + context.stack_truncate_to(&frame); // 13. Let pc be ! NewPromiseCapability(%Promise%). let (promise, ResolvingFunctions { resolve, reject }) = JsPromise::new_pending(context); diff --git a/core/engine/src/native_function/mod.rs b/core/engine/src/native_function/mod.rs index c54e75ae9c9..fb2f6b7afa2 100644 --- a/core/engine/src/native_function/mod.rs +++ b/core/engine/src/native_function/mod.rs @@ -327,12 +327,9 @@ pub(crate) fn native_function_call( argument_count: usize, context: &mut InternalMethodCallContext<'_>, ) -> JsResult { - let args = context - .vm - .stack - .calling_convention_pop_arguments(argument_count); - let _func = context.vm.stack.pop(); - let this = context.vm.stack.pop(); + let args = context.stack_calling_convention_pop_arguments(argument_count); + let _func = context.stack_pop(); + let this = context.stack_pop(); // We technically don't need this since native functions don't push any new frames to the // vm, but we'll eventually have to combine the native stack with the vm stack. @@ -349,17 +346,16 @@ pub(crate) fn native_function_call( .expect("the object should be a native function object") .clone(); - let pc = context.vm.frame().pc; + let pc = context.frame().pc; let native_source_info = context.native_source_info(); context - .vm - .shadow_stack + .shadow_stack_mut() .push_native(pc, name, native_source_info); let mut realm = realm.unwrap_or_else(|| context.realm().clone()); context.swap_realm(&mut realm); - context.vm.native_active_function = Some(this_function_object); + context.set_native_active_function(Some(this_function_object)); let result = if constructor.is_some() { function.call(&JsValue::undefined(), &args, context) @@ -368,12 +364,12 @@ pub(crate) fn native_function_call( } .map_err(|err| err.inject_realm(context.realm().clone())); - context.vm.native_active_function = None; + context.set_native_active_function(None); context.swap_realm(&mut realm); - context.vm.shadow_stack.pop(); + context.shadow_stack_mut().pop(); - context.vm.stack.push(result?); + context.stack_push(result?); Ok(CallValue::Complete) } @@ -404,25 +400,21 @@ fn native_function_construct( .expect("the object should be a native function object") .clone(); - let pc = context.vm.frame().pc; + let pc = context.frame().pc; let native_source_info = context.native_source_info(); context - .vm - .shadow_stack + .shadow_stack_mut() .push_native(pc, name, native_source_info); let mut realm = realm.unwrap_or_else(|| context.realm().clone()); context.swap_realm(&mut realm); - context.vm.native_active_function = Some(this_function_object); + context.set_native_active_function(Some(this_function_object)); - let new_target = context.vm.stack.pop(); - let args = context - .vm - .stack - .calling_convention_pop_arguments(argument_count); - let _func = context.vm.stack.pop(); - let _this = context.vm.stack.pop(); + let new_target = context.stack_pop(); + let args = context.stack_calling_convention_pop_arguments(argument_count); + let _func = context.stack_pop(); + let _this = context.stack_pop(); let result = function .call(&new_target, &args, context) @@ -450,12 +442,12 @@ fn native_function_construct( } }); - context.vm.native_active_function = None; + context.set_native_active_function(None); context.swap_realm(&mut realm); - context.vm.shadow_stack.pop(); + context.shadow_stack_mut().pop(); - context.vm.stack.push(result?); + context.stack_push(result?); Ok(CallValue::Complete) } diff --git a/core/engine/src/object/builtins/jspromise.rs b/core/engine/src/object/builtins/jspromise.rs index f291ac62c4b..320500aa307 100644 --- a/core/engine/src/object/builtins/jspromise.rs +++ b/core/engine/src/object/builtins/jspromise.rs @@ -1230,9 +1230,9 @@ impl JsPromise { use std::cell::Cell; // Clone the stack since we split it. - let stack = context.vm.stack.clone(); + let stack = context.stack_clone(); let gen_ctx = GeneratorContext::from_current(context, None); - context.vm.stack = stack; + context.stack_replace(stack); // 3. Let fulfilledClosure be a new Abstract Closure with parameters (value) that captures asyncContext and performs the following steps when called: // 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »). @@ -1250,16 +1250,16 @@ impl JsPromise { // NOTE: We need to get the object before resuming, since it could clear the stack. let async_generator = r#gen.async_generator_object()?; - std::mem::swap(&mut context.vm.stack, &mut r#gen.stack); + context.stack_swap(&mut r#gen.stack); let frame = r#gen .call_frame .take() .js_expect("should have a call frame")?; let fp = frame.fp; let rp = frame.rp; - context.vm.push_frame(frame); - context.vm.frame_mut().fp = fp; - context.vm.frame_mut().rp = rp; + context.push_frame(frame); + context.frame_mut().fp = fp; + context.frame_mut().rp = rp; if let crate::native_function::CoroutineState::Yielded(value) = continuation.call(Ok(args.get_or_undefined(0).clone()), context)? @@ -1268,8 +1268,8 @@ impl JsPromise { .await_native(continuation.clone(), context); } - std::mem::swap(&mut context.vm.stack, &mut r#gen.stack); - r#gen.call_frame = context.vm.pop_frame(); + context.stack_swap(&mut r#gen.stack); + r#gen.call_frame = context.pop_frame(); assert!(r#gen.call_frame.is_some()); if let Some(async_generator) = async_generator { @@ -1290,9 +1290,9 @@ impl JsPromise { .length(1) .build(); - let stack = context.vm.stack.clone(); + let stack = context.stack_clone(); let gen_ctx = GeneratorContext::from_current(context, None); - context.vm.stack = stack; + context.stack_replace(stack); // 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called: // 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »). @@ -1312,16 +1312,16 @@ impl JsPromise { // NOTE: We need to get the object before resuming, since it could clear the stack. let async_generator = r#gen.async_generator_object()?; - std::mem::swap(&mut context.vm.stack, &mut r#gen.stack); + context.stack_swap(&mut r#gen.stack); let frame = r#gen .call_frame .take() .js_expect("should have a call frame")?; let fp = frame.fp; let rp = frame.rp; - context.vm.push_frame(frame); - context.vm.frame_mut().fp = fp; - context.vm.frame_mut().rp = rp; + context.push_frame(frame); + context.frame_mut().fp = fp; + context.frame_mut().rp = rp; if let crate::native_function::CoroutineState::Yielded(value) = continuation .call( @@ -1333,8 +1333,8 @@ impl JsPromise { .await_native(continuation.clone(), context); } - std::mem::swap(&mut context.vm.stack, &mut r#gen.stack); - r#gen.call_frame = context.vm.pop_frame(); + context.stack_swap(&mut r#gen.stack); + r#gen.call_frame = context.pop_frame(); assert!(r#gen.call_frame.is_some()); if let Some(async_generator) = async_generator { diff --git a/core/engine/src/object/operations.rs b/core/engine/src/object/operations.rs index e1bc063ca3b..5db7579aa50 100644 --- a/core/engine/src/object/operations.rs +++ b/core/engine/src/object/operations.rs @@ -437,28 +437,28 @@ impl JsObject { // NOTE(HalidOdat): For object's that are not callable we implement a special __call__ internal method // that throws on call. - context.vm.stack.push(this.clone()); // this - context.vm.stack.push(self.clone()); // func + context.stack_push(this.clone()); // this + context.stack_push(self.clone()); // func let argument_count = args.len(); - context.vm.stack.calling_convention_push_arguments(args); + context.stack_calling_convention_push_arguments(args); // 3. Return ? F.[[Call]](V, argumentsList). - let frame_index = context.vm.frames.len(); + let frame_index = context.frames().len(); if self.__call__(argument_count).resolve(context)? { - return Ok(context.vm.stack.pop()); + return Ok(context.stack_pop()); } - if frame_index + 1 == context.vm.frames.len() { - context.vm.frame_mut().set_exit_early(true); + if frame_index + 1 == context.frames().len() { + context.frame_mut().set_exit_early(true); } else { - context.vm.frames[frame_index + 1].set_exit_early(true); + context.frames_mut()[frame_index + 1].set_exit_early(true); } - context.vm.host_call_depth += 1; + context.inc_host_call_depth(); let result = context.run().consume(); - context.vm.host_call_depth = context.vm.host_call_depth.saturating_sub(1); + context.dec_host_call_depth(); - context.vm.pop_frame().js_expect("frame must exist")?; + context.pop_frame().js_expect("frame must exist")?; result } @@ -486,35 +486,35 @@ impl JsObject { // 1. If newTarget is not present, set newTarget to F. let new_target = new_target.unwrap_or(self); - context.vm.stack.push(JsValue::undefined()); - context.vm.stack.push(self.clone()); // func + context.stack_push(JsValue::undefined()); + context.stack_push(self.clone()); // func let argument_count = args.len(); - context.vm.stack.calling_convention_push_arguments(args); - context.vm.stack.push(new_target.clone()); + context.stack_calling_convention_push_arguments(args); + context.stack_push(new_target.clone()); // 2. If argumentsList is not present, set argumentsList to a new empty List. // 3. Return ? F.[[Construct]](argumentsList, newTarget). - let frame_index = context.vm.frames.len(); + let frame_index = context.frames().len(); if self.__construct__(argument_count).resolve(context)? { - let result = context.vm.stack.pop(); + let result = context.stack_pop(); return Ok(result .as_object() .js_expect("construct value should be an object")? .clone()); } - if frame_index + 1 == context.vm.frames.len() { - context.vm.frame_mut().set_exit_early(true); + if frame_index + 1 == context.frames().len() { + context.frame_mut().set_exit_early(true); } else { - context.vm.frames[frame_index + 1].set_exit_early(true); + context.frames_mut()[frame_index + 1].set_exit_early(true); } - context.vm.host_call_depth += 1; + context.inc_host_call_depth(); let result = context.run().consume(); - context.vm.host_call_depth = context.vm.host_call_depth.saturating_sub(1); + context.dec_host_call_depth(); - context.vm.pop_frame().js_expect("frame must exist")?; + context.pop_frame().js_expect("frame must exist")?; Ok(result? .as_object() diff --git a/core/engine/src/script.rs b/core/engine/src/script.rs index ceba9c24a9a..741075bd505 100644 --- a/core/engine/src/script.rs +++ b/core/engine/src/script.rs @@ -177,7 +177,7 @@ impl Script { self.prepare_run(context)?; let record = context.run(); - context.vm.pop_frame(); + context.pop_frame(); record.consume() } @@ -210,7 +210,7 @@ impl Script { let record = context.run_async_with_budget(budget).await; - context.vm.pop_frame(); + context.pop_frame(); record.consume() } @@ -219,7 +219,7 @@ impl Script { let codeblock = self.codeblock(context)?; let global_env = EnvironmentStack::new(); - context.vm.push_frame_with_stack( + context.push_frame_with_stack( CallFrame::new( codeblock.clone(), Some(ActiveRunnable::Script(self.clone())), @@ -237,7 +237,7 @@ impl Script { context .global_declaration_instantiation(&codeblock) .inspect_err(|_| { - context.vm.pop_frame(); + context.pop_frame(); })?; Ok(()) diff --git a/core/engine/src/vm/code_block.rs b/core/engine/src/vm/code_block.rs index d9eec2fc949..e939f115db4 100644 --- a/core/engine/src/vm/code_block.rs +++ b/core/engine/src/vm/code_block.rs @@ -1106,7 +1106,7 @@ pub(crate) fn create_function_object( let is_generator = code.is_generator(); let function = OrdinaryFunction::new( code, - context.vm.frame().environments.snapshot_for_closure(), + context.frame().environments.snapshot_for_closure(), script_or_module, context.realm().clone(), ); @@ -1175,7 +1175,7 @@ pub(crate) fn create_function_object_fast(code: Gc, context: &mut Con let has_prototype_property = code.has_prototype_property(); let function = OrdinaryFunction::new( code, - context.vm.frame().environments.snapshot_for_closure(), + context.frame().environments.snapshot_for_closure(), script_or_module, context.realm().clone(), ); diff --git a/core/engine/src/vm/mod.rs b/core/engine/src/vm/mod.rs index f01c9bb47dd..af061693997 100644 --- a/core/engine/src/vm/mod.rs +++ b/core/engine/src/vm/mod.rs @@ -879,7 +879,7 @@ impl Context { match self.execute_one( |context, opcode| { - let frame = context.vm.frame(); + let frame = context.frame(); let pc = frame.pc as usize; OPCODE_HANDLERS_BUDGET[opcode as usize](context, pc, &mut runtime_budget) @@ -912,7 +912,7 @@ impl Context { match self.execute_one( |context, opcode| { - let frame = context.vm.frame(); + let frame = context.frame(); let pc = frame.pc as usize; OPCODE_HANDLERS[opcode as usize](context, pc) diff --git a/core/engine/src/vm/opcode/arguments.rs b/core/engine/src/vm/opcode/arguments.rs index 47081552dc4..394f7309eb5 100644 --- a/core/engine/src/vm/opcode/arguments.rs +++ b/core/engine/src/vm/opcode/arguments.rs @@ -14,16 +14,14 @@ pub(crate) struct CreateMappedArgumentsObject; impl CreateMappedArgumentsObject { #[inline(always)] pub(super) fn operation(value: RegisterOperand, context: &mut Context) { - let frame = context.vm.frame(); + let frame = context.frame(); let function_object = context - .vm - .stack - .get_function(context.vm.frame()) + .stack_get_function() .expect("there should be a function object"); let code = frame.code_block().clone(); - let args = context.vm.stack.get_arguments(context.vm.frame()); + let args = context.stack_get_arguments(); let env = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .current_declarative_ref(frame.realm.environment()) @@ -37,7 +35,7 @@ impl CreateMappedArgumentsObject { &env, context, ); - context.vm.set_register(value.into(), arguments.into()); + context.set_register(value.into(), arguments.into()); } } @@ -57,9 +55,9 @@ pub(crate) struct CreateUnmappedArgumentsObject; impl CreateUnmappedArgumentsObject { #[inline(always)] pub(super) fn operation(dst: RegisterOperand, context: &mut Context) { - let args = context.vm.stack.get_arguments(context.vm.frame()).to_vec(); + let args = context.stack_get_arguments().to_vec(); let arguments = UnmappedArguments::new(&args, context); - context.vm.set_register(dst.into(), arguments.into()); + context.set_register(dst.into(), arguments.into()); } } diff --git a/core/engine/src/vm/opcode/await/mod.rs b/core/engine/src/vm/opcode/await/mod.rs index 2dce3496414..efc3dfedc45 100644 --- a/core/engine/src/vm/opcode/await/mod.rs +++ b/core/engine/src/vm/opcode/await/mod.rs @@ -26,7 +26,7 @@ impl Await { value: RegisterOperand, context: &mut Context, ) -> ControlFlow { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); // 2. Let promise be ? PromiseResolve(%Promise%, value). let promise = match Promise::promise_resolve( @@ -138,7 +138,7 @@ impl Await { context, ); - context.vm.set_return_value(return_value); + context.set_return_value(return_value); context.handle_yield() } } @@ -165,7 +165,7 @@ impl CreatePromiseCapability { ) .js_expect("cannot fail per spec")?; - context.vm.set_promise_capability(promise_capability) + context.set_promise_capability(promise_capability) } } diff --git a/core/engine/src/vm/opcode/binary_ops/logical.rs b/core/engine/src/vm/opcode/binary_ops/logical.rs index 140f1303af7..61dea25ffd2 100644 --- a/core/engine/src/vm/opcode/binary_ops/logical.rs +++ b/core/engine/src/vm/opcode/binary_ops/logical.rs @@ -13,9 +13,9 @@ pub(crate) struct LogicalAnd; impl LogicalAnd { #[inline(always)] pub(crate) fn operation((exit, lhs): (Address, RegisterOperand), context: &mut Context) { - let lhs = context.vm.get_register(lhs.into()); + let lhs = context.get_register(lhs.into()); if !lhs.to_boolean() { - context.vm.frame_mut().pc = u32::from(exit); + context.frame_mut().pc = u32::from(exit); } } } @@ -36,9 +36,9 @@ pub(crate) struct LogicalOr; impl LogicalOr { #[inline(always)] pub(crate) fn operation((exit, lhs): (Address, RegisterOperand), context: &mut Context) { - let lhs = context.vm.get_register(lhs.into()); + let lhs = context.get_register(lhs.into()); if lhs.to_boolean() { - context.vm.frame_mut().pc = u32::from(exit); + context.frame_mut().pc = u32::from(exit); } } } @@ -59,9 +59,9 @@ pub(crate) struct Coalesce; impl Coalesce { #[inline(always)] pub(crate) fn operation((exit, lhs): (Address, RegisterOperand), context: &mut Context) { - let lhs = context.vm.get_register(lhs.into()); + let lhs = context.get_register(lhs.into()); if !lhs.is_null_or_undefined() { - context.vm.frame_mut().pc = u32::from(exit); + context.frame_mut().pc = u32::from(exit); } } } diff --git a/core/engine/src/vm/opcode/binary_ops/macro_defined.rs b/core/engine/src/vm/opcode/binary_ops/macro_defined.rs index 2b9d49580a5..8fb8d1ca75f 100644 --- a/core/engine/src/vm/opcode/binary_ops/macro_defined.rs +++ b/core/engine/src/vm/opcode/binary_ops/macro_defined.rs @@ -18,13 +18,13 @@ macro_rules! implement_bin_ops { (dst, lhs, rhs): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); $( // Fast path: try numeric operation without cloning. if let Some(value) = JsValue::$fast_fn(lhs, rhs) { - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); return Ok(()); } )? @@ -33,7 +33,7 @@ macro_rules! implement_bin_ops { let lhs = lhs.clone(); let rhs = rhs.clone(); let value = lhs.$op(&rhs, context)?; - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/binary_ops/mod.rs b/core/engine/src/vm/opcode/binary_ops/mod.rs index f9cad347c05..3453a458cc4 100644 --- a/core/engine/src/vm/opcode/binary_ops/mod.rs +++ b/core/engine/src/vm/opcode/binary_ops/mod.rs @@ -20,10 +20,10 @@ impl StrictEq { (dst, lhs, rhs): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); let value = lhs.strict_equals(rhs); - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); } } @@ -46,10 +46,10 @@ impl StrictNotEq { (dst, lhs, rhs): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); let value = !lhs.strict_equals(rhs); - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); } } @@ -72,7 +72,7 @@ impl In { (dst, lhs, rhs): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let rhs = context.vm.get_register(rhs.into()).clone(); + let rhs = context.get_register(rhs.into()).clone(); let Some(rhs) = rhs.as_object() else { return Err(JsNativeError::typ() .with_message(format!( @@ -81,10 +81,10 @@ impl In { )) .into()); }; - let lhs = context.vm.get_register(lhs.into()).clone(); + let lhs = context.get_register(lhs.into()).clone(); let key = lhs.to_property_key(context)?; let value = rhs.has_property(key, context)?; - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); Ok(()) } } @@ -113,7 +113,7 @@ impl InPrivate { .frame() .code_block() .constant_string(index.into()); - let rhs = context.vm.get_register(rhs.into()); + let rhs = context.get_register(rhs.into()); let Some(rhs) = rhs.as_object() else { return Err(JsNativeError::typ() @@ -133,7 +133,7 @@ impl InPrivate { let value = rhs.private_element_find(&name, true, true).is_some(); - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/call/mod.rs b/core/engine/src/vm/opcode/call/mod.rs index 891ac4efe75..5b1bf9fda06 100644 --- a/core/engine/src/vm/opcode/call/mod.rs +++ b/core/engine/src/vm/opcode/call/mod.rs @@ -51,8 +51,8 @@ impl CallEval { .vm .stack .calling_convention_pop_arguments(argument_count.into()); - let _func = context.vm.stack.pop(); - let _this = context.vm.stack.pop(); + let _func = context.stack_pop(); + let _this = context.stack_pop(); if let Some(x) = arguments.first() { // i. Let argList be ? ArgumentListEvaluation of arguments. // ii. If argList has no elements, return undefined. @@ -60,7 +60,7 @@ impl CallEval { // iv. If the source text matched by this CallExpression is strict mode code, // let strictCaller be true. Otherwise let strictCaller be false. // v. Return ? PerformEval(evalArg, strictCaller, true). - let strict = context.vm.frame().code_block.strict(); + let strict = context.frame().code_block.strict(); let scope = context .vm .frame() @@ -73,10 +73,10 @@ impl CallEval { strict, context, )?; - context.vm.stack.push(result); + context.stack_push(result); } else { // NOTE: This is a deviation from the spec, to optimize the case when we dont pass anything to `eval`. - context.vm.stack.push(JsValue::undefined()); + context.stack_push(JsValue::undefined()); } return Ok(()); @@ -104,7 +104,7 @@ impl CallEvalSpread { #[inline(always)] pub(super) fn operation(index: IndexOperand, context: &mut Context) -> JsResult<()> { // Get the arguments that are stored as an array object on the stack. - let arguments_array = context.vm.stack.pop(); + let arguments_array = context.stack_pop(); let arguments_array_object = arguments_array .as_object() .expect("arguments array in call spread function must be an object"); @@ -114,7 +114,7 @@ impl CallEvalSpread { .to_dense_indexed_properties() .expect("arguments array in call spread function must be dense"); - let func = context.vm.stack.calling_convention_get_function(0); + let func = context.stack_calling_convention_get_function(0); let Some(object) = func.as_object() else { return Err(JsNativeError::typ() @@ -130,8 +130,8 @@ impl CallEvalSpread { // a. If SameValue(func, %eval%) is true, then let eval = context.intrinsics().objects().eval(); if JsObject::equals(&object, &eval) { - let _func = context.vm.stack.pop(); - let _this = context.vm.stack.pop(); + let _func = context.stack_pop(); + let _this = context.stack_pop(); if let Some(x) = arguments.first() { // i. Let argList be ? ArgumentListEvaluation of arguments. // ii. If argList has no elements, return undefined. @@ -139,8 +139,8 @@ impl CallEvalSpread { // iv. If the source text matched by this CallExpression is strict mode code, // let strictCaller be true. Otherwise let strictCaller be false. // v. Return ? PerformEval(evalArg, strictCaller, true). - let strict = context.vm.frame().code_block.strict(); - let scope = context.vm.frame().code_block().constant_scope(index.into()); + let strict = context.frame().code_block.strict(); + let scope = context.frame().code_block().constant_scope(index.into()); let result = crate::builtins::eval::Eval::perform_eval( x, true, @@ -148,10 +148,10 @@ impl CallEvalSpread { strict, context, )?; - context.vm.stack.push(result); + context.stack_push(result); } else { // NOTE: This is a deviation from the spec, to optimize the case when we dont pass anything to `eval`. - context.vm.stack.push(JsValue::undefined()); + context.stack_push(JsValue::undefined()); } return Ok(()); @@ -220,7 +220,7 @@ impl CallSpread { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) -> JsResult<()> { // Get the arguments that are stored as an array object on the stack. - let arguments_array = context.vm.stack.pop(); + let arguments_array = context.stack_pop(); let arguments_array_object = arguments_array .as_object() .expect("arguments array in call spread function must be an object"); @@ -565,10 +565,10 @@ impl ImportCall { // 3. Let argRef be ? Evaluation of AssignmentExpression. // 4. Let specifier be ? GetValue(argRef). - let specifier = context.vm.get_register(specifier_op.into()).clone(); + let specifier = context.get_register(specifier_op.into()).clone(); // Get options if provided - let options = context.vm.get_register(options_op.into()).clone(); + let options = context.get_register(options_op.into()).clone(); // 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). let cap = PromiseCapability::new( @@ -585,7 +585,7 @@ impl ImportCall { Err(err) => { let err = err.into_opaque(context)?; cap.reject().call(&JsValue::undefined(), &[err], context)?; - context.vm.set_register(specifier_op.into(), promise.into()); + context.set_register(specifier_op.into(), promise.into()); return Ok(()); } }; @@ -595,7 +595,7 @@ impl ImportCall { Err(err) => { let err = err.into_opaque(context)?; cap.reject().call(&JsValue::undefined(), &[err], context)?; - context.vm.set_register(specifier_op.into(), promise.into()); + context.set_register(specifier_op.into(), promise.into()); return Ok(()); } }; @@ -611,7 +611,7 @@ impl ImportCall { context.enqueue_job(job.into()); // 9. Return promiseCapability.[[Promise]]. - context.vm.set_register(specifier_op.into(), promise.into()); + context.set_register(specifier_op.into(), promise.into()); Ok(()) } diff --git a/core/engine/src/vm/opcode/concat/mod.rs b/core/engine/src/vm/opcode/concat/mod.rs index eee34e20fa4..45f76d6f939 100644 --- a/core/engine/src/vm/opcode/concat/mod.rs +++ b/core/engine/src/vm/opcode/concat/mod.rs @@ -18,11 +18,11 @@ impl ConcatToString { ) -> JsResult<()> { let mut strings = Vec::with_capacity(values.len()); for value in values { - let val = context.vm.get_register(value.into()).clone(); + let val = context.get_register(value.into()).clone(); strings.push(val.to_string(context)?); } let s = JsString::concat_array(&strings.iter().map(JsString::as_str).collect::>()); - context.vm.set_register(string.into(), s.into()); + context.set_register(string.into(), s.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/control_flow/jump.rs b/core/engine/src/vm/opcode/control_flow/jump.rs index b1d21b59f41..9fde0acc892 100644 --- a/core/engine/src/vm/opcode/control_flow/jump.rs +++ b/core/engine/src/vm/opcode/control_flow/jump.rs @@ -14,7 +14,7 @@ pub(crate) struct Jump; impl Jump { #[inline(always)] pub(crate) fn operation(address: Address, context: &mut Context) { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } @@ -34,9 +34,9 @@ pub(crate) struct JumpIfTrue; impl JumpIfTrue { #[inline(always)] pub(crate) fn operation((address, value): (Address, RegisterOperand), context: &mut Context) { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); if value.to_boolean() { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } } @@ -57,9 +57,9 @@ pub(crate) struct JumpIfFalse; impl JumpIfFalse { #[inline(always)] pub(crate) fn operation((address, value): (Address, RegisterOperand), context: &mut Context) { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); if !value.to_boolean() { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } } @@ -80,9 +80,9 @@ pub(crate) struct JumpIfNotUndefined; impl JumpIfNotUndefined { #[inline(always)] pub(crate) fn operation((address, value): (Address, RegisterOperand), context: &mut Context) { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); if !value.is_undefined() { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } } @@ -103,9 +103,9 @@ pub(crate) struct JumpIfNullOrUndefined; impl JumpIfNullOrUndefined { #[inline(always)] pub(crate) fn operation((address, value): (Address, RegisterOperand), context: &mut Context) { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); if value.is_null_or_undefined() { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } } @@ -129,18 +129,18 @@ impl JumpIfNotLessThan { (address, lhs, rhs): (Address, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); if let Some(result) = lhs.lt_fast(rhs) { if !result { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } return Ok(()); } let lhs = lhs.clone(); let rhs = rhs.clone(); if !lhs.lt(&rhs, context)? { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } Ok(()) } @@ -165,18 +165,18 @@ impl JumpIfNotLessThanOrEqual { (address, lhs, rhs): (Address, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); if let Some(result) = lhs.le_fast(rhs) { if !result { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } return Ok(()); } let lhs = lhs.clone(); let rhs = rhs.clone(); if !lhs.le(&rhs, context)? { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } Ok(()) } @@ -201,18 +201,18 @@ impl JumpIfNotGreaterThan { (address, lhs, rhs): (Address, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); if let Some(result) = lhs.gt_fast(rhs) { if !result { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } return Ok(()); } let lhs = lhs.clone(); let rhs = rhs.clone(); if !lhs.gt(&rhs, context)? { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } Ok(()) } @@ -237,18 +237,18 @@ impl JumpIfNotGreaterThanOrEqual { (address, lhs, rhs): (Address, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); if let Some(result) = lhs.ge_fast(rhs) { if !result { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } return Ok(()); } let lhs = lhs.clone(); let rhs = rhs.clone(); if !lhs.ge(&rhs, context)? { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } Ok(()) } @@ -273,10 +273,10 @@ impl JumpIfNotEqual { (address, lhs, rhs): (Address, RegisterOperand, RegisterOperand), context: &mut Context, ) { - let lhs = context.vm.get_register(lhs.into()); - let rhs = context.vm.get_register(rhs.into()); + let lhs = context.get_register(lhs.into()); + let rhs = context.get_register(rhs.into()); if lhs != rhs { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } } @@ -297,7 +297,7 @@ pub(crate) struct JumpTable; impl JumpTable { #[inline(always)] pub(crate) fn operation((index, addresses): (u32, ThinVec
), context: &mut Context) { - let value = context.vm.get_register(index as usize); + let value = context.get_register(index as usize); let Some(offset) = value.as_i32().map(|i| i as usize) else { return; }; @@ -306,7 +306,7 @@ impl JumpTable { return; }; - context.vm.frame_mut().pc = u32::from(pc); + context.frame_mut().pc = u32::from(pc); } } diff --git a/core/engine/src/vm/opcode/control_flow/return.rs b/core/engine/src/vm/opcode/control_flow/return.rs index 182479da999..7667eb2dcd0 100644 --- a/core/engine/src/vm/opcode/control_flow/return.rs +++ b/core/engine/src/vm/opcode/control_flow/return.rs @@ -38,19 +38,19 @@ pub(crate) struct CheckReturn; impl CheckReturn { #[inline(always)] pub(crate) fn operation((): (), context: &mut Context) -> ControlFlow { - let frame = context.vm.frame(); + let frame = context.frame(); if !frame.construct() { return ControlFlow::Continue(()); } - let this = &context.vm.stack.get_this(frame); - let result = context.vm.take_return_value(); + let this = &context.stack_get_this(); + let result = context.take_return_value(); let result = if result.is_object() { result } else if !this.is_undefined() { this.clone() } else if !result.is_undefined() { - context.vm.pending_exception = Some( + context.set_pending_exception( // Avoid setting the realm here, since it needs to be set by the parent // execution context. JsNativeError::typ() @@ -59,15 +59,15 @@ impl CheckReturn { ); return context.handle_throw(); } else { - let frame = context.vm.frame(); + let frame = context.frame(); if frame.has_this_value_cached() { this.clone() } else { - match context.vm.frame().environments.get_this_binding() { + match context.frame().environments.get_this_binding() { Err(err) => { // Avoid setting the realm here, since it needs to be set by the parent // execution context. - context.vm.pending_exception = Some(err); + context.set_pending_exception(err); return context.handle_throw(); } Ok(Some(this)) => this, @@ -76,7 +76,7 @@ impl CheckReturn { } }; - context.vm.set_return_value(result); + context.set_return_value(result); ControlFlow::Continue(()) } } @@ -97,8 +97,8 @@ pub(crate) struct SetAccumulator; impl SetAccumulator { #[inline(always)] pub(crate) fn operation(register: RegisterOperand, context: &mut Context) { - let value = context.vm.get_register(register.into()); - context.vm.set_return_value(value.clone()); + let value = context.get_register(register.into()); + context.set_return_value(value.clone()); } } @@ -118,8 +118,8 @@ pub(crate) struct Move; impl Move { #[inline(always)] pub(crate) fn operation((dst, src): (RegisterOperand, RegisterOperand), context: &mut Context) { - let value = context.vm.get_register(src.into()); - context.vm.set_register(dst.into(), value.clone()); + let value = context.get_register(src.into()); + context.set_register(dst.into(), value.clone()); } } @@ -139,8 +139,8 @@ pub(crate) struct PopIntoRegister; impl PopIntoRegister { #[inline(always)] pub(crate) fn operation(dst: RegisterOperand, context: &mut Context) { - let value = context.vm.stack.pop(); - context.vm.set_register(dst.into(), value); + let value = context.stack_pop(); + context.set_register(dst.into(), value); } } @@ -160,8 +160,8 @@ pub(crate) struct PushFromRegister; impl PushFromRegister { #[inline(always)] pub(crate) fn operation(dst: RegisterOperand, context: &mut Context) { - let value = context.vm.get_register(dst.into()); - context.vm.stack.push(value.clone()); + let value = context.get_register(dst.into()); + context.stack_push(value.clone()); } } @@ -181,9 +181,7 @@ pub(crate) struct SetRegisterFromAccumulator; impl SetRegisterFromAccumulator { #[inline(always)] pub(crate) fn operation(register: RegisterOperand, context: &mut Context) { - context - .vm - .set_register(register.into(), context.vm.get_return_value()); + context.set_register(register.into(), context.get_return_value()); } } diff --git a/core/engine/src/vm/opcode/control_flow/throw.rs b/core/engine/src/vm/opcode/control_flow/throw.rs index caa93f26dc1..7fa702ae34d 100644 --- a/core/engine/src/vm/opcode/control_flow/throw.rs +++ b/core/engine/src/vm/opcode/control_flow/throw.rs @@ -21,13 +21,13 @@ impl Throw { value: RegisterOperand, context: &mut Context, ) -> ControlFlow { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); let error = JsError::from_opaque(value.clone()); - context.vm.pending_exception = Some(error); + context.set_pending_exception(error); // Note: -1 because we increment after fetching the opcode. - let pc = context.vm.frame().pc - 1; - if context.vm.handle_exception_at(pc) { + let pc = context.frame().pc - 1; + if context.handle_exception_at(pc) { return ControlFlow::Continue(()); } @@ -52,8 +52,8 @@ impl ReThrow { #[inline(always)] pub(crate) fn operation((): (), context: &mut Context) -> ControlFlow { // Note: -1 because we increment after fetching the opcode. - let pc = context.vm.frame().pc.saturating_sub(1); - if context.vm.handle_exception_at(pc) { + let pc = context.frame().pc.saturating_sub(1); + if context.handle_exception_at(pc) { return ControlFlow::Continue(()); } @@ -62,7 +62,7 @@ impl ReThrow { // // Note: If we reached this stage then we there is no handler to handle this, // so return (only for generators). - if context.vm.pending_exception.is_none() { + if !context.has_pending_exception() { return context.handle_return(); } @@ -89,12 +89,12 @@ impl Exception { dst: RegisterOperand, context: &mut Context, ) -> ControlFlow { - if let Some(error) = context.vm.pending_exception.take() { + if let Some(error) = context.take_pending_exception() { let error = match error.into_opaque(context) { Ok(e) => e, Err(e) => return context.handle_error(e), }; - context.vm.set_register(dst.into(), error); + context.set_register(dst.into(), error); return ControlFlow::Continue(()); } @@ -126,12 +126,12 @@ impl MaybeException { (has_exception, exception): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - if let Some(error) = context.vm.pending_exception.take() { + if let Some(error) = context.take_pending_exception() { let error = error.into_opaque(context)?; - context.vm.set_register(exception.into(), error); - context.vm.set_register(has_exception.into(), true.into()); + context.set_register(exception.into(), error); + context.set_register(has_exception.into(), true.into()); } else { - context.vm.set_register(has_exception.into(), false.into()); + context.set_register(has_exception.into(), false.into()); } Ok(()) } @@ -153,11 +153,7 @@ pub(crate) struct ThrowNewTypeError; impl ThrowNewTypeError { #[inline(always)] pub(crate) fn operation(index: IndexOperand, context: &mut Context) -> JsError { - let msg = context - .vm - .frame() - .code_block() - .constant_string(index.into()); + let msg = context.frame().code_block().constant_string(index.into()); let msg = msg .to_std_string() .expect("throw message must be an ASCII string"); @@ -181,11 +177,7 @@ pub(crate) struct ThrowNewReferenceError; impl ThrowNewReferenceError { #[inline(always)] pub(crate) fn operation(index: IndexOperand, context: &mut Context) -> JsError { - let msg = context - .vm - .frame() - .code_block() - .constant_string(index.into()); + let msg = context.frame().code_block().constant_string(index.into()); let msg = msg .to_std_string() .expect("throw message must be an ASCII string"); diff --git a/core/engine/src/vm/opcode/copy/mod.rs b/core/engine/src/vm/opcode/copy/mod.rs index 6e76a49c204..cf5c75d70ff 100644 --- a/core/engine/src/vm/opcode/copy/mod.rs +++ b/core/engine/src/vm/opcode/copy/mod.rs @@ -15,11 +15,11 @@ impl CopyDataProperties { (object, source, keys): (RegisterOperand, RegisterOperand, ThinVec), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); - let source = context.vm.get_register(source.into()).clone(); + let object = context.get_register(object.into()).clone(); + let source = context.get_register(source.into()).clone(); let mut excluded_keys = Vec::with_capacity(keys.len()); for key in keys { - let key = context.vm.get_register(key.into()).clone(); + let key = context.get_register(key.into()).clone(); excluded_keys.push( key.to_property_key(context) .expect("key must be property key"), diff --git a/core/engine/src/vm/opcode/define/class/getter.rs b/core/engine/src/vm/opcode/define/class/getter.rs index 11432391c08..8a2b35201b7 100644 --- a/core/engine/src/vm/opcode/define/class/getter.rs +++ b/core/engine/src/vm/opcode/define/class/getter.rs @@ -21,8 +21,8 @@ impl DefineClassStaticGetterByName { (function, class, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let class = context.vm.get_register(class.into()).clone(); + let function = context.get_register(function.into()).clone(); + let class = context.get_register(class.into()).clone(); let class = class.as_object().expect("class must be object"); let key = context .vm @@ -78,8 +78,8 @@ impl DefineClassGetterByName { (function, class_proto, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let class_proto = context.vm.get_register(class_proto.into()).clone(); + let function = context.get_register(function.into()).clone(); + let class_proto = context.get_register(class_proto.into()).clone(); let class_proto = class_proto.as_object().expect("class must be object"); let key = context .vm @@ -135,9 +135,9 @@ impl DefineClassStaticGetterByValue { (function, key, class): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let class = context.vm.get_register(class.into()).clone(); + let function = context.get_register(function.into()).clone(); + let key = context.get_register(key.into()).clone(); + let class = context.get_register(class.into()).clone(); let class = class.as_object().expect("class must be object"); let key = key .to_property_key(context) @@ -191,9 +191,9 @@ impl DefineClassGetterByValue { (function, key, class_proto): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let class_proto = context.vm.get_register(class_proto.into()).clone(); + let function = context.get_register(function.into()).clone(); + let key = context.get_register(key.into()).clone(); + let class_proto = context.get_register(class_proto.into()).clone(); let class_proto = class_proto.as_object().expect("class must be object"); let key = key .to_property_key(context) diff --git a/core/engine/src/vm/opcode/define/class/method.rs b/core/engine/src/vm/opcode/define/class/method.rs index 066ae94b27c..011775d5ba8 100644 --- a/core/engine/src/vm/opcode/define/class/method.rs +++ b/core/engine/src/vm/opcode/define/class/method.rs @@ -19,8 +19,8 @@ impl DefineClassStaticMethodByName { (function, class, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let class = context.vm.get_register(class.into()).clone(); + let function = context.get_register(function.into()).clone(); + let class = context.get_register(class.into()).clone(); let class = class.as_object().expect("class must be object"); let key = context .vm @@ -67,8 +67,8 @@ impl DefineClassMethodByName { (function, class_proto, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let class_proto = context.vm.get_register(class_proto.into()).clone(); + let function = context.get_register(function.into()).clone(); + let class_proto = context.get_register(class_proto.into()).clone(); let class_proto = class_proto.as_object().expect("class must be object"); let key = context .vm @@ -115,9 +115,9 @@ impl DefineClassStaticMethodByValue { (function, key, class): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let class = context.vm.get_register(class.into()).clone(); + let function = context.get_register(function.into()).clone(); + let key = context.get_register(key.into()).clone(); + let class = context.get_register(class.into()).clone(); let class = class.as_object().expect("class must be object"); let key = key .to_property_key(context) @@ -166,9 +166,9 @@ impl DefineClassMethodByValue { (function, key, class_proto): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let class_proto = context.vm.get_register(class_proto.into()).clone(); + let function = context.get_register(function.into()).clone(); + let key = context.get_register(key.into()).clone(); + let class_proto = context.get_register(class_proto.into()).clone(); let class_proto = class_proto.as_object().expect("class must be object"); let key = key .to_property_key(context) diff --git a/core/engine/src/vm/opcode/define/class/setter.rs b/core/engine/src/vm/opcode/define/class/setter.rs index 431b5937fa5..54cc3bd9a15 100644 --- a/core/engine/src/vm/opcode/define/class/setter.rs +++ b/core/engine/src/vm/opcode/define/class/setter.rs @@ -21,8 +21,8 @@ impl DefineClassStaticSetterByName { (function, class, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let class = context.vm.get_register(class.into()).clone(); + let function = context.get_register(function.into()).clone(); + let class = context.get_register(class.into()).clone(); let class = class.as_object().expect("class must be object"); let key = context .vm @@ -79,8 +79,8 @@ impl DefineClassSetterByName { (function, class_proto, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let class_proto = context.vm.get_register(class_proto.into()).clone(); + let function = context.get_register(function.into()).clone(); + let class_proto = context.get_register(class_proto.into()).clone(); let class_proto = class_proto.as_object().expect("class must be object"); let key = context .vm @@ -138,9 +138,9 @@ impl DefineClassStaticSetterByValue { (function, key, class): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let class = context.vm.get_register(class.into()).clone(); + let function = context.get_register(function.into()).clone(); + let key = context.get_register(key.into()).clone(); + let class = context.get_register(class.into()).clone(); let class = class.as_object().expect("class must be object"); let key = key .to_property_key(context) @@ -195,9 +195,9 @@ impl DefineClassSetterByValue { (function, key, class_proto): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let class_proto = context.vm.get_register(class_proto.into()).clone(); + let function = context.get_register(function.into()).clone(); + let key = context.get_register(key.into()).clone(); + let class_proto = context.get_register(class_proto.into()).clone(); let class_proto = class_proto.as_object().expect("class must be object"); let key = key .to_property_key(context) diff --git a/core/engine/src/vm/opcode/define/mod.rs b/core/engine/src/vm/opcode/define/mod.rs index 984e4a774b2..d04ccb00197 100644 --- a/core/engine/src/vm/opcode/define/mod.rs +++ b/core/engine/src/vm/opcode/define/mod.rs @@ -18,10 +18,10 @@ impl DefVar { #[inline(always)] pub(super) fn operation(index: IndexOperand, context: &mut Context) { // TODO: spec specifies to return `empty` on empty vars, but we're trying to initialize. - let binding_locator = context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.put_value_if_uninitialized( binding_locator.scope(), @@ -52,8 +52,8 @@ impl DefInitVar { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); - let frame = context.vm.frame(); + let value = context.get_register(value.into()).clone(); + let frame = context.frame(); let strict = frame.code_block.strict(); let mut binding_locator = frame.code_block.bindings[usize::from(index)].clone(); context.find_runtime_binding(&mut binding_locator)?; @@ -82,10 +82,10 @@ impl PutLexicalValue { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) { - let value = context.vm.get_register(value.into()).clone(); - let binding_locator = context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let value = context.get_register(value.into()).clone(); + let binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame.environments.put_lexical_value( binding_locator.scope(), diff --git a/core/engine/src/vm/opcode/define/own_property.rs b/core/engine/src/vm/opcode/define/own_property.rs index e3c8c5a9a38..cdea1d65316 100644 --- a/core/engine/src/vm/opcode/define/own_property.rs +++ b/core/engine/src/vm/opcode/define/own_property.rs @@ -18,8 +18,8 @@ impl DefineOwnPropertyByName { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); - let value = context.vm.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); let name = context .vm .frame() @@ -59,9 +59,9 @@ impl DefineOwnPropertyByValue { (value, key, object): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let object = context.vm.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); + let key = context.get_register(key.into()).clone(); + let object = context.get_register(object.into()).clone(); let object = object.to_object(context)?; let key = key.to_property_key(context)?; let success = object.__define_own_property__( diff --git a/core/engine/src/vm/opcode/delete/mod.rs b/core/engine/src/vm/opcode/delete/mod.rs index f301e8e608a..c0de218d064 100644 --- a/core/engine/src/vm/opcode/delete/mod.rs +++ b/core/engine/src/vm/opcode/delete/mod.rs @@ -18,9 +18,9 @@ impl DeletePropertyByName { (object_register, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.take_register(object_register.into()); + let object = context.take_register(object_register.into()); let object = object.to_object(context)?; - let code_block = context.vm.frame().code_block(); + let code_block = context.frame().code_block(); let key = code_block.constant_string(index.into()).into(); let strict = code_block.strict(); @@ -56,8 +56,8 @@ impl DeletePropertyByValue { (object_register, key): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object_register.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); + let object = context.get_register(object_register.into()).clone(); + let key = context.get_register(key.into()).clone(); let object = object.to_object(context)?; let property_key = key.to_property_key(context)?; @@ -65,7 +65,7 @@ impl DeletePropertyByValue { &property_key, &mut InternalMethodPropertyContext::new(context), )?; - if !result && context.vm.frame().code_block().strict() { + if !result && context.frame().code_block().strict() { return Err(JsNativeError::typ() .with_message("Cannot delete property") .into()); @@ -96,11 +96,10 @@ impl DeleteName { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let mut binding_locator = - context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let mut binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); context.find_runtime_binding(&mut binding_locator)?; let deleted = context.delete_binding(&binding_locator)?; - context.vm.set_register(value.into(), deleted.into()); + context.set_register(value.into(), deleted.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/environment/mod.rs b/core/engine/src/vm/opcode/environment/mod.rs index 0152358462c..a12ddb6c766 100644 --- a/core/engine/src/vm/opcode/environment/mod.rs +++ b/core/engine/src/vm/opcode/environment/mod.rs @@ -23,7 +23,7 @@ impl GetFunctionObject { context: &mut Context, ) -> JsResult<()> { let env = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -33,9 +33,7 @@ impl GetFunctionObject { let function_object_v = env.slots().function_object().clone().into(); - context - .vm - .set_register(function_object.into(), function_object_v); + context.set_register(function_object.into(), function_object_v); Ok(()) } @@ -57,24 +55,20 @@ pub(crate) struct This; impl This { #[inline(always)] pub(super) fn operation(dst: RegisterOperand, context: &mut Context) -> JsResult<()> { - if context.vm.frame().has_this_value_cached() { - let this = context.vm.stack.get_this(context.vm.frame()); - context.vm.set_register(dst.into(), this); + if context.frame().has_this_value_cached() { + let this = context.stack_get_this(); + context.set_register(dst.into(), this); return Ok(()); } let this = context - .vm .frame() .environments .get_this_binding()? .unwrap_or(context.realm().global_this().clone().into()); - context.vm.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; - context.vm.stack.set_this( - context.vm.frames.last().expect("frame must exist"), - this.clone(), - ); - context.vm.set_register(dst.into(), this); + context.frame_mut().flags |= CallFrameFlags::THIS_VALUE_CACHED; + context.stack_set_this(this.clone()); + context.set_register(dst.into(), this); Ok(()) } } @@ -98,11 +92,11 @@ impl ThisForObjectEnvironmentName { (dst, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let binding_locator = context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); let this = context .this_from_object_environment_binding(&binding_locator)? .map_or(JsValue::undefined(), Into::into); - context.vm.set_register(dst.into(), this); + context.set_register(dst.into(), this); Ok(()) } } @@ -124,9 +118,7 @@ impl SuperCall { #[inline(always)] pub(super) fn operation(argument_count: IndexOperand, context: &mut Context) -> JsResult<()> { let super_constructor = context - .vm - .stack - .calling_convention_get_function(argument_count.into()) + .stack_calling_convention_get_function(argument_count.into()) .clone(); let Some(super_constructor) = super_constructor.as_constructor() else { @@ -136,7 +128,7 @@ impl SuperCall { }; let this_env = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -150,7 +142,7 @@ impl SuperCall { .expect("must have new.target") .clone(); - context.vm.stack.push(new_target); + context.stack_push(new_target); super_constructor .__construct__(argument_count.into()) @@ -176,7 +168,7 @@ impl SuperCallSpread { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) -> JsResult<()> { // Get the arguments that are stored as an array object on the stack. - let arguments_array = context.vm.stack.pop(); + let arguments_array = context.stack_pop(); let arguments_array_object = arguments_array .as_object() .expect("arguments array in call spread function must be an object"); @@ -186,7 +178,7 @@ impl SuperCallSpread { .to_dense_indexed_properties() .expect("arguments array in call spread function must be dense"); - let super_constructor = context.vm.stack.pop(); + let super_constructor = context.stack_pop(); let Some(super_constructor) = super_constructor.as_constructor() else { return Err(JsNativeError::typ() @@ -194,15 +186,12 @@ impl SuperCallSpread { .into()); }; - context.vm.stack.push(super_constructor.clone()); + context.stack_push(super_constructor.clone()); - context - .vm - .stack - .calling_convention_push_arguments(&arguments); + context.stack_calling_convention_push_arguments(&arguments); let this_env = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -216,7 +205,7 @@ impl SuperCallSpread { .expect("must have new.target") .clone(); - context.vm.stack.push(new_target); + context.stack_push(new_target); super_constructor .__construct__(arguments.len()) @@ -242,7 +231,7 @@ impl SuperCallDerived { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) -> JsResult<()> { let this_env = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -266,15 +255,15 @@ impl SuperCallDerived { .into()); } - context.vm.stack.push(JsValue::undefined()); - context.vm.stack.push(super_constructor.clone()); - for argument in Vec::from(context.vm.stack.get_arguments(context.vm.frame())) { - context.vm.stack.push(argument.clone()); + context.stack_push(JsValue::undefined()); + context.stack_push(super_constructor.clone()); + for argument in Vec::from(context.stack_get_arguments()) { + context.stack_push(argument.clone()); } - context.vm.stack.push(new_target); + context.stack_push(new_target); super_constructor - .__construct__(context.vm.frame().argument_count as usize) + .__construct__(context.frame().argument_count as usize) .resolve(context)?; Ok(()) } @@ -301,7 +290,6 @@ impl BindThisValue { // let result = context - .vm .get_register(value.into()) .as_object() .expect("construct result should be an object") @@ -309,7 +297,7 @@ impl BindThisValue { // 7. Let thisER be GetThisEnvironment(). let this_env = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -328,7 +316,7 @@ impl BindThisValue { result.initialize_instance_elements(&active_function, context)?; // 12. Return result. - context.vm.set_register(value.into(), result.into()); + context.set_register(value.into(), result.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/function.rs b/core/engine/src/vm/opcode/function.rs index aa1e70fb325..07924a6e8da 100644 --- a/core/engine/src/vm/opcode/function.rs +++ b/core/engine/src/vm/opcode/function.rs @@ -17,8 +17,8 @@ impl SetHomeObject { (function, home): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()); - let home = context.vm.get_register(home.into()); + let function = context.get_register(function.into()); + let home = context.get_register(home.into()); function .as_object() @@ -53,7 +53,7 @@ pub(crate) struct GetHomeObject; impl GetHomeObject { #[inline(always)] pub(crate) fn operation(function: RegisterOperand, context: &mut Context) -> JsResult<()> { - let function_v = context.vm.get_register(function.into()); + let function_v = context.get_register(function.into()); let home_object = function_v .as_object() @@ -63,7 +63,7 @@ impl GetHomeObject { .get_home_object() .map_or_else(JsValue::null, |o| o.clone().into()); - context.vm.set_register(function.into(), home_object); + context.set_register(function.into(), home_object); Ok(()) } } @@ -94,13 +94,13 @@ impl GetMethod { (object, name_index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function_val = context.vm.take_register(object.into()); - let code_block = context.vm.frame().code_block(); + let function_val = context.take_register(object.into()); + let code_block = context.frame().code_block(); let key = code_block.constant_string(name_index.into()); let method = function_val.get_method(key, context)?; - context.vm.set_register( + context.set_register( object.into(), method.map_or_else(JsValue::undefined, JsValue::from), ); diff --git a/core/engine/src/vm/opcode/generator/mod.rs b/core/engine/src/vm/opcode/generator/mod.rs index 78b1b743736..ca6b98ade78 100644 --- a/core/engine/src/vm/opcode/generator/mod.rs +++ b/core/engine/src/vm/opcode/generator/mod.rs @@ -23,7 +23,7 @@ pub(crate) struct Generator; impl Generator { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) -> ControlFlow { - let active_function = context.vm.stack.get_function(context.vm.frame()); + let active_function = context.stack_get_function(); let this_function_object = active_function.expect("active function should be set to the generator"); @@ -46,7 +46,7 @@ impl Generator { generator.borrow_mut().data_mut().state = GeneratorState::SuspendedStart { context: gen_ctx }; - context.vm.set_return_value(generator.upcast().into()); + context.set_return_value(generator.upcast().into()); context.handle_yield() } } @@ -67,7 +67,7 @@ pub(crate) struct AsyncGenerator; impl AsyncGenerator { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) -> ControlFlow { - let active_function = context.vm.stack.get_function(context.vm.frame()); + let active_function = context.stack_get_function(); let this_function_object = active_function.expect("active function should be set to the generator"); @@ -90,7 +90,7 @@ impl AsyncGenerator { let gen_ctx = GeneratorContext::from_current(context, Some(generator.clone().upcast())); generator.borrow_mut().data_mut().context = Some(gen_ctx); - context.vm.set_return_value(generator.upcast().into()); + context.set_return_value(generator.upcast().into()); context.handle_yield() } } @@ -113,7 +113,6 @@ impl AsyncGeneratorClose { pub(super) fn operation((): (), context: &mut Context) -> JsResult<()> { // Step 3.e-g in [AsyncGeneratorStart](https://tc39.es/ecma262/#sec-asyncgeneratorstart) let generator = context - .vm .async_generator_object() .expect("There should be a object") .downcast::() @@ -129,12 +128,10 @@ impl AsyncGeneratorClose { // h. If result is a normal completion, set result to NormalCompletion(undefined). // i. If result is a return completion, set result to NormalCompletion(result.[[Value]]). - let return_value = context.vm.take_return_value(); + let return_value = context.take_return_value(); let result = context - .vm - .pending_exception - .take() + .take_pending_exception() .map_or(Ok(return_value), Err); drop(r#gen); diff --git a/core/engine/src/vm/opcode/generator/yield_stm.rs b/core/engine/src/vm/opcode/generator/yield_stm.rs index 8e91aa3fbdf..3dbcd395bce 100644 --- a/core/engine/src/vm/opcode/generator/yield_stm.rs +++ b/core/engine/src/vm/opcode/generator/yield_stm.rs @@ -22,8 +22,8 @@ impl GeneratorYield { value: RegisterOperand, context: &mut Context, ) -> ControlFlow { - let value = context.vm.get_register(value.into()); - context.vm.set_return_value(value.clone()); + let value = context.get_register(value.into()); + context.set_return_value(value.clone()); context.handle_yield() } } @@ -63,7 +63,7 @@ impl AsyncGeneratorYield { .expect("must be async generator object"); // 5. Let completion be NormalCompletion(value). - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); let completion = Ok(value.clone()); // TODO: 6. Assert: The execution context stack has at least two elements. @@ -86,11 +86,11 @@ impl AsyncGeneratorYield { // c. Let resumptionValue be Completion(toYield.[[Completion]]). let resume_kind = match next.completion.clone() { CompletionRecord::Normal(val) => { - context.vm.stack.push(val); + context.stack_push(val); GeneratorResumeKind::Normal } CompletionRecord::Return(val) => { - context.vm.stack.push(val); + context.stack_push(val); GeneratorResumeKind::Return } CompletionRecord::Throw(err) => { @@ -98,12 +98,12 @@ impl AsyncGeneratorYield { Ok(e) => e, Err(e) => return context.handle_error(e), }; - context.vm.stack.push(err); + context.stack_push(err); GeneratorResumeKind::Throw } }; - context.vm.stack.push(resume_kind); + context.stack_push(resume_kind); // d. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue). return ControlFlow::Continue(()); @@ -119,7 +119,7 @@ impl AsyncGeneratorYield { // d. Resume callerContext passing undefined. If genContext is ever resumed again, let resumptionValue be the Completion Record with which it is resumed. // e. Assert: If control reaches here, then genContext is the running execution context again. // f. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue). - context.vm.set_return_value(JsValue::undefined()); + context.set_return_value(JsValue::undefined()); context.handle_yield() } } diff --git a/core/engine/src/vm/opcode/get/argument.rs b/core/engine/src/vm/opcode/get/argument.rs index 296bbed0217..261fce2bcea 100644 --- a/core/engine/src/vm/opcode/get/argument.rs +++ b/core/engine/src/vm/opcode/get/argument.rs @@ -16,10 +16,10 @@ impl GetArgument { let value = context .vm .stack - .get_argument(context.vm.frame(), index.into()) + .get_argument(context.frame(), index.into()) .cloned() .unwrap_or_default(); - context.vm.set_register(dst.into(), value); + context.set_register(dst.into(), value); } } diff --git a/core/engine/src/vm/opcode/get/function.rs b/core/engine/src/vm/opcode/get/function.rs index ce11d25f03d..c5219141e57 100644 --- a/core/engine/src/vm/opcode/get/function.rs +++ b/core/engine/src/vm/opcode/get/function.rs @@ -22,7 +22,7 @@ impl GetFunction { .code_block() .constant_function(index.into()); let function = create_function_object_fast(code, context); - context.vm.set_register(dst.into(), function.into()); + context.set_register(dst.into(), function.into()); } } diff --git a/core/engine/src/vm/opcode/get/name.rs b/core/engine/src/vm/opcode/get/name.rs index d44f028ccc0..5fc022a3836 100644 --- a/core/engine/src/vm/opcode/get/name.rs +++ b/core/engine/src/vm/opcode/get/name.rs @@ -19,14 +19,13 @@ impl GetName { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let mut binding_locator = - context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let mut binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); context.find_runtime_binding(&mut binding_locator)?; let result = context.get_binding(&binding_locator)?.ok_or_else(|| { let name = binding_locator.name().to_std_string_escaped(); JsNativeError::reference().with_message(format!("{name} is not defined")) })?; - context.vm.set_register(value.into(), result); + context.set_register(value.into(), result); Ok(()) } } @@ -50,14 +49,13 @@ impl GetNameGlobal { (dst, index, ic_index): (RegisterOperand, IndexOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let mut binding_locator = - context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let mut binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); context.find_runtime_binding(&mut binding_locator)?; if binding_locator.is_global() { let object = context.global_object(); - let ic = &context.vm.frame().code_block().ic[usize::from(ic_index)]; + let ic = &context.frame().code_block().ic[usize::from(ic_index)]; let object_borrowed = object.borrow(); if let Some((shape, slot)) = ic.get(object_borrowed.shape()) { @@ -77,7 +75,7 @@ impl GetNameGlobal { context, )?; } - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); return Ok(()); } @@ -96,13 +94,13 @@ impl GetNameGlobal { // Cache the property. let slot = *context.slot(); if slot.is_cacheable() { - let ic = &context.vm.frame().code_block.ic[usize::from(ic_index)]; + let ic = &context.frame().code_block.ic[usize::from(ic_index)]; let object_borrowed = object.borrow(); let shape = object_borrowed.shape(); ic.set(shape, slot); } - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); return Ok(()); } @@ -111,7 +109,7 @@ impl GetNameGlobal { JsNativeError::reference().with_message(format!("{name} is not defined")) })?; - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); Ok(()) } } @@ -132,11 +130,10 @@ pub(crate) struct GetLocator; impl GetLocator { #[inline(always)] pub(crate) fn operation(index: IndexOperand, context: &mut Context) -> JsResult<()> { - let mut binding_locator = - context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let mut binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); context.find_runtime_binding(&mut binding_locator)?; - context.vm.frame_mut().binding_stack.push(binding_locator); + context.frame_mut().binding_stack.push(binding_locator); Ok(()) } @@ -162,16 +159,15 @@ impl GetNameAndLocator { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let mut binding_locator = - context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let mut binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); context.find_runtime_binding(&mut binding_locator)?; let result = context.get_binding(&binding_locator)?.ok_or_else(|| { let name = binding_locator.name().to_std_string_escaped(); JsNativeError::reference().with_message(format!("{name} is not defined")) })?; - context.vm.frame_mut().binding_stack.push(binding_locator); - context.vm.set_register(value.into(), result); + context.frame_mut().binding_stack.push(binding_locator); + context.set_register(value.into(), result); Ok(()) } } @@ -195,8 +191,7 @@ impl GetNameOrUndefined { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let mut binding_locator = - context.vm.frame().code_block.bindings[usize::from(index)].clone(); + let mut binding_locator = context.frame().code_block.bindings[usize::from(index)].clone(); let is_global = binding_locator.is_global(); @@ -213,7 +208,7 @@ impl GetNameOrUndefined { .into()); }; - context.vm.set_register(value.into(), result); + context.set_register(value.into(), result); Ok(()) } } diff --git a/core/engine/src/vm/opcode/get/private.rs b/core/engine/src/vm/opcode/get/private.rs index fd372558608..ff1fc390b84 100644 --- a/core/engine/src/vm/opcode/get/private.rs +++ b/core/engine/src/vm/opcode/get/private.rs @@ -21,7 +21,7 @@ impl GetPrivateField { .frame() .code_block() .constant_string(index.into()); - let object = context.vm.get_register(object.into()).clone(); + let object = context.get_register(object.into()).clone(); let object = object.to_object(context)?; let name = context .vm @@ -31,7 +31,7 @@ impl GetPrivateField { .expect("private name must be in environment"); let result = object.private_get(&name, context)?; - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); Ok(()) } } diff --git a/core/engine/src/vm/opcode/get/property.rs b/core/engine/src/vm/opcode/get/property.rs index 9e531555fa0..575fbb301ac 100644 --- a/core/engine/src/vm/opcode/get/property.rs +++ b/core/engine/src/vm/opcode/get/property.rs @@ -16,7 +16,7 @@ fn get_by_name( && object.is_array() { let value = object.borrow().properties().storage[0].clone(); - context.vm.set_register(dst.into(), value); + context.set_register(dst.into(), value); return Ok(()); } else if let Some(string) = object.as_string() { // NOTE: Since we’re using the prototype returned directly by `base_class()`, @@ -37,7 +37,7 @@ fn get_by_name( // `to_object()` would produce, such as `Number.prototype`, `String.prototype`, etc. let object = object.base_class(context)?; - let ic = &context.vm.frame().code_block().ic[usize::from(index)]; + let ic = &context.frame().code_block().ic[usize::from(index)]; let object_borrowed = object.borrow(); if let Some((shape, slot)) = ic.get(object_borrowed.shape()) { let mut result = if slot.attributes.contains(SlotAttributes::PROTOTYPE) { @@ -56,7 +56,7 @@ fn get_by_name( .expect("should contain getter") .call(receiver, &[], context)?; } - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); return Ok(()); } @@ -70,13 +70,13 @@ fn get_by_name( // Cache the property. let slot = *context.slot(); if slot.is_cacheable() { - let ic = &context.vm.frame().code_block.ic[usize::from(index)]; + let ic = &context.frame().code_block.ic[usize::from(index)]; let object_borrowed = object.borrow(); let shape = object_borrowed.shape(); ic.set(shape, slot); } - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); Ok(()) } @@ -89,8 +89,8 @@ fn get_by_value( ), context: &mut Context, ) -> JsResult<()> { - let key_value = context.vm.get_register(key.into()).clone(); - let base = context.vm.get_register(object.into()).clone(); + let key_value = context.get_register(key.into()).clone(); + let base = context.get_register(object.into()).clone(); let object = base.base_class(context)?; let key_value = key_value.to_property_key(context)?; @@ -106,10 +106,10 @@ fn get_by_value( if let Some(element) = object_borrowed.properties().get_dense_property(index.get()) { if PUSH_KEY { - context.vm.set_register(key.into(), key_value.into()); + context.set_register(key.into(), key_value.into()); } - context.vm.set_register(dst.into(), element); + context.set_register(dst.into(), element); return Ok(()); } } else if let Some(string) = base.as_string() { @@ -120,9 +120,9 @@ fn get_by_value( }); if PUSH_KEY { - context.vm.set_register(key.into(), key_value.into()); + context.set_register(key.into(), key_value.into()); } - context.vm.set_register(dst.into(), value); + context.set_register(dst.into(), value); return Ok(()); } } @@ -131,16 +131,16 @@ fn get_by_value( let value = string.len().into(); if PUSH_KEY { - context.vm.set_register(key.into(), key_value.into()); + context.set_register(key.into(), key_value.into()); } - context.vm.set_register(dst.into(), value); + context.set_register(dst.into(), value); return Ok(()); } } _ => {} } - let receiver = context.vm.get_register(receiver.into()); + let receiver = context.get_register(receiver.into()); // Slow path: let result = object.__get__( @@ -150,9 +150,9 @@ fn get_by_value( )?; if PUSH_KEY { - context.vm.set_register(key.into(), key_value.into()); + context.set_register(key.into(), key_value.into()); } - context.vm.set_register(dst.into(), result); + context.set_register(dst.into(), result); Ok(()) } @@ -165,7 +165,7 @@ impl GetLengthProperty { (dst, object, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); + let object = context.get_register(object.into()).clone(); get_by_name::((dst, &object, &object, index), context) } } @@ -189,7 +189,7 @@ impl GetPropertyByName { (dst, object, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); + let object = context.get_register(object.into()).clone(); get_by_name::((dst, &object, &object, index), context) } } @@ -218,8 +218,8 @@ impl GetPropertyByNameWithThis { ), context: &mut Context, ) -> JsResult<()> { - let receiver = context.vm.get_register(receiver.into()).clone(); - let object = context.vm.get_register(value.into()).clone(); + let receiver = context.get_register(receiver.into()).clone(); + let object = context.get_register(value.into()).clone(); get_by_name::((dst, &object, &receiver, index), context) } } diff --git a/core/engine/src/vm/opcode/iteration/for_in.rs b/core/engine/src/vm/opcode/iteration/for_in.rs index 2a532b5e6c1..7f562e819c2 100644 --- a/core/engine/src/vm/opcode/iteration/for_in.rs +++ b/core/engine/src/vm/opcode/iteration/for_in.rs @@ -14,7 +14,7 @@ pub(crate) struct CreateForInIterator; impl CreateForInIterator { #[inline(always)] pub(crate) fn operation(value: RegisterOperand, context: &mut Context) -> JsResult<()> { - let object = context.vm.get_register(value.into()).clone(); + let object = context.get_register(value.into()).clone(); let object = object.to_object(context)?; let (iterator, next_method) = ForInIterator::create_for_in_iterator(JsValue::new(object), context); diff --git a/core/engine/src/vm/opcode/iteration/get.rs b/core/engine/src/vm/opcode/iteration/get.rs index d7bc79f3df5..f0eb3b62449 100644 --- a/core/engine/src/vm/opcode/iteration/get.rs +++ b/core/engine/src/vm/opcode/iteration/get.rs @@ -14,9 +14,9 @@ pub(crate) struct GetIterator; impl GetIterator { #[inline(always)] pub(crate) fn operation(value: RegisterOperand, context: &mut Context) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); + let value = context.get_register(value.into()).clone(); let iterator = value.get_iterator(IteratorHint::Sync, context)?; - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); Ok(()) } } @@ -37,9 +37,9 @@ pub(crate) struct GetAsyncIterator; impl GetAsyncIterator { #[inline(always)] pub(crate) fn operation(value: RegisterOperand, context: &mut Context) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); + let value = context.get_register(value.into()).clone(); let iterator = value.get_iterator(IteratorHint::Async, context)?; - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); Ok(()) } } diff --git a/core/engine/src/vm/opcode/iteration/iterator.rs b/core/engine/src/vm/opcode/iteration/iterator.rs index b053816835e..e9da3700d10 100644 --- a/core/engine/src/vm/opcode/iteration/iterator.rs +++ b/core/engine/src/vm/opcode/iteration/iterator.rs @@ -74,7 +74,7 @@ impl IteratorPush { .get_register(iterator.into()) .as_object() .js_expect("iterator should be an object")?; - let next = context.vm.get_register(next.into()).clone(); + let next = context.get_register(next.into()).clone(); context .vm @@ -111,12 +111,12 @@ impl IteratorUpdateResult { .iterators .pop() .js_expect("iterator stack should have at least an iterator")?; - let result_v = context.vm.take_register(result.into()); + let result_v = context.take_register(result.into()); iterator.update_result(result_v, context)?; context .vm .set_register(result.into(), iterator.done().into()); - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); Ok(()) } @@ -147,7 +147,7 @@ impl IteratorNext { iterator.step(context)?; - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); Ok(()) } @@ -192,9 +192,9 @@ impl IteratorFinishAsyncNext { return Ok(()); } - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); iterator.update_result(value.clone(), context)?; - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); Ok(()) } } @@ -224,7 +224,7 @@ impl IteratorResult { .last_result() .object() .clone(); - context.vm.set_register(value.into(), last_result.into()); + context.set_register(value.into(), last_result.into()); } } @@ -252,9 +252,9 @@ impl IteratorValue { .expect("iterator on the call frame must exist"); let iter_value = iterator.value(context)?; - context.vm.set_register(value.into(), iter_value); + context.set_register(value.into(), iter_value); - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); Ok(()) } @@ -283,7 +283,7 @@ impl IteratorDone { .last() .expect("iterator on the call frame must exist") .done(); - context.vm.set_register(done.into(), value.into()); + context.set_register(done.into(), value.into()); } } @@ -306,13 +306,13 @@ impl IteratorReturn { (value, called): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let Some(record) = context.vm.frame_mut().iterators.pop() else { - context.vm.set_register(called.into(), false.into()); + let Some(record) = context.frame_mut().iterators.pop() else { + context.set_register(called.into(), false.into()); return Ok(()); }; if record.done() { - context.vm.set_register(called.into(), false.into()); + context.set_register(called.into(), false.into()); return Ok(()); } @@ -320,18 +320,18 @@ impl IteratorReturn { .iterator() .get_method(js_string!("return"), context)? else { - context.vm.set_register(called.into(), false.into()); + context.set_register(called.into(), false.into()); return Ok(()); }; - let old_return_value = context.vm.get_return_value(); + let old_return_value = context.get_return_value(); let return_value = ret.call(&record.iterator().clone().into(), &[], context)?; - context.vm.set_return_value(old_return_value); + context.set_return_value(old_return_value); - context.vm.set_register(value.into(), return_value); - context.vm.set_register(called.into(), true.into()); + context.set_register(value.into(), return_value); + context.set_register(called.into(), true.into()); Ok(()) } @@ -366,7 +366,7 @@ impl IteratorToArray { let done = match iterator.step(context) { Ok(done) => done, Err(err) => { - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); return Err(err); } }; @@ -378,15 +378,15 @@ impl IteratorToArray { match iterator.value(context) { Ok(value) => values.push(value), Err(err) => { - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); return Err(err); } } } - context.vm.frame_mut().iterators.push(iterator); + context.frame_mut().iterators.push(iterator); let result = Array::create_array_from_list(values, context); - context.vm.set_register(array.into(), result.into()); + context.set_register(array.into(), result.into()); Ok(()) } } @@ -407,8 +407,8 @@ pub(crate) struct IteratorStackEmpty; impl IteratorStackEmpty { #[inline(always)] pub(crate) fn operation(empty: RegisterOperand, context: &mut Context) { - let is_empty = context.vm.frame().iterators.is_empty(); - context.vm.set_register(empty.into(), is_empty.into()); + let is_empty = context.frame().iterators.is_empty(); + context.set_register(empty.into(), is_empty.into()); } } @@ -429,9 +429,9 @@ impl CreateIteratorResult { #[inline(always)] pub(crate) fn operation((value, done): (RegisterOperand, IndexOperand), context: &mut Context) { let done = u32::from(done) != 0; - let val = context.vm.take_register(value.into()); + let val = context.take_register(value.into()); let result = create_iter_result_object(val, done, context); - context.vm.set_register(value.into(), result); + context.set_register(value.into(), result); } } diff --git a/core/engine/src/vm/opcode/iteration/loop_ops.rs b/core/engine/src/vm/opcode/iteration/loop_ops.rs index 21cd262fd6c..972b973843a 100644 --- a/core/engine/src/vm/opcode/iteration/loop_ops.rs +++ b/core/engine/src/vm/opcode/iteration/loop_ops.rs @@ -11,8 +11,8 @@ pub(crate) struct IncrementLoopIteration; impl IncrementLoopIteration { #[inline(always)] pub(crate) fn operation((): (), context: &mut Context) -> JsResult<()> { - let max = context.vm.runtime_limits.loop_iteration_limit(); - let frame = context.vm.frame_mut(); + let max = context.loop_iteration_limit(); + let frame = context.frame_mut(); let previous_iteration_count = frame.loop_iteration_count; if previous_iteration_count > max { diff --git a/core/engine/src/vm/opcode/meta/mod.rs b/core/engine/src/vm/opcode/meta/mod.rs index b1ec082a394..e51065d2793 100644 --- a/core/engine/src/vm/opcode/meta/mod.rs +++ b/core/engine/src/vm/opcode/meta/mod.rs @@ -17,7 +17,7 @@ impl NewTarget { #[inline(always)] pub(super) fn operation(dst: RegisterOperand, context: &mut Context) { let new_target = if let Some(new_target) = { - let frame = context.vm.frame(); + let frame = context.frame(); frame .environments .get_this_environment(frame.realm.environment()) @@ -28,7 +28,7 @@ impl NewTarget { } else { JsValue::undefined() }; - context.vm.set_register(dst.into(), new_target); + context.set_register(dst.into(), new_target); } } @@ -90,7 +90,7 @@ impl ImportMeta { // b. Return importMeta. // f. Return importMeta. - context.vm.set_register(dst.into(), import_meta.into()); + context.set_register(dst.into(), import_meta.into()); } } diff --git a/core/engine/src/vm/opcode/mod.rs b/core/engine/src/vm/opcode/mod.rs index e304514a8fc..99e12e9aebf 100644 --- a/core/engine/src/vm/opcode/mod.rs +++ b/core/engine/src/vm/opcode/mod.rs @@ -419,9 +419,9 @@ macro_rules! generate_opcodes { #[inline(always)] #[allow(unused_parens)] fn [](context: &mut Context, pc: usize) -> ControlFlow { - let bytes = &context.vm.frame().code_block.bytecode.bytes; + let bytes = &context.frame().code_block.bytecode.bytes; let (args, next_pc) = <($($($FieldType),*)?)>::decode(bytes, pc + 1); - context.vm.frame_mut().pc = next_pc as u32; + context.frame_mut().pc = next_pc as u32; let result = $Variant::operation(args, context); IntoCompletionRecord::into_completion_record(result, context) } @@ -434,9 +434,9 @@ macro_rules! generate_opcodes { #[allow(unused_parens)] fn [](context: &mut Context, pc: usize, budget: &mut u32) -> ControlFlow { *budget = budget.saturating_sub(u32::from($Variant::COST)); - let bytes = &context.vm.frame().code_block.bytecode.bytes; + let bytes = &context.frame().code_block.bytecode.bytes; let (args, next_pc) = <($($($FieldType),*)?)>::decode(bytes, pc + 1); - context.vm.frame_mut().pc = next_pc as u32; + context.frame_mut().pc = next_pc as u32; let result = $Variant::operation(args, context); IntoCompletionRecord::into_completion_record(result, context) } diff --git a/core/engine/src/vm/opcode/new/mod.rs b/core/engine/src/vm/opcode/new/mod.rs index a09237a4555..92090e23686 100644 --- a/core/engine/src/vm/opcode/new/mod.rs +++ b/core/engine/src/vm/opcode/new/mod.rs @@ -21,7 +21,7 @@ impl New { .ok_or_else(|| JsNativeError::typ().with_message("not a constructor"))? .clone(); - context.vm.stack.push(cons.clone()); // Push new.target + context.stack_push(cons.clone()); // Push new.target cons.__construct__(argument_count.into()).resolve(context)?; Ok(()) @@ -45,7 +45,7 @@ impl NewSpread { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) -> JsResult<()> { // Get the arguments that are stored as an array object on the stack. - let arguments_array = context.vm.stack.pop(); + let arguments_array = context.stack_pop(); let arguments_array_object = arguments_array .as_object() .expect("arguments array in call spread function must be an object"); @@ -55,7 +55,7 @@ impl NewSpread { .to_dense_indexed_properties() .expect("arguments array in call spread function must be dense"); - let func = context.vm.stack.pop(); + let func = context.stack_pop(); let cons = func .as_object() @@ -63,12 +63,12 @@ impl NewSpread { .clone(); let argument_count = arguments.len(); - context.vm.stack.push(func); + context.stack_push(func); context .vm .stack .calling_convention_push_arguments(&arguments); - context.vm.stack.push(cons.clone()); // Push new.target + context.stack_push(cons.clone()); // Push new.target cons.__construct__(argument_count).resolve(context)?; Ok(()) diff --git a/core/engine/src/vm/opcode/object.rs b/core/engine/src/vm/opcode/object.rs index 098aa8c8ca0..6183273c2df 100644 --- a/core/engine/src/vm/opcode/object.rs +++ b/core/engine/src/vm/opcode/object.rs @@ -17,8 +17,8 @@ impl SetPrototype { (object, value): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); - let value = context.vm.get_register(value.into()); + let object = context.get_register(object.into()).clone(); + let value = context.get_register(value.into()); let prototype = if let Some(prototype) = value.as_object() { Some(prototype.clone()) @@ -63,7 +63,7 @@ impl GetPrototype { .__get_prototype_of__(context)? .map_or_else(JsValue::null, JsValue::from); - context.vm.set_register(object.into(), proto_object); + context.set_register(object.into(), proto_object); Ok(()) } } diff --git a/core/engine/src/vm/opcode/pop/mod.rs b/core/engine/src/vm/opcode/pop/mod.rs index 609310f37a1..7319fdba28e 100644 --- a/core/engine/src/vm/opcode/pop/mod.rs +++ b/core/engine/src/vm/opcode/pop/mod.rs @@ -10,7 +10,7 @@ pub(crate) struct Pop; impl Pop { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) { - let _val = context.vm.stack.pop(); + let _val = context.stack_pop(); } } @@ -30,7 +30,7 @@ pub(crate) struct PopEnvironment; impl PopEnvironment { #[inline(always)] pub(super) fn operation((): (), context: &mut Context) { - context.vm.frame_mut().environments.pop(); + context.frame_mut().environments.pop(); } } diff --git a/core/engine/src/vm/opcode/push/array.rs b/core/engine/src/vm/opcode/push/array.rs index 6c0df378d36..3df61d351c4 100644 --- a/core/engine/src/vm/opcode/push/array.rs +++ b/core/engine/src/vm/opcode/push/array.rs @@ -20,7 +20,7 @@ impl StoreNewArray { .templates() .array() .create(Array, Vec::from([JsValue::new(0)])); - context.vm.set_register(array.into(), value.into()); + context.set_register(array.into(), value.into()); } } @@ -43,7 +43,7 @@ impl PushValueToArray { (value, array): (RegisterOperand, RegisterOperand), context: &mut Context, ) { - let value = context.vm.get_register(value.into()).clone(); + let value = context.get_register(value.into()).clone(); let o = context .vm .get_register(array.into()) @@ -87,7 +87,7 @@ pub(crate) struct PushElisionToArray; impl PushElisionToArray { #[inline(always)] pub(crate) fn operation(array: RegisterOperand, context: &mut Context) -> JsResult<()> { - let array = context.vm.get_register(array.into()).clone(); + let array = context.get_register(array.into()).clone(); let o = array.as_object().expect("should always be an object"); let len = o .length_of_array_like(context) @@ -117,7 +117,7 @@ pub(crate) struct PushIteratorToArray; impl PushIteratorToArray { #[inline(always)] pub(crate) fn operation(array: RegisterOperand, context: &mut Context) -> JsResult<()> { - let array = context.vm.get_register(array.into()).clone(); + let array = context.get_register(array.into()).clone(); let mut iterator = context .vm .frame_mut() diff --git a/core/engine/src/vm/opcode/push/class/field.rs b/core/engine/src/vm/opcode/push/class/field.rs index 869cf090d37..26358887ad6 100644 --- a/core/engine/src/vm/opcode/push/class/field.rs +++ b/core/engine/src/vm/opcode/push/class/field.rs @@ -23,9 +23,9 @@ impl PushClassField { ), context: &mut Context, ) -> JsResult<()> { - let class = context.vm.get_register(class.into()).clone(); - let name = context.vm.get_register(name.into()).clone(); - let function = context.vm.get_register(function.into()).clone(); + let class = context.get_register(class.into()).clone(); + let name = context.get_register(name.into()).clone(); + let function = context.get_register(function.into()).clone(); let is_anonymous_function = u32::from(is_anonymous_function) != 0; let name = name.to_property_key(context)?; @@ -74,8 +74,8 @@ impl PushClassFieldPrivate { (class, function, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) { - let class = context.vm.get_register(class.into()); - let function = context.vm.get_register(function.into()); + let class = context.get_register(class.into()); + let function = context.get_register(function.into()); let name = context .vm .frame() diff --git a/core/engine/src/vm/opcode/push/class/mod.rs b/core/engine/src/vm/opcode/push/class/mod.rs index 9336fccc579..8fe9a71c4a3 100644 --- a/core/engine/src/vm/opcode/push/class/mod.rs +++ b/core/engine/src/vm/opcode/push/class/mod.rs @@ -24,8 +24,8 @@ impl StoreClassPrototype { (dst, class, superclass): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let class = context.vm.get_register(class.into()).clone(); - let superclass = context.vm.get_register(superclass.into()).clone(); + let class = context.get_register(class.into()).clone(); + let superclass = context.get_register(superclass.into()).clone(); // // Taken from `15.7.14 Runtime Semantics: ClassDefinitionEvaluation`: // @@ -68,7 +68,7 @@ impl StoreClassPrototype { class_object.set_prototype(Some(constructor_parent)); } - context.vm.set_register(dst.into(), proto_parent); + context.set_register(dst.into(), proto_parent); Ok(()) } } diff --git a/core/engine/src/vm/opcode/push/class/private.rs b/core/engine/src/vm/opcode/push/class/private.rs index 28212d06edf..c0e249375a4 100644 --- a/core/engine/src/vm/opcode/push/class/private.rs +++ b/core/engine/src/vm/opcode/push/class/private.rs @@ -25,9 +25,9 @@ impl PushClassPrivateMethod { ), context: &mut Context, ) { - let object = context.vm.get_register(object.into()).clone(); - let prototype = context.vm.get_register(prototype.into()).clone(); - let value = context.vm.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); + let prototype = context.get_register(prototype.into()).clone(); + let value = context.get_register(value.into()).clone(); let name = context .vm .frame() @@ -88,8 +88,8 @@ impl PushClassPrivateGetter { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) { - let object = context.vm.get_register(object.into()); - let value = context.vm.get_register(value.into()); + let object = context.get_register(object.into()); + let value = context.get_register(value.into()); let name = context .vm .frame() @@ -131,8 +131,8 @@ impl PushClassPrivateSetter { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) { - let object = context.vm.get_register(object.into()); - let value = context.vm.get_register(value.into()); + let object = context.get_register(object.into()); + let value = context.get_register(value.into()); let name = context .vm .frame() diff --git a/core/engine/src/vm/opcode/push/environment.rs b/core/engine/src/vm/opcode/push/environment.rs index f18593ab029..d4787189eb7 100644 --- a/core/engine/src/vm/opcode/push/environment.rs +++ b/core/engine/src/vm/opcode/push/environment.rs @@ -17,8 +17,8 @@ pub(crate) struct PushScope; impl PushScope { #[inline(always)] pub(crate) fn operation(index: IndexOperand, context: &mut Context) { - let scope = context.vm.frame().code_block().constant_scope(index.into()); - let frame = context.vm.frame_mut(); + let scope = context.frame().code_block().constant_scope(index.into()); + let frame = context.frame_mut(); let global = frame.realm.environment(); frame .environments @@ -42,9 +42,9 @@ pub(crate) struct PushObjectEnvironment; impl PushObjectEnvironment { #[inline(always)] pub(crate) fn operation(value: RegisterOperand, context: &mut Context) -> JsResult<()> { - let object = context.vm.get_register(value.into()).clone(); + let object = context.get_register(value.into()).clone(); let object = object.to_object(context)?; - context.vm.frame_mut().environments.push_object(object); + context.frame_mut().environments.push_object(object); Ok(()) } } @@ -68,7 +68,7 @@ impl PushPrivateEnvironment { (class, name_indices): (RegisterOperand, ThinVec), context: &mut Context, ) { - let class = context.vm.get_register(class.into()); + let class = context.get_register(class.into()); let class = class.as_object().expect("should be a object"); let mut names = Vec::with_capacity(name_indices.len()); for index in name_indices { @@ -111,7 +111,7 @@ pub(crate) struct PopPrivateEnvironment; impl PopPrivateEnvironment { #[inline(always)] pub(crate) fn operation((): (), context: &mut Context) { - context.vm.frame_mut().environments.pop_private(); + context.frame_mut().environments.pop_private(); } } diff --git a/core/engine/src/vm/opcode/push/literal.rs b/core/engine/src/vm/opcode/push/literal.rs index 62d20fbf735..ba5623cb13d 100644 --- a/core/engine/src/vm/opcode/push/literal.rs +++ b/core/engine/src/vm/opcode/push/literal.rs @@ -17,13 +17,13 @@ pub(crate) struct StoreLiteral; impl StoreLiteral { #[inline(always)] pub(crate) fn operation((dst, index): (RegisterOperand, IndexOperand), context: &mut Context) { - let constant = &context.vm.frame().code_block().constants[usize::from(index)]; + let constant = &context.frame().code_block().constants[usize::from(index)]; let value: JsValue = match constant { Constant::BigInt(v) => v.clone().into(), Constant::String(v) => v.clone().into(), _ => unreachable!("constant should be a string or bigint"), }; - context.vm.set_register(dst.into(), value); + context.set_register(dst.into(), value); } } @@ -46,11 +46,11 @@ impl StoreRegexp { (dst, pattern_index, flags_index): (RegisterOperand, IndexOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let code_block = context.vm.frame().code_block(); + let code_block = context.frame().code_block(); let pattern = code_block.constant_string(pattern_index.into()); let flags = code_block.constant_string(flags_index.into()); let regexp = JsRegExp::new(pattern, flags, context)?; - context.vm.set_register(dst.into(), regexp.into()); + context.set_register(dst.into(), regexp.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/push/mod.rs b/core/engine/src/vm/opcode/push/mod.rs index fc3a8beb257..d26f3513c8a 100644 --- a/core/engine/src/vm/opcode/push/mod.rs +++ b/core/engine/src/vm/opcode/push/mod.rs @@ -29,7 +29,7 @@ macro_rules! implement_store_generics { impl $name { #[inline(always)] pub(super) fn operation(dst: RegisterOperand, context: &mut Context) { - context.vm.set_register(dst.into(), $push_value.into()); + context.set_register(dst.into(), $push_value.into()); } } diff --git a/core/engine/src/vm/opcode/push/numbers.rs b/core/engine/src/vm/opcode/push/numbers.rs index 7b1e92143d2..e65169d6796 100644 --- a/core/engine/src/vm/opcode/push/numbers.rs +++ b/core/engine/src/vm/opcode/push/numbers.rs @@ -15,7 +15,7 @@ macro_rules! implement_store_numbers_with_conversion { impl $name { #[inline(always)] pub(crate) fn operation((dst, value): (RegisterOperand, $num_type), context: &mut Context) { - context.vm.set_register(dst.into(), i32::from(value).into()); + context.set_register(dst.into(), i32::from(value).into()); } } @@ -39,7 +39,7 @@ macro_rules! implement_store_numbers_no_conversion { impl $name { #[inline(always)] pub(crate) fn operation((dst, value): (RegisterOperand, $num_type), context: &mut Context) { - context.vm.set_register(dst.into(), value.into()); + context.set_register(dst.into(), value.into()); } } diff --git a/core/engine/src/vm/opcode/push/object.rs b/core/engine/src/vm/opcode/push/object.rs index 30dcb696024..b9989c8eda4 100644 --- a/core/engine/src/vm/opcode/push/object.rs +++ b/core/engine/src/vm/opcode/push/object.rs @@ -19,7 +19,7 @@ impl StoreEmptyObject { .templates() .ordinary_object() .create(OrdinaryObject, Vec::default()); - context.vm.set_register(dst.into(), o.into()); + context.set_register(dst.into(), o.into()); } } diff --git a/core/engine/src/vm/opcode/rest_parameter/mod.rs b/core/engine/src/vm/opcode/rest_parameter/mod.rs index 169864f9de5..c974459e9d8 100644 --- a/core/engine/src/vm/opcode/rest_parameter/mod.rs +++ b/core/engine/src/vm/opcode/rest_parameter/mod.rs @@ -11,21 +11,17 @@ pub(crate) struct RestParameterInit; impl RestParameterInit { #[inline(always)] pub(super) fn operation(dst: RegisterOperand, context: &mut Context) { - let array = if let Some(rest) = context - .vm - .stack - .pop_rest_arguments(context.vm.frames.last().expect("frame must exist")) - { + let array = if let Some(rest) = context.stack_pop_rest_arguments() { let rest_count = rest.len() as u32; let array = Array::create_array_from_list(rest, context); - context.vm.frame_mut().argument_count -= rest_count; + context.frame_mut().argument_count -= rest_count; // Adjust rp since draining rest arguments shifted the register slots down. - context.vm.frame_mut().rp -= rest_count; + context.frame_mut().rp -= rest_count; array } else { Array::array_create(0, None, context).expect("could not create an empty array") }; - context.vm.set_register(dst.into(), array.into()); + context.set_register(dst.into(), array.into()); } } diff --git a/core/engine/src/vm/opcode/set/class_prototype.rs b/core/engine/src/vm/opcode/set/class_prototype.rs index 1d1c8566d8e..0dcff84fff8 100644 --- a/core/engine/src/vm/opcode/set/class_prototype.rs +++ b/core/engine/src/vm/opcode/set/class_prototype.rs @@ -21,7 +21,7 @@ impl SetClassPrototype { (dst, prototype, class): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) { - let prototype = context.vm.get_register(prototype.into()); + let prototype = context.get_register(prototype.into()); let prototype = match prototype.variant() { JsVariant::Object(proto) => Some(proto.clone()), JsVariant::Null => None, @@ -36,7 +36,7 @@ impl SetClassPrototype { OrdinaryObject, ) .upcast(); - let class = context.vm.get_register(class.into()).clone(); + let class = context.get_register(class.into()).clone(); { let class_object = class.as_object().expect("class must be object"); @@ -70,7 +70,7 @@ impl SetClassPrototype { ) .expect("cannot fail per spec"); - context.vm.set_register(dst.into(), proto.into()); + context.set_register(dst.into(), proto.into()); } } diff --git a/core/engine/src/vm/opcode/set/name.rs b/core/engine/src/vm/opcode/set/name.rs index be97dd7bfd3..a20aca3b9c3 100644 --- a/core/engine/src/vm/opcode/set/name.rs +++ b/core/engine/src/vm/opcode/set/name.rs @@ -50,8 +50,8 @@ impl SetName { (value, index): (RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); - let code_block = context.vm.frame().code_block(); + let value = context.get_register(value.into()).clone(); + let code_block = context.frame().code_block(); let mut binding_locator = code_block.bindings[usize::from(index)].clone(); let strict = code_block.strict(); @@ -81,13 +81,13 @@ pub(crate) struct SetNameByLocator; impl SetNameByLocator { #[inline(always)] pub(crate) fn operation(value: RegisterOperand, context: &mut Context) -> JsResult<()> { - let frame = context.vm.frame_mut(); + let frame = context.frame_mut(); let strict = frame.code_block.strict(); let binding_locator = frame .binding_stack .pop() .expect("locator should have been popped before"); - let value = context.vm.get_register(value.into()).clone(); + let value = context.get_register(value.into()).clone(); verify_initialized(&binding_locator, context)?; @@ -107,7 +107,7 @@ impl Operation for SetNameByLocator { fn verify_initialized(locator: &BindingLocator, context: &mut Context) -> JsResult<()> { if !context.is_initialized_binding(locator)? { let key = locator.name(); - let strict = context.vm.frame().code_block.strict(); + let strict = context.frame().code_block.strict(); let message = match locator.scope() { BindingLocatorScope::GlobalObject if strict => Some(format!( diff --git a/core/engine/src/vm/opcode/set/private.rs b/core/engine/src/vm/opcode/set/private.rs index 04bdf2bcf9e..797f87be492 100644 --- a/core/engine/src/vm/opcode/set/private.rs +++ b/core/engine/src/vm/opcode/set/private.rs @@ -23,8 +23,8 @@ impl SetPrivateField { .frame() .code_block() .constant_string(index.into()); - let value = context.vm.get_register(value.into()).clone(); - let object = context.vm.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); let base_obj = object.to_object(context)?; let name = context .vm @@ -57,8 +57,8 @@ impl DefinePrivateField { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); - let value = context.vm.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); let name = context .vm .frame() @@ -94,8 +94,8 @@ impl SetPrivateMethod { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) { - let object = context.vm.get_register(object.into()).clone(); - let value = context.vm.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); let name = context .vm .frame() @@ -144,8 +144,8 @@ impl SetPrivateSetter { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) { - let object = context.vm.get_register(object.into()); - let value = context.vm.get_register(value.into()); + let object = context.get_register(object.into()); + let value = context.get_register(value.into()); let name = context .vm .frame() @@ -186,8 +186,8 @@ impl SetPrivateGetter { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) { - let object = context.vm.get_register(object.into()); - let value = context.vm.get_register(value.into()); + let object = context.get_register(object.into()); + let value = context.get_register(value.into()); let name = context .vm .frame() diff --git a/core/engine/src/vm/opcode/set/property.rs b/core/engine/src/vm/opcode/set/property.rs index 6bf6d66c1f6..55f2c4cb799 100644 --- a/core/engine/src/vm/opcode/set/property.rs +++ b/core/engine/src/vm/opcode/set/property.rs @@ -18,11 +18,11 @@ fn set_by_name( index: IndexOperand, context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); + let value = context.get_register(value.into()).clone(); let object = value_object.to_object(context)?; - let ic = &context.vm.frame().code_block().ic[usize::from(index)]; + let ic = &context.frame().code_block().ic[usize::from(index)]; let object_borrowed = object.borrow(); if let Some((shape, slot)) = ic.get(object_borrowed.shape()) { @@ -64,7 +64,7 @@ fn set_by_name( let context = &mut InternalMethodPropertyContext::new(context); let succeeded = object.__set__(name.clone(), value.clone(), receiver.clone(), context)?; - if !succeeded && context.vm.frame().code_block.strict() { + if !succeeded && context.frame().code_block.strict() { return Err(JsNativeError::typ() .with_message(format!("cannot set non-writable property: {name}")) .into()); @@ -73,7 +73,7 @@ fn set_by_name( // Cache the property. let slot = *context.slot(); if succeeded && slot.is_cacheable() { - let ic = &context.vm.frame().code_block.ic[usize::from(index)]; + let ic = &context.frame().code_block.ic[usize::from(index)]; let object_borrowed = object.borrow(); let shape = object_borrowed.shape(); ic.set(shape, slot); @@ -95,7 +95,7 @@ impl SetPropertyByName { (value, object, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); + let object = context.get_register(object.into()).clone(); set_by_name(value, &object, &object, index, context) } } @@ -124,8 +124,8 @@ impl SetPropertyByNameWithThis { ), context: &mut Context, ) -> JsResult<()> { - let value_object = context.vm.get_register(object.into()).clone(); - let receiver = context.vm.get_register(receiver.into()).clone(); + let value_object = context.get_register(object.into()).clone(); + let receiver = context.get_register(receiver.into()).clone(); set_by_name(value, &value_object, &receiver, index, context) } } @@ -154,10 +154,10 @@ impl SetPropertyByValue { ), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let receiver = context.vm.get_register(receiver.into()).clone(); - let object = context.vm.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); + let key = context.get_register(key.into()).clone(); + let receiver = context.get_register(receiver.into()).clone(); + let object = context.get_register(object.into()).clone(); let object = object.to_object(context)?; let key = key.to_property_key(context)?; @@ -190,7 +190,7 @@ impl SetPropertyByValue { receiver.clone(), &mut context.into(), )?; - if !succeeded && context.vm.frame().code_block.strict() { + if !succeeded && context.frame().code_block.strict() { return Err(JsNativeError::typ() .with_message(format!("cannot set non-writable property: {key}")) .into()); @@ -219,8 +219,8 @@ impl SetPropertyGetterByName { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); - let value = context.vm.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); let name = context .vm .frame() @@ -267,9 +267,9 @@ impl SetPropertyGetterByValue { (value, key, object): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let object = context.vm.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); + let key = context.get_register(key.into()).clone(); + let object = context.get_register(object.into()).clone(); let object = object.to_object(context)?; let name = key.to_property_key(context)?; @@ -311,8 +311,8 @@ impl SetPropertySetterByName { (object, value, index): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let object = context.vm.get_register(object.into()).clone(); - let value = context.vm.get_register(value.into()).clone(); + let object = context.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); let name = context .vm .frame() @@ -360,9 +360,9 @@ impl SetPropertySetterByValue { (value, key, object): (RegisterOperand, RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); - let key = context.vm.get_register(key.into()).clone(); - let object = context.vm.get_register(object.into()).clone(); + let value = context.get_register(value.into()).clone(); + let key = context.get_register(key.into()).clone(); + let object = context.get_register(object.into()).clone(); let object = object.to_object(context)?; let name = key.to_property_key(context)?; @@ -405,8 +405,8 @@ impl SetFunctionName { (function, name, prefix): (RegisterOperand, RegisterOperand, IndexOperand), context: &mut Context, ) -> JsResult<()> { - let function = context.vm.get_register(function.into()).clone(); - let name = context.vm.get_register(name.into()).clone(); + let function = context.get_register(function.into()).clone(); + let name = context.get_register(name.into()).clone(); let name = match name.variant() { JsVariant::String(name) => PropertyKey::from(name.clone()), JsVariant::Symbol(name) => PropertyKey::from(name.clone()), diff --git a/core/engine/src/vm/opcode/switch/mod.rs b/core/engine/src/vm/opcode/switch/mod.rs index 63dc2f51adf..1c15dfcaa0f 100644 --- a/core/engine/src/vm/opcode/switch/mod.rs +++ b/core/engine/src/vm/opcode/switch/mod.rs @@ -18,10 +18,10 @@ impl Case { (address, value, condition): (Address, RegisterOperand, RegisterOperand), context: &mut Context, ) { - let value = context.vm.get_register(value.into()); - let condition = context.vm.get_register(condition.into()); + let value = context.get_register(value.into()); + let condition = context.get_register(condition.into()); if value.strict_equals(condition) { - context.vm.frame_mut().pc = u32::from(address); + context.frame_mut().pc = u32::from(address); } } } diff --git a/core/engine/src/vm/opcode/templates/mod.rs b/core/engine/src/vm/opcode/templates/mod.rs index 6cdcb99e3f4..e3a781ed8ac 100644 --- a/core/engine/src/vm/opcode/templates/mod.rs +++ b/core/engine/src/vm/opcode/templates/mod.rs @@ -23,8 +23,8 @@ impl TemplateLookup { context: &mut Context, ) { if let Some(template) = context.realm().lookup_template(site) { - context.vm.set_register(dst.into(), template.into()); - context.vm.frame_mut().pc = u32::from(jump); + context.set_register(dst.into(), template.into()); + context.frame_mut().pc = u32::from(jump); } } } @@ -58,7 +58,7 @@ impl TemplateCreate { let mut cooked = true; for value in values { if cooked { - let cooked_value = context.vm.get_register(value as usize); + let cooked_value = context.get_register(value as usize); template .define_property_or_throw( index, @@ -71,7 +71,7 @@ impl TemplateCreate { ) .expect("should not fail on new array"); } else { - let raw_value = context.vm.get_register(value as usize); + let raw_value = context.get_register(value as usize); raw_obj .define_property_or_throw( index, @@ -109,7 +109,7 @@ impl TemplateCreate { context.realm().push_template(site, template.clone()); - context.vm.set_register(dst.into(), template.into()); + context.set_register(dst.into(), template.into()); } } diff --git a/core/engine/src/vm/opcode/to/mod.rs b/core/engine/src/vm/opcode/to/mod.rs index 1ca38b9c4b3..bfaafdff8fa 100644 --- a/core/engine/src/vm/opcode/to/mod.rs +++ b/core/engine/src/vm/opcode/to/mod.rs @@ -14,9 +14,9 @@ impl ToPropertyKey { (value, dst): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.get_register(value.into()).clone(); + let value = context.get_register(value.into()).clone(); let key = value.to_property_key(context)?; - context.vm.set_register(dst.into(), key.into()); + context.set_register(dst.into(), key.into()); Ok(()) } } diff --git a/core/engine/src/vm/opcode/unary_ops/decrement.rs b/core/engine/src/vm/opcode/unary_ops/decrement.rs index 0747993cf5f..d86e7b54884 100644 --- a/core/engine/src/vm/opcode/unary_ops/decrement.rs +++ b/core/engine/src/vm/opcode/unary_ops/decrement.rs @@ -17,7 +17,7 @@ impl Dec { (dst, src): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.take_register(src.into()); + let value = context.take_register(src.into()); let (numeric, value) = match value.variant() { JsVariant::Integer32(number) if number > i32::MIN => { @@ -31,8 +31,8 @@ impl Dec { ), }, }; - context.vm.set_register(src.into(), numeric); - context.vm.set_register(dst.into(), value); + context.set_register(src.into(), numeric); + context.set_register(dst.into(), value); Ok(()) } } diff --git a/core/engine/src/vm/opcode/unary_ops/increment.rs b/core/engine/src/vm/opcode/unary_ops/increment.rs index 5b3edc2a7b8..8927df62bf7 100644 --- a/core/engine/src/vm/opcode/unary_ops/increment.rs +++ b/core/engine/src/vm/opcode/unary_ops/increment.rs @@ -17,7 +17,7 @@ impl Inc { (dst, src): (RegisterOperand, RegisterOperand), context: &mut Context, ) -> JsResult<()> { - let value = context.vm.take_register(src.into()); + let value = context.take_register(src.into()); let (numeric, value) = match value.variant() { JsVariant::Integer32(number) if number < i32::MAX => { @@ -31,8 +31,8 @@ impl Inc { ), }, }; - context.vm.set_register(src.into(), numeric); - context.vm.set_register(dst.into(), value); + context.set_register(src.into(), numeric); + context.set_register(dst.into(), value); Ok(()) } } diff --git a/core/engine/src/vm/opcode/unary_ops/logical.rs b/core/engine/src/vm/opcode/unary_ops/logical.rs index 4b584b3ec11..f5d9ab07c96 100644 --- a/core/engine/src/vm/opcode/unary_ops/logical.rs +++ b/core/engine/src/vm/opcode/unary_ops/logical.rs @@ -13,9 +13,9 @@ pub(crate) struct LogicalNot; impl LogicalNot { #[inline(always)] pub(crate) fn operation(value: RegisterOperand, context: &mut Context) { - context.vm.set_register( + context.set_register( value.into(), - (!context.vm.get_register(value.into()).to_boolean()).into(), + (!context.get_register(value.into()).to_boolean()).into(), ); } } diff --git a/core/engine/src/vm/opcode/unary_ops/mod.rs b/core/engine/src/vm/opcode/unary_ops/mod.rs index d2ed6920956..ad9c3425579 100644 --- a/core/engine/src/vm/opcode/unary_ops/mod.rs +++ b/core/engine/src/vm/opcode/unary_ops/mod.rs @@ -20,9 +20,9 @@ pub(crate) struct TypeOf; impl TypeOf { #[inline(always)] pub(super) fn operation(value: RegisterOperand, context: &mut Context) { - context.vm.set_register( + context.set_register( value.into(), - context.vm.get_register(value.into()).js_type_of().into(), + context.get_register(value.into()).js_type_of().into(), ); } } @@ -49,7 +49,7 @@ impl Pos { .clone() .to_number(context)? .into(); - context.vm.set_register(value.into(), v); + context.set_register(value.into(), v); Ok(()) } } @@ -76,7 +76,7 @@ impl Neg { .clone() .to_numeric(context)? { - Numeric::Number(number) => context.vm.set_register(value.into(), number.neg().into()), + Numeric::Number(number) => context.set_register(value.into(), number.neg().into()), Numeric::BigInt(bigint) => context .vm .set_register(value.into(), JsBigInt::neg(&bigint).into()), diff --git a/core/engine/src/vm/opcode/value/mod.rs b/core/engine/src/vm/opcode/value/mod.rs index e437f8f551e..383e6dbb8fc 100644 --- a/core/engine/src/vm/opcode/value/mod.rs +++ b/core/engine/src/vm/opcode/value/mod.rs @@ -11,7 +11,7 @@ pub(crate) struct ValueNotNullOrUndefined; impl ValueNotNullOrUndefined { #[inline(always)] pub(super) fn operation(value: RegisterOperand, context: &mut Context) -> JsResult<()> { - let value = context.vm.get_register(value.into()); + let value = context.get_register(value.into()); if value.is_null() { return Err(JsNativeError::typ() .with_message("Cannot destructure 'null' value") @@ -42,8 +42,8 @@ pub(crate) struct IsObject; impl IsObject { #[inline(always)] pub(super) fn operation(value: RegisterOperand, context: &mut Context) { - let is_object = context.vm.get_register(value.into()).is_object(); - context.vm.set_register(value.into(), is_object.into()); + let is_object = context.get_register(value.into()).is_object(); + context.set_register(value.into(), is_object.into()); } }