Skip to content

Commit

Permalink
CLI: Add an option to set the interpreter stack size
Browse files Browse the repository at this point in the history
  • Loading branch information
kateinoigakukun committed Oct 5, 2024
1 parent c5da9df commit 3a9e6df
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
10 changes: 9 additions & 1 deletion Sources/CLI/Commands/Run.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ struct Run: ParsableCommand {
@Option(help: ArgumentHelp("The execution threading model to use", visibility: .hidden))
var threadingModel: ThreadingModel?

@Option(
help: ArgumentHelp(
"The size of the interpreter stack in bytes",
valueName: "bytes"
)
)
var stackSize: Int?

@Argument
var path: String

Expand Down Expand Up @@ -149,7 +157,7 @@ struct Run: ParsableCommand {
case .token: threadingModel = .token
case nil: threadingModel = nil
}
return EngineConfiguration(threadingModel: threadingModel)
return EngineConfiguration(threadingModel: threadingModel, stackSize: self.stackSize)
}

func instantiateWASI(module: Module, interceptor: EngineInterceptor?) throws -> () throws -> Void {
Expand Down
20 changes: 19 additions & 1 deletion Sources/WasmKit/Engine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,31 @@ public struct EngineConfiguration {
/// The compilation mode to use for WebAssembly modules.
public var compilationMode: CompilationMode

/// The stack size for the virtual machine interpreter. (Default: 64KB)
///
/// Note: Typically, there are three kinds of stacks in a WebAssembly execution:
/// 1. The native stack, which is used for native function calls.
/// 2. The interpreter stack, which is used for allocating "local"
/// variables in the WebAssembly function and call frames of the
/// WebAssembly-level function calls.
/// 3. The shadow stack, which is used by WebAssembly programs compiled
/// by LLVM-based compilers to implement pointers to local variables.
/// This stack is allocated in the WebAssembly memory space by
/// wasm-ld, so the interpreter does not care about it.
///
/// The stack size here refers to the second stack, the interpreter stack
/// size, so you may need to increase this value if you see
/// "call stack exhausted" ``Trap`` errors thrown by the interpreter.
public var stackSize: Int

/// Initializes a new instance of `EngineConfiguration`.
/// - Parameter threadingModel: The threading model to use for the virtual
/// machine interpreter. If `nil`, the default threading model for the
/// current platform will be used.
public init(threadingModel: ThreadingModel? = nil, compilationMode: CompilationMode = .lazy) {
public init(threadingModel: ThreadingModel? = nil, compilationMode: CompilationMode = .lazy, stackSize: Int? = nil) {
self.threadingModel = threadingModel ?? .defaultForCurrentPlatform
self.compilationMode = compilationMode
self.stackSize = stackSize ?? (1 << 16)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/WasmKit/Execution/Execution.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct Execution {
store: StoreRef,
body: (inout Execution, Sp) throws -> T
) rethrows -> T {
let limit = Int(UInt16.max)
let limit = store.value.engine.configuration.stackSize
let valueStack = UnsafeMutablePointer<StackSlot>.allocate(capacity: limit)
defer {
valueStack.deallocate()
Expand Down

0 comments on commit 3a9e6df

Please sign in to comment.