Skip to content

Commit 27dbbc7

Browse files
committed
Pass Sp in Breakpoint, add executeWasm instance method
1 parent 6246506 commit 27dbbc7

File tree

5 files changed

+63
-16
lines changed

5 files changed

+63
-16
lines changed

Sources/WasmKit/Execution/Debugger.swift

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
}
5050

5151
private let valueStack: Sp
52-
private let execution: Execution
52+
private var execution: Execution
5353
private let store: Store
5454

5555
/// Parsed in-memory representation of a Wasm module instantiated for debugging.
@@ -66,7 +66,9 @@
6666

6767
private(set) var breakpoints = [Int: CodeSlot]()
6868

69-
private var iseqPc: Pc?
69+
private var currentBreakpoint: Execution.Breakpoint?
70+
71+
private var pc = Pc.allocate(capacity: 1)
7072

7173
package init(module: Module, store: Store, imports: Imports) throws {
7274
let limit = store.engine.configuration.stackSize / MemoryLayout<StackSlot>.stride
@@ -83,6 +85,7 @@
8385
self.store = store
8486
self.execution = Execution(store: StoreRef(store), stackEnd: valueStack.advanced(by: limit))
8587
self.threadingModel = store.engine.configuration.threadingModel
88+
self.pc.pointee = Instruction.endOfExecution.headSlot(threadingModel: threadingModel)
8689
}
8790

8891
package mutating func stopAtEntrypoint() throws {
@@ -125,33 +128,42 @@
125128
iseq.pointee = oldCodeSlot
126129
}
127130

128-
/// Returns: `true` if current instance ran to completion, `false` if it stopped at a breakpoint.
129-
package mutating func run() throws -> Bool {
131+
/// Returns: `[Value]` result of `entrypointFunction` if current instance ran to completion, `nil` if it stopped at a breakpoint.
132+
package mutating func run() throws -> [Value]? {
130133
do {
131-
try self.entrypointFunction()
132-
return true
134+
return try self.execution.executeWasm(
135+
threadingModel: self.threadingModel,
136+
function: self.entrypointFunction.handle,
137+
type: self.entrypointFunction.type,
138+
arguments: [],
139+
sp: self.valueStack,
140+
pc: self.pc
141+
)
133142
} catch let breakpoint as Execution.Breakpoint {
134-
self.iseqPc = breakpoint.pc
135-
return false
143+
self.currentBreakpoint = breakpoint
144+
return nil
136145
}
137146
}
138147

139148
/// Array of addresses in the Wasm binary of executed instructions on the call stack.
140149
package var currentCallStack: [Int] {
141-
let isDebuggable = self.instance.handle.isDebuggable
150+
guard let currentBreakpoint else {
151+
return []
152+
}
142153

143-
var result = Execution.captureBacktrace(sp: self.valueStack, store: self.store).symbols.compactMap {
154+
var result = Execution.captureBacktrace(sp: currentBreakpoint.sp, store: self.store).symbols.compactMap {
144155
return self.instance.handle.iseqToWasmMapping[$0.address]
145156
}
146-
if let iseqPc, let wasmPc = self.instance.handle.iseqToWasmMapping[iseqPc] {
157+
if let wasmPc = self.instance.handle.iseqToWasmMapping[currentBreakpoint.pc] {
147158
result.append(wasmPc)
148159
}
149160

150161
return result
151162
}
152163

153164
deinit {
154-
valueStack.deallocate()
165+
self.valueStack.deallocate()
166+
self.pc.deallocate()
155167
}
156168
}
157169

Sources/WasmKit/Execution/Execution.swift

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ func executeWasm(
286286
function handle: InternalFunction,
287287
type: FunctionType,
288288
arguments: [Value],
289-
callerInstance: InternalInstance
290289
) throws -> [Value] {
291290
// NOTE: `store` variable must not outlive this function
292291
let store = StoreRef(store)
@@ -319,6 +318,41 @@ func executeWasm(
319318
}
320319

321320
extension Execution {
321+
322+
#if WasmDebuggingSupport
323+
324+
mutating func executeWasm(
325+
threadingModel: EngineConfiguration.ThreadingModel,
326+
function handle: InternalFunction,
327+
type: FunctionType,
328+
arguments: [Value],
329+
sp: Sp,
330+
pc: Pc
331+
) throws -> [Value] {
332+
// Advance the stack pointer to be able to reference negative indices
333+
// for saving slots.
334+
let sp = sp.advanced(by: FrameHeaderLayout.numberOfSavingSlots)
335+
// Mark root stack pointer and current function as nil.
336+
sp.previousSP = nil
337+
sp.currentFunction = nil
338+
for (index, argument) in arguments.enumerated() {
339+
sp[VReg(index)] = UntypedValue(argument)
340+
}
341+
342+
try self.execute(
343+
sp: sp,
344+
pc: pc,
345+
handle: handle,
346+
type: type
347+
)
348+
349+
return type.results.enumerated().map { (i, type) in
350+
sp[VReg(i)].cast(to: type)
351+
}
352+
}
353+
354+
#endif
355+
322356
/// A namespace for the "current memory" (Md and Ms) management.
323357
enum CurrentMemory {
324358
/// Assigns the current memory to the given internal memory.
@@ -369,6 +403,7 @@ extension Execution {
369403

370404
/// An ``Error`` thrown when a breakpoint is triggered.
371405
struct Breakpoint: Error, @unchecked Sendable {
406+
let sp: Sp
372407
let pc: Pc
373408
}
374409

Sources/WasmKit/Execution/Function.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ extension InternalFunction {
172172
store: store,
173173
function: self,
174174
type: resolvedType,
175-
arguments: arguments,
176-
callerInstance: entity.instance
175+
arguments: arguments
177176
)
178177
} else {
179178
let entity = host

Sources/WasmKit/Execution/Instructions/Control.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ extension Execution {
226226

227227
mutating func breakpoint(sp: inout Sp, pc: Pc) throws -> (Pc, CodeSlot) {
228228
throw Breakpoint(
229+
sp: sp,
229230
// Throw `pc` value before the breakpoint was triggered to allow resumption in same place
230231
pc: pc - 1
231232
)

Tests/WasmKitTests/DebuggerTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
try debugger.stopAtEntrypoint()
3030
#expect(debugger.breakpoints.count == 1)
3131

32-
#expect(try debugger.run() == false)
32+
#expect(try debugger.run() == nil)
3333

3434
let expectedPc = try #require(debugger.breakpoints.keys.first)
3535
#expect(debugger.currentCallStack == [expectedPc])

0 commit comments

Comments
 (0)