Skip to content

Commit

Permalink
fix(es/compat): Fix finally handling of generator (#7215)
Browse files Browse the repository at this point in the history
**Description:**

Update generator implementation to match
https://github.com/microsoft/TypeScript/blob/e83d61398ea0e4231e882121dd6c6bcfe4fdc9e4/src/compiler/transformers/generators.ts

**Related issue:**

 - Closes #5913.
  • Loading branch information
kdy1 committed Apr 6, 2023
1 parent 150e54d commit f5c62fb
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 210 deletions.
50 changes: 47 additions & 3 deletions crates/swc_ecma_transforms_compat/src/es2015/generator.rs
Expand Up @@ -37,6 +37,16 @@ struct Wrapper {
unresolved_ctxt: SyntaxContext,
}

macro_rules! dev_span {
($($tt:tt)*) => {{
if cfg!(debug_assertions) {
Some(tracing::span!(tracing::Level::ERROR, $($tt)*).entered())
} else {
None
}
}};
}

impl VisitMut for Wrapper {
noop_visit_mut_type!();

Expand Down Expand Up @@ -338,7 +348,7 @@ struct Generator {
clauses: Option<Vec<SwitchCase>>,
stmts: Option<Vec<Stmt>>,
/// Index to `blocks`
exception_block_stack: Vec<Ptr<CodeBlock>>,
exception_block_stack: Option<Vec<Ptr<CodeBlock>>>,
/// Index to `blocks`
current_exception_block: Option<Ptr<CodeBlock>>,
/// Index to `blocks`
Expand Down Expand Up @@ -1425,6 +1435,8 @@ impl Generator {
}

fn transform_and_emit_stmt(&mut self, node: Stmt) {
let _tracing = dev_span!("transform_and_emit_stmt");

let saved_in_statement_containing_yield = self.in_statement_containing_yield;
if !self.in_statement_containing_yield {
self.in_statement_containing_yield = contains_yield(&node);
Expand Down Expand Up @@ -1608,6 +1620,8 @@ impl Generator {
}

fn transform_and_emit_while_stmt(&mut self, mut node: WhileStmt) {
let _tracing = dev_span!("transform_and_emit_while_stmt");

if contains_yield(&node) {
// [source]
// while (i < 10) {
Expand All @@ -1628,7 +1642,7 @@ impl Generator {
self.mark_label(loop_label);
node.test.visit_mut_with(self);
self.emit_break_when_false(end_label, node.test, None);
self.transform_and_emit_stmt(*node.body);
self.transform_and_emit_embedded_stmt(*node.body);
self.emit_break(loop_label, None);
self.end_loop_block();
} else {
Expand Down Expand Up @@ -2015,6 +2029,8 @@ impl Generator {
}

fn transform_and_emit_try_stmt(&mut self, mut node: TryStmt) {
let _tracing = dev_span!("transform_and_emit_try_stmt");

if contains_yield(&node) {
// [source]
// try {
Expand Down Expand Up @@ -2236,11 +2252,15 @@ impl Generator {
let b = block.borrow();
if let CodeBlock::With(block) = &*b {
self.mark_label(block.end_label);
} else {
unreachable!()
}
}

/// Begins a code block for a generated `try` statement.
fn begin_exception_block(&mut self) -> Label {
let _tracing = dev_span!("begin_exception_block");

let start_label = self.define_label();
let end_label = self.define_label();
self.mark_label(start_label);
Expand Down Expand Up @@ -2305,6 +2325,8 @@ impl Generator {

/// Enters the `finally` block of a generated `try` statement.
fn begin_finally_block(&mut self) {
let _tracing = dev_span!("begin_finally_block");

debug_assert!(self.peek_block_kind() == Some(CodeBlockKind::Exception));

let block = self.peek_block().unwrap();
Expand All @@ -2319,6 +2341,8 @@ impl Generator {
self.mark_label(finally_label);
block.state = ExceptionBlockState::Finally;
block.finally_label = Some(finally_label);
} else {
unreachable!()
}
}

Expand All @@ -2337,6 +2361,8 @@ impl Generator {
self.mark_label(block.end_label);
self.emit_nop();
block.state = ExceptionBlockState::Done;
} else {
unreachable!()
}
}

Expand All @@ -2357,6 +2383,8 @@ impl Generator {
/// - `continue_label`: A Label used to mark the operation to which to jump
/// when a `continue` statement targets this block.
fn begin_loop_block(&mut self, continue_label: Label) -> Label {
let _tracing = dev_span!("begin_loop_block");

let break_label = self.define_label();
self.begin_block(CodeBlock::Loop(LoopBlock {
is_script: false,
Expand All @@ -2377,6 +2405,8 @@ impl Generator {
if !block.is_script {
self.mark_label(break_label);
}
} else {
unreachable!()
}
}

Expand Down Expand Up @@ -2414,6 +2444,8 @@ impl Generator {
if !block.is_script {
self.mark_label(break_label);
}
} else {
unreachable!()
}
}

Expand Down Expand Up @@ -2469,6 +2501,8 @@ impl Generator {
if block.label_text == *label_text {
return true;
}
} else {
unreachable!()
}
} else {
break;
Expand Down Expand Up @@ -2542,6 +2576,9 @@ impl Generator {
fn create_label(&mut self, label: Option<Label>) -> Box<Expr> {
if let Some(label) = label {
if label.0 > 0 {
#[cfg(debug_assertions)]
debug!("create_label: label={:?}", label);

if self.label_exprs.is_none() {
self.label_exprs = Some(Default::default());
}
Expand Down Expand Up @@ -3079,13 +3116,20 @@ impl Generator {
CodeBlock::Exception(_) => {
if block_action == BlockAction::Open {
self.exception_block_stack
.get_or_insert_with(Default::default)
.extend(self.current_exception_block.clone());

// https://github.com/swc-project/swc/issues/5913
if self.stmts.is_none() {
self.stmts = Some(Default::default());
}

#[cfg(debug_assertions)]
debug!("Current exception block: open = Some({:?})", block);
self.current_exception_block = Some(block.clone());
} else if block_action == BlockAction::Close {
self.current_exception_block = self.exception_block_stack.pop();
self.current_exception_block =
self.exception_block_stack.as_mut().unwrap().pop();
#[cfg(debug_assertions)]
debug!(
"Current exception block: close = {:?}",
Expand Down
@@ -0,0 +1,39 @@
function* gen() {
var firstTime = true;
outer:
while (true) {
yield 0;
try {
while (true) {
yield 1;
if (firstTime) {
firstTime = false;
yield 2;
continue outer;
} else {
yield 3;
break;
}
}
yield 4;
break;
} finally {
yield 5;
}
yield 6;
}
yield 7;
}

const iter = gen();
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
@@ -0,0 +1,19 @@
function* generator() {
try {
while (true) {
yield "foo";
}
} finally {
yield "bar";
}
}

function test() {
const gen = generator();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
}

test();
@@ -0,0 +1,18 @@
function* generator() {
try {
while (true) {
yield "foo";
}
} finally {
}
}

function test() {
const gen = generator();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
}

test();

1 comment on commit f5c62fb

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: f5c62fb Previous: 29bf176 Ratio
es/full/bugs-1 297887 ns/iter (± 8273) 313216 ns/iter (± 19124) 0.95
es/full/minify/libraries/antd 1708675716 ns/iter (± 13080524) 1718337751 ns/iter (± 21939043) 0.99
es/full/minify/libraries/d3 321163144 ns/iter (± 5263550) 322602712 ns/iter (± 13295432) 1.00
es/full/minify/libraries/echarts 1299586608 ns/iter (± 17548868) 1301575524 ns/iter (± 7647533) 1.00
es/full/minify/libraries/jquery 94303220 ns/iter (± 1961968) 93505495 ns/iter (± 1963386) 1.01
es/full/minify/libraries/lodash 107963576 ns/iter (± 1454116) 109557504 ns/iter (± 2040503) 0.99
es/full/minify/libraries/moment 53652203 ns/iter (± 1210034) 53737654 ns/iter (± 487012) 1.00
es/full/minify/libraries/react 19886759 ns/iter (± 354004) 19356310 ns/iter (± 269376) 1.03
es/full/minify/libraries/terser 263167151 ns/iter (± 2630864) 261999112 ns/iter (± 5986185) 1.00
es/full/minify/libraries/three 473532528 ns/iter (± 12770710) 473190603 ns/iter (± 9015928) 1.00
es/full/minify/libraries/typescript 3179197425 ns/iter (± 10945685) 3157048692 ns/iter (± 29360778) 1.01
es/full/minify/libraries/victory 723331835 ns/iter (± 10793945) 710037195 ns/iter (± 10173852) 1.02
es/full/minify/libraries/vue 137598976 ns/iter (± 1870970) 135142259 ns/iter (± 2261328) 1.02
es/full/codegen/es3 28741 ns/iter (± 53) 28546 ns/iter (± 108) 1.01
es/full/codegen/es5 28885 ns/iter (± 39) 28539 ns/iter (± 77) 1.01
es/full/codegen/es2015 28753 ns/iter (± 73) 28559 ns/iter (± 67) 1.01
es/full/codegen/es2016 28808 ns/iter (± 57) 28633 ns/iter (± 53) 1.01
es/full/codegen/es2017 28858 ns/iter (± 52) 28583 ns/iter (± 60) 1.01
es/full/codegen/es2018 28818 ns/iter (± 50) 28598 ns/iter (± 107) 1.01
es/full/codegen/es2019 28775 ns/iter (± 75) 28581 ns/iter (± 55) 1.01
es/full/codegen/es2020 28829 ns/iter (± 35) 28604 ns/iter (± 56) 1.01
es/full/all/es3 183526999 ns/iter (± 2257301) 183341317 ns/iter (± 3307410) 1.00
es/full/all/es5 172080995 ns/iter (± 2643161) 170774806 ns/iter (± 3576268) 1.01
es/full/all/es2015 135003859 ns/iter (± 1594732) 135627928 ns/iter (± 2645015) 1.00
es/full/all/es2016 132372915 ns/iter (± 2447110) 134293127 ns/iter (± 1583264) 0.99
es/full/all/es2017 129660010 ns/iter (± 1942841) 131926852 ns/iter (± 2894526) 0.98
es/full/all/es2018 126265145 ns/iter (± 996973) 127290224 ns/iter (± 2445613) 0.99
es/full/all/es2019 125649432 ns/iter (± 2009867) 124988799 ns/iter (± 1867643) 1.01
es/full/all/es2020 118347273 ns/iter (± 1909621) 118626800 ns/iter (± 1678973) 1.00
es/full/parser 518673 ns/iter (± 9770) 519944 ns/iter (± 8497) 1.00
es/full/base/fixer 22450 ns/iter (± 36) 23908 ns/iter (± 44) 0.94
es/full/base/resolver_and_hygiene 84658 ns/iter (± 80) 86798 ns/iter (± 119) 0.98
serialization of serde 121 ns/iter (± 0) 121 ns/iter (± 0) 1
css/minify/libraries/bootstrap 28130545 ns/iter (± 135161) 28053072 ns/iter (± 96641) 1.00
css/visitor/compare/clone 2111513 ns/iter (± 9402) 2125911 ns/iter (± 13255) 0.99
css/visitor/compare/visit_mut_span 2322442 ns/iter (± 5156) 2328496 ns/iter (± 7794) 1.00
css/visitor/compare/visit_mut_span_panic 2365179 ns/iter (± 8564) 2375483 ns/iter (± 13318) 1.00
css/visitor/compare/fold_span 3072558 ns/iter (± 23811) 3097449 ns/iter (± 13512) 0.99
css/visitor/compare/fold_span_panic 3242183 ns/iter (± 23156) 3299278 ns/iter (± 25789) 0.98
css/lexer/bootstrap_5_1_3 5135530 ns/iter (± 12780) 5138769 ns/iter (± 13598) 1.00
css/lexer/foundation_6_7_4 4307869 ns/iter (± 960) 4347796 ns/iter (± 1110) 0.99
css/lexer/tailwind_3_1_1 822698 ns/iter (± 202) 829645 ns/iter (± 450) 0.99
css/parser/bootstrap_5_1_3 21581385 ns/iter (± 208820) 21848205 ns/iter (± 136802) 0.99
css/parser/foundation_6_7_4 17116520 ns/iter (± 133353) 17310432 ns/iter (± 96648) 0.99
css/parser/tailwind_3_1_1 3224638 ns/iter (± 6829) 3239811 ns/iter (± 2718) 1.00
es/codegen/colors 318029 ns/iter (± 179230) 319205 ns/iter (± 179048) 1.00
es/codegen/large 1258294 ns/iter (± 651243) 1254491 ns/iter (± 666075) 1.00
es/codegen/with-parser/colors 46567 ns/iter (± 88) 46525 ns/iter (± 86) 1.00
es/codegen/with-parser/large 503813 ns/iter (± 1532) 502923 ns/iter (± 912) 1.00
es/minify/libraries/antd 1504513671 ns/iter (± 17929336) 1492444067 ns/iter (± 15183991) 1.01
es/minify/libraries/d3 274374253 ns/iter (± 4459809) 276374858 ns/iter (± 5129867) 0.99
es/minify/libraries/echarts 1138249606 ns/iter (± 6773480) 1142937029 ns/iter (± 9012060) 1.00
es/minify/libraries/jquery 81749266 ns/iter (± 1249613) 81547685 ns/iter (± 1028406) 1.00
es/minify/libraries/lodash 98468601 ns/iter (± 1260674) 98908271 ns/iter (± 1578756) 1.00
es/minify/libraries/moment 47098950 ns/iter (± 677657) 46560353 ns/iter (± 386548) 1.01
es/minify/libraries/react 17545694 ns/iter (± 194147) 17419336 ns/iter (± 219082) 1.01
es/minify/libraries/terser 223168919 ns/iter (± 3181756) 226215390 ns/iter (± 3096409) 0.99
es/minify/libraries/three 390705776 ns/iter (± 4105785) 395828764 ns/iter (± 9566426) 0.99
es/minify/libraries/typescript 2695322893 ns/iter (± 17622984) 2667650481 ns/iter (± 23697600) 1.01
es/minify/libraries/victory 620851839 ns/iter (± 16523072) 633714352 ns/iter (± 9791495) 0.98
es/minify/libraries/vue 120318793 ns/iter (± 1898591) 120631536 ns/iter (± 997190) 1.00
es/visitor/compare/clone 2336631 ns/iter (± 12999) 2332782 ns/iter (± 7453) 1.00
es/visitor/compare/visit_mut_span 2725236 ns/iter (± 14548) 2716574 ns/iter (± 6591) 1.00
es/visitor/compare/visit_mut_span_panic 2731612 ns/iter (± 6985) 2752112 ns/iter (± 18688) 0.99
es/visitor/compare/fold_span 3823444 ns/iter (± 24843) 3875822 ns/iter (± 33370) 0.99
es/visitor/compare/fold_span_panic 3940480 ns/iter (± 13576) 3978344 ns/iter (± 29677) 0.99
es/lexer/colors 13019 ns/iter (± 22) 12927 ns/iter (± 65) 1.01
es/lexer/angular 6362582 ns/iter (± 2938) 6325567 ns/iter (± 7284) 1.01
es/lexer/backbone 786193 ns/iter (± 529) 779221 ns/iter (± 223) 1.01
es/lexer/jquery 4399706 ns/iter (± 2024) 4359274 ns/iter (± 2843) 1.01
es/lexer/jquery mobile 6876206 ns/iter (± 16021) 6801831 ns/iter (± 2043) 1.01
es/lexer/mootools 3437768 ns/iter (± 919) 3423194 ns/iter (± 13578) 1.00
es/lexer/underscore 651970 ns/iter (± 362) 643450 ns/iter (± 230) 1.01
es/lexer/three 20890317 ns/iter (± 21722) 20742346 ns/iter (± 22761) 1.01
es/lexer/yui 3848842 ns/iter (± 1640) 3832499 ns/iter (± 1507) 1.00
es/parser/colors 28583 ns/iter (± 49) 28628 ns/iter (± 42) 1.00
es/parser/angular 15468261 ns/iter (± 281269) 15393043 ns/iter (± 179118) 1.00
es/parser/backbone 2166518 ns/iter (± 11617) 2163715 ns/iter (± 14116) 1.00
es/parser/jquery 11983384 ns/iter (± 134984) 11963110 ns/iter (± 120330) 1.00
es/parser/jquery mobile 19813218 ns/iter (± 385209) 19088144 ns/iter (± 261323) 1.04
es/parser/mootools 8920781 ns/iter (± 30897) 8878811 ns/iter (± 31614) 1.00
es/parser/underscore 1826987 ns/iter (± 9398) 1831705 ns/iter (± 11122) 1.00
es/parser/three 56264827 ns/iter (± 432888) 56312628 ns/iter (± 246064) 1.00
es/parser/yui 9230184 ns/iter (± 176190) 9102650 ns/iter (± 62468) 1.01
es/preset-env/usage/builtin_type 146580 ns/iter (± 35619) 143185 ns/iter (± 33785) 1.02
es/preset-env/usage/property 21624 ns/iter (± 85) 21006 ns/iter (± 85) 1.03
es/resolver/typescript 123783041 ns/iter (± 1513865) 122063215 ns/iter (± 3675970) 1.01
es/fixer/typescript 89765977 ns/iter (± 834325) 88314191 ns/iter (± 2125323) 1.02
es/hygiene/typescript 194858886 ns/iter (± 2169915) 189908825 ns/iter (± 2398242) 1.03
es/resolver_with_hygiene/typescript 352700820 ns/iter (± 1618185) 340671684 ns/iter (± 1953378) 1.04
es/visitor/base-perf/module_clone 80369 ns/iter (± 941) 80464 ns/iter (± 407) 1.00
es/visitor/base-perf/fold_empty 90071 ns/iter (± 349) 90677 ns/iter (± 428) 0.99
es/visitor/base-perf/fold_noop_impl_all 90706 ns/iter (± 431) 90806 ns/iter (± 275) 1.00
es/visitor/base-perf/fold_noop_impl_vec 91284 ns/iter (± 544) 91371 ns/iter (± 349) 1.00
es/visitor/base-perf/boxing_boxed_clone 57 ns/iter (± 0) 56 ns/iter (± 0) 1.02
es/visitor/base-perf/boxing_unboxed_clone 41 ns/iter (± 0) 41 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 103 ns/iter (± 0) 101 ns/iter (± 0) 1.02
es/visitor/base-perf/boxing_unboxed 78 ns/iter (± 0) 78 ns/iter (± 0) 1
es/visitor/base-perf/visit_contains_this 3359 ns/iter (± 58) 3373 ns/iter (± 57) 1.00
es/base/parallel/resolver/typescript 6721082482 ns/iter (± 417118607) 6599639811 ns/iter (± 654346091) 1.02
es/base/parallel/hygiene/typescript 2211318464 ns/iter (± 9873068) 2219663313 ns/iter (± 26072352) 1.00
misc/visitors/time-complexity/time 5 103 ns/iter (± 0) 102 ns/iter (± 0) 1.01
misc/visitors/time-complexity/time 10 349 ns/iter (± 0) 342 ns/iter (± 6) 1.02
misc/visitors/time-complexity/time 15 666 ns/iter (± 9) 669 ns/iter (± 17) 1.00
misc/visitors/time-complexity/time 20 1259 ns/iter (± 19) 1240 ns/iter (± 0) 1.02
misc/visitors/time-complexity/time 40 6893 ns/iter (± 4) 6925 ns/iter (± 7) 1.00
misc/visitors/time-complexity/time 60 17164 ns/iter (± 90) 17227 ns/iter (± 117) 1.00
es/full-target/es2016 252029 ns/iter (± 870) 252336 ns/iter (± 3079) 1.00
es/full-target/es2017 245172 ns/iter (± 324) 245315 ns/iter (± 326) 1.00
es/full-target/es2018 234157 ns/iter (± 279) 235095 ns/iter (± 239) 1.00
es2020_nullish_coalescing 93262 ns/iter (± 379) 95002 ns/iter (± 238) 0.98
es2020_optional_chaining 124375 ns/iter (± 377) 124228 ns/iter (± 244) 1.00
es2022_class_properties 148638 ns/iter (± 283) 148265 ns/iter (± 267) 1.00
es2018_object_rest_spread 96676 ns/iter (± 249) 96044 ns/iter (± 220) 1.01
es2019_optional_catch_binding 85489 ns/iter (± 237) 85416 ns/iter (± 148) 1.00
es2017_async_to_generator 85988 ns/iter (± 234) 85927 ns/iter (± 151) 1.00
es2016_exponentiation 90318 ns/iter (± 401) 90380 ns/iter (± 187) 1.00
es2015_arrow 94076 ns/iter (± 276) 93784 ns/iter (± 179) 1.00
es2015_block_scoped_fn 92430 ns/iter (± 383) 92013 ns/iter (± 243) 1.00
es2015_block_scoping 169865 ns/iter (± 274) 170411 ns/iter (± 196) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.