Skip to content

Commit a1c5415

Browse files
authored
feat(es/transforms): Allocate stacks dynamically (#8867)
**Description:** - This PR introduces an in-tree testing system for Deno. - This PR adds `stacker` cargo-feature to `swc_ecma_utils`. **Related issue:** - #1627 - Closes #8840
1 parent 81a57fd commit a1c5415

File tree

25 files changed

+5569
-104
lines changed

25 files changed

+5569
-104
lines changed

.github/workflows/CI.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,10 +683,15 @@ jobs:
683683
cargo test -p swc_ecma_minifier --features concurrent
684684
685685
- name: Run cargo test (all features)
686-
if: matrix.settings.crate == 'swc_ecma_parser' || matrix.settings.crate == 'swc_ecma_loader' || matrix.settings.crate == 'swc_ecma_transforms'
686+
if: matrix.settings.crate == 'swc_ecma_parser' || matrix.settings.crate == 'swc_ecma_loader'
687687
run: |
688688
cargo test -p ${{ matrix.settings.crate }} --all-features
689689
690+
- name: Run cargo test (transforms with stacker)
691+
if: matrix.settings.crate == 'swc_ecma_transforms'
692+
run: |
693+
cargo test -p ${{ matrix.settings.crate }} --all-features --features swc_ecma_utils/stacker
694+
690695
- name: Run cargo test (concurrent)
691696
if: runner.os == 'Linux' && matrix.settings.crate != 'swc_ecma_minifier'
692697
shell: bash

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/swc_core/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ common_plugin_transform = [
186186
css_plugin_transform = ["common_plugin_transform", "__css_plugin_transform"]
187187
ecma_plugin_transform = ["common_plugin_transform", "__ecma_plugin_transform"]
188188

189+
# Use `stacker` to avoid stack overflow.
190+
stacker = ["swc_ecma_parser/stacker", "swc_ecma_utils/stacker"]
191+
189192
# Host features to enable plugin `runner` runtime.
190193
# native feature is for the host environment does not have, or cannot access
191194
# to the wasm runtime (i.e cli, or @swc/core node bindings).

crates/swc_ecma_minifier/src/util/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::time::Instant;
55
use rustc_hash::FxHashSet;
66
use swc_common::{util::take::Take, Mark, Span, Spanned, DUMMY_SP};
77
use swc_ecma_ast::*;
8-
use swc_ecma_utils::{ModuleItemLike, StmtLike, Value};
8+
use swc_ecma_utils::{stack_size::maybe_grow_default, ModuleItemLike, StmtLike, Value};
99
use swc_ecma_visit::{noop_visit_type, visit_obj_and_computed, Visit, VisitWith};
1010

1111
pub(crate) mod base54;
@@ -510,6 +510,10 @@ impl Visit for EvalFinder {
510510

511511
visit_obj_and_computed!();
512512

513+
fn visit_expr(&mut self, n: &Expr) {
514+
maybe_grow_default(|| n.visit_children_with(self));
515+
}
516+
513517
fn visit_ident(&mut self, i: &Ident) {
514518
if i.sym == "eval" {
515519
self.found = true;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#![cfg(all(
2+
feature = "swc_ecma_transforms_proposal",
3+
feature = "swc_ecma_transforms_typescript",
4+
))]
5+
use std::path::PathBuf;
6+
7+
use swc_common::{chain, Mark};
8+
use swc_ecma_parser::Syntax;
9+
use swc_ecma_transforms::{fixer, helpers::inject_helpers, hygiene, resolver};
10+
use swc_ecma_transforms_proposal::{
11+
decorator_2022_03::decorator_2022_03,
12+
explicit_resource_management::explicit_resource_management,
13+
};
14+
use swc_ecma_transforms_testing::test_fixture;
15+
use swc_ecma_transforms_typescript::typescript;
16+
17+
#[testing::fixture("tests/fixture/deno/**/input.ts")]
18+
fn stack_overflow(input: PathBuf) {
19+
run_test(input);
20+
}
21+
22+
fn run_test(input: PathBuf) {
23+
let output = input.with_file_name("output.js");
24+
25+
test_fixture(
26+
Syntax::Typescript(Default::default()),
27+
&|_tester| {
28+
let unresolved_mark = Mark::new();
29+
let top_level_mark = Mark::new();
30+
31+
chain!(
32+
resolver(unresolved_mark, top_level_mark, true),
33+
decorator_2022_03(),
34+
explicit_resource_management(),
35+
inject_helpers(top_level_mark),
36+
typescript(
37+
typescript::Config {
38+
verbatim_module_syntax: false,
39+
import_not_used_as_values: typescript::ImportsNotUsedAsValues::Remove,
40+
no_empty_export: true,
41+
import_export_assign_config:
42+
typescript::TsImportExportAssignConfig::Preserve,
43+
ts_enum_is_mutable: true,
44+
},
45+
top_level_mark
46+
),
47+
fixer(None),
48+
hygiene(),
49+
)
50+
},
51+
&input,
52+
&output,
53+
Default::default(),
54+
)
55+
}

0 commit comments

Comments
 (0)