Browse Source

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

* Close iterator after generator return while array destructuring

* Add MaybeException opcode and remove handler check
pull/3187/head
Haled Odat 1 year ago committed by GitHub
parent
commit
2b01ef1c27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      boa_engine/src/bytecompiler/declaration/declaration_pattern.rs
  2. 4
      boa_engine/src/vm/code_block.rs
  3. 4
      boa_engine/src/vm/flowgraph/mod.rs
  4. 24
      boa_engine/src/vm/opcode/control_flow/throw.rs
  5. 11
      boa_engine/src/vm/opcode/mod.rs

10
boa_engine/src/bytecompiler/declaration/declaration_pattern.rs

@ -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;

4
boa_engine/src/vm/code_block.rs

@ -566,6 +566,7 @@ impl CodeBlock {
| Opcode::Throw
| Opcode::ReThrow
| Opcode::Exception
| Opcode::MaybeException
| Opcode::This
| Opcode::Super
| Opcode::Return
@ -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"),
}
}
}

4
boa_engine/src/vm/flowgraph/mod.rs

@ -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);
@ -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"),
}
}

24
boa_engine/src/vm/opcode/control_flow/throw.rs

@ -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:

11
boa_engine/src/vm/opcode/mod.rs

@ -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`].
@ -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
@ -1764,8 +1771,6 @@ generate_impl! {
Reserved62 => Reserved,
/// Reserved [`Opcode`].
Reserved63 => Reserved,
/// Reserved [`Opcode`].
Reserved64 => Reserved,
}
}

Loading…
Cancel
Save