From f5c62fbbf8ccbadec4daae4a2158b7b2fc707a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Apr 2023 18:37:21 +0900 Subject: [PATCH] fix(es/compat): Fix `finally` handling of `generator` (#7215) **Description:** Update generator implementation to match https://github.com/microsoft/TypeScript/blob/e83d61398ea0e4231e882121dd6c6bcfe4fdc9e4/src/compiler/transformers/generators.ts **Related issue:** - Closes https://github.com/swc-project/swc/issues/5913. --- .../src/es2015/generator.rs | 50 ++++- .../async-to-generator/issue-1892/exec.js | 39 ++++ .../async-to-generator/issue-5913/1/exec.js | 19 ++ .../async-to-generator/issue-5913/2/exec.js | 18 ++ .../tests/es2015_generator.rs | 207 ------------------ 5 files changed, 123 insertions(+), 210 deletions(-) create mode 100644 crates/swc_ecma_transforms_compat/tests/async-to-generator/issue-1892/exec.js create mode 100644 crates/swc_ecma_transforms_compat/tests/async-to-generator/issue-5913/1/exec.js create mode 100644 crates/swc_ecma_transforms_compat/tests/async-to-generator/issue-5913/2/exec.js diff --git a/crates/swc_ecma_transforms_compat/src/es2015/generator.rs b/crates/swc_ecma_transforms_compat/src/es2015/generator.rs index 2093ef21042d..afff021a6eca 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/generator.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/generator.rs @@ -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!(); @@ -338,7 +348,7 @@ struct Generator { clauses: Option>, stmts: Option>, /// Index to `blocks` - exception_block_stack: Vec>, + exception_block_stack: Option>>, /// Index to `blocks` current_exception_block: Option>, /// Index to `blocks` @@ -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); @@ -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) { @@ -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 { @@ -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 { @@ -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); @@ -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(); @@ -2319,6 +2341,8 @@ impl Generator { self.mark_label(finally_label); block.state = ExceptionBlockState::Finally; block.finally_label = Some(finally_label); + } else { + unreachable!() } } @@ -2337,6 +2361,8 @@ impl Generator { self.mark_label(block.end_label); self.emit_nop(); block.state = ExceptionBlockState::Done; + } else { + unreachable!() } } @@ -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, @@ -2377,6 +2405,8 @@ impl Generator { if !block.is_script { self.mark_label(break_label); } + } else { + unreachable!() } } @@ -2414,6 +2444,8 @@ impl Generator { if !block.is_script { self.mark_label(break_label); } + } else { + unreachable!() } } @@ -2469,6 +2501,8 @@ impl Generator { if block.label_text == *label_text { return true; } + } else { + unreachable!() } } else { break; @@ -2542,6 +2576,9 @@ impl Generator { fn create_label(&mut self, label: Option