Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close iterator after generator return call while array destructuring assignment #3164

Merged
merged 2 commits into from
Jul 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions boa_engine/src/bytecompiler/declaration/declaration_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,15 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::ValueNotNullOrUndefined);
self.emit_opcode(Opcode::GetIterator);

// TODO: maybe, refactor this to be more condensed.
let handler_index = self.push_handler();
for element in pattern.bindings() {
self.compile_array_pattern_element(element, def);
}

self.emit_opcode(Opcode::PushFalse);

let exit = self.jump();
self.patch_handler(handler_index);
self.emit_opcode(Opcode::Exception);
self.emit_opcode(Opcode::PushTrue);
self.patch_jump(exit);
self.emit_opcode(Opcode::MaybeException);

// stack: hasPending, exception?

self.current_stack_value_count += 2;

Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ impl CodeBlock {
| Opcode::Throw
| Opcode::ReThrow
| Opcode::Exception
| Opcode::MaybeException
| Opcode::This
| Opcode::Super
| Opcode::Return
Expand Down Expand Up @@ -677,8 +678,7 @@ impl CodeBlock {
| Opcode::Reserved60
| Opcode::Reserved61
| Opcode::Reserved62
| Opcode::Reserved63
| Opcode::Reserved64 => unreachable!("Reserved opcodes are unrechable"),
| Opcode::Reserved63 => unreachable!("Reserved opcodes are unrechable"),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/flowgraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ impl CodeBlock {
| Opcode::GetReturnValue
| Opcode::SetReturnValue
| Opcode::Exception
| Opcode::MaybeException
| Opcode::Nop => {
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
Expand Down Expand Up @@ -606,8 +607,7 @@ impl CodeBlock {
| Opcode::Reserved60
| Opcode::Reserved61
| Opcode::Reserved62
| Opcode::Reserved63
| Opcode::Reserved64 => unreachable!("Reserved opcodes are unrechable"),
| Opcode::Reserved63 => unreachable!("Reserved opcodes are unrechable"),
}
}

Expand Down
24 changes: 24 additions & 0 deletions boa_engine/src/vm/opcode/control_flow/throw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@ impl Operation for Exception {
}
}

/// `MaybeException` implements the Opcode Operation for `Opcode::MaybeException`
///
/// Operation:
/// - Get the thrown pending exception if it's set and push `true`, otherwise push only `false`.
#[derive(Debug, Clone, Copy)]
pub(crate) struct MaybeException;

impl Operation for MaybeException {
const NAME: &'static str = "MaybeException";
const INSTRUCTION: &'static str = "INST - MaybeException";

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
if let Some(error) = context.vm.pending_exception.take() {
let error = error.to_opaque(context);
context.vm.push(error);
context.vm.push(true);
return Ok(CompletionType::Normal);
}

context.vm.push(false);
Ok(CompletionType::Normal)
}
}

/// `ThrowNewTypeError` implements the Opcode Operation for `Opcode::ThrowNewTypeError`
///
/// Operation:
Expand Down
11 changes: 8 additions & 3 deletions boa_engine/src/vm/opcode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,7 @@ generate_impl! {
/// Stack: **=>**
ReThrow,

/// Get the thrown pending exception and push on the stack.
/// Get the thrown pending exception (if it's set) and push on the stack.
///
/// If there is no pending exception, which can happend if we are handling `return()` call on generator,
/// then we rethrow the empty exception. See [`Opcode::ReThrow`].
Expand All @@ -1157,6 +1157,13 @@ generate_impl! {
/// Stack: **=>** exception
Exception,

/// Get the thrown pending exception if it's set and push `true`, otherwise push only `false`.
///
/// Operands:
///
/// Stack: **=>** (`true`, exception) or `false`
MaybeException,

/// Throw a new `TypeError` exception
///
/// Operands: message: u32
Expand Down Expand Up @@ -1764,8 +1771,6 @@ generate_impl! {
Reserved62 => Reserved,
/// Reserved [`Opcode`].
Reserved63 => Reserved,
/// Reserved [`Opcode`].
Reserved64 => Reserved,
}
}

Expand Down