|
49 | 49 | } |
50 | 50 |
|
51 | 51 | private let valueStack: Sp |
52 | | - private let execution: Execution |
| 52 | + private var execution: Execution |
53 | 53 | private let store: Store |
54 | 54 |
|
55 | 55 | /// Parsed in-memory representation of a Wasm module instantiated for debugging. |
|
66 | 66 |
|
67 | 67 | private(set) var breakpoints = [Int: CodeSlot]() |
68 | 68 |
|
69 | | - private var iseqPc: Pc? |
| 69 | + private var currentBreakpoint: Execution.Breakpoint? |
| 70 | + |
| 71 | + private var pc = Pc.allocate(capacity: 1) |
70 | 72 |
|
71 | 73 | package init(module: Module, store: Store, imports: Imports) throws { |
72 | 74 | let limit = store.engine.configuration.stackSize / MemoryLayout<StackSlot>.stride |
|
83 | 85 | self.store = store |
84 | 86 | self.execution = Execution(store: StoreRef(store), stackEnd: valueStack.advanced(by: limit)) |
85 | 87 | self.threadingModel = store.engine.configuration.threadingModel |
| 88 | + self.pc.pointee = Instruction.endOfExecution.headSlot(threadingModel: threadingModel) |
86 | 89 | } |
87 | 90 |
|
88 | 91 | package mutating func stopAtEntrypoint() throws { |
|
125 | 128 | iseq.pointee = oldCodeSlot |
126 | 129 | } |
127 | 130 |
|
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]? { |
130 | 133 | 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 | + ) |
133 | 142 | } catch let breakpoint as Execution.Breakpoint { |
134 | | - self.iseqPc = breakpoint.pc |
135 | | - return false |
| 143 | + self.currentBreakpoint = breakpoint |
| 144 | + return nil |
136 | 145 | } |
137 | 146 | } |
138 | 147 |
|
139 | 148 | /// Array of addresses in the Wasm binary of executed instructions on the call stack. |
140 | 149 | package var currentCallStack: [Int] { |
141 | | - let isDebuggable = self.instance.handle.isDebuggable |
| 150 | + guard let currentBreakpoint else { |
| 151 | + return [] |
| 152 | + } |
142 | 153 |
|
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 { |
144 | 155 | return self.instance.handle.iseqToWasmMapping[$0.address] |
145 | 156 | } |
146 | | - if let iseqPc, let wasmPc = self.instance.handle.iseqToWasmMapping[iseqPc] { |
| 157 | + if let wasmPc = self.instance.handle.iseqToWasmMapping[currentBreakpoint.pc] { |
147 | 158 | result.append(wasmPc) |
148 | 159 | } |
149 | 160 |
|
150 | 161 | return result |
151 | 162 | } |
152 | 163 |
|
153 | 164 | deinit { |
154 | | - valueStack.deallocate() |
| 165 | + self.valueStack.deallocate() |
| 166 | + self.pc.deallocate() |
155 | 167 | } |
156 | 168 | } |
157 | 169 |
|
|
0 commit comments