Skip to content

Commit 935f877

Browse files
committed
Fix breakpoint resumption test expectation
1 parent a57ec75 commit 935f877

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
lines changed

Sources/WasmKit/Execution/Debugger.swift

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
package struct Debugger: ~Copyable {
4646
package enum Error: Swift.Error {
4747
case entrypointFunctionNotFound
48+
case unknownCurrentFunctionForResumedBreakpoint(UnsafeMutablePointer<UInt64>)
4849
case noInstructionMappingAvailable(Int)
50+
case noReverseInstructionMappingAvailable(UnsafeMutablePointer<UInt64>)
4951
}
5052

5153
private let valueStack: Sp
@@ -66,7 +68,7 @@
6668

6769
private(set) var breakpoints = [Int: CodeSlot]()
6870

69-
private var currentBreakpoint: Execution.Breakpoint?
71+
private var currentBreakpoint: (iseq: Execution.Breakpoint, wasmPc: Int)?
7072

7173
private var pc = Pc.allocate(capacity: 1)
7274

@@ -131,16 +133,58 @@
131133
/// Returns: `[Value]` result of `entrypointFunction` if current instance ran to completion, `nil` if it stopped at a breakpoint.
132134
package mutating func run() throws -> [Value]? {
133135
do {
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-
)
136+
if let currentBreakpoint {
137+
// Remove the breakpoint before resuming
138+
try self.disableBreakpoint(address: currentBreakpoint.wasmPc)
139+
self.execution.resetError()
140+
141+
var sp = currentBreakpoint.iseq.sp
142+
var pc = currentBreakpoint.iseq.pc
143+
var md: Md = nil
144+
var ms: Ms = 0
145+
146+
guard let currentFunction = sp.currentFunction else {
147+
throw Error.unknownCurrentFunctionForResumedBreakpoint(sp)
148+
}
149+
150+
Execution.CurrentMemory.mayUpdateCurrentInstance(
151+
instance: currentFunction.instance,
152+
from: self.instance.handle,
153+
md: &md,
154+
ms: &ms
155+
)
156+
157+
do {
158+
switch self.threadingModel {
159+
case .direct:
160+
try self.execution.runDirectThreaded(sp: sp, pc: pc, md: md, ms: ms)
161+
case .token:
162+
try self.execution.runTokenThreaded(sp: &sp, pc: &pc, md: &md, ms: &ms)
163+
}
164+
} catch is Execution.EndOfExecution {
165+
}
166+
167+
let type = self.store.engine.funcTypeInterner.resolve(currentFunction.type)
168+
return type.results.enumerated().map { (i, type) in
169+
sp[VReg(i)].cast(to: type)
170+
}
171+
} else {
172+
return try self.execution.executeWasm(
173+
threadingModel: self.threadingModel,
174+
function: self.entrypointFunction.handle,
175+
type: self.entrypointFunction.type,
176+
arguments: [],
177+
sp: self.valueStack,
178+
pc: self.pc
179+
)
180+
}
142181
} catch let breakpoint as Execution.Breakpoint {
143-
self.currentBreakpoint = breakpoint
182+
let pc = breakpoint.pc
183+
guard let wasmPc = self.instance.handle.iseqToWasmMapping[pc] else {
184+
throw Error.noReverseInstructionMappingAvailable(pc)
185+
}
186+
187+
self.currentBreakpoint = (breakpoint, wasmPc)
144188
return nil
145189
}
146190
}
@@ -151,12 +195,10 @@
151195
return []
152196
}
153197

154-
var result = Execution.captureBacktrace(sp: currentBreakpoint.sp, store: self.store).symbols.compactMap {
198+
var result = Execution.captureBacktrace(sp: currentBreakpoint.iseq.sp, store: self.store).symbols.compactMap {
155199
return self.instance.handle.iseqToWasmMapping[$0.address]
156200
}
157-
if let wasmPc = self.instance.handle.iseqToWasmMapping[currentBreakpoint.pc] {
158-
result.append(wasmPc)
159-
}
201+
result.append(currentBreakpoint.wasmPc)
160202

161203
return result
162204
}

Sources/WasmKit/Execution/Execution.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,11 @@ extension Execution {
557557
self.trap = (rawError, sp)
558558
}
559559

560+
/// Used by the debugger to resume execution after breakpoints.
561+
mutating func resetError() {
562+
self.trap = nil
563+
}
564+
560565
@inline(__always)
561566
func checkStackBoundary(_ sp: Sp) throws {
562567
guard sp < stackEnd else { throw Trap(.callStackExhausted) }

Tests/WasmKitTests/DebuggerTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
let expectedPc = try #require(debugger.breakpoints.keys.first)
3535
#expect(debugger.currentCallStack == [expectedPc])
36+
37+
#expect(try debugger.run() == [.i32(42)])
3638
}
3739

3840
@Test

0 commit comments

Comments
 (0)