@ton/sandbox 0.21.0-debugger.2 → 0.21.0-debugger.3
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/dist/debugger/DebugInfoCache.js +22 -4
- package/dist/debugger/Debuggee.d.ts +32 -5
- package/dist/debugger/Debuggee.js +90 -13
- package/dist/debugger/TVMDebugSession.js +23 -12
- package/dist/executor/Executor.d.ts +4 -0
- package/dist/executor/Executor.js +22 -0
- package/dist/executor/emulator-emscripten.js +1 -1
- package/dist/executor/emulator-emscripten.wasm.js +1 -1
- package/package.json +3 -2
|
@@ -14,13 +14,31 @@ function registerCompiledContract(c) {
|
|
|
14
14
|
const sm = {};
|
|
15
15
|
for (let i = 0; i < locations.length; i++) {
|
|
16
16
|
const di = locations[i];
|
|
17
|
-
|
|
18
|
-
continue;
|
|
19
|
-
sm[i] = {
|
|
17
|
+
const common = {
|
|
20
18
|
path: (0, node_path_1.resolve)(di.file),
|
|
21
19
|
line: di.line,
|
|
22
|
-
|
|
20
|
+
function: di.func,
|
|
23
21
|
};
|
|
22
|
+
if (di.ret) {
|
|
23
|
+
sm[i] = {
|
|
24
|
+
...common,
|
|
25
|
+
type: 'return',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
else if (di.is_catch) {
|
|
29
|
+
sm[i] = {
|
|
30
|
+
...common,
|
|
31
|
+
type: 'catch',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sm[i] = {
|
|
36
|
+
...common,
|
|
37
|
+
type: 'statement',
|
|
38
|
+
variables: di.vars ?? [],
|
|
39
|
+
firstStatement: di.first_stmt,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
24
42
|
}
|
|
25
43
|
exports.defaultDebugInfoCache.set(c.code.hash().toString('base64'), {
|
|
26
44
|
sourceMap: sm,
|
|
@@ -2,11 +2,19 @@
|
|
|
2
2
|
import EventEmitter from 'node:events';
|
|
3
3
|
import { Executor, GetMethodArgs, RunTransactionArgs } from '../executor/Executor';
|
|
4
4
|
import { Cell, TupleItem } from '@ton/core';
|
|
5
|
-
export type SourceMapEntry = {
|
|
5
|
+
export type SourceMapEntry = ({
|
|
6
6
|
path: string;
|
|
7
7
|
line: number;
|
|
8
|
+
function: string;
|
|
9
|
+
}) & ({
|
|
10
|
+
type: 'statement';
|
|
8
11
|
variables: string[];
|
|
9
|
-
|
|
12
|
+
firstStatement?: true;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'return';
|
|
15
|
+
} | {
|
|
16
|
+
type: 'catch';
|
|
17
|
+
});
|
|
10
18
|
export type SourceMap = {
|
|
11
19
|
[k: number]: SourceMapEntry;
|
|
12
20
|
};
|
|
@@ -26,6 +34,11 @@ export type Variable = {
|
|
|
26
34
|
name: string;
|
|
27
35
|
value: TupleItem;
|
|
28
36
|
};
|
|
37
|
+
type StackFrame = {
|
|
38
|
+
function: string;
|
|
39
|
+
path: string;
|
|
40
|
+
line: number;
|
|
41
|
+
};
|
|
29
42
|
export declare class Debuggee extends EventEmitter {
|
|
30
43
|
executor: Executor;
|
|
31
44
|
ptr: number;
|
|
@@ -37,7 +50,7 @@ export declare class Debuggee extends EventEmitter {
|
|
|
37
50
|
codeCells: Map<string, Cell>;
|
|
38
51
|
breakpoints: Map<string, Breakpoint[]>;
|
|
39
52
|
breakpointID: number;
|
|
40
|
-
frames:
|
|
53
|
+
frames: StackFrame[];
|
|
41
54
|
globals: GlobalEntry[];
|
|
42
55
|
finishedCallback: (v: any) => void;
|
|
43
56
|
constructor(executor: Executor, finishedCallback: (v: any) => void);
|
|
@@ -49,7 +62,9 @@ export declare class Debuggee extends EventEmitter {
|
|
|
49
62
|
getAvailableLines(path: string): number[];
|
|
50
63
|
isLineAvailable(path: string, line: number): boolean;
|
|
51
64
|
continue(): void;
|
|
52
|
-
|
|
65
|
+
stepIn(): void;
|
|
66
|
+
stepOver(): void;
|
|
67
|
+
stepOut(): void;
|
|
53
68
|
startGetMethod(args: GetMethodArgs): void;
|
|
54
69
|
startTransaction(args: RunTransactionArgs): void;
|
|
55
70
|
getC7(): TupleItem;
|
|
@@ -59,6 +74,8 @@ export declare class Debuggee extends EventEmitter {
|
|
|
59
74
|
offset: number;
|
|
60
75
|
};
|
|
61
76
|
getStack(): TupleItem[];
|
|
77
|
+
getContParam(): number;
|
|
78
|
+
setContParam(param: number): number;
|
|
62
79
|
getLocalVariables(): Variable[] | undefined;
|
|
63
80
|
getGlobalVariables(): Variable[] | undefined;
|
|
64
81
|
currentDebugInfoNumber(): number | undefined;
|
|
@@ -73,7 +90,17 @@ export declare class Debuggee extends EventEmitter {
|
|
|
73
90
|
setBreakpoint(path: string, line: number): Breakpoint;
|
|
74
91
|
sendEvent(event: string, ...args: any[]): void;
|
|
75
92
|
onFinished(): void;
|
|
76
|
-
|
|
93
|
+
stackFrames(): StackFrame[];
|
|
94
|
+
stepUntil(what: {
|
|
95
|
+
type: 'breakpoint';
|
|
96
|
+
} | {
|
|
97
|
+
type: 'any-line';
|
|
98
|
+
stopEvent: 'stopOnBreakpoint' | 'stopOnStep';
|
|
99
|
+
} | {
|
|
100
|
+
type: 'next-line';
|
|
101
|
+
} | {
|
|
102
|
+
type: 'out';
|
|
103
|
+
}): void;
|
|
77
104
|
prepareGetMethod(args: GetMethodArgs, debugInfo: DebugInfo): void;
|
|
78
105
|
prepareTransaction(args: RunTransactionArgs, code: Cell, debugInfo: DebugInfo): void;
|
|
79
106
|
start(debug: boolean, stopOnEntry: boolean): void;
|
|
@@ -63,10 +63,16 @@ class Debuggee extends node_events_1.default {
|
|
|
63
63
|
return lines.indexOf(line) >= 0;
|
|
64
64
|
}
|
|
65
65
|
continue() {
|
|
66
|
-
this.
|
|
66
|
+
this.stepUntil({ type: 'breakpoint' });
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
this.
|
|
68
|
+
stepIn() {
|
|
69
|
+
this.stepUntil({ type: 'any-line', stopEvent: 'stopOnStep' });
|
|
70
|
+
}
|
|
71
|
+
stepOver() {
|
|
72
|
+
this.stepUntil({ type: 'next-line' });
|
|
73
|
+
}
|
|
74
|
+
stepOut() {
|
|
75
|
+
this.stepUntil({ type: 'out' });
|
|
70
76
|
}
|
|
71
77
|
startGetMethod(args) {
|
|
72
78
|
this.ptr = this.executor.sbsGetMethodSetup(args);
|
|
@@ -112,9 +118,25 @@ class Debuggee extends node_events_1.default {
|
|
|
112
118
|
return this.executor.sbsTransactionStack(this.ptr);
|
|
113
119
|
}
|
|
114
120
|
}
|
|
121
|
+
getContParam() {
|
|
122
|
+
switch (this.debugType) {
|
|
123
|
+
case 'get':
|
|
124
|
+
return this.executor.sbsGetMethodGetContParam(this.ptr);
|
|
125
|
+
case 'tx':
|
|
126
|
+
return this.executor.sbsTransactionGetContParam(this.ptr);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
setContParam(param) {
|
|
130
|
+
switch (this.debugType) {
|
|
131
|
+
case 'get':
|
|
132
|
+
return this.executor.sbsGetMethodSetContParam(this.ptr, param);
|
|
133
|
+
case 'tx':
|
|
134
|
+
return this.executor.sbsTransactionSetContParam(this.ptr, param);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
115
137
|
getLocalVariables() {
|
|
116
138
|
const sme = this.currentSourceMapEntry();
|
|
117
|
-
if (sme === undefined) {
|
|
139
|
+
if (sme === undefined || sme.type !== 'statement') {
|
|
118
140
|
return undefined;
|
|
119
141
|
}
|
|
120
142
|
const vars = [];
|
|
@@ -231,7 +253,20 @@ class Debuggee extends node_events_1.default {
|
|
|
231
253
|
}
|
|
232
254
|
this.finishedCallback(r);
|
|
233
255
|
}
|
|
234
|
-
|
|
256
|
+
stackFrames() {
|
|
257
|
+
return this.frames;
|
|
258
|
+
}
|
|
259
|
+
stepUntil(what) {
|
|
260
|
+
let until;
|
|
261
|
+
switch (what.type) {
|
|
262
|
+
case 'next-line':
|
|
263
|
+
case 'out': {
|
|
264
|
+
until = { type: what.type, depth: this.frames.length };
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
default:
|
|
268
|
+
until = what;
|
|
269
|
+
}
|
|
235
270
|
while (true) {
|
|
236
271
|
const finished = this.vmStep();
|
|
237
272
|
if (finished) {
|
|
@@ -239,14 +274,56 @@ class Debuggee extends node_events_1.default {
|
|
|
239
274
|
return;
|
|
240
275
|
}
|
|
241
276
|
const sme = this.currentSourceMapEntry();
|
|
242
|
-
if (sme !== undefined
|
|
243
|
-
|
|
244
|
-
|
|
277
|
+
if (sme !== undefined) {
|
|
278
|
+
switch (sme.type) {
|
|
279
|
+
case 'statement': {
|
|
280
|
+
if (sme.firstStatement) {
|
|
281
|
+
this.frames.push({
|
|
282
|
+
function: sme.function,
|
|
283
|
+
path: sme.path,
|
|
284
|
+
line: sme.line,
|
|
285
|
+
});
|
|
286
|
+
this.setContParam(this.frames.length);
|
|
287
|
+
}
|
|
288
|
+
this.frames[this.frames.length - 1].line = sme.line;
|
|
289
|
+
switch (until.type) {
|
|
290
|
+
case 'breakpoint': {
|
|
291
|
+
if (this.hasBreakpoint(sme.path, sme.line)) {
|
|
292
|
+
this.sendEvent('stopOnBreakpoint');
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case 'any-line': {
|
|
298
|
+
this.sendEvent(until.stopEvent);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
case 'next-line': {
|
|
302
|
+
if (this.frames.length <= until.depth) {
|
|
303
|
+
this.sendEvent('stopOnStep');
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
case 'out': {
|
|
309
|
+
if (this.frames.length < until.depth) {
|
|
310
|
+
this.sendEvent('stopOnStep');
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case 'return': {
|
|
319
|
+
this.frames.pop();
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case 'catch': {
|
|
323
|
+
this.frames = this.frames.slice(0, this.getContParam());
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
245
326
|
}
|
|
246
|
-
else if (stopEvent !== undefined) {
|
|
247
|
-
this.sendEvent(stopEvent);
|
|
248
|
-
}
|
|
249
|
-
return;
|
|
250
327
|
}
|
|
251
328
|
}
|
|
252
329
|
}
|
|
@@ -263,7 +340,7 @@ class Debuggee extends node_events_1.default {
|
|
|
263
340
|
start(debug, stopOnEntry) {
|
|
264
341
|
if (debug) {
|
|
265
342
|
if (stopOnEntry) {
|
|
266
|
-
this.
|
|
343
|
+
this.stepUntil({ type: 'any-line', stopEvent: 'stopOnBreakpoint' });
|
|
267
344
|
}
|
|
268
345
|
else {
|
|
269
346
|
this.continue();
|
|
@@ -139,15 +139,15 @@ class TVMDebugSession extends debugadapter_1.LoggingDebugSession {
|
|
|
139
139
|
this.sendResponse(response);
|
|
140
140
|
}
|
|
141
141
|
nextRequest(response, args, request) {
|
|
142
|
-
this.debuggee.
|
|
142
|
+
this.debuggee.stepOver();
|
|
143
143
|
this.sendResponse(response);
|
|
144
144
|
}
|
|
145
145
|
stepInRequest(response, args, request) {
|
|
146
|
-
this.debuggee.
|
|
146
|
+
this.debuggee.stepIn();
|
|
147
147
|
this.sendResponse(response);
|
|
148
148
|
}
|
|
149
149
|
stepOutRequest(response, args, request) {
|
|
150
|
-
this.debuggee.
|
|
150
|
+
this.debuggee.stepOut();
|
|
151
151
|
this.sendResponse(response);
|
|
152
152
|
}
|
|
153
153
|
stackTraceRequest(response, args, request) {
|
|
@@ -159,26 +159,37 @@ class TVMDebugSession extends debugadapter_1.LoggingDebugSession {
|
|
|
159
159
|
this.sendResponse(response);
|
|
160
160
|
return;
|
|
161
161
|
}
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
const frames = this.debuggee.stackFrames();
|
|
163
|
+
response.body.totalFrames = frames.length;
|
|
164
|
+
if (args.startFrame ?? 0 >= frames.length) {
|
|
164
165
|
response.body.stackFrames = [];
|
|
165
166
|
this.sendResponse(response);
|
|
166
167
|
return;
|
|
167
168
|
}
|
|
168
|
-
response.body.stackFrames = [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
response.body.stackFrames = [];
|
|
170
|
+
for (let i = args.startFrame ?? 0; i < frames.length; i++) {
|
|
171
|
+
const frame = frames[i];
|
|
172
|
+
response.body.stackFrames.push({
|
|
173
|
+
id: i === frames.length - 1 ? TVMDebugSession.stackFrameID : 0,
|
|
174
|
+
name: frame.function,
|
|
175
|
+
line: frame.line,
|
|
172
176
|
column: 0,
|
|
173
177
|
source: {
|
|
174
|
-
name: (0, node_path_1.basename)(
|
|
175
|
-
path:
|
|
178
|
+
name: (0, node_path_1.basename)(frame.path),
|
|
179
|
+
path: frame.path,
|
|
176
180
|
},
|
|
177
|
-
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
response.body.stackFrames.reverse();
|
|
178
184
|
this.sendResponse(response);
|
|
179
185
|
}
|
|
180
186
|
scopesRequest(response, args, request) {
|
|
181
187
|
response.body = response.body || {};
|
|
188
|
+
if (args.frameId !== TVMDebugSession.stackFrameID) {
|
|
189
|
+
response.body.scopes = [];
|
|
190
|
+
this.sendResponse(response);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
182
193
|
const sme = this.debuggee.currentSourceMapEntry();
|
|
183
194
|
if (sme === undefined) {
|
|
184
195
|
response.body.scopes = [];
|
|
@@ -99,6 +99,8 @@ export declare class Executor implements IExecutor {
|
|
|
99
99
|
sbsGetMethodStep(ptr: number): boolean;
|
|
100
100
|
sbsGetMethodStack(ptr: number): TupleItem[];
|
|
101
101
|
sbsGetMethodC7(ptr: number): TupleItem;
|
|
102
|
+
sbsGetMethodGetContParam(ptr: number): number;
|
|
103
|
+
sbsGetMethodSetContParam(ptr: number, param: number): number;
|
|
102
104
|
sbsGetMethodCodePos(ptr: number): {
|
|
103
105
|
hash: string;
|
|
104
106
|
offset: number;
|
|
@@ -116,5 +118,7 @@ export declare class Executor implements IExecutor {
|
|
|
116
118
|
};
|
|
117
119
|
sbsTransactionStack(ptr: number): TupleItem[];
|
|
118
120
|
sbsTransactionC7(ptr: number): TupleItem;
|
|
121
|
+
sbsTransactionGetContParam(ptr: number): number;
|
|
122
|
+
sbsTransactionSetContParam(ptr: number, param: number): number;
|
|
119
123
|
sbsTransactionResult(ptr: number): EmulationResult;
|
|
120
124
|
}
|
|
@@ -253,6 +253,17 @@ class Executor {
|
|
|
253
253
|
]));
|
|
254
254
|
return (0, core_1.parseTuple)((0, core_1.beginCell)().storeUint(1, 24).storeRef(core_1.Cell.EMPTY).storeSlice(core_1.Cell.fromBase64(resp).beginParse()).endCell())[0];
|
|
255
255
|
}
|
|
256
|
+
sbsGetMethodGetContParam(ptr) {
|
|
257
|
+
return this.invoke('_sbs_get_cont_param', [
|
|
258
|
+
ptr
|
|
259
|
+
]);
|
|
260
|
+
}
|
|
261
|
+
sbsGetMethodSetContParam(ptr, param) {
|
|
262
|
+
return this.invoke('_sbs_set_cont_param', [
|
|
263
|
+
ptr,
|
|
264
|
+
param
|
|
265
|
+
]);
|
|
266
|
+
}
|
|
256
267
|
sbsGetMethodCodePos(ptr) {
|
|
257
268
|
const resp = this.extractString(this.invoke('_sbs_get_code_pos', [
|
|
258
269
|
ptr
|
|
@@ -317,6 +328,17 @@ class Executor {
|
|
|
317
328
|
]));
|
|
318
329
|
return (0, core_1.parseTuple)((0, core_1.beginCell)().storeUint(1, 24).storeRef(core_1.Cell.EMPTY).storeSlice(core_1.Cell.fromBase64(resp).beginParse()).endCell())[0];
|
|
319
330
|
}
|
|
331
|
+
sbsTransactionGetContParam(ptr) {
|
|
332
|
+
return this.invoke('_em_sbs_get_cont_param', [
|
|
333
|
+
ptr
|
|
334
|
+
]);
|
|
335
|
+
}
|
|
336
|
+
sbsTransactionSetContParam(ptr, param) {
|
|
337
|
+
return this.invoke('_em_sbs_set_cont_param', [
|
|
338
|
+
ptr,
|
|
339
|
+
param
|
|
340
|
+
]);
|
|
341
|
+
}
|
|
320
342
|
sbsTransactionResult(ptr) {
|
|
321
343
|
const result = JSON.parse(this.extractString(this.invoke('_em_sbs_result', [
|
|
322
344
|
ptr
|