warpo 3.1.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/asconfig.schema.json +10 -2
- package/dist/common/leb128.d.ts +5 -0
- package/dist/common/leb128.js +17 -0
- package/dist/common/leb128.js.map +1 -0
- package/dist/debug_server/debugSession.d.ts +31 -2
- package/dist/debug_server/debugSession.js +491 -126
- package/dist/debug_server/debugSession.js.map +1 -1
- package/dist/debug_server/debugTrace.d.ts +2 -0
- package/dist/debug_server/debugTrace.js +38 -0
- package/dist/debug_server/debugTrace.js.map +1 -0
- package/dist/debug_server/debugger.d.ts +6 -2
- package/dist/debug_server/debuggerWasmModule.d.ts +7 -0
- package/dist/debug_server/debuggerWasmModule.js +162 -17
- package/dist/debug_server/debuggerWasmModule.js.map +1 -1
- package/dist/debug_server/nodeDebugger.d.ts +18 -2
- package/dist/debug_server/nodeDebugger.js +134 -30
- package/dist/debug_server/nodeDebugger.js.map +1 -1
- package/dist/debug_server/tests/debugSession.test.js +598 -21
- package/dist/debug_server/tests/debugSession.test.js.map +1 -1
- package/dist/debug_server/tests/testModule/debugger_breakpoint_update.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_breakpoint_update.js +10 -0
- package/dist/debug_server/tests/testModule/debugger_breakpoint_update.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_breakpoint_validation.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_breakpoint_validation.js +12 -0
- package/dist/debug_server/tests/testModule/debugger_breakpoint_validation.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_function_closure.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_function_closure.js +24 -0
- package/dist/debug_server/tests/testModule/debugger_function_closure.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_generic_function.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_generic_function.js +10 -0
- package/dist/debug_server/tests/testModule/debugger_generic_function.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_import.case.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_import.case.js +9 -0
- package/dist/debug_server/tests/testModule/debugger_import.case.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_import.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_import.js +6 -0
- package/dist/debug_server/tests/testModule/debugger_import.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_member_function.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_member_function.js +16 -0
- package/dist/debug_server/tests/testModule/debugger_member_function.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_pause.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_pause.js +9 -0
- package/dist/debug_server/tests/testModule/debugger_pause.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_stepping.d.ts +3 -0
- package/dist/debug_server/tests/testModule/debugger_stepping.js +28 -0
- package/dist/debug_server/tests/testModule/debugger_stepping.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_typed_array.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_typed_array.js +52 -0
- package/dist/debug_server/tests/testModule/debugger_typed_array.js.map +1 -0
- package/dist/debug_server/tests/testModule/debugger_utf8_const_str.d.ts +1 -0
- package/dist/debug_server/tests/testModule/debugger_utf8_const_str.js +10 -0
- package/dist/debug_server/tests/testModule/debugger_utf8_const_str.js.map +1 -0
- package/dist/dwarf/dwarfParser.js +6 -13
- package/dist/dwarf/dwarfParser.js.map +1 -1
- package/dist/dwarf/functionDebugInfo.d.ts +3 -0
- package/dist/dwarf/functionDebugInfo.js +24 -0
- package/dist/dwarf/functionDebugInfo.js.map +1 -1
- package/dist/test_runner/core/compiler.js +2 -0
- package/dist/test_runner/core/compiler.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { DebugClient } from "@vscode/debugadapter-testsupport";
|
|
4
4
|
import * as assert from "node:assert/strict";
|
|
5
|
+
import * as fs from "node:fs";
|
|
5
6
|
import * as path from "node:path";
|
|
6
7
|
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
@@ -23,7 +24,7 @@ async function buildModule(source, extraSources = []) {
|
|
|
23
24
|
const name = path.basename(source, ".ts");
|
|
24
25
|
let buildOutput = "";
|
|
25
26
|
const exitCode = await build({
|
|
26
|
-
argv: [source, ...extraSources, "-o", output, "--debug", "--use", "abort="],
|
|
27
|
+
argv: [source, ...extraSources, "-o", output, "--debug", "--enable-feature", "tail-call", "--use", "abort="],
|
|
27
28
|
cwd: TEST_MODULE_DIR,
|
|
28
29
|
onStdout: (chunk) => {
|
|
29
30
|
buildOutput += chunk;
|
|
@@ -73,8 +74,13 @@ function findVariable(variables, name) {
|
|
|
73
74
|
async function launchAndWaitForBreakpoint(dc, launchArgs) {
|
|
74
75
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
75
76
|
await dc.launchRequest(launchArgs);
|
|
77
|
+
await dc.configurationDoneRequest({});
|
|
76
78
|
await stoppedPromise;
|
|
77
79
|
}
|
|
80
|
+
async function launchAndConfigure(dc, launchArgs) {
|
|
81
|
+
await dc.launchRequest(launchArgs);
|
|
82
|
+
await dc.configurationDoneRequest({});
|
|
83
|
+
}
|
|
78
84
|
async function readFrameLocals(dc, frame) {
|
|
79
85
|
const scopesResponse = await dc.scopesRequest({ frameId: frame.id });
|
|
80
86
|
const localsScope = assertDefined(scopesResponse.body.scopes.find((scope) => scope.name.startsWith("Local:")));
|
|
@@ -132,18 +138,49 @@ void describe("WarpoDebugSession", () => {
|
|
|
132
138
|
await waitForExit(serverChild, 1000);
|
|
133
139
|
}
|
|
134
140
|
});
|
|
135
|
-
void it("should
|
|
141
|
+
void it("should return breakpoints unverified before a wasm module is loaded", async () => {
|
|
136
142
|
await dc.initializeRequest();
|
|
137
143
|
const response = await dc.setBreakpointsRequest({
|
|
138
144
|
source: { path: "test.ts" },
|
|
139
145
|
breakpoints: [{ line: 5 }, { line: 10 }],
|
|
140
146
|
});
|
|
141
147
|
assert.equal(response.body.breakpoints.length, 2);
|
|
142
|
-
assert.equal(response.body.breakpoints[0].verified,
|
|
148
|
+
assert.equal(response.body.breakpoints[0].verified, false);
|
|
143
149
|
assert.equal(response.body.breakpoints[0].line, 5);
|
|
144
|
-
assert.equal(response.body.breakpoints[1].verified,
|
|
150
|
+
assert.equal(response.body.breakpoints[1].verified, false);
|
|
145
151
|
assert.equal(response.body.breakpoints[1].line, 10);
|
|
146
152
|
});
|
|
153
|
+
void it("should reject breakpoints without wasm bytecode mappings", { timeout: 10000 }, async () => {
|
|
154
|
+
const source = sourcePath("debugger_breakpoint_validation.ts");
|
|
155
|
+
const output = await buildModule(source);
|
|
156
|
+
const validLine = 7;
|
|
157
|
+
await dc.initializeRequest();
|
|
158
|
+
const initialResponse = await dc.setBreakpointsRequest({
|
|
159
|
+
source: { path: source },
|
|
160
|
+
breakpoints: [{ line: validLine }],
|
|
161
|
+
});
|
|
162
|
+
assert.equal(initialResponse.body.breakpoints[0].verified, false);
|
|
163
|
+
const breakpointChangedPromise = dc.waitForEvent("breakpoint");
|
|
164
|
+
const launchArgs = {
|
|
165
|
+
program: output,
|
|
166
|
+
launchType: "wasm file",
|
|
167
|
+
runtime: "node",
|
|
168
|
+
entryFunctionName: "_start",
|
|
169
|
+
};
|
|
170
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
171
|
+
const breakpointChangedEvent = await breakpointChangedPromise;
|
|
172
|
+
const breakpointChangedBody = breakpointChangedEvent.body;
|
|
173
|
+
assert.equal(breakpointChangedBody?.reason, "changed");
|
|
174
|
+
assert.equal(breakpointChangedBody?.breakpoint?.verified, true);
|
|
175
|
+
const response = await dc.setBreakpointsRequest({
|
|
176
|
+
source: { path: source },
|
|
177
|
+
breakpoints: [{ line: 5 }, { line: 6 }, { line: validLine }],
|
|
178
|
+
});
|
|
179
|
+
assert.equal(response.body.breakpoints[0].verified, false);
|
|
180
|
+
assert.equal(response.body.breakpoints[1].verified, false);
|
|
181
|
+
assert.equal(response.body.breakpoints[2].verified, true);
|
|
182
|
+
await dc.disconnectRequest({ terminateDebuggee: true });
|
|
183
|
+
});
|
|
147
184
|
void it("should stop in a unit test after returning from main", { timeout: 15000 }, async () => {
|
|
148
185
|
const testSource = sourcePath("unittest_debug.case.ts");
|
|
149
186
|
const implementationSource = sourcePath("unittest_debug.ts");
|
|
@@ -173,33 +210,89 @@ void describe("WarpoDebugSession", () => {
|
|
|
173
210
|
assert.equal(assertDefined(stackTraceResponse.body.stackFrames[0]).source?.path, normalizeDebugPath(testSource));
|
|
174
211
|
assert.equal(stackTraceResponse.body.stackFrames[0].line, 9);
|
|
175
212
|
});
|
|
213
|
+
void it("should step over a JavaScript import during step into", { timeout: 15000 }, async () => {
|
|
214
|
+
const implementationSource = sourcePath("debugger_import.ts");
|
|
215
|
+
await dc.initializeRequest();
|
|
216
|
+
await dc.setBreakpointsRequest({
|
|
217
|
+
source: { path: implementationSource },
|
|
218
|
+
breakpoints: [{ line: 7 }],
|
|
219
|
+
});
|
|
220
|
+
const launchArgs = {
|
|
221
|
+
launchType: "unittest",
|
|
222
|
+
runtime: "node",
|
|
223
|
+
cwd: TEST_MODULE_DIR,
|
|
224
|
+
warpoPath: WARPO_CLI,
|
|
225
|
+
};
|
|
226
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
227
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
228
|
+
await dc.stepInRequest({ threadId: 1 });
|
|
229
|
+
await stoppedPromise;
|
|
230
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
231
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
232
|
+
assert.equal(frame.source?.path, normalizeDebugPath(implementationSource));
|
|
233
|
+
assert.equal(frame.line, 8);
|
|
234
|
+
});
|
|
176
235
|
void it("should report the built wasm as a loaded source on launch", { timeout: 5000 }, async () => {
|
|
177
236
|
const source = sourcePath("debugger_basic.ts");
|
|
178
237
|
const output = await buildModule(source);
|
|
179
238
|
const breakpointLine = 13;
|
|
239
|
+
const traceFile = path.join(TEST_MODULE_DIR, "build", "test_debug_trace.log");
|
|
240
|
+
if (fs.existsSync(traceFile)) {
|
|
241
|
+
fs.unlinkSync(traceFile);
|
|
242
|
+
}
|
|
180
243
|
await dc.initializeRequest();
|
|
181
244
|
const breakpointResponse = await dc.setBreakpointsRequest({
|
|
182
245
|
source: { path: source },
|
|
183
246
|
breakpoints: [{ line: breakpointLine }],
|
|
184
247
|
});
|
|
185
248
|
assert.equal(breakpointResponse.body.breakpoints.length, 1);
|
|
186
|
-
assert.equal(breakpointResponse.body.breakpoints[0].verified,
|
|
249
|
+
assert.equal(breakpointResponse.body.breakpoints[0].verified, false);
|
|
187
250
|
assert.equal(breakpointResponse.body.breakpoints[0].line, breakpointLine);
|
|
188
251
|
const launchArgs = {
|
|
189
252
|
program: output,
|
|
190
253
|
launchType: "wasm file",
|
|
191
254
|
runtime: "node",
|
|
192
255
|
entryFunctionName: "_start",
|
|
256
|
+
debugSessionLogFile: traceFile,
|
|
193
257
|
};
|
|
194
258
|
const loadedSourcePromise = waitForLoadedWasmSource(dc, output);
|
|
195
259
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
196
|
-
await dc
|
|
260
|
+
await launchAndConfigure(dc, launchArgs);
|
|
197
261
|
const loadedSourceEvent = await loadedSourcePromise;
|
|
198
262
|
const loadedSourceBody = loadedSourceEvent.body;
|
|
199
263
|
await stoppedPromise;
|
|
200
264
|
assert.equal(loadedSourceBody?.reason, "new");
|
|
201
265
|
assert.equal(loadedSourceBody?.source?.path, path.resolve(output));
|
|
202
266
|
assert.equal(loadedSourceBody?.source?.name, path.basename(output));
|
|
267
|
+
assert.equal(fs.existsSync(traceFile), true, "debugSessionLogFile should be created on launch");
|
|
268
|
+
if (fs.existsSync(traceFile)) {
|
|
269
|
+
fs.unlinkSync(traceFile);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
void it("should restart the debuggee and restore breakpoints", { timeout: 10000 }, async () => {
|
|
273
|
+
const source = sourcePath("debugger_basic.ts");
|
|
274
|
+
const output = await buildModule(source);
|
|
275
|
+
const breakpointLine = 13;
|
|
276
|
+
await dc.initializeRequest();
|
|
277
|
+
await dc.setBreakpointsRequest({
|
|
278
|
+
source: { path: source },
|
|
279
|
+
breakpoints: [{ line: breakpointLine }],
|
|
280
|
+
});
|
|
281
|
+
const launchArgs = {
|
|
282
|
+
program: output,
|
|
283
|
+
launchType: "wasm file",
|
|
284
|
+
runtime: "node",
|
|
285
|
+
entryFunctionName: "_start",
|
|
286
|
+
};
|
|
287
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
288
|
+
const restartedStop = waitForBreakpointStop(dc);
|
|
289
|
+
await dc.restartRequest({});
|
|
290
|
+
await restartedStop;
|
|
291
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
292
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
293
|
+
assert.equal(frame.source?.path, normalizeDebugPath(source));
|
|
294
|
+
assert.equal(frame.line, breakpointLine);
|
|
295
|
+
await dc.disconnectRequest({ terminateDebuggee: true });
|
|
203
296
|
});
|
|
204
297
|
void it("should reject a wasm launch when the file is missing", { timeout: 5000 }, async () => {
|
|
205
298
|
await dc.initializeRequest();
|
|
@@ -211,7 +304,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
211
304
|
};
|
|
212
305
|
const stderrPromise = waitForStderrOutput(dc);
|
|
213
306
|
const terminatedPromise = dc.waitForEvent("terminated");
|
|
214
|
-
await dc
|
|
307
|
+
await launchAndConfigure(dc, launchArgs);
|
|
215
308
|
const stderrEvent = await stderrPromise;
|
|
216
309
|
const stderrBody = stderrEvent.body;
|
|
217
310
|
assert.match(stderrBody?.output ?? "", /Wasm file not found/);
|
|
@@ -229,7 +322,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
229
322
|
};
|
|
230
323
|
const stderrPromise = waitForStderrOutput(dc);
|
|
231
324
|
const terminatedPromise = dc.waitForEvent("terminated");
|
|
232
|
-
await dc
|
|
325
|
+
await launchAndConfigure(dc, launchArgs);
|
|
233
326
|
const stderrEvent = await stderrPromise;
|
|
234
327
|
const stderrBody = stderrEvent.body;
|
|
235
328
|
assert.match(stderrBody?.output ?? "", /Failed to load wasm module/);
|
|
@@ -263,6 +356,240 @@ void describe("WarpoDebugSession", () => {
|
|
|
263
356
|
const d = assertDefined(variablesResponse.body.variables.find((candidate) => candidate.name === "d"));
|
|
264
357
|
assert.equal(d.type, "f64");
|
|
265
358
|
});
|
|
359
|
+
void it("should stop in every instantiated generic function", { timeout: 10000 }, async () => {
|
|
360
|
+
const source = sourcePath("debugger_generic_function.ts");
|
|
361
|
+
const output = await buildModule(source);
|
|
362
|
+
const breakpointLine = 4;
|
|
363
|
+
await dc.initializeRequest();
|
|
364
|
+
await dc.setBreakpointsRequest({
|
|
365
|
+
source: { path: source },
|
|
366
|
+
breakpoints: [{ line: breakpointLine }],
|
|
367
|
+
});
|
|
368
|
+
const launchArgs = {
|
|
369
|
+
program: output,
|
|
370
|
+
launchType: "wasm file",
|
|
371
|
+
runtime: "node",
|
|
372
|
+
entryFunctionName: "main",
|
|
373
|
+
};
|
|
374
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
375
|
+
const firstStackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
376
|
+
const firstFrame = assertDefined(firstStackTraceResponse.body.stackFrames[0]);
|
|
377
|
+
const firstVariablesResponse = await readFrameLocals(dc, firstFrame);
|
|
378
|
+
const firstValue = assertDefined(findVariable(firstVariablesResponse.body.variables, "value"));
|
|
379
|
+
const secondStop = waitForBreakpointStop(dc);
|
|
380
|
+
await dc.continueRequest({ threadId: 1 });
|
|
381
|
+
await secondStop;
|
|
382
|
+
const secondStackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
383
|
+
const secondFrame = assertDefined(secondStackTraceResponse.body.stackFrames[0]);
|
|
384
|
+
const secondVariablesResponse = await readFrameLocals(dc, secondFrame);
|
|
385
|
+
const secondValue = assertDefined(findVariable(secondVariablesResponse.body.variables, "value"));
|
|
386
|
+
assert.deepEqual([firstValue.type, secondValue.type].toSorted((left, right) => (left ?? "").localeCompare(right ?? "")), ["f64", "i32"]);
|
|
387
|
+
assert.match(firstFrame.name, /identity</);
|
|
388
|
+
assert.match(secondFrame.name, /identity</);
|
|
389
|
+
});
|
|
390
|
+
void it("should remove a breakpoint from a concrete function", { timeout: 5000 }, async () => {
|
|
391
|
+
const source = sourcePath("debugger_basic.ts");
|
|
392
|
+
const output = await buildModule(source);
|
|
393
|
+
const breakpointLine = 13;
|
|
394
|
+
await dc.initializeRequest();
|
|
395
|
+
await dc.setBreakpointsRequest({
|
|
396
|
+
source: { path: source },
|
|
397
|
+
breakpoints: [{ line: breakpointLine }],
|
|
398
|
+
});
|
|
399
|
+
const launchArgs = {
|
|
400
|
+
program: output,
|
|
401
|
+
launchType: "wasm file",
|
|
402
|
+
runtime: "node",
|
|
403
|
+
entryFunctionName: "_start",
|
|
404
|
+
};
|
|
405
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
406
|
+
const terminatedPromise = dc.waitForEvent("terminated");
|
|
407
|
+
await dc.setBreakpointsRequest({
|
|
408
|
+
source: { path: source },
|
|
409
|
+
breakpoints: [],
|
|
410
|
+
});
|
|
411
|
+
await dc.continueRequest({ threadId: 1 });
|
|
412
|
+
await terminatedPromise;
|
|
413
|
+
});
|
|
414
|
+
void it("should remove breakpoints from every instantiated generic function", { timeout: 10000 }, async () => {
|
|
415
|
+
const source = sourcePath("debugger_generic_function.ts");
|
|
416
|
+
const output = await buildModule(source);
|
|
417
|
+
const breakpointLine = 4;
|
|
418
|
+
await dc.initializeRequest();
|
|
419
|
+
await dc.setBreakpointsRequest({
|
|
420
|
+
source: { path: source },
|
|
421
|
+
breakpoints: [{ line: breakpointLine }],
|
|
422
|
+
});
|
|
423
|
+
const launchArgs = {
|
|
424
|
+
program: output,
|
|
425
|
+
launchType: "wasm file",
|
|
426
|
+
runtime: "node",
|
|
427
|
+
entryFunctionName: "main",
|
|
428
|
+
};
|
|
429
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
430
|
+
const terminatedPromise = dc.waitForEvent("terminated");
|
|
431
|
+
await dc.setBreakpointsRequest({
|
|
432
|
+
source: { path: source },
|
|
433
|
+
breakpoints: [],
|
|
434
|
+
});
|
|
435
|
+
await dc.continueRequest({ threadId: 1 });
|
|
436
|
+
await terminatedPromise;
|
|
437
|
+
});
|
|
438
|
+
void it("should add breakpoints after launch and while the program is executing", { timeout: 10000 }, async () => {
|
|
439
|
+
const source = sourcePath("debugger_breakpoint_update.ts");
|
|
440
|
+
const output = await buildModule(source);
|
|
441
|
+
const initialBreakpointLine = 6;
|
|
442
|
+
const addedBreakpointLine = 8;
|
|
443
|
+
await dc.initializeRequest();
|
|
444
|
+
await dc.setBreakpointsRequest({
|
|
445
|
+
source: { path: source },
|
|
446
|
+
breakpoints: [{ line: initialBreakpointLine }],
|
|
447
|
+
});
|
|
448
|
+
const launchArgs = {
|
|
449
|
+
program: output,
|
|
450
|
+
launchType: "wasm file",
|
|
451
|
+
runtime: "node",
|
|
452
|
+
entryFunctionName: "_start",
|
|
453
|
+
};
|
|
454
|
+
const firstStop = waitForBreakpointStop(dc);
|
|
455
|
+
await dc.launchRequest(launchArgs);
|
|
456
|
+
const initialBreakpointResponse = await dc.setBreakpointsRequest({
|
|
457
|
+
source: { path: source },
|
|
458
|
+
breakpoints: [{ line: initialBreakpointLine }],
|
|
459
|
+
});
|
|
460
|
+
assert.equal(initialBreakpointResponse.body.breakpoints[0].line, initialBreakpointLine);
|
|
461
|
+
await dc.configurationDoneRequest({});
|
|
462
|
+
await firstStop;
|
|
463
|
+
const secondStop = waitForBreakpointStop(dc);
|
|
464
|
+
await dc.continueRequest({ threadId: 1 });
|
|
465
|
+
const breakpointResponse = await dc.setBreakpointsRequest({
|
|
466
|
+
source: { path: source },
|
|
467
|
+
breakpoints: [{ line: addedBreakpointLine }],
|
|
468
|
+
});
|
|
469
|
+
assert.equal(breakpointResponse.body.breakpoints[0].line, addedBreakpointLine);
|
|
470
|
+
await secondStop;
|
|
471
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
472
|
+
assert.equal(assertDefined(stackTraceResponse.body.stackFrames[0]).line, addedBreakpointLine);
|
|
473
|
+
await dc.disconnectRequest({ terminateDebuggee: true });
|
|
474
|
+
});
|
|
475
|
+
void it("should expose this in a class member function", { timeout: 5000 }, async () => {
|
|
476
|
+
const source = sourcePath("debugger_member_function.ts");
|
|
477
|
+
const output = await buildModule(source);
|
|
478
|
+
const breakpointLine = 12;
|
|
479
|
+
await dc.initializeRequest();
|
|
480
|
+
await dc.setBreakpointsRequest({
|
|
481
|
+
source: { path: source },
|
|
482
|
+
breakpoints: [{ line: breakpointLine }],
|
|
483
|
+
});
|
|
484
|
+
const launchArgs = {
|
|
485
|
+
program: output,
|
|
486
|
+
launchType: "wasm file",
|
|
487
|
+
runtime: "node",
|
|
488
|
+
entryFunctionName: "_start",
|
|
489
|
+
};
|
|
490
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
491
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
492
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
493
|
+
assert.match(frame.name, /Counter#add/);
|
|
494
|
+
const variablesResponse = await readFrameLocals(dc, frame);
|
|
495
|
+
const thisVariable = assertDefined(findVariable(variablesResponse.body.variables, "this"));
|
|
496
|
+
assert.ok(thisVariable.type?.endsWith("Counter"));
|
|
497
|
+
assert.ok(thisVariable.variablesReference > 0);
|
|
498
|
+
const thisFieldsResponse = await dc.variablesRequest({ variablesReference: thisVariable.variablesReference });
|
|
499
|
+
const value = assertDefined(thisFieldsResponse.body.variables.find((candidate) => candidate.name === "value"));
|
|
500
|
+
assert.equal(value.type, "i32");
|
|
501
|
+
assert.equal(value.value, "40");
|
|
502
|
+
const delta = assertDefined(findVariable(variablesResponse.body.variables, "delta"));
|
|
503
|
+
assert.equal(delta.type, "i32");
|
|
504
|
+
assert.equal(delta.value, "2");
|
|
505
|
+
});
|
|
506
|
+
void it("should expose a function object's name without its runtime fields", { timeout: 10000 }, async () => {
|
|
507
|
+
const source = sourcePath("debugger_function_closure.ts");
|
|
508
|
+
const output = await buildModule(source);
|
|
509
|
+
await dc.initializeRequest();
|
|
510
|
+
await dc.setBreakpointsRequest({
|
|
511
|
+
source: { path: source },
|
|
512
|
+
breakpoints: [{ line: 25 }],
|
|
513
|
+
});
|
|
514
|
+
const launchArgs = {
|
|
515
|
+
program: output,
|
|
516
|
+
launchType: "wasm file",
|
|
517
|
+
runtime: "node",
|
|
518
|
+
entryFunctionName: "_start",
|
|
519
|
+
};
|
|
520
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
521
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
522
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
523
|
+
const variablesResponse = await readFrameLocals(dc, frame);
|
|
524
|
+
const f1 = assertDefined(findVariable(variablesResponse.body.variables, "f1"));
|
|
525
|
+
assert.ok(f1.variablesReference > 0);
|
|
526
|
+
const f1FieldsResponse = await dc.variablesRequest({ variablesReference: f1.variablesReference });
|
|
527
|
+
assert.deepEqual(f1FieldsResponse.body.variables.map((variable) => variable.name), ["name", "[[scopes]]"]);
|
|
528
|
+
const f1Name = assertDefined(findVariable(f1FieldsResponse.body.variables, "name"));
|
|
529
|
+
assert.match(f1Name.value, /outer/);
|
|
530
|
+
assert.equal(f1Name.type, "string");
|
|
531
|
+
assert.equal(f1Name.variablesReference, 0);
|
|
532
|
+
const f1Scopes = assertDefined(findVariable(f1FieldsResponse.body.variables, "[[scopes]]"));
|
|
533
|
+
assert.equal(f1Scopes.value, "Scopes[2]");
|
|
534
|
+
assert.equal(f1Scopes.type, "Scopes");
|
|
535
|
+
assert.ok(f1Scopes.variablesReference > 0);
|
|
536
|
+
const f1ScopeArrayResponse = await dc.variablesRequest({ variablesReference: f1Scopes.variablesReference });
|
|
537
|
+
assert.deepEqual(f1ScopeArrayResponse.body.variables.map((variable) => variable.name), ["0", "1"]);
|
|
538
|
+
const f1MiddleScope = assertDefined(findVariable(f1ScopeArrayResponse.body.variables, "0"));
|
|
539
|
+
assert.equal(f1MiddleScope.value, "Closure(middle)");
|
|
540
|
+
assert.ok(f1MiddleScope.variablesReference > 0);
|
|
541
|
+
const f1MiddleScopeResponse = await dc.variablesRequest({ variablesReference: f1MiddleScope.variablesReference });
|
|
542
|
+
const f1CapturedB = assertDefined(findVariable(f1MiddleScopeResponse.body.variables, "b"));
|
|
543
|
+
assert.equal(f1CapturedB.value, "2");
|
|
544
|
+
assert.equal(f1CapturedB.type, "i32");
|
|
545
|
+
const f1OuterScope = assertDefined(findVariable(f1ScopeArrayResponse.body.variables, "1"));
|
|
546
|
+
assert.equal(f1OuterScope.value, "Closure(outer)");
|
|
547
|
+
assert.ok(f1OuterScope.variablesReference > 0);
|
|
548
|
+
const f1OuterScopeResponse = await dc.variablesRequest({ variablesReference: f1OuterScope.variablesReference });
|
|
549
|
+
const f1CapturedA = assertDefined(findVariable(f1OuterScopeResponse.body.variables, "a"));
|
|
550
|
+
assert.equal(f1CapturedA.value, "5");
|
|
551
|
+
assert.equal(f1CapturedA.type, "i32");
|
|
552
|
+
const f1CapturedC = assertDefined(findVariable(f1OuterScopeResponse.body.variables, "c"));
|
|
553
|
+
assert.ok(f1CapturedC.variablesReference > 0);
|
|
554
|
+
const f1CapturedCResponse = await dc.variablesRequest({ variablesReference: f1CapturedC.variablesReference });
|
|
555
|
+
const f1CapturedCValue = assertDefined(findVariable(f1CapturedCResponse.body.variables, "a"));
|
|
556
|
+
assert.equal(f1CapturedCValue.value, "10");
|
|
557
|
+
assert.equal(f1CapturedCValue.type, "i32");
|
|
558
|
+
const f2 = assertDefined(findVariable(variablesResponse.body.variables, "f2"));
|
|
559
|
+
assert.ok(f2.variablesReference > 0);
|
|
560
|
+
const f2FieldsResponse = await dc.variablesRequest({ variablesReference: f2.variablesReference });
|
|
561
|
+
assert.deepEqual(f2FieldsResponse.body.variables.map((variable) => variable.name), ["name", "[[scopes]]"]);
|
|
562
|
+
const f2Name = assertDefined(findVariable(f2FieldsResponse.body.variables, "name"));
|
|
563
|
+
assert.match(f2Name.value, /outer/);
|
|
564
|
+
assert.equal(f2Name.type, "string");
|
|
565
|
+
assert.equal(f2Name.variablesReference, 0);
|
|
566
|
+
const f2Scopes = assertDefined(findVariable(f2FieldsResponse.body.variables, "[[scopes]]"));
|
|
567
|
+
assert.equal(f2Scopes.value, "Scopes[2]");
|
|
568
|
+
assert.equal(f2Scopes.type, "Scopes");
|
|
569
|
+
assert.ok(f2Scopes.variablesReference > 0);
|
|
570
|
+
const f2ScopeArrayResponse = await dc.variablesRequest({ variablesReference: f2Scopes.variablesReference });
|
|
571
|
+
assert.deepEqual(f2ScopeArrayResponse.body.variables.map((variable) => variable.name), ["0", "1"]);
|
|
572
|
+
const f2MiddleScope = assertDefined(findVariable(f2ScopeArrayResponse.body.variables, "0"));
|
|
573
|
+
assert.equal(f2MiddleScope.value, "Closure(middle)");
|
|
574
|
+
assert.ok(f2MiddleScope.variablesReference > 0);
|
|
575
|
+
const f2MiddleScopeResponse = await dc.variablesRequest({ variablesReference: f2MiddleScope.variablesReference });
|
|
576
|
+
const f2CapturedB = assertDefined(findVariable(f2MiddleScopeResponse.body.variables, "b"));
|
|
577
|
+
assert.equal(f2CapturedB.value, "2");
|
|
578
|
+
assert.equal(f2CapturedB.type, "i32");
|
|
579
|
+
const f2OuterScope = assertDefined(findVariable(f2ScopeArrayResponse.body.variables, "1"));
|
|
580
|
+
assert.equal(f2OuterScope.value, "Closure(outer)");
|
|
581
|
+
assert.ok(f2OuterScope.variablesReference > 0);
|
|
582
|
+
const f2OuterScopeResponse = await dc.variablesRequest({ variablesReference: f2OuterScope.variablesReference });
|
|
583
|
+
const f2CapturedA = assertDefined(findVariable(f2OuterScopeResponse.body.variables, "a"));
|
|
584
|
+
assert.equal(f2CapturedA.value, "10");
|
|
585
|
+
assert.equal(f2CapturedA.type, "i32");
|
|
586
|
+
const f2CapturedC = assertDefined(findVariable(f2OuterScopeResponse.body.variables, "c"));
|
|
587
|
+
assert.ok(f2CapturedC.variablesReference > 0);
|
|
588
|
+
const f2CapturedCResponse = await dc.variablesRequest({ variablesReference: f2CapturedC.variablesReference });
|
|
589
|
+
const f2CapturedCValue = assertDefined(findVariable(f2CapturedCResponse.body.variables, "a"));
|
|
590
|
+
assert.equal(f2CapturedCValue.value, "15");
|
|
591
|
+
assert.equal(f2CapturedCValue.type, "i32");
|
|
592
|
+
});
|
|
266
593
|
void it("should expose wasm call stack frames after hitting a breakpoint", { timeout: 5000 }, async () => {
|
|
267
594
|
const source = sourcePath("debugger_basic.ts");
|
|
268
595
|
const output = await buildModule(source);
|
|
@@ -328,7 +655,6 @@ void describe("WarpoDebugSession", () => {
|
|
|
328
655
|
const calleeSource = sourcePath("debugger_callee.ts");
|
|
329
656
|
const output = await buildModule(entrySource, [calleeSource]);
|
|
330
657
|
const breakpointLine = 41;
|
|
331
|
-
await dc.initializeRequest();
|
|
332
658
|
await dc.setBreakpointsRequest({
|
|
333
659
|
source: { path: calleeSource },
|
|
334
660
|
breakpoints: [{ line: breakpointLine }],
|
|
@@ -356,6 +682,184 @@ void describe("WarpoDebugSession", () => {
|
|
|
356
682
|
assert.equal(callerSeed.type, "i32");
|
|
357
683
|
assert.equal(callerSeed.value, "23");
|
|
358
684
|
});
|
|
685
|
+
void it("should step into a callee", { timeout: 10000 }, async () => {
|
|
686
|
+
const entrySource = sourcePath("debugger_stepping.ts");
|
|
687
|
+
const output = await buildModule(entrySource);
|
|
688
|
+
await dc.initializeRequest();
|
|
689
|
+
await dc.setBreakpointsRequest({
|
|
690
|
+
source: { path: entrySource },
|
|
691
|
+
breakpoints: [{ line: 5 }],
|
|
692
|
+
});
|
|
693
|
+
const launchArgs = {
|
|
694
|
+
program: output,
|
|
695
|
+
launchType: "wasm file",
|
|
696
|
+
runtime: "node",
|
|
697
|
+
entryFunctionName: "_start",
|
|
698
|
+
};
|
|
699
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
700
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
701
|
+
await dc.stepInRequest({ threadId: 1 });
|
|
702
|
+
await stoppedPromise;
|
|
703
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
704
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
705
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
706
|
+
assert.equal(frame.line, 11);
|
|
707
|
+
});
|
|
708
|
+
void it("should pause at a valid source line", { timeout: 10000 }, async () => {
|
|
709
|
+
const entrySource = sourcePath("debugger_pause.ts");
|
|
710
|
+
const output = await buildModule(entrySource);
|
|
711
|
+
await dc.initializeRequest();
|
|
712
|
+
await dc.setBreakpointsRequest({
|
|
713
|
+
source: { path: entrySource },
|
|
714
|
+
breakpoints: [{ line: 4 }],
|
|
715
|
+
});
|
|
716
|
+
const launchArgs = {
|
|
717
|
+
program: output,
|
|
718
|
+
launchType: "wasm file",
|
|
719
|
+
runtime: "node",
|
|
720
|
+
entryFunctionName: "_start",
|
|
721
|
+
};
|
|
722
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
723
|
+
const continuedPromise = dc.waitForEvent("continued");
|
|
724
|
+
await dc.continueRequest({ threadId: 1 });
|
|
725
|
+
await continuedPromise;
|
|
726
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
727
|
+
await dc.pauseRequest({ threadId: 1 });
|
|
728
|
+
const stoppedEvent = await stoppedPromise;
|
|
729
|
+
const stoppedBody = stoppedEvent.body;
|
|
730
|
+
assert.equal(stoppedBody?.reason, "pause");
|
|
731
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
732
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
733
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
734
|
+
assert.ok(frame.line > 0);
|
|
735
|
+
const terminatedPromise = dc.waitForEvent("terminated");
|
|
736
|
+
await dc.terminateRequest({ restart: false });
|
|
737
|
+
await terminatedPromise;
|
|
738
|
+
});
|
|
739
|
+
void it("should step out of a callee and stop at the caller", { timeout: 10000 }, async () => {
|
|
740
|
+
const entrySource = sourcePath("debugger_stepping.ts");
|
|
741
|
+
const output = await buildModule(entrySource);
|
|
742
|
+
await dc.initializeRequest();
|
|
743
|
+
await dc.setBreakpointsRequest({
|
|
744
|
+
source: { path: entrySource },
|
|
745
|
+
breakpoints: [{ line: 5 }],
|
|
746
|
+
});
|
|
747
|
+
const launchArgs = {
|
|
748
|
+
program: output,
|
|
749
|
+
launchType: "wasm file",
|
|
750
|
+
runtime: "node",
|
|
751
|
+
entryFunctionName: "_start",
|
|
752
|
+
};
|
|
753
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
754
|
+
const enteredCallee = dc.waitForEvent("stopped");
|
|
755
|
+
await dc.stepInRequest({ threadId: 1 });
|
|
756
|
+
await enteredCallee;
|
|
757
|
+
const returnedToCaller = dc.waitForEvent("stopped");
|
|
758
|
+
await dc.stepOutRequest({ threadId: 1 });
|
|
759
|
+
await returnedToCaller;
|
|
760
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
761
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
762
|
+
assert.match(frame.name, /_start/);
|
|
763
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
764
|
+
assert.equal(frame.line, 5);
|
|
765
|
+
});
|
|
766
|
+
void it("should step over a callee and stop at the caller's next line", { timeout: 10000 }, async () => {
|
|
767
|
+
const entrySource = sourcePath("debugger_stepping.ts");
|
|
768
|
+
const output = await buildModule(entrySource);
|
|
769
|
+
await dc.initializeRequest();
|
|
770
|
+
const breakpointResponse = await dc.setBreakpointsRequest({
|
|
771
|
+
source: { path: entrySource },
|
|
772
|
+
breakpoints: [{ line: 5 }],
|
|
773
|
+
});
|
|
774
|
+
assert.equal(breakpointResponse.body.breakpoints.length, 1);
|
|
775
|
+
const launchArgs = {
|
|
776
|
+
program: output,
|
|
777
|
+
launchType: "wasm file",
|
|
778
|
+
runtime: "node",
|
|
779
|
+
entryFunctionName: "_start",
|
|
780
|
+
};
|
|
781
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
782
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
783
|
+
await dc.nextRequest({ threadId: 1 });
|
|
784
|
+
await stoppedPromise;
|
|
785
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
786
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
787
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
788
|
+
assert.equal(frame.line, 6);
|
|
789
|
+
});
|
|
790
|
+
void it("should step over a function-object call and stop at the caller's next line", { timeout: 10000 }, async () => {
|
|
791
|
+
const entrySource = sourcePath("debugger_stepping.ts");
|
|
792
|
+
const output = await buildModule(entrySource);
|
|
793
|
+
await dc.initializeRequest();
|
|
794
|
+
const breakpointResponse = await dc.setBreakpointsRequest({
|
|
795
|
+
source: { path: entrySource },
|
|
796
|
+
breakpoints: [{ line: 18 }],
|
|
797
|
+
});
|
|
798
|
+
assert.equal(breakpointResponse.body.breakpoints.length, 1);
|
|
799
|
+
const launchArgs = {
|
|
800
|
+
program: output,
|
|
801
|
+
launchType: "wasm file",
|
|
802
|
+
runtime: "node",
|
|
803
|
+
entryFunctionName: "indirectStart",
|
|
804
|
+
};
|
|
805
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
806
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
807
|
+
await dc.nextRequest({ threadId: 1 });
|
|
808
|
+
await stoppedPromise;
|
|
809
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
810
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
811
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
812
|
+
assert.equal(frame.line, 19);
|
|
813
|
+
});
|
|
814
|
+
void it("should step into a function-object call", { timeout: 10000 }, async () => {
|
|
815
|
+
const entrySource = sourcePath("debugger_stepping.ts");
|
|
816
|
+
const output = await buildModule(entrySource);
|
|
817
|
+
await dc.initializeRequest();
|
|
818
|
+
const breakpointResponse = await dc.setBreakpointsRequest({
|
|
819
|
+
source: { path: entrySource },
|
|
820
|
+
breakpoints: [{ line: 18 }],
|
|
821
|
+
});
|
|
822
|
+
assert.equal(breakpointResponse.body.breakpoints.length, 1);
|
|
823
|
+
const launchArgs = {
|
|
824
|
+
program: output,
|
|
825
|
+
launchType: "wasm file",
|
|
826
|
+
runtime: "node",
|
|
827
|
+
entryFunctionName: "indirectStart",
|
|
828
|
+
};
|
|
829
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
830
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
831
|
+
await dc.stepInRequest({ threadId: 1 });
|
|
832
|
+
await stoppedPromise;
|
|
833
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
834
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
835
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
836
|
+
assert.equal(frame.line, 11);
|
|
837
|
+
});
|
|
838
|
+
void it("should step over a call that is the last instruction of a function", { timeout: 10000 }, async () => {
|
|
839
|
+
const entrySource = sourcePath("debugger_stepping.ts");
|
|
840
|
+
const output = await buildModule(entrySource);
|
|
841
|
+
await dc.initializeRequest();
|
|
842
|
+
const breakpointResponse = await dc.setBreakpointsRequest({
|
|
843
|
+
source: { path: entrySource },
|
|
844
|
+
breakpoints: [{ line: 24 }],
|
|
845
|
+
});
|
|
846
|
+
assert.equal(breakpointResponse.body.breakpoints.length, 1);
|
|
847
|
+
const launchArgs = {
|
|
848
|
+
program: output,
|
|
849
|
+
launchType: "wasm file",
|
|
850
|
+
runtime: "node",
|
|
851
|
+
entryFunctionName: "tailCallStart",
|
|
852
|
+
};
|
|
853
|
+
await launchAndWaitForBreakpoint(dc, launchArgs);
|
|
854
|
+
const stoppedPromise = dc.waitForEvent("stopped");
|
|
855
|
+
await dc.nextRequest({ threadId: 1 });
|
|
856
|
+
await stoppedPromise;
|
|
857
|
+
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
858
|
+
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
859
|
+
assert.match(frame.name, /tailCallStart/);
|
|
860
|
+
assert.equal(frame.source?.path, normalizeDebugPath(entrySource));
|
|
861
|
+
assert.equal(frame.line, 29);
|
|
862
|
+
});
|
|
359
863
|
void it("should stop on a return breakpoint before evaluating its value", { timeout: 5000 }, async () => {
|
|
360
864
|
const entrySource = sourcePath("debugger_caller.ts");
|
|
361
865
|
const calleeSource = sourcePath("debugger_callee.ts");
|
|
@@ -420,7 +924,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
420
924
|
entryFunctionName: "_start",
|
|
421
925
|
};
|
|
422
926
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
423
|
-
await dc
|
|
927
|
+
await launchAndConfigure(dc, launchArgs);
|
|
424
928
|
await stoppedPromise;
|
|
425
929
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
426
930
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -473,7 +977,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
473
977
|
entryFunctionName: "_start",
|
|
474
978
|
};
|
|
475
979
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
476
|
-
await dc
|
|
980
|
+
await launchAndConfigure(dc, launchArgs);
|
|
477
981
|
await stoppedPromise;
|
|
478
982
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
479
983
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -511,7 +1015,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
511
1015
|
entryFunctionName: "_start",
|
|
512
1016
|
};
|
|
513
1017
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
514
|
-
await dc
|
|
1018
|
+
await launchAndConfigure(dc, launchArgs);
|
|
515
1019
|
await stoppedPromise;
|
|
516
1020
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
517
1021
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -567,6 +1071,79 @@ void describe("WarpoDebugSession", () => {
|
|
|
567
1071
|
{ name: "2", type: "u8", value: "34", variablesReference: 0 },
|
|
568
1072
|
]);
|
|
569
1073
|
});
|
|
1074
|
+
void it("should display utf8.ConstStr values", { timeout: 5000 }, async () => {
|
|
1075
|
+
const source = sourcePath("debugger_utf8_const_str.ts");
|
|
1076
|
+
const output = await buildModule(source);
|
|
1077
|
+
const breakpointLine = 11;
|
|
1078
|
+
await dc.initializeRequest();
|
|
1079
|
+
await dc.setBreakpointsRequest({
|
|
1080
|
+
source: { path: source },
|
|
1081
|
+
breakpoints: [{ line: breakpointLine }],
|
|
1082
|
+
});
|
|
1083
|
+
const launchArgs = {
|
|
1084
|
+
program: output,
|
|
1085
|
+
launchType: "wasm file",
|
|
1086
|
+
runtime: "node",
|
|
1087
|
+
entryFunctionName: "_start",
|
|
1088
|
+
};
|
|
1089
|
+
const { variablesResponse } = await launchAndReadTopFrameLocals(dc, launchArgs);
|
|
1090
|
+
const value = assertDefined(findVariable(variablesResponse.body.variables, "s"));
|
|
1091
|
+
assert.equal(value.type, "~lib/warpo/utf8/const_str/ConstStr");
|
|
1092
|
+
assert.equal(value.value, '"abcdef"');
|
|
1093
|
+
assert.equal(value.variablesReference, 0);
|
|
1094
|
+
});
|
|
1095
|
+
void it("should expand typed array values by index", { timeout: 5000 }, async () => {
|
|
1096
|
+
const source = sourcePath("debugger_typed_array.ts");
|
|
1097
|
+
const output = await buildModule(source);
|
|
1098
|
+
const breakpointLine = 41;
|
|
1099
|
+
await dc.initializeRequest();
|
|
1100
|
+
await dc.setBreakpointsRequest({
|
|
1101
|
+
source: { path: source },
|
|
1102
|
+
breakpoints: [{ line: breakpointLine }],
|
|
1103
|
+
});
|
|
1104
|
+
const launchArgs = {
|
|
1105
|
+
program: output,
|
|
1106
|
+
launchType: "wasm file",
|
|
1107
|
+
runtime: "node",
|
|
1108
|
+
entryFunctionName: "_start",
|
|
1109
|
+
};
|
|
1110
|
+
const { variablesResponse } = await launchAndReadTopFrameLocals(dc, launchArgs);
|
|
1111
|
+
const expected = [
|
|
1112
|
+
{ name: "int8", type: "~lib/typedarray/Int8Array", elementType: "i8", values: ["-8", "8"] },
|
|
1113
|
+
{ name: "uint8", type: "~lib/typedarray/Uint8Array", elementType: "u8", values: ["9", "19"] },
|
|
1114
|
+
{
|
|
1115
|
+
name: "uint8Clamped",
|
|
1116
|
+
type: "~lib/typedarray/Uint8ClampedArray",
|
|
1117
|
+
elementType: "u8",
|
|
1118
|
+
values: ["29", "39"],
|
|
1119
|
+
},
|
|
1120
|
+
{ name: "int16", type: "~lib/typedarray/Int16Array", elementType: "i16", values: ["-49", "49"] },
|
|
1121
|
+
{ name: "uint16", type: "~lib/typedarray/Uint16Array", elementType: "u16", values: ["59", "69"] },
|
|
1122
|
+
{ name: "int32", type: "~lib/typedarray/Int32Array", elementType: "i32", values: ["-79", "79"] },
|
|
1123
|
+
{ name: "uint32", type: "~lib/typedarray/Uint32Array", elementType: "u32", values: ["89", "99"] },
|
|
1124
|
+
{ name: "int64", type: "~lib/typedarray/Int64Array", elementType: "i64", values: ["-109", "109"] },
|
|
1125
|
+
{ name: "uint64", type: "~lib/typedarray/Uint64Array", elementType: "u64", values: ["119", "129"] },
|
|
1126
|
+
{ name: "float32", type: "~lib/typedarray/Float32Array", elementType: "f32", values: ["1.5", "2.5"] },
|
|
1127
|
+
{ name: "float64", type: "~lib/typedarray/Float64Array", elementType: "f64", values: ["3.5", "4.5"] },
|
|
1128
|
+
];
|
|
1129
|
+
for (const expectedArray of expected) {
|
|
1130
|
+
const variable = assertDefined(findVariable(variablesResponse.body.variables, expectedArray.name));
|
|
1131
|
+
assert.equal(variable.type, expectedArray.type);
|
|
1132
|
+
assert.ok(variable.variablesReference > 0);
|
|
1133
|
+
const elementsResponse = await dc.variablesRequest({ variablesReference: variable.variablesReference });
|
|
1134
|
+
assert.deepEqual(elementsResponse.body.variables.map((element) => ({
|
|
1135
|
+
name: element.name,
|
|
1136
|
+
type: element.type,
|
|
1137
|
+
value: element.value,
|
|
1138
|
+
variablesReference: element.variablesReference,
|
|
1139
|
+
})), expectedArray.values.map((value, index) => ({
|
|
1140
|
+
name: index.toString(),
|
|
1141
|
+
type: expectedArray.elementType,
|
|
1142
|
+
value,
|
|
1143
|
+
variablesReference: 0,
|
|
1144
|
+
})));
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
570
1147
|
void it("should expand class array elements as objects", { timeout: 5000 }, async () => {
|
|
571
1148
|
const source = sourcePath("debugger_class_array.ts");
|
|
572
1149
|
const output = await buildModule(source);
|
|
@@ -583,7 +1160,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
583
1160
|
entryFunctionName: "_start",
|
|
584
1161
|
};
|
|
585
1162
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
586
|
-
await dc
|
|
1163
|
+
await launchAndConfigure(dc, launchArgs);
|
|
587
1164
|
await stoppedPromise;
|
|
588
1165
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
589
1166
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -629,7 +1206,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
629
1206
|
entryFunctionName: "_start",
|
|
630
1207
|
};
|
|
631
1208
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
632
|
-
await dc
|
|
1209
|
+
await launchAndConfigure(dc, launchArgs);
|
|
633
1210
|
await stoppedPromise;
|
|
634
1211
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
635
1212
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -675,7 +1252,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
675
1252
|
entryFunctionName: "_start",
|
|
676
1253
|
};
|
|
677
1254
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
678
|
-
await dc
|
|
1255
|
+
await launchAndConfigure(dc, launchArgs);
|
|
679
1256
|
await stoppedPromise;
|
|
680
1257
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
681
1258
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -737,7 +1314,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
737
1314
|
entryFunctionName: "_start",
|
|
738
1315
|
};
|
|
739
1316
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
740
|
-
await dc
|
|
1317
|
+
await launchAndConfigure(dc, launchArgs);
|
|
741
1318
|
await stoppedPromise;
|
|
742
1319
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
743
1320
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -798,7 +1375,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
798
1375
|
entryFunctionName: "_start",
|
|
799
1376
|
};
|
|
800
1377
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
801
|
-
await dc
|
|
1378
|
+
await launchAndConfigure(dc, launchArgs);
|
|
802
1379
|
await stoppedPromise;
|
|
803
1380
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
804
1381
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -882,7 +1459,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
882
1459
|
entryFunctionName: "_start",
|
|
883
1460
|
};
|
|
884
1461
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
885
|
-
await dc
|
|
1462
|
+
await launchAndConfigure(dc, launchArgs);
|
|
886
1463
|
await stoppedPromise;
|
|
887
1464
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
888
1465
|
const frame = stackTraceResponse.body.stackFrames[0];
|
|
@@ -958,7 +1535,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
958
1535
|
entryFunctionName: "_start",
|
|
959
1536
|
};
|
|
960
1537
|
const stoppedPromise = waitForBreakpointStop(dc);
|
|
961
|
-
await dc
|
|
1538
|
+
await launchAndConfigure(dc, launchArgs);
|
|
962
1539
|
await stoppedPromise;
|
|
963
1540
|
const stackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
964
1541
|
const frame = assertDefined(stackTraceResponse.body.stackFrames[0]);
|
|
@@ -1003,7 +1580,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
1003
1580
|
entryFunctionName: "_start",
|
|
1004
1581
|
};
|
|
1005
1582
|
const firstStoppedPromise = waitForBreakpointStop(dc);
|
|
1006
|
-
await dc
|
|
1583
|
+
await launchAndConfigure(dc, launchArgs);
|
|
1007
1584
|
await firstStoppedPromise;
|
|
1008
1585
|
const firstStackTraceResponse = await dc.stackTraceRequest({ threadId: 1, startFrame: 0, levels: 1 });
|
|
1009
1586
|
const firstScopesResponse = await dc.scopesRequest({ frameId: firstStackTraceResponse.body.stackFrames[0].id });
|
|
@@ -1079,7 +1656,7 @@ void describe("WarpoDebugSession", () => {
|
|
|
1079
1656
|
};
|
|
1080
1657
|
const stoppedPromise = dc.waitForEvent("stopped");
|
|
1081
1658
|
const terminatedPromise = dc.waitForEvent("terminated");
|
|
1082
|
-
await dc
|
|
1659
|
+
await launchAndConfigure(dc, launchArgs);
|
|
1083
1660
|
const stoppedEvent = await stoppedPromise;
|
|
1084
1661
|
const stoppedBody = stoppedEvent.body;
|
|
1085
1662
|
assert.equal(stoppedBody?.reason, "exception");
|