Skip to content

Commit

Permalink
Fix jump bug
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Mar 21, 2023
1 parent 1acfa2c commit 7ccf1b6
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 33 deletions.
9 changes: 4 additions & 5 deletions boa_engine/src/bytecompiler/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,14 @@ impl ByteCompiler<'_, '_> {
self.patch_jump(start);
} else if self.in_async_generator {
self.emit_opcode(Opcode::Await);
self.emit_opcode(Opcode::AsyncGeneratorNext);
let jump_return = self.emit_opcode_with_operand(Opcode::JumpIfFalse);
let jump = self.emit_opcode_with_operand(Opcode::JumpIfFalse);
let (skip_yield, skip_yield_await) =
self.emit_opcode_with_two_operands(Opcode::AsyncGeneratorNext);
self.emit_opcode(Opcode::Yield);
self.emit_opcode(Opcode::GeneratorNext);
self.patch_jump(jump);
self.patch_jump(skip_yield);
self.emit_opcode(Opcode::Await);
self.emit_opcode(Opcode::GeneratorNext);
self.patch_jump(jump_return);
self.patch_jump(skip_yield_await);
} else {
self.emit_opcode(Opcode::Yield);
self.emit_opcode(Opcode::GeneratorNext);
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use indoc::indoc;
mod control_flow;
mod function;
mod operators;
mod spread;
mod promise;
mod spread;

use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction};

Expand Down
32 changes: 17 additions & 15 deletions boa_engine/src/tests/promise.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use indoc::indoc;

use crate::{job::SimpleJobQueue, Context, run_test_actions_with, TestAction};
use crate::{job::SimpleJobQueue, run_test_actions_with, Context, TestAction};

#[test]
#[allow(clippy::redundant_closure_for_method_calls)]
fn issue_2658() {
let queue = &SimpleJobQueue::new();
let context = &mut Context::builder().job_queue(queue).build().unwrap();
run_test_actions_with([
TestAction::run(
indoc! {
run_test_actions_with(
[
TestAction::run(indoc! {
r#"
let result1;
let result2;
Expand All @@ -29,15 +30,16 @@ fn issue_2658() {
}
};
const genTwo = agf(iterTwo);
genTwo.next().then(v => { console.log(v) });
genTwo.next().then(v => { console.log(v) });
genTwo.next().then(v => { result1 = v; });
genTwo.next().then(v => { result2 = v; });
"#
}
),
TestAction::inspect_context(|ctx| ctx.run_jobs()),
TestAction::assert("!result1.done"),
TestAction::assert_eq("result1.value", 5),
TestAction::assert("!result2.done"),
TestAction::assert_eq("result2.value", 5),
], context)
}
}),
TestAction::inspect_context(|ctx| ctx.run_jobs()),
TestAction::assert("!result1.done"),
TestAction::assert_eq("result1.value", 5),
TestAction::assert("!result2.done"),
TestAction::assert_eq("result2.value", 5),
],
context,
);
}
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 @@ -264,7 +264,8 @@ impl CodeBlock {
| Opcode::Continue
| Opcode::LoopContinue
| Opcode::LoopStart
| Opcode::TryStart => {
| Opcode::TryStart
| Opcode::AsyncGeneratorNext => {
let operand1 = self.read::<u32>(*pc);
*pc += size_of::<u32>();
let operand2 = self.read::<u32>(*pc);
Expand Down Expand Up @@ -436,7 +437,6 @@ impl CodeBlock {
| Opcode::PopOnReturnSub
| Opcode::Yield
| Opcode::GeneratorNext
| Opcode::AsyncGeneratorNext
| Opcode::PushClassField
| Opcode::SuperCallDerived
| Opcode::Await
Expand Down
24 changes: 23 additions & 1 deletion boa_engine/src/vm/flowgraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,29 @@ impl CodeBlock {
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
}
Opcode::AsyncGeneratorNext => {
let skip_yield = self.read::<u32>(pc);
pc += size_of::<u32>();
let skip_yield_await = self.read::<u32>(pc);
pc += size_of::<u32>();
graph.add_node(previous_pc, NodeShape::None, opcode_str.into(), Color::None);

graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
graph.add_edge(
previous_pc,
skip_yield as usize,
Some("return value pending".into()),
Color::None,
EdgeStyle::Line,
);
graph.add_edge(
previous_pc,
skip_yield_await as usize,
Some("yield value pending".into()),
Color::None,
EdgeStyle::Line,
);
}
Opcode::TryStart => {
let next_address = self.read::<u32>(pc);
pc += size_of::<u32>();
Expand Down Expand Up @@ -494,7 +517,6 @@ impl CodeBlock {
| Opcode::PopOnReturnSub
| Opcode::Yield
| Opcode::GeneratorNext
| Opcode::AsyncGeneratorNext
| Opcode::PushClassField
| Opcode::SuperCallDerived
| Opcode::Await
Expand Down
6 changes: 5 additions & 1 deletion boa_engine/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,11 @@ impl Context<'_> {
return CompletionRecord::Normal(result);
}
EarlyReturnType::Yield => {
let result = self.vm.stack.pop().unwrap_or(JsValue::Undefined);
let result = self
.vm
.stack
.pop()
.expect("Yield must always return a result.");
self.vm.frame_mut().early_return = None;
return CompletionRecord::Return(result);
}
Expand Down
11 changes: 5 additions & 6 deletions boa_engine/src/vm/opcode/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ impl Operation for AsyncGeneratorNext {
const INSTRUCTION: &'static str = "INST - AsyncGeneratorNext";

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let skip_yield = context.vm.read::<u32>();
let skip_yield_await = context.vm.read::<u32>();

if context.vm.frame().generator_resume_kind == GeneratorResumeKind::Throw {
return Err(JsError::from_opaque(context.vm.pop()));
}
Expand Down Expand Up @@ -104,17 +107,13 @@ impl Operation for AsyncGeneratorNext {
Err(e) => e.clone().to_opaque(context),
};
context.vm.push(value);
context.vm.push(true);
context.vm.frame_mut().pc = skip_yield as usize;
} else {
context.vm.push(completion.clone()?);
context.vm.push(false);
context.vm.frame_mut().pc = skip_yield_await as usize;
}

context.vm.push(false);
} else {
gen.state = AsyncGeneratorState::SuspendedYield;
context.vm.push(true);
context.vm.push(true);
}
Ok(CompletionType::Normal)
}
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/opcode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,9 +1499,9 @@ generate_impl! {

/// Resumes the current generator function.
///
/// Operands:
/// Operands: skip_yield: u32, skip_yield_await: u32
///
/// Stack: received **=>** `Option<value>`, skip_0, skip_1
/// Stack: received **=>** `Option<value>`
AsyncGeneratorNext,

/// Delegates the current generator function to another generator.
Expand Down

0 comments on commit 7ccf1b6

Please sign in to comment.