diff --git a/boa_engine/src/bytecompiler/statement/labelled.rs b/boa_engine/src/bytecompiler/statement/labelled.rs index bab66e8d7a4..860a13b4ac0 100644 --- a/boa_engine/src/bytecompiler/statement/labelled.rs +++ b/boa_engine/src/bytecompiler/statement/labelled.rs @@ -1,7 +1,4 @@ -use crate::{ - bytecompiler::{ByteCompiler, NodeKind}, - vm::Opcode, -}; +use crate::bytecompiler::{ByteCompiler, NodeKind}; use boa_ast::{ statement::{Labelled, LabelledItem}, Statement, @@ -11,7 +8,6 @@ impl ByteCompiler<'_, '_> { /// Compile a [`Labelled`] `boa_ast` node pub(crate) fn compile_labelled(&mut self, labelled: &Labelled, use_expr: bool) { let labelled_loc = self.next_opcode_location(); - let end_label = self.emit_opcode_with_operand(Opcode::LabelledStart); self.push_labelled_control_info(labelled.label(), labelled_loc, use_expr); match labelled.item() { @@ -38,8 +34,6 @@ impl ByteCompiler<'_, '_> { } } - let labelled_end = self.next_opcode_location(); - self.patch_jump_with_target(end_label, labelled_end); self.pop_labelled_control_info(); } } diff --git a/boa_engine/src/bytecompiler/statement/loop.rs b/boa_engine/src/bytecompiler/statement/loop.rs index 79630e18294..195e081602f 100644 --- a/boa_engine/src/bytecompiler/statement/loop.rs +++ b/boa_engine/src/bytecompiler/statement/loop.rs @@ -104,7 +104,6 @@ impl ByteCompiler<'_, '_> { if env_labels.is_some() { self.emit_opcode(Opcode::PopEnvironment); } - self.emit_opcode(Opcode::LoopEnd); if let Some(env_labels) = env_labels { let env_index = self.pop_compile_environment(); @@ -233,7 +232,6 @@ impl ByteCompiler<'_, '_> { self.patch_jump(exit); self.pop_loop_control_info(); - self.emit_opcode(Opcode::LoopEnd); self.iterator_close(false); @@ -379,7 +377,6 @@ impl ByteCompiler<'_, '_> { self.patch_jump(exit); self.pop_loop_control_info(); - self.emit_opcode(Opcode::LoopEnd); self.iterator_close(for_of_loop.r#await()); } @@ -404,7 +401,6 @@ impl ByteCompiler<'_, '_> { self.patch_jump(exit); self.pop_loop_control_info(); - self.emit_opcode(Opcode::LoopEnd); } pub(crate) fn compile_do_while_loop( @@ -433,6 +429,5 @@ impl ByteCompiler<'_, '_> { self.patch_jump(exit); self.pop_loop_control_info(); - self.emit_opcode(Opcode::LoopEnd); } } diff --git a/boa_engine/src/bytecompiler/statement/switch.rs b/boa_engine/src/bytecompiler/statement/switch.rs index 65e57a33a44..6fd0ccaf3cd 100644 --- a/boa_engine/src/bytecompiler/statement/switch.rs +++ b/boa_engine/src/bytecompiler/statement/switch.rs @@ -51,7 +51,6 @@ impl ByteCompiler<'_, '_> { } self.pop_switch_control_info(); - self.emit_opcode(Opcode::LoopEnd); let env_index = self.pop_compile_environment(); self.patch_jump_with_target(push_env, env_index); diff --git a/boa_engine/src/bytecompiler/statement/try.rs b/boa_engine/src/bytecompiler/statement/try.rs index c5d1fb11f2f..1909bb0376f 100644 --- a/boa_engine/src/bytecompiler/statement/try.rs +++ b/boa_engine/src/bytecompiler/statement/try.rs @@ -1,5 +1,5 @@ use crate::{ - bytecompiler::{jump_control::JumpControlInfoFlags, ByteCompiler, Label}, + bytecompiler::{jump_control::JumpControlInfoFlags, ByteCompiler}, vm::{BindingOpcode, Opcode}, }; use boa_ast::{ @@ -25,6 +25,7 @@ impl ByteCompiler<'_, '_> { self.emit_opcode(Opcode::TryEnd); + // TODO: simplify when there is finally but no catch. if has_finally { self.emit_opcode(Opcode::PushZero); if has_catch { @@ -50,7 +51,6 @@ impl ByteCompiler<'_, '_> { // Pop and push control loops post FinallyStart, as FinallyStart resets flow control variables. // Handle finally header operations let finally_start = self.next_opcode_location(); - let finally_end = self.emit_opcode_with_operand(Opcode::FinallyStart); self.jump_info .last_mut() @@ -58,7 +58,7 @@ impl ByteCompiler<'_, '_> { .flags |= JumpControlInfoFlags::IN_FINALLY; self.patch_jump_with_target(finally_loc, finally_start); // Compile finally statement body - self.compile_finally_stmt(finally, finally_end, has_catch); + self.compile_finally_stmt(finally, has_catch); self.pop_try_control_info(finally_start); } else { @@ -103,12 +103,7 @@ impl ByteCompiler<'_, '_> { } } - pub(crate) fn compile_finally_stmt( - &mut self, - finally: &Finally, - finally_end_label: Label, - has_catch: bool, - ) { + pub(crate) fn compile_finally_stmt(&mut self, finally: &Finally, has_catch: bool) { // TODO: We could probably remove the Get/SetReturnValue if we check that there is no break/continues statements. self.emit_opcode(Opcode::GetReturnValue); self.compile_block(finally.block(), true); @@ -122,7 +117,5 @@ impl ByteCompiler<'_, '_> { // Rethrow error if error happend! self.emit_opcode(Opcode::ReThrow); self.patch_jump(has_throw_exit); - - self.patch_jump(finally_end_label); } } diff --git a/boa_engine/src/vm/code_block.rs b/boa_engine/src/vm/code_block.rs index 8bca6192c13..9a876db1a84 100644 --- a/boa_engine/src/vm/code_block.rs +++ b/boa_engine/src/vm/code_block.rs @@ -315,8 +315,6 @@ impl CodeBlock { | Opcode::JumpIfFalse | Opcode::JumpIfNotUndefined | Opcode::JumpIfNullOrUndefined - | Opcode::FinallyStart - | Opcode::LabelledStart | Opcode::Case | Opcode::Default | Opcode::LogicalAnd @@ -346,11 +344,6 @@ impl CodeBlock { *pc += size_of::(); format!("{operand1}, {operand2}") } - Opcode::Break | Opcode::Continue => { - let operand = self.read::(*pc); - *pc += size_of::(); - format!("{operand}") - } Opcode::TemplateLookup | Opcode::TemplateCreate => { let operand1 = self.read::(*pc); *pc += size_of::(); @@ -535,11 +528,9 @@ impl CodeBlock { | Opcode::Super | Opcode::Return | Opcode::PopEnvironment - | Opcode::LoopEnd | Opcode::LoopContinue | Opcode::LoopStart | Opcode::IteratorLoopStart - | Opcode::LabelledEnd | Opcode::CreateForInIterator | Opcode::GetIterator | Opcode::GetAsyncIterator @@ -637,7 +628,13 @@ impl CodeBlock { | Opcode::Reserved51 | Opcode::Reserved52 | Opcode::Reserved53 - | Opcode::Reserved54 => unreachable!("Reserved opcodes are unrechable"), + | Opcode::Reserved54 + | Opcode::Reserved55 + | Opcode::Reserved56 + | Opcode::Reserved57 + | Opcode::Reserved58 + | Opcode::Reserved59 + | Opcode::Reserved60 => unreachable!("Reserved opcodes are unrechable"), } } } diff --git a/boa_engine/src/vm/flowgraph/mod.rs b/boa_engine/src/vm/flowgraph/mod.rs index 04f3032064e..6cb70fc9008 100644 --- a/boa_engine/src/vm/flowgraph/mod.rs +++ b/boa_engine/src/vm/flowgraph/mod.rs @@ -130,14 +130,6 @@ impl CodeBlock { EdgeStyle::Line, ); } - Opcode::LabelledStart => { - let end_address = self.read::(pc); - pc += size_of::(); - - let label = format!("{opcode_str} {end_address}"); - graph.add_node(previous_pc, NodeShape::None, label.into(), Color::Red); - graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line); - } Opcode::TemplateLookup | Opcode::TemplateCreate => { let start_address = self.read::(pc); pc += size_of::(); @@ -148,34 +140,6 @@ impl CodeBlock { graph.add_node(previous_pc, NodeShape::None, label.into(), Color::Red); graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line); } - Opcode::Break => { - let jump_operand = self.read::(pc); - pc += size_of::(); - - let label = format!("{opcode_str} {jump_operand}"); - graph.add_node(previous_pc, NodeShape::None, label.into(), Color::Red); - graph.add_edge( - previous_pc, - jump_operand as usize, - Some("BREAK".into()), - Color::Red, - EdgeStyle::Line, - ); - } - Opcode::Continue => { - let jump_operand = self.read::(pc); - pc += size_of::(); - - let label = format!("{opcode_str} {jump_operand}"); - graph.add_node(previous_pc, NodeShape::None, label.into(), Color::Red); - graph.add_edge( - previous_pc, - jump_operand as usize, - Some("CONTINUE".into()), - Color::Red, - EdgeStyle::Line, - ); - } Opcode::LogicalAnd | Opcode::LogicalOr | Opcode::Coalesce => { let exit = self.read::(pc); pc += size_of::(); @@ -272,8 +236,7 @@ impl CodeBlock { | Opcode::Call | Opcode::New | Opcode::SuperCall - | Opcode::ConcatToString - | Opcode::FinallyStart => { + | Opcode::ConcatToString => { pc += size_of::(); graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None); graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line); @@ -580,11 +543,9 @@ impl CodeBlock { | Opcode::ToBoolean | Opcode::This | Opcode::Super - | Opcode::LoopEnd | Opcode::LoopContinue | Opcode::LoopStart | Opcode::IteratorLoopStart - | Opcode::LabelledEnd | Opcode::CreateForInIterator | Opcode::GetIterator | Opcode::GetAsyncIterator @@ -707,7 +668,13 @@ impl CodeBlock { | Opcode::Reserved51 | Opcode::Reserved52 | Opcode::Reserved53 - | Opcode::Reserved54 => unreachable!("Reserved opcodes are unrechable"), + | Opcode::Reserved54 + | Opcode::Reserved55 + | Opcode::Reserved56 + | Opcode::Reserved57 + | Opcode::Reserved58 + | Opcode::Reserved59 + | Opcode::Reserved60 => unreachable!("Reserved opcodes are unrechable"), } } diff --git a/boa_engine/src/vm/opcode/control_flow/break.rs b/boa_engine/src/vm/opcode/control_flow/break.rs deleted file mode 100644 index 7627551b12c..00000000000 --- a/boa_engine/src/vm/opcode/control_flow/break.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::{ - vm::{opcode::Operation, CompletionType}, - Context, JsResult, -}; - -/// `Break` implements the Opcode Operation for `Opcode::Break` -/// -/// Operation: -/// - Pop required environments and jump to address. -pub(crate) struct Break; - -impl Operation for Break { - const NAME: &'static str = "Break"; - const INSTRUCTION: &'static str = "INST - Break"; - - fn execute(context: &mut Context<'_>) -> JsResult { - let jump_address = context.vm.read::(); - - // 3. Set program counter and finally return fields. - context.vm.frame_mut().pc = jump_address; - Ok(CompletionType::Normal) - } -} diff --git a/boa_engine/src/vm/opcode/control_flow/continue.rs b/boa_engine/src/vm/opcode/control_flow/continue.rs deleted file mode 100644 index c365c62dc73..00000000000 --- a/boa_engine/src/vm/opcode/control_flow/continue.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::{ - vm::{opcode::Operation, CompletionType}, - Context, JsResult, -}; - -/// `Continue` implements the Opcode Operation for `Opcode::Continue` -/// -/// Operands: -/// - Target address -/// - Initial environments to reconcile on continue (will be tracked along with changes to environment stack) -/// -/// Operation: -/// - Initializes the `AbruptCompletionRecord` for a delayed continued in a `Opcode::FinallyEnd` -pub(crate) struct Continue; - -impl Operation for Continue { - const NAME: &'static str = "Continue"; - const INSTRUCTION: &'static str = "INST - Continue"; - - fn execute(context: &mut Context<'_>) -> JsResult { - let jump_address = context.vm.read::(); - - context.vm.frame_mut().pc = jump_address; - Ok(CompletionType::Normal) - } -} diff --git a/boa_engine/src/vm/opcode/control_flow/finally.rs b/boa_engine/src/vm/opcode/control_flow/finally.rs deleted file mode 100644 index aa0273530ab..00000000000 --- a/boa_engine/src/vm/opcode/control_flow/finally.rs +++ /dev/null @@ -1,139 +0,0 @@ -use crate::{ - vm::{opcode::Operation, CompletionType}, - Context, JsResult, -}; - -/// `FinallyStart` implements the Opcode Operation for `Opcode::FinallyStart` -/// -/// Operation: -/// - Start of a finally block. -#[derive(Debug, Clone, Copy)] -pub(crate) struct FinallyStart; - -impl Operation for FinallyStart { - const NAME: &'static str = "FinallyStart"; - const INSTRUCTION: &'static str = "INST - FinallyStart"; - - fn execute(context: &mut Context<'_>) -> JsResult { - let _exit = context.vm.read::(); - Ok(CompletionType::Normal) - } -} - -/// `FinallyEnd` implements the Opcode Operation for `Opcode::FinallyEnd` -/// -/// Operation: -/// - End of a finally block. -#[derive(Debug, Clone, Copy)] -pub(crate) struct FinallyEnd; - -impl Operation for FinallyEnd { - const NAME: &'static str = "FinallyEnd"; - const INSTRUCTION: &'static str = "INST - FinallyEnd"; - - fn execute(_context: &mut Context<'_>) -> JsResult { - // let finally_candidates = context - // .vm - // .frame() - // .env_stack - // .iter() - // .filter(|env| env.is_finally_env() && context.vm.frame().pc < env.start_address()); - - // let next_finally = match finally_candidates.last() { - // Some(env) => env.start_address(), - // _ => u32::MAX, - // }; - - // let mut envs_to_pop = 0; - // match context.vm.frame().abrupt_completion { - // Some(record) if next_finally < record.target() => { - // context.vm.frame_mut().pc = next_finally; - - // while let Some(env_entry) = context.vm.frame().env_stack.last() { - // if next_finally <= env_entry.exit_address() { - // break; - // } - - // envs_to_pop += env_entry.env_num(); - // context.vm.frame_mut().env_stack.pop(); - // } - - // let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop); - // context.vm.environments.truncate(env_truncation_len); - // } - // Some(record) if record.is_break() && context.vm.frame().pc < record.target() => { - // // handle the continuation of an abrupt break. - // context.vm.frame_mut().pc = record.target(); - // while let Some(env_entry) = context.vm.frame().env_stack.last() { - // if record.target() == env_entry.exit_address() { - // break; - // } - - // envs_to_pop += env_entry.env_num(); - // context.vm.frame_mut().env_stack.pop(); - // } - - // context.vm.frame_mut().abrupt_completion = None; - - // let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop); - // context.vm.environments.truncate(env_truncation_len); - // } - // Some(record) if record.is_continue() && context.vm.frame().pc > record.target() => { - // // Handle the continuation of an abrupt continue - // context.vm.frame_mut().pc = record.target(); - // while let Some(env_entry) = context.vm.frame().env_stack.last() { - // if env_entry.start_address() == record.target() { - // break; - // } - // envs_to_pop += env_entry.env_num(); - // context.vm.frame_mut().env_stack.pop(); - // } - - - // context.vm.frame_mut().abrupt_completion = None; - // let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop); - // context.vm.environments.truncate(env_truncation_len); - // } - // Some(record) if record.is_return() => { - // return Ok(CompletionType::Return); - // } - // Some(record) - // if record.is_throw_with_target() && context.vm.frame().pc < record.target() => - // { - // context.vm.frame_mut().pc = record.target(); - // while let Some(env_entry) = context.vm.frame_mut().env_stack.pop() { - // envs_to_pop += env_entry.env_num(); - // if env_entry.start_address() == record.target() { - // break; - // } - // } - // context.vm.frame_mut().abrupt_completion = None; - // let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop); - // context.vm.environments.truncate(env_truncation_len); - // } - // Some(record) if !record.is_throw_with_target() => { - // let current_stack = context - // .vm - // .frame_mut() - // .env_stack - // .pop() - // .expect("Popping current finally stack."); - // let env_truncation_len = context - // .vm - // .environments - // .len() - // .saturating_sub(current_stack.env_num()); - // context.vm.environments.truncate(env_truncation_len); - - // let err = JsError::from_opaque(context.vm.pop()); - // context.vm.err = Some(err); - // return Ok(CompletionType::Throw); - // } - // _ => { - // context.vm.frame_mut().env_stack.pop(); - // } - // } - - Ok(CompletionType::Normal) - } -} diff --git a/boa_engine/src/vm/opcode/control_flow/labelled.rs b/boa_engine/src/vm/opcode/control_flow/labelled.rs deleted file mode 100644 index afc8e96d8be..00000000000 --- a/boa_engine/src/vm/opcode/control_flow/labelled.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::{ - vm::{opcode::Operation, CompletionType}, - Context, JsResult, -}; - -/// `LabelledStart` implements the Opcode Operation for `Opcode::LabelledStart` -/// -/// Operation: -/// - Start of a labelled block. -#[derive(Debug, Clone, Copy)] -pub(crate) struct LabelledStart; - -impl Operation for LabelledStart { - const NAME: &'static str = "LabelledStart"; - const INSTRUCTION: &'static str = "INST - LabelledStart"; - - fn execute(context: &mut Context<'_>) -> JsResult { - let _end = context.vm.read::(); - Ok(CompletionType::Normal) - } -} - -/// `LabelledEnd` implements the Opcode Operation for `Opcode::LabelledEnd` -/// -/// Operation: -/// - Clean up environments at the end of labelled block. -#[derive(Debug, Clone, Copy)] -pub(crate) struct LabelledEnd; - -impl Operation for LabelledEnd { - const NAME: &'static str = "LabelledEnd"; - const INSTRUCTION: &'static str = "INST - LabelledEnd"; - - fn execute(_context: &mut Context<'_>) -> JsResult { - Ok(CompletionType::Normal) - } -} diff --git a/boa_engine/src/vm/opcode/control_flow/mod.rs b/boa_engine/src/vm/opcode/control_flow/mod.rs index fa3a4d7637c..961180b0e10 100644 --- a/boa_engine/src/vm/opcode/control_flow/mod.rs +++ b/boa_engine/src/vm/opcode/control_flow/mod.rs @@ -1,15 +1,7 @@ -pub(crate) mod r#break; -pub(crate) mod r#continue; -pub(crate) mod finally; -pub(crate) mod labelled; pub(crate) mod r#return; pub(crate) mod throw; pub(crate) mod r#try; -pub(crate) use finally::*; -pub(crate) use labelled::*; -pub(crate) use r#break::*; -pub(crate) use r#continue::*; pub(crate) use r#return::*; pub(crate) use r#try::*; pub(crate) use throw::*; diff --git a/boa_engine/src/vm/opcode/mod.rs b/boa_engine/src/vm/opcode/mod.rs index bdeaf64865e..465464c0f53 100644 --- a/boa_engine/src/vm/opcode/mod.rs +++ b/boa_engine/src/vm/opcode/mod.rs @@ -1166,27 +1166,6 @@ generate_impl! { /// Stack: **=>** TryEnd, - /// Start of a finally block. - /// - /// Operands: - /// - /// Stack: **=>** - FinallyStart, - - /// Unconditional Jump - /// - /// Operands: Jump Address: u32 - /// - /// Stack: **=>** - Break, - - /// Unconditional Jump - /// - /// Operands: Jump Address: u32 - /// - /// Stack: **=>** - Continue, - /// Pops value converts it to boolean and pushes it back. /// /// Operands: @@ -1403,27 +1382,6 @@ generate_impl! { /// Stack: **=>** LoopContinue, - /// Clean up environments at the end of a loop and return it's value. - /// - /// Operands: - /// - /// Stack: **=>** value - LoopEnd, - - /// Push labelled start marker. - /// - /// Operands: Exit Address: u32, - /// - /// Stack: **=>** - LabelledStart, - - /// Clean up environments at the end of a labelled block. - /// - /// Operands: - /// - /// Stack: **=>** - LabelledEnd, - /// Creates the ForInIterator of an object. /// /// Stack: object **=>** @@ -1802,6 +1760,18 @@ generate_impl! { Reserved53 => Reserved, /// Reserved [`Opcode`]. Reserved54 => Reserved, + /// Reserved [`Opcode`]. + Reserved55 => Reserved, + /// Reserved [`Opcode`]. + Reserved56 => Reserved, + /// Reserved [`Opcode`]. + Reserved57 => Reserved, + /// Reserved [`Opcode`]. + Reserved58 => Reserved, + /// Reserved [`Opcode`]. + Reserved59 => Reserved, + /// Reserved [`Opcode`]. + Reserved60 => Reserved, } }