(state, ev)
| 330 | |
| 331 | // returns formatted string, or null if it should be dropped by scope |
| 332 | function formatEvent(state, ev) { |
| 333 | const type = ev[0]; |
| 334 | switch (type) { |
| 335 | case "call": { |
| 336 | const from = np(ev[1]), to = np(ev[2]), depth = ev[3]; |
| 337 | const r = resolve(to); |
| 338 | if (!inScope(state, r.lib)) return null; |
| 339 | return `${C.cyan}CALL${C.reset} ${sym(from)} -> ${r.text} ${C.dim}depth=${depth}${C.reset}`; |
| 340 | } |
| 341 | case "ret": { |
| 342 | const from = np(ev[1]), to = np(ev[2]); |
| 343 | const r = resolve(from); |
| 344 | if (!inScope(state, r.lib)) return null; |
| 345 | return `${C.dim}RET ${C.reset} ${r.text} -> ${sym(to)}`; |
| 346 | } |
| 347 | case "block": { |
| 348 | const start = np(ev[1]), end = np(ev[2]); |
| 349 | const r = resolve(start); |
| 350 | if (!inScope(state, r.lib)) return null; |
| 351 | const size = end && start ? parseInt(end.sub(start).toString(), 16) : 0; |
| 352 | return `${C.yellow}BLOCK${C.reset} ${r.text} ${C.dim}(${size}B)${C.reset}`; |
| 353 | } |
| 354 | case "compile": { |
| 355 | const start = np(ev[1]); |
| 356 | const r = resolve(start); |
| 357 | if (!inScope(state, r.lib)) return null; |
| 358 | return `${C.dim}COMPILE${C.reset} ${r.text}`; |
| 359 | } |
| 360 | case "exec": { |
| 361 | const pc = np(ev[1]); |
| 362 | const r = resolve(pc); |
| 363 | if (!inScope(state, r.lib)) return null; |
| 364 | return `EXEC ${r.text}`; |
| 365 | } |
| 366 | default: |
| 367 | return null; |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | function stopStalk(tid, reason) { |
| 372 | const state = stalked.get(tid); |
no test coverage detected