From 71e92e0334ebac00bacc533d4a946cefa48f9629 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 21 Nov 2025 04:48:46 +0000 Subject: [PATCH 1/4] Wasm: bump default stack size to 128K (#2026) The default of 64K is too low, especially as tail calls are not available by default on Wasm. It also means Swift Testing is unusable in `main` development snapshots due to stack overflows. rdar://160218251 --- .../Jobs/WebAssemblyToolchain+LinkerSupport.swift | 6 ++++++ Tests/SwiftDriverTests/SwiftDriverTests.swift | 1 + 2 files changed, 7 insertions(+) diff --git a/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift index 4dc47ea4d..9b1b6d804 100644 --- a/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift @@ -166,6 +166,12 @@ extension WebAssemblyToolchain { commandLine.appendFlag(.Xlinker) commandLine.appendFlag("--table-base=\(SWIFT_ABI_WASM32_LEAST_VALID_POINTER)") + // Set slightly higher than the default (64K) stack size so that basic + // workflows like Swift Testing can run within this limited stack space. + let SWIFT_WASM_DEFAULT_STACK_SIZE = 1024 * 128 + commandLine.appendFlag(.Xlinker) + commandLine.appendFlag("--stack-size=\(SWIFT_WASM_DEFAULT_STACK_SIZE)") + // Delegate to Clang for sanitizers. It will figure out the correct linker // options. if linkerOutputType == .executable && !sanitizers.isEmpty { diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 57559f00d..15be56581 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -2766,6 +2766,7 @@ final class SwiftDriverTests: XCTestCase { XCTAssertTrue(cmd.contains(.responseFilePath(.absolute(path.appending(components: "wasi", "static-executable-args.lnk"))))) XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--global-base=4096")])) XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--table-base=4096")])) + XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--stack-size=\(128 * 1024)")])) XCTAssertTrue(cmd.contains(.flag("-O3"))) XCTAssertEqual(linkJob.outputs[0].file, try toPath("Test")) From d819c7afd2b17bb6c5bb3b50fcae5f8a2007b969 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 21 Nov 2025 08:53:10 +0000 Subject: [PATCH 2/4] Wasm: fix stack size flag (no double dash, add `-z` The current invocation as is leads to `wasm-ld: error: unknown argument: --stack-size=131072` --- .../SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift index 9b1b6d804..0e4e31e02 100644 --- a/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift @@ -170,7 +170,9 @@ extension WebAssemblyToolchain { // workflows like Swift Testing can run within this limited stack space. let SWIFT_WASM_DEFAULT_STACK_SIZE = 1024 * 128 commandLine.appendFlag(.Xlinker) - commandLine.appendFlag("--stack-size=\(SWIFT_WASM_DEFAULT_STACK_SIZE)") + commandLine.appendFlag("-z") + commandLine.appendFlag(.Xlinker) + commandLine.appendFlag("stack-size=\(SWIFT_WASM_DEFAULT_STACK_SIZE)") // Delegate to Clang for sanitizers. It will figure out the correct linker // options. From 850fb66c81911814f76157b79e175d0ef2e3a7e9 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 21 Nov 2025 08:58:06 +0000 Subject: [PATCH 3/4] Wasm: update stack size linker options in tests Adjust `SwiftDriverTests/testLinking` for correct CLI options format. --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 15be56581..26c26ffcc 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -2766,7 +2766,7 @@ final class SwiftDriverTests: XCTestCase { XCTAssertTrue(cmd.contains(.responseFilePath(.absolute(path.appending(components: "wasi", "static-executable-args.lnk"))))) XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--global-base=4096")])) XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--table-base=4096")])) - XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--stack-size=\(128 * 1024)")])) + XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("-z"), .flag("stack-size=\(128 * 1024)")])) XCTAssertTrue(cmd.contains(.flag("-O3"))) XCTAssertEqual(linkJob.outputs[0].file, try toPath("Test")) From 7f2e11d2f62c50d3e33043f7777fb28a10eb3b05 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 21 Nov 2025 10:20:36 +0000 Subject: [PATCH 4/4] Add missing `-Xlinker` in `SwiftDriverTests.testLinking` --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 26c26ffcc..afea39e1e 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -2766,7 +2766,7 @@ final class SwiftDriverTests: XCTestCase { XCTAssertTrue(cmd.contains(.responseFilePath(.absolute(path.appending(components: "wasi", "static-executable-args.lnk"))))) XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--global-base=4096")])) XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("--table-base=4096")])) - XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("-z"), .flag("stack-size=\(128 * 1024)")])) + XCTAssertTrue(cmd.contains(subsequence: [.flag("-Xlinker"), .flag("-z"), .flag("-Xlinker"), .flag("stack-size=\(128 * 1024)")])) XCTAssertTrue(cmd.contains(.flag("-O3"))) XCTAssertEqual(linkJob.outputs[0].file, try toPath("Test"))