mirror of https://github.com/boa-dev/boa.git
Haled Odat
1 year ago
committed by
GitHub
30 changed files with 314 additions and 633 deletions
@ -1,33 +1,18 @@
|
||||
use crate::{bytecompiler::ByteCompiler, vm::Opcode}; |
||||
use boa_ast::{operations::returns_value, statement::If}; |
||||
use crate::bytecompiler::ByteCompiler; |
||||
use boa_ast::statement::If; |
||||
|
||||
impl ByteCompiler<'_, '_> { |
||||
pub(crate) fn compile_if(&mut self, node: &If, use_expr: bool) { |
||||
self.compile_expr(node.cond(), true); |
||||
let jelse = self.jump_if_false(); |
||||
|
||||
if !returns_value(node.body()) { |
||||
self.emit_opcode(Opcode::PushUndefined); |
||||
} |
||||
self.compile_stmt(node.body(), true); |
||||
self.compile_stmt(node.body(), use_expr, true); |
||||
|
||||
let exit = self.jump(); |
||||
self.patch_jump(jelse); |
||||
match node.else_node() { |
||||
None => { |
||||
self.emit_opcode(Opcode::PushUndefined); |
||||
} |
||||
Some(else_body) => { |
||||
if !returns_value(else_body) { |
||||
self.emit_opcode(Opcode::PushUndefined); |
||||
} |
||||
self.compile_stmt(else_body, true); |
||||
} |
||||
if let Some(else_body) = node.else_node() { |
||||
self.compile_stmt(else_body, use_expr, true); |
||||
} |
||||
self.patch_jump(exit); |
||||
|
||||
if !use_expr { |
||||
self.emit_opcode(Opcode::Pop); |
||||
} |
||||
} |
||||
} |
||||
|
@ -1,91 +0,0 @@
|
||||
use crate::{ |
||||
vm::{call_frame::EnvStackEntry, opcode::Operation, CompletionType}, |
||||
Context, JsResult, |
||||
}; |
||||
|
||||
/// `CatchStart` implements the Opcode Operation for `Opcode::CatchStart`
|
||||
///
|
||||
/// Operation:
|
||||
/// - Start of a catch block.
|
||||
#[derive(Debug, Clone, Copy)] |
||||
pub(crate) struct CatchStart; |
||||
|
||||
impl Operation for CatchStart { |
||||
const NAME: &'static str = "CatchStart"; |
||||
const INSTRUCTION: &'static str = "INST - CatchStart"; |
||||
|
||||
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> { |
||||
let start = context.vm.frame().pc - 1; |
||||
let finally = context.vm.read::<u32>(); |
||||
|
||||
context |
||||
.vm |
||||
.frame_mut() |
||||
.env_stack |
||||
.push(EnvStackEntry::new(start, finally - 1).with_catch_flag()); |
||||
|
||||
context.vm.frame_mut().abrupt_completion = None; |
||||
Ok(CompletionType::Normal) |
||||
} |
||||
} |
||||
|
||||
/// `CatchEnd` implements the Opcode Operation for `Opcode::CatchEnd`
|
||||
///
|
||||
/// Operation:
|
||||
/// - End of a catch block.
|
||||
#[derive(Debug, Clone, Copy)] |
||||
pub(crate) struct CatchEnd; |
||||
|
||||
impl Operation for CatchEnd { |
||||
const NAME: &'static str = "CatchEnd"; |
||||
const INSTRUCTION: &'static str = "INST - CatchEnd"; |
||||
|
||||
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> { |
||||
let mut envs_to_pop = 0_usize; |
||||
while let Some(env_entry) = context.vm.frame_mut().env_stack.pop() { |
||||
envs_to_pop += env_entry.env_num(); |
||||
|
||||
if env_entry.is_catch_env() { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop); |
||||
context.vm.environments.truncate(env_truncation_len); |
||||
|
||||
Ok(CompletionType::Normal) |
||||
} |
||||
} |
||||
|
||||
/// `CatchEnd2` implements the Opcode Operation for `Opcode::CatchEnd2`
|
||||
///
|
||||
/// Operation:
|
||||
/// - End of a catch block
|
||||
#[derive(Debug, Clone, Copy)] |
||||
pub(crate) struct CatchEnd2; |
||||
|
||||
impl Operation for CatchEnd2 { |
||||
const NAME: &'static str = "CatchEnd2"; |
||||
const INSTRUCTION: &'static str = "INST - CatchEnd2"; |
||||
|
||||
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> { |
||||
if let Some(catch_entry) = context |
||||
.vm |
||||
.frame() |
||||
.env_stack |
||||
.last() |
||||
.filter(|entry| entry.is_catch_env()) |
||||
{ |
||||
let env_truncation_len = context |
||||
.vm |
||||
.environments |
||||
.len() |
||||
.saturating_sub(catch_entry.env_num()); |
||||
context.vm.environments.truncate(env_truncation_len); |
||||
|
||||
context.vm.frame_mut().env_stack.pop(); |
||||
} |
||||
|
||||
Ok(CompletionType::Normal) |
||||
} |
||||
} |
Loading…
Reference in new issue