@@ -1782,6 +1782,12 @@ static void generate_yield(Bytecode::Generator& generator,
1782
1782
1783
1783
Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::generate_bytecode (Bytecode::Generator& generator, [[maybe_unused]] Optional<Bytecode::Operand> preferred_dst) const
1784
1784
{
1785
+ // Note: We need to catch any scheduled exceptions and reschedule them on re-entry
1786
+ // as the act of yielding would otherwise clear them out
1787
+ // This only applies when we are in a finalizer
1788
+ bool is_in_finalizer = generator.is_in_finalizer ();
1789
+ Optional<Bytecode::Register> saved_exception;
1790
+
1785
1791
Bytecode::Generator::SourceLocationScope scope (generator, *this );
1786
1792
VERIFY (generator.is_in_generator_function ());
1787
1793
@@ -1890,6 +1896,11 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::ge
1890
1896
auto current_value = Bytecode::Operand (generator.allocate_register ());
1891
1897
generator.emit_iterator_value (current_value, inner_result);
1892
1898
1899
+ if (is_in_finalizer) {
1900
+ saved_exception = generator.allocate_register ();
1901
+ generator.emit <Bytecode::Op::Mov>(Bytecode::Operand (*saved_exception), Bytecode::Operand (Bytecode::Register::exception ()));
1902
+ }
1903
+
1893
1904
generate_yield (generator,
1894
1905
Bytecode::Label { continuation_block },
1895
1906
current_value,
@@ -2077,6 +2088,10 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::ge
2077
2088
generate_yield (generator, Bytecode::Label { continuation_block }, received, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier, AwaitBeforeYield::No);
2078
2089
2079
2090
generator.switch_to_basic_block (continuation_block);
2091
+
2092
+ if (is_in_finalizer)
2093
+ generator.emit <Bytecode::Op::Mov>(Bytecode::Operand (Bytecode::Register::exception ()), Bytecode::Operand (*saved_exception));
2094
+
2080
2095
generator.emit <Bytecode::Op::Mov>(received_completion, Bytecode::Operand (Bytecode::Register (0 )));
2081
2096
get_received_completion_type_and_value (generator, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier);
2082
2097
generator.emit <Bytecode::Op::Jump>(Bytecode::Label { loop_block });
@@ -2092,8 +2107,18 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::ge
2092
2107
argument = generator.add_constant (js_undefined ());
2093
2108
2094
2109
auto & continuation_block = generator.make_block ();
2110
+
2111
+ if (is_in_finalizer) {
2112
+ saved_exception = generator.allocate_register ();
2113
+ generator.emit <Bytecode::Op::Mov>(Bytecode::Operand (*saved_exception), Bytecode::Operand (Bytecode::Register::exception ()));
2114
+ }
2115
+
2095
2116
generate_yield (generator, Bytecode::Label { continuation_block }, *argument, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier, AwaitBeforeYield::Yes);
2096
2117
generator.switch_to_basic_block (continuation_block);
2118
+
2119
+ if (is_in_finalizer)
2120
+ generator.emit <Bytecode::Op::Mov>(Bytecode::Operand (Bytecode::Register::exception ()), Bytecode::Operand (*saved_exception));
2121
+
2097
2122
generator.emit <Bytecode::Op::Mov>(received_completion, Bytecode::Operand (Bytecode::Register (0 )));
2098
2123
get_received_completion_type_and_value (generator, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier);
2099
2124
@@ -2190,9 +2215,6 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> IfStatement::genera
2190
2215
Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> ContinueStatement::generate_bytecode (Bytecode::Generator& generator, [[maybe_unused]] Optional<Bytecode::Operand> preferred_dst) const
2191
2216
{
2192
2217
Bytecode::Generator::SourceLocationScope scope (generator, *this );
2193
- // FIXME: Handle finally blocks in a graceful manner
2194
- // We need to execute the finally block, but tell it to resume
2195
- // execution at the designated block
2196
2218
if (!m_target_label.has_value ()) {
2197
2219
generator.generate_continue ();
2198
2220
return Optional<Bytecode::Operand> {};
0 commit comments