Skip to content

Commit 535a246

Browse files
CLI: Add an option to set the interpreter stack size
1 parent c5da9df commit 535a246

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

Sources/CLI/Commands/Run.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ struct Run: ParsableCommand {
5555
@Option(help: ArgumentHelp("The execution threading model to use", visibility: .hidden))
5656
var threadingModel: ThreadingModel?
5757

58+
@Option(
59+
help: ArgumentHelp(
60+
"The size of the interpreter stack in bytes",
61+
valueName: "bytes"
62+
)
63+
)
64+
var stackSize: Int?
65+
5866
@Argument
5967
var path: String
6068

@@ -149,7 +157,7 @@ struct Run: ParsableCommand {
149157
case .token: threadingModel = .token
150158
case nil: threadingModel = nil
151159
}
152-
return EngineConfiguration(threadingModel: threadingModel)
160+
return EngineConfiguration(threadingModel: threadingModel, stackSize: self.stackSize)
153161
}
154162

155163
func instantiateWASI(module: Module, interceptor: EngineInterceptor?) throws -> () throws -> Void {

Sources/WasmKit/Engine.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,31 @@ public struct EngineConfiguration {
6868
/// The compilation mode to use for WebAssembly modules.
6969
public var compilationMode: CompilationMode
7070

71+
/// The stack size for the virtual machine interpreter. (Default: 64KB)
72+
///
73+
/// Note: Typically, there are three kinds of stacks in a WebAssembly execution:
74+
/// 1. The native stack, which is used for native function calls.
75+
/// 2. The interpreter stack, which is used for allocating "local"
76+
/// variables in the WebAssembly function and call frames of the
77+
/// WebAssembly-level function calls.
78+
/// 3. The shadow stack, which is used by WebAssembly programs compiled
79+
/// by LLVM-based compilers to implement pointers to local variables.
80+
/// This stack is allocated in the WebAssembly memory space by
81+
/// wasm-ld, so the interpreter does not care about it.
82+
///
83+
/// The stack size here refers to the second stack, the interpreter stack
84+
/// size, so you may need to increase this value if you see
85+
/// "call stack exhausted" ``Trap`` errors thrown by the interpreter.
86+
public var stackSize: Int
87+
7188
/// Initializes a new instance of `EngineConfiguration`.
7289
/// - Parameter threadingModel: The threading model to use for the virtual
7390
/// machine interpreter. If `nil`, the default threading model for the
7491
/// current platform will be used.
75-
public init(threadingModel: ThreadingModel? = nil, compilationMode: CompilationMode = .lazy) {
92+
public init(threadingModel: ThreadingModel? = nil, compilationMode: CompilationMode = .lazy, stackSize: Int? = nil) {
7693
self.threadingModel = threadingModel ?? .defaultForCurrentPlatform
7794
self.compilationMode = compilationMode
95+
self.stackSize = stackSize ?? (1 << 16)
7896
}
7997
}
8098

Sources/WasmKit/Execution/Execution.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct Execution {
2020
store: StoreRef,
2121
body: (inout Execution, Sp) throws -> T
2222
) rethrows -> T {
23-
let limit = Int(UInt16.max)
23+
let limit = store.value.engine.configuration.stackSize
2424
let valueStack = UnsafeMutablePointer<StackSlot>.allocate(capacity: limit)
2525
defer {
2626
valueStack.deallocate()

0 commit comments

Comments
 (0)