Skip to content

Commit 1309bae

Browse files
committed
Add iSeqToWasmMapping to InstanceEntity
1 parent 345ddb3 commit 1309bae

File tree

11 files changed

+67
-29
lines changed

11 files changed

+67
-29
lines changed

Sources/GDBRemoteProtocol/GDBTargetResponseEncoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package struct GDBTargetResponseEncoder: MessageToByteEncoder {
1919
case .ok:
2020
out.writeBytes("ok#da".utf8)
2121

22-
case .hostInfo(let info):
22+
case .keyValuePairs(let info):
2323
out.writeBytes(info.map { (key, value) in "\(key):\(value);" }.joined().appendedChecksum)
2424

2525
case .vContSupportedActions(let actions):

Sources/WasmKit/Execution/Errors.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,30 @@ struct Backtrace: CustomStringConvertible, Sendable {
88
struct Symbol {
99
/// The name of the symbol.
1010
let name: String?
11+
let debuggingAddress: DebuggingAddress
12+
13+
/// Address of the symbol for debugging purposes.
14+
enum DebuggingAddress: CustomStringConvertible, @unchecked Sendable {
15+
case iseq(Pc)
16+
case wasm(UInt64)
17+
18+
var description: String {
19+
switch self {
20+
case .iseq(let pc): "iseq(\(Int(bitPattern: pc)))"
21+
case .wasm(let wasmAddress): "wasm(\(wasmAddress))"
22+
}
23+
}
24+
}
1125
}
1226

1327
/// The symbols in the backtrace.
14-
let symbols: [Symbol?]
28+
let symbols: [Symbol]
1529

1630
/// Textual description of the backtrace.
1731
var description: String {
1832
symbols.enumerated().map { (index, symbol) in
19-
let name = symbol?.name ?? "unknown"
20-
return " \(index): \(name)"
33+
let name = symbol.name ?? "unknown"
34+
return " \(symbol.debuggingAddress): \(name)"
2135
}.joined(separator: "\n")
2236
}
2337
}

Sources/WasmKit/Execution/Execution.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,14 @@ struct Execution {
6161

6262
static func captureBacktrace(sp: Sp, store: Store) -> Backtrace {
6363
var frames = FrameIterator(sp: sp)
64-
var symbols: [Backtrace.Symbol?] = []
64+
var symbols: [Backtrace.Symbol] = []
6565
while let frame = frames.next() {
6666
guard let function = frame.function else {
67-
symbols.append(nil)
67+
symbols.append(.init(name: nil, debuggingAddress: .iseq(frame.pc)))
6868
continue
6969
}
7070
let symbolName = store.nameRegistry.symbolicate(.wasm(function))
71-
symbols.append(
72-
Backtrace.Symbol(
73-
name: symbolName
74-
)
75-
)
71+
symbols.append(.init(name: symbolName, debuggingAddress: .iseq(frame.pc)))
7672
}
7773
return Backtrace(symbols: symbols)
7874
}

Sources/WasmKit/Execution/Function.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ struct WasmFunctionEntity {
243243
switch code {
244244
case .uncompiled(let code):
245245
return try compile(store: store, code: code)
246-
case .compiled(let iseq), .compiledAndPatchable(_, let iseq):
246+
case .compiled(let iseq), .debuggable(_, let iseq):
247247
return iseq
248248
}
249249
}
@@ -280,10 +280,14 @@ extension EntityHandle<WasmFunctionEntity> {
280280
case .uncompiled(let code):
281281
return try self.withValue {
282282
let iseq = try $0.compile(store: store, code: code)
283-
$0.code = .compiled(iseq)
283+
if $0.instance.isDebuggable {
284+
$0.code = .debuggable(code, iseq)
285+
} else {
286+
$0.code = .compiled(iseq)
287+
}
284288
return iseq
285289
}
286-
case .compiled(let iseq), .compiledAndPatchable(_, let iseq):
290+
case .compiled(let iseq), .debuggable(_, let iseq):
287291
return iseq
288292
}
289293
}
@@ -316,7 +320,7 @@ struct InstructionSequence {
316320
enum CodeBody {
317321
case uncompiled(InternalUncompiledCode)
318322
case compiled(InstructionSequence)
319-
case compiledAndPatchable(InternalUncompiledCode, InstructionSequence)
323+
case debuggable(InternalUncompiledCode, InstructionSequence)
320324
}
321325

322326
extension Reference {

Sources/WasmKit/Execution/Instances.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ struct InstanceEntity /* : ~Copyable */ {
8383
var functionRefs: Set<InternalFunction>
8484
var features: WasmFeatureSet
8585
var dataCount: UInt32?
86+
var isDebuggable: Bool
87+
var iSeqToWasmMapping: [Pc: UInt64]
8688

8789
static var empty: InstanceEntity {
8890
InstanceEntity(
@@ -96,7 +98,9 @@ struct InstanceEntity /* : ~Copyable */ {
9698
exports: [:],
9799
functionRefs: [],
98100
features: [],
99-
dataCount: nil
101+
dataCount: nil,
102+
isDebuggable: false,
103+
iSeqToWasmMapping: [:]
100104
)
101105
}
102106

Sources/WasmKit/Execution/StoreAllocator.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ extension StoreAllocator {
251251
module: Module,
252252
engine: Engine,
253253
resourceLimiter: any ResourceLimiter,
254-
imports: Imports
254+
imports: Imports,
255+
isDebuggable: Bool
255256
) throws -> InternalInstance {
256257
// Step 1 of module allocation algorithm, according to Wasm 2.0 spec.
257258

@@ -450,7 +451,9 @@ extension StoreAllocator {
450451
exports: exports,
451452
functionRefs: functionRefs,
452453
features: module.features,
453-
dataCount: module.dataCount
454+
dataCount: module.dataCount,
455+
isDebuggable: isDebuggable,
456+
iSeqToWasmMapping: [:]
454457
)
455458
instancePointer.initialize(to: instanceEntity)
456459
instanceInitialized = true

Sources/WasmKit/Module.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,21 @@ public struct Module {
138138
Instance(handle: try self.instantiateHandle(store: store, imports: imports), store: store)
139139
}
140140

141+
#if WasmDebuggingSupport
142+
/// Instantiate this module in the given imports.
143+
///
144+
/// - Parameters:
145+
/// - store: The ``Store`` to allocate the instance in.
146+
/// - imports: The imports to use for instantiation. All imported entities
147+
/// must be allocated in the given store.
148+
public func instantiate(store: Store, imports: Imports = [:], isDebuggable: Bool) throws -> Instance {
149+
Instance(handle: try self.instantiateHandle(store: store, imports: imports, isDebuggable: isDebuggable), store: store)
150+
}
151+
#endif
152+
141153
/// > Note:
142154
/// <https://webassembly.github.io/spec/core/exec/modules.html#instantiation>
143-
private func instantiateHandle(store: Store, imports: Imports) throws -> InternalInstance {
155+
private func instantiateHandle(store: Store, imports: Imports, isDebuggable: Bool = false) throws -> InternalInstance {
144156
try ModuleValidator(module: self).validate()
145157

146158
// Steps 5-8.
@@ -152,7 +164,8 @@ public struct Module {
152164
let instance = try store.allocator.allocate(
153165
module: self, engine: store.engine,
154166
resourceLimiter: store.resourceLimiter,
155-
imports: imports
167+
imports: imports,
168+
isDebuggable: isDebuggable
156169
)
157170

158171
if let nameSection = customSections.first(where: { $0.name == "name" }) {

Sources/WasmKit/Translator.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -822,8 +822,6 @@ struct InstructionTranslator: InstructionVisitor {
822822
let functionIndex: FunctionIndex
823823
/// Whether a call to this function should be intercepted
824824
let isIntercepting: Bool
825-
/// Whether Wasm debugging facilities are currently enabled.
826-
let isDebugging: Bool
827825
var constantSlots: ConstSlots
828826
let validator: InstructionValidator
829827

@@ -836,8 +834,7 @@ struct InstructionTranslator: InstructionVisitor {
836834
locals: [WasmTypes.ValueType],
837835
functionIndex: FunctionIndex,
838836
codeSize: Int,
839-
isIntercepting: Bool,
840-
isDebugging: Bool = false
837+
isIntercepting: Bool
841838
) throws {
842839
self.allocator = allocator
843840
self.funcTypeInterner = funcTypeInterner
@@ -854,7 +851,6 @@ struct InstructionTranslator: InstructionVisitor {
854851
self.locals = Locals(types: type.parameters + locals)
855852
self.functionIndex = functionIndex
856853
self.isIntercepting = isIntercepting
857-
self.isDebugging = isDebugging
858854
self.constantSlots = ConstSlots(stackLayout: stackLayout)
859855
self.validator = InstructionValidator(context: module)
860856

@@ -2247,7 +2243,7 @@ struct InstructionTranslator: InstructionVisitor {
22472243
}
22482244

22492245
mutating func visitUnknown(_ opcode: [UInt8]) throws -> Bool {
2250-
guard self.isDebugging && opcode.count == 1 && opcode[0] == 0xFF else {
2246+
guard self.module.isDebuggable && opcode.count == 1 && opcode[0] == 0xFF else {
22512247
return false
22522248
}
22532249

Tests/GDBRemoteProtocolTests/RemoteProtocolTests.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import GDBRemoteProtocol
2+
import Logging
23
import NIOCore
34
import Testing
45

56
@Suite
67
struct LLDBRemoteProtocolTests {
78
@Test
89
func decoding() throws {
9-
var decoder = GDBHostCommandDecoder()
10+
var logger = Logger(label: "com.swiftwasm.WasmKit.tests")
11+
logger.logLevel = .critical
12+
var decoder = GDBHostCommandDecoder(logger: logger)
1013

1114
var buffer = ByteBuffer(string: "+$g#67")
1215
var packet = try decoder.decode(buffer: &buffer)

Tests/WasmKitTests/ExecutionTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
"""
112112
) { trap in
113113
#expect(
114-
trap.backtrace?.symbols.compactMap(\.?.name) == [
114+
trap.backtrace?.symbols.compactMap(\.name) == [
115115
"foo",
116116
"bar",
117117
"_start",
@@ -138,7 +138,7 @@
138138
"""
139139
) { trap in
140140
#expect(
141-
trap.backtrace?.symbols.compactMap(\.?.name) == [
141+
trap.backtrace?.symbols.compactMap(\.name) == [
142142
"wasm function[1]",
143143
"bar",
144144
"_start",

0 commit comments

Comments
 (0)