wasm-idle 0.7.2 → 1.0.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.
Files changed (386) hide show
  1. package/README.md +760 -81
  2. package/dist/index.d.ts +4 -9
  3. package/dist/index.js +2 -4
  4. package/dist/playground/applicationAssets.d.ts +4 -0
  5. package/dist/playground/applicationAssets.js +277 -0
  6. package/dist/playground/assemblyscript.d.ts +41 -0
  7. package/dist/playground/assemblyscript.js +630 -0
  8. package/dist/playground/assetBridge.d.ts +18 -7
  9. package/dist/playground/assetBridge.js +824 -100
  10. package/dist/playground/assets.d.ts +813 -19
  11. package/dist/playground/assets.js +2096 -156
  12. package/dist/playground/awk.d.ts +5 -0
  13. package/dist/playground/awk.js +60 -0
  14. package/dist/playground/bash.d.ts +53 -0
  15. package/dist/playground/bash.js +1096 -0
  16. package/dist/playground/bashWorkerProtocol.d.ts +88 -0
  17. package/dist/playground/bashWorkerProtocol.js +135 -0
  18. package/dist/playground/bqn.d.ts +5 -0
  19. package/dist/playground/bqn.js +57 -0
  20. package/dist/playground/bqnPreflight.d.ts +26 -0
  21. package/dist/playground/bqnPreflight.js +399 -0
  22. package/dist/playground/c3.d.ts +15 -0
  23. package/dist/playground/c3.js +154 -0
  24. package/dist/playground/clang.d.ts +35 -19
  25. package/dist/playground/clang.js +241 -52
  26. package/dist/playground/clangAssetIntegrity.d.ts +32 -0
  27. package/dist/playground/clangAssetIntegrity.js +8 -0
  28. package/dist/playground/clojurescript.d.ts +5 -0
  29. package/dist/playground/clojurescript.js +59 -0
  30. package/dist/playground/clojurescriptPreflight.d.ts +26 -0
  31. package/dist/playground/clojurescriptPreflight.js +383 -0
  32. package/dist/playground/cobol.d.ts +46 -0
  33. package/dist/playground/cobol.js +703 -0
  34. package/dist/playground/d.d.ts +47 -0
  35. package/dist/playground/d.js +644 -0
  36. package/dist/playground/dOuterAssets.d.ts +16 -0
  37. package/dist/playground/dOuterAssets.js +163 -0
  38. package/dist/playground/dotnet.d.ts +99 -0
  39. package/dist/playground/dotnet.js +1131 -0
  40. package/dist/playground/duckdb.d.ts +36 -0
  41. package/dist/playground/duckdb.js +542 -0
  42. package/dist/playground/elixir.d.ts +18 -10
  43. package/dist/playground/elixir.js +630 -96
  44. package/dist/playground/elixirAssets.d.ts +6 -0
  45. package/dist/playground/elixirAssets.js +33 -0
  46. package/dist/playground/executionObservation.d.ts +22 -0
  47. package/dist/playground/executionObservation.js +65 -0
  48. package/dist/playground/forth.d.ts +5 -0
  49. package/dist/playground/forth.js +53 -0
  50. package/dist/playground/forthPreflight.d.ts +24 -0
  51. package/dist/playground/forthPreflight.js +198 -0
  52. package/dist/playground/fortran.d.ts +47 -0
  53. package/dist/playground/fortran.js +651 -0
  54. package/dist/playground/fortranAssets.d.ts +6 -0
  55. package/dist/playground/fortranAssets.js +27 -0
  56. package/dist/playground/gleam.d.ts +6 -0
  57. package/dist/playground/gleam.js +33 -0
  58. package/dist/playground/go.d.ts +17 -11
  59. package/dist/playground/go.js +376 -72
  60. package/dist/playground/goDebugInstrumentation.d.ts +1 -0
  61. package/dist/playground/goDebugInstrumentation.js +229 -0
  62. package/dist/playground/haskell.d.ts +44 -0
  63. package/dist/playground/haskell.js +678 -0
  64. package/dist/playground/haskellAssets.d.ts +24 -0
  65. package/dist/playground/haskellAssets.js +93 -0
  66. package/dist/playground/index.d.ts +1 -1
  67. package/dist/playground/index.js +360 -111
  68. package/dist/playground/j.d.ts +5 -0
  69. package/dist/playground/j.js +60 -0
  70. package/dist/playground/jPreflight.d.ts +26 -0
  71. package/dist/playground/jPreflight.js +372 -0
  72. package/dist/playground/janet.d.ts +5 -0
  73. package/dist/playground/janet.js +64 -0
  74. package/dist/playground/java.d.ts +24 -10
  75. package/dist/playground/java.js +706 -84
  76. package/dist/playground/javaSource.d.ts +5 -0
  77. package/dist/playground/javaSource.js +16 -0
  78. package/dist/playground/javaStdin.d.ts +1 -1
  79. package/dist/playground/javaStdin.js +13 -4
  80. package/dist/playground/julia.d.ts +5 -0
  81. package/dist/playground/julia.js +64 -0
  82. package/dist/playground/lfortran.d.ts +8 -0
  83. package/dist/playground/lfortran.js +30 -0
  84. package/dist/playground/lfortranAssets.d.ts +21 -0
  85. package/dist/playground/lfortranAssets.js +118 -0
  86. package/dist/playground/lisp.d.ts +45 -0
  87. package/dist/playground/lisp.js +640 -0
  88. package/dist/playground/lispAssets.d.ts +9 -0
  89. package/dist/playground/lispAssets.js +74 -0
  90. package/dist/playground/lldbManifest.d.ts +3 -0
  91. package/dist/playground/lldbManifest.js +155 -0
  92. package/dist/playground/lldbSession.d.ts +115 -0
  93. package/dist/playground/lldbSession.js +1347 -0
  94. package/dist/playground/loadingProgress.d.ts +16 -0
  95. package/dist/playground/loadingProgress.js +166 -0
  96. package/dist/playground/lua.d.ts +44 -0
  97. package/dist/playground/lua.js +630 -0
  98. package/dist/playground/nim.d.ts +5 -0
  99. package/dist/playground/nim.js +76 -0
  100. package/dist/playground/objectivec.d.ts +39 -0
  101. package/dist/playground/objectivec.js +288 -0
  102. package/dist/playground/ocaml.d.ts +28 -10
  103. package/dist/playground/ocaml.js +815 -253
  104. package/dist/playground/octave.d.ts +43 -0
  105. package/dist/playground/octave.js +783 -0
  106. package/dist/playground/options.d.ts +19 -40
  107. package/dist/playground/options.js +2 -1
  108. package/dist/playground/pascal.d.ts +5 -0
  109. package/dist/playground/pascal.js +60 -0
  110. package/dist/playground/perl.d.ts +5 -0
  111. package/dist/playground/perl.js +61 -0
  112. package/dist/playground/php.d.ts +44 -0
  113. package/dist/playground/php.js +665 -0
  114. package/dist/playground/prolog.d.ts +6 -0
  115. package/dist/playground/prolog.js +75 -0
  116. package/dist/playground/python.d.ts +20 -14
  117. package/dist/playground/python.js +445 -101
  118. package/dist/playground/pythonPackageLock.d.ts +6 -0
  119. package/dist/playground/pythonPackageLock.js +56 -0
  120. package/dist/playground/r.d.ts +44 -0
  121. package/dist/playground/r.js +637 -0
  122. package/dist/playground/ruby.d.ts +46 -0
  123. package/dist/playground/ruby.js +732 -0
  124. package/dist/playground/rubyAssets.d.ts +23 -0
  125. package/dist/playground/rubyAssets.js +68 -0
  126. package/dist/playground/rubyTestPreflight.d.ts +2 -0
  127. package/dist/playground/rubyTestPreflight.js +18 -0
  128. package/dist/playground/runtimeModule.d.ts +1 -0
  129. package/dist/playground/runtimeModule.js +5 -0
  130. package/dist/playground/rust.d.ts +44 -13
  131. package/dist/playground/rust.js +714 -76
  132. package/dist/playground/rustExecutableGraph.d.ts +85 -0
  133. package/dist/playground/rustExecutableGraph.js +946 -0
  134. package/dist/playground/rustWorkerLimits.d.ts +17 -0
  135. package/dist/playground/rustWorkerLimits.js +34 -0
  136. package/dist/playground/sandbox.d.ts +16 -10
  137. package/dist/playground/sharedBuffer.d.ts +6 -0
  138. package/dist/playground/sharedBuffer.js +12 -0
  139. package/dist/playground/sqlite.d.ts +38 -0
  140. package/dist/playground/sqlite.js +550 -0
  141. package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -0
  142. package/dist/playground/staticRuntimeModuleVersion.js +2 -0
  143. package/dist/playground/staticRuntimePreflight.d.ts +13 -0
  144. package/dist/playground/staticRuntimePreflight.js +231 -0
  145. package/dist/playground/staticRuntimePreflightExecute.d.ts +8 -0
  146. package/dist/playground/staticRuntimePreflightExecute.js +66 -0
  147. package/dist/playground/staticRuntimePreflightProtocol.d.ts +68 -0
  148. package/dist/playground/staticRuntimePreflightProtocol.js +339 -0
  149. package/dist/playground/staticStdinRing.d.ts +45 -0
  150. package/dist/playground/staticStdinRing.js +158 -0
  151. package/dist/playground/staticWorkerRuntime.d.ts +154 -0
  152. package/dist/playground/staticWorkerRuntime.js +1917 -0
  153. package/dist/playground/stdinBuffer.d.ts +9 -7
  154. package/dist/playground/stdinBuffer.js +9 -18
  155. package/dist/playground/swift.d.ts +5 -0
  156. package/dist/playground/swift.js +17 -0
  157. package/dist/playground/tcl.d.ts +5 -0
  158. package/dist/playground/tcl.js +62 -0
  159. package/dist/playground/teavmConfig.d.ts +1 -1
  160. package/dist/playground/teavmConfig.js +2 -2
  161. package/dist/playground/tinygo.d.ts +48 -18
  162. package/dist/playground/tinygo.js +1202 -329
  163. package/dist/playground/tinygoExecutableGraph.d.ts +44 -0
  164. package/dist/playground/tinygoExecutableGraph.js +449 -0
  165. package/dist/playground/typescript.d.ts +55 -0
  166. package/dist/playground/typescript.js +924 -0
  167. package/dist/playground/wasm.d.ts +43 -0
  168. package/dist/playground/wasm.js +608 -0
  169. package/dist/playground/wasmAwkVersion.d.ts +59 -0
  170. package/dist/playground/wasmAwkVersion.js +31 -0
  171. package/dist/playground/wasmBashVersion.d.ts +63 -0
  172. package/dist/playground/wasmBashVersion.js +36 -0
  173. package/dist/playground/wasmBqnVersion.d.ts +24 -0
  174. package/dist/playground/wasmBqnVersion.js +24 -0
  175. package/dist/playground/wasmC3Version.d.ts +20 -0
  176. package/dist/playground/wasmC3Version.js +21 -0
  177. package/dist/playground/wasmClojureScriptVersion.d.ts +21 -0
  178. package/dist/playground/wasmClojureScriptVersion.js +21 -0
  179. package/dist/playground/wasmDIntegrity.d.ts +15 -0
  180. package/dist/playground/wasmDIntegrity.js +15 -0
  181. package/dist/playground/wasmDVersion.d.ts +1 -0
  182. package/dist/playground/wasmDVersion.js +1 -0
  183. package/dist/playground/wasmDebugVersion.d.ts +6 -0
  184. package/dist/playground/wasmDebugVersion.js +6 -0
  185. package/dist/playground/wasmDotnetVersion.d.ts +1 -0
  186. package/dist/playground/wasmDotnetVersion.js +1 -0
  187. package/dist/playground/wasmElixirVersion.d.ts +21 -1
  188. package/dist/playground/wasmElixirVersion.js +21 -1
  189. package/dist/playground/wasmForthVersion.d.ts +18 -0
  190. package/dist/playground/wasmForthVersion.js +18 -0
  191. package/dist/playground/wasmFortranExecutionAssets.d.ts +15 -0
  192. package/dist/playground/wasmFortranExecutionAssets.js +15 -0
  193. package/dist/playground/wasmFortranVersion.d.ts +1 -0
  194. package/dist/playground/wasmFortranVersion.js +1 -0
  195. package/dist/playground/wasmGleamVersion.d.ts +5 -0
  196. package/dist/playground/wasmGleamVersion.js +5 -0
  197. package/dist/playground/wasmGoVersion.d.ts +1 -1
  198. package/dist/playground/wasmGoVersion.js +1 -1
  199. package/dist/playground/wasmHaskellVersion.d.ts +1 -0
  200. package/dist/playground/wasmHaskellVersion.js +1 -0
  201. package/dist/playground/wasmJVersion.d.ts +24 -0
  202. package/dist/playground/wasmJVersion.js +24 -0
  203. package/dist/playground/wasmJanetVersion.d.ts +53 -0
  204. package/dist/playground/wasmJanetVersion.js +30 -0
  205. package/dist/playground/wasmJuliaVersion.d.ts +71 -0
  206. package/dist/playground/wasmJuliaVersion.js +39 -0
  207. package/dist/playground/wasmLfortranVersion.d.ts +28 -0
  208. package/dist/playground/wasmLfortranVersion.js +29 -0
  209. package/dist/playground/wasmLispVersion.d.ts +1 -0
  210. package/dist/playground/wasmLispVersion.js +1 -0
  211. package/dist/playground/wasmLuaVersion.d.ts +1 -0
  212. package/dist/playground/wasmLuaVersion.js +1 -0
  213. package/dist/playground/wasmNimVersion.d.ts +125 -0
  214. package/dist/playground/wasmNimVersion.js +66 -0
  215. package/dist/playground/wasmObjectiveCVersion.d.ts +27 -0
  216. package/dist/playground/wasmObjectiveCVersion.js +27 -0
  217. package/dist/playground/wasmOcamlVersion.d.ts +12 -1
  218. package/dist/playground/wasmOcamlVersion.js +12 -1
  219. package/dist/playground/wasmOctaveVersion.d.ts +1 -0
  220. package/dist/playground/wasmOctaveVersion.js +1 -0
  221. package/dist/playground/wasmPascalVersion.d.ts +61 -0
  222. package/dist/playground/wasmPascalVersion.js +34 -0
  223. package/dist/playground/wasmPerlVersion.d.ts +71 -0
  224. package/dist/playground/wasmPerlVersion.js +39 -0
  225. package/dist/playground/wasmPrologVersion.d.ts +31 -0
  226. package/dist/playground/wasmPrologVersion.js +31 -0
  227. package/dist/playground/wasmRVersion.d.ts +1 -0
  228. package/dist/playground/wasmRVersion.js +1 -0
  229. package/dist/playground/wasmRustVersion.d.ts +1306 -1
  230. package/dist/playground/wasmRustVersion.js +1458 -1
  231. package/dist/playground/wasmSwiftVersion.d.ts +1 -0
  232. package/dist/playground/wasmSwiftVersion.js +1 -0
  233. package/dist/playground/wasmTclVersion.d.ts +85 -0
  234. package/dist/playground/wasmTclVersion.js +46 -0
  235. package/dist/playground/wasmTinyGoVersion.d.ts +98 -1
  236. package/dist/playground/wasmTinyGoVersion.js +107 -1
  237. package/dist/playground/wasmTypeScriptVersion.d.ts +5 -0
  238. package/dist/playground/wasmTypeScriptVersion.js +5 -0
  239. package/dist/playground/wasmWatVersion.d.ts +1 -0
  240. package/dist/playground/wasmWatVersion.js +1 -0
  241. package/dist/playground/wasmZigVersion.d.ts +13 -0
  242. package/dist/playground/wasmZigVersion.js +13 -0
  243. package/dist/playground/wat.d.ts +44 -0
  244. package/dist/playground/wat.js +622 -0
  245. package/dist/playground/worker/assemblyscript.js +339 -0
  246. package/dist/playground/worker/assets.d.ts +7 -0
  247. package/dist/playground/worker/assets.js +288 -39
  248. package/dist/playground/worker/bash.js +338 -0
  249. package/dist/playground/worker/bashNestedBootstrap.d.ts +6 -0
  250. package/dist/playground/worker/bashNestedBootstrap.js +59 -0
  251. package/dist/playground/worker/bashRuntime.d.ts +89 -0
  252. package/dist/playground/worker/bashRuntime.js +982 -0
  253. package/dist/playground/worker/clang.js +92 -13
  254. package/dist/playground/worker/cobol.js +107 -0
  255. package/dist/playground/worker/d.js +199 -0
  256. package/dist/playground/worker/dotnet.js +141 -0
  257. package/dist/playground/worker/duckdb.d.ts +1 -0
  258. package/dist/playground/worker/duckdb.js +136 -0
  259. package/dist/playground/worker/elixir.js +307 -41
  260. package/dist/playground/worker/fortran.d.ts +1 -0
  261. package/dist/playground/worker/fortran.js +295 -0
  262. package/dist/playground/worker/go.js +246 -40
  263. package/dist/playground/worker/haskell.d.ts +7 -0
  264. package/dist/playground/worker/haskell.js +465 -0
  265. package/dist/playground/worker/java.js +59 -20
  266. package/dist/playground/worker/lisp.d.ts +1 -0
  267. package/dist/playground/worker/lisp.js +195 -0
  268. package/dist/playground/worker/lua.d.ts +1 -0
  269. package/dist/playground/worker/lua.js +163 -0
  270. package/dist/playground/worker/objectivec.d.ts +1 -0
  271. package/dist/playground/worker/objectivec.js +10 -0
  272. package/dist/playground/worker/ocaml.js +206 -58
  273. package/dist/playground/worker/php.d.ts +1 -0
  274. package/dist/playground/worker/php.js +261 -0
  275. package/dist/playground/worker/python.js +201 -44
  276. package/dist/playground/worker/r.d.ts +1 -0
  277. package/dist/playground/worker/r.js +192 -0
  278. package/dist/playground/worker/ruby.d.ts +1 -0
  279. package/dist/playground/worker/ruby.js +248 -0
  280. package/dist/playground/worker/runtimeAssetFetch.d.ts +15 -0
  281. package/dist/playground/worker/runtimeAssetFetch.js +375 -0
  282. package/dist/playground/worker/rust.js +546 -20
  283. package/dist/playground/worker/sqlite.d.ts +1 -0
  284. package/dist/playground/worker/sqlite.js +112 -0
  285. package/dist/playground/worker/staticRuntimePreflight.d.ts +1 -0
  286. package/dist/playground/worker/staticRuntimePreflight.js +56 -0
  287. package/dist/playground/worker/tinygo.js +34 -9
  288. package/dist/playground/worker/typescript.d.ts +1 -0
  289. package/dist/playground/worker/typescript.js +251 -0
  290. package/dist/playground/worker/wasm.d.ts +1 -0
  291. package/dist/playground/worker/wasm.js +273 -0
  292. package/dist/playground/worker/wat.d.ts +1 -0
  293. package/dist/playground/worker/wat.js +188 -0
  294. package/dist/playground/worker/zig.d.ts +8 -0
  295. package/dist/playground/worker/zig.js +578 -0
  296. package/dist/playground/workerProgress.d.ts +15 -0
  297. package/dist/playground/workerProgress.js +72 -0
  298. package/dist/playground/workerSession.d.ts +28 -0
  299. package/dist/playground/workerSession.js +164 -0
  300. package/dist/playground/zig.d.ts +46 -0
  301. package/dist/playground/zig.js +690 -0
  302. package/dist/playground/zigAssets.d.ts +6 -0
  303. package/dist/playground/zigAssets.js +49 -0
  304. package/package.json +234 -105
  305. package/dist/clang/app.d.ts +0 -75
  306. package/dist/clang/app.js +0 -744
  307. package/dist/clang/apply.d.ts +0 -2
  308. package/dist/clang/apply.js +0 -11
  309. package/dist/clang/color.d.ts +0 -3
  310. package/dist/clang/color.js +0 -3
  311. package/dist/clang/encode.d.ts +0 -4
  312. package/dist/clang/encode.js +0 -20
  313. package/dist/clang/error.d.ts +0 -14
  314. package/dist/clang/error.js +0 -27
  315. package/dist/clang/gccCompat.d.ts +0 -15
  316. package/dist/clang/gccCompat.js +0 -767
  317. package/dist/clang/index.d.ts +0 -85
  318. package/dist/clang/index.js +0 -1077
  319. package/dist/clang/memory/index.d.ts +0 -4
  320. package/dist/clang/memory/index.js +0 -4
  321. package/dist/clang/memory/memFs.d.ts +0 -35
  322. package/dist/clang/memory/memFs.js +0 -132
  323. package/dist/clang/memory/memory.d.ts +0 -22
  324. package/dist/clang/memory/memory.js +0 -73
  325. package/dist/clang/memory/tar.d.ts +0 -2
  326. package/dist/clang/memory/tar.js +0 -59
  327. package/dist/clang/url.d.ts +0 -4
  328. package/dist/clang/url.js +0 -5
  329. package/dist/clang/wasm.d.ts +0 -4
  330. package/dist/clang/wasm.js +0 -50
  331. package/dist/clangd/config.d.ts +0 -18
  332. package/dist/clangd/config.js +0 -14
  333. package/dist/clangd/jsonStream.d.ts +0 -9
  334. package/dist/clangd/jsonStream.js +0 -48
  335. package/dist/clangd/session.d.ts +0 -18
  336. package/dist/clangd/session.js +0 -112
  337. package/dist/clangd/worker.js +0 -131
  338. package/dist/debug/controller.svelte.d.ts +0 -43
  339. package/dist/debug/controller.svelte.js +0 -268
  340. package/dist/debug/editor/index.d.ts +0 -2
  341. package/dist/debug/editor/index.js +0 -1
  342. package/dist/debug/editor/monaco.d.ts +0 -26
  343. package/dist/debug/editor/monaco.js +0 -128
  344. package/dist/debug/expression.d.ts +0 -26
  345. package/dist/debug/expression.js +0 -547
  346. package/dist/debug/index.d.ts +0 -8
  347. package/dist/debug/index.js +0 -5
  348. package/dist/debug/language/cpp.d.ts +0 -2
  349. package/dist/debug/language/cpp.js +0 -7
  350. package/dist/debug/language/index.d.ts +0 -3
  351. package/dist/debug/language/index.js +0 -2
  352. package/dist/debug/language/python.d.ts +0 -2
  353. package/dist/debug/language/python.js +0 -14
  354. package/dist/debug/language/types.d.ts +0 -6
  355. package/dist/debug/locals.d.ts +0 -2
  356. package/dist/debug/locals.js +0 -8
  357. package/dist/lsp/cpp/server.d.ts +0 -2
  358. package/dist/lsp/cpp/server.js +0 -68
  359. package/dist/lsp/index.d.ts +0 -5
  360. package/dist/lsp/index.js +0 -4
  361. package/dist/lsp/python/main.worker.js +0 -92
  362. package/dist/lsp/python/package/arcturus_python_lsp/__init__.py +0 -3
  363. package/dist/lsp/python/package/arcturus_python_lsp/server.py +0 -462
  364. package/dist/lsp/python/server.d.ts +0 -2
  365. package/dist/lsp/python/server.js +0 -54
  366. package/dist/lsp/registry.d.ts +0 -2
  367. package/dist/lsp/registry.js +0 -12
  368. package/dist/lsp/runtime.d.ts +0 -5
  369. package/dist/lsp/runtime.js +0 -31
  370. package/dist/lsp/types.d.ts +0 -17
  371. package/dist/terminal/Terminal.svelte +0 -422
  372. package/dist/terminal/Terminal.svelte.d.ts +0 -26
  373. package/dist/terminal/index.d.ts +0 -7
  374. package/dist/terminal/index.js +0 -5
  375. package/dist/terminal/plugin/index.d.ts +0 -9
  376. package/dist/terminal/plugin/index.js +0 -19
  377. package/dist/terminal/theme.d.ts +0 -49
  378. package/dist/terminal/theme.js +0 -49
  379. package/dist/terminal/types.d.ts +0 -18
  380. package/dist/utils/vscodeJsonrpcBrowser.d.ts +0 -5
  381. package/dist/utils/vscodeJsonrpcBrowser.js +0 -4
  382. /package/dist/{clangd/worker.d.ts → playground/worker/assemblyscript.d.ts} +0 -0
  383. /package/dist/{debug/language/types.js → playground/worker/bash.d.ts} +0 -0
  384. /package/dist/{lsp/python/main.worker.d.ts → playground/worker/cobol.d.ts} +0 -0
  385. /package/dist/{lsp/types.js → playground/worker/d.d.ts} +0 -0
  386. /package/dist/{terminal/types.js → playground/worker/dotnet.d.ts} +0 -0
@@ -0,0 +1,1347 @@
1
+ import { ProtocolError } from '@wasm-idle/core';
2
+ import { createBrowserLldbSession, DapProtocolError } from '@wasm-idle/llvm-core/debug';
3
+ import { loadVerifiedDebugRuntimeManifest } from './lldbManifest';
4
+ const MAX_DEBUG_MEMORY_BYTES = 256;
5
+ const MAX_DEBUG_IDENTIFIER_CODE_UNITS = 4096;
6
+ const MAX_DEBUG_DATA_BREAKPOINTS = 256;
7
+ function pauseReason(reason, command) {
8
+ if (reason === 'breakpoint')
9
+ return 'breakpoint';
10
+ if (reason === 'data breakpoint')
11
+ return 'dataBreakpoint';
12
+ if (reason === 'entry')
13
+ return 'entry';
14
+ if (reason === 'pause')
15
+ return 'pause';
16
+ if (command === 'nextLine')
17
+ return 'nextLine';
18
+ if (command === 'stepOut')
19
+ return 'stepOut';
20
+ return 'step';
21
+ }
22
+ function invalidDapPayload(subject, path, expectation) {
23
+ throw new ProtocolError(`Invalid LLDB DAP ${subject} at ${path}: ${expectation}.`);
24
+ }
25
+ function invalidDapResponse(command, path, expectation) {
26
+ invalidDapPayload(`${command} response`, path, expectation);
27
+ }
28
+ function assertDapRecord(value, command, path) {
29
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
30
+ invalidDapResponse(command, path, 'expected an object');
31
+ }
32
+ }
33
+ function assertDapString(value, command, path) {
34
+ if (typeof value !== 'string')
35
+ invalidDapResponse(command, path, 'expected a string');
36
+ }
37
+ function assertDapBoolean(value, command, path) {
38
+ if (typeof value !== 'boolean')
39
+ invalidDapResponse(command, path, 'expected a boolean');
40
+ }
41
+ function assertDapPositiveSafeInteger(value, subject, path) {
42
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 1) {
43
+ invalidDapPayload(subject, path, 'expected a positive safe integer');
44
+ }
45
+ }
46
+ function assertDapNonNegativeSafeInteger(value, command, path) {
47
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
48
+ invalidDapResponse(command, path, 'expected a non-negative safe integer');
49
+ }
50
+ }
51
+ function dapResponseCollection(response, command, path) {
52
+ assertDapRecord(response, command, 'body');
53
+ const collection = response[path];
54
+ if (!Array.isArray(collection))
55
+ invalidDapResponse(command, path, 'expected an array');
56
+ return collection;
57
+ }
58
+ function dapOptionalNonNegativeSafeInteger(record, property, command, path) {
59
+ const value = record[property];
60
+ if (value === undefined)
61
+ return undefined;
62
+ assertDapNonNegativeSafeInteger(value, command, `${path}.${property}`);
63
+ return value;
64
+ }
65
+ function snapshotBreakpointLines(lines) {
66
+ if (lines.some((line) => !Number.isSafeInteger(line) || line < 1)) {
67
+ throw new RangeError('LLDB breakpoint lines must be positive safe integers.');
68
+ }
69
+ return [...lines];
70
+ }
71
+ function assertPositiveSafeIntegerArgument(value, name) {
72
+ if (!Number.isSafeInteger(value) || value < 1) {
73
+ throw new RangeError(`${name} must be a positive safe integer.`);
74
+ }
75
+ }
76
+ function assertNonNegativeSafeIntegerArgument(value, name) {
77
+ if (!Number.isSafeInteger(value) || value < 0) {
78
+ throw new RangeError(`${name} must be a non-negative safe integer.`);
79
+ }
80
+ }
81
+ function assertBoundedNonEmptyStringArgument(value, name) {
82
+ if (typeof value !== 'string' || value.length === 0) {
83
+ throw new TypeError(`${name} must be a non-empty string.`);
84
+ }
85
+ if (value.length > MAX_DEBUG_IDENTIFIER_CODE_UNITS) {
86
+ throw new RangeError(`${name} must not exceed ${MAX_DEBUG_IDENTIFIER_CODE_UNITS} UTF-16 code units.`);
87
+ }
88
+ }
89
+ function assertOptionalBooleanArgument(value, name) {
90
+ if (value !== undefined && typeof value !== 'boolean') {
91
+ throw new TypeError(`${name} must be a boolean.`);
92
+ }
93
+ }
94
+ export class LldbSandboxSession {
95
+ options;
96
+ session;
97
+ startupAbortController;
98
+ activeThreadId = 1;
99
+ activeFrameId;
100
+ stoppedFrames = [];
101
+ supportsValueFormatting = false;
102
+ command = null;
103
+ pauseRequested = false;
104
+ pauseRequestVersion = 0;
105
+ targetStopped = false;
106
+ entryPhase = 'done';
107
+ entrySetup;
108
+ stopped = false;
109
+ stateVersion = 0;
110
+ completionResolve;
111
+ completionReject;
112
+ sessionDisposal;
113
+ pendingInput = [];
114
+ pendingEof = false;
115
+ inputReady = false;
116
+ lifecycleVersion = 0;
117
+ initialized = false;
118
+ supportsEvaluateExpressions = false;
119
+ supportsReadMemory = false;
120
+ supportsWriteMemory = false;
121
+ supportsDataBreakpoints = false;
122
+ breakpointVersion = 0;
123
+ scopeRequestVersion = 0;
124
+ dapExitCode = null;
125
+ breakpointsBySource = new Map();
126
+ breakpointRequestVersions = new Map();
127
+ sourceContentSha256ByPath = new Map();
128
+ constructor(options) {
129
+ this.options = options;
130
+ const sourceBreakpoints = options.sourceBreakpoints?.length
131
+ ? options.sourceBreakpoints
132
+ : [{ sourcePath: options.sourcePath, lines: options.breakpoints }];
133
+ for (const { sourcePath, lines } of sourceBreakpoints) {
134
+ this.breakpointsBySource.set(sourcePath, snapshotBreakpointLines(lines));
135
+ }
136
+ for (const source of options.artifact.sources) {
137
+ if (source.contentSha256) {
138
+ this.sourceContentSha256ByPath.set(source.path, source.contentSha256);
139
+ }
140
+ }
141
+ }
142
+ async start() {
143
+ if (this.session || this.startupAbortController) {
144
+ throw new Error('LLDB sandbox session is already running.');
145
+ }
146
+ const previousDisposal = this.sessionDisposal;
147
+ const lifecycleVersion = ++this.lifecycleVersion;
148
+ const startupAbortController = new AbortController();
149
+ this.startupAbortController = startupAbortController;
150
+ this.targetStopped = false;
151
+ this.stopped = false;
152
+ this.entryPhase =
153
+ this.options.pauseOnEntry && this.options.pauseAtMain ? 'initial' : 'done';
154
+ this.pauseRequested = false;
155
+ this.initialized = false;
156
+ this.dapExitCode = null;
157
+ let rejectCompletion;
158
+ const completion = new Promise((resolve, reject) => {
159
+ this.completionResolve = resolve;
160
+ this.completionReject = reject;
161
+ rejectCompletion = reject;
162
+ });
163
+ void completion.catch(() => undefined);
164
+ if (previousDisposal) {
165
+ try {
166
+ await previousDisposal;
167
+ }
168
+ catch (error) {
169
+ if (lifecycleVersion !== this.lifecycleVersion)
170
+ return completion;
171
+ if (this.startupAbortController === startupAbortController) {
172
+ this.startupAbortController = undefined;
173
+ }
174
+ this.stopped = true;
175
+ rejectCompletion(error instanceof Error
176
+ ? error
177
+ : new Error('Unable to dispose the previous LLDB debug session.'));
178
+ return completion;
179
+ }
180
+ if (lifecycleVersion !== this.lifecycleVersion ||
181
+ startupAbortController.signal.aborted) {
182
+ return completion;
183
+ }
184
+ }
185
+ let manifest;
186
+ try {
187
+ manifest = await loadVerifiedDebugRuntimeManifest(this.options.manifestUrl, this.options.manifestReceipt, this.options.fetchImpl ?? fetch, startupAbortController.signal);
188
+ }
189
+ catch (error) {
190
+ if (lifecycleVersion !== this.lifecycleVersion)
191
+ return completion;
192
+ throw error;
193
+ }
194
+ finally {
195
+ if (this.startupAbortController === startupAbortController) {
196
+ this.startupAbortController = undefined;
197
+ }
198
+ }
199
+ this.supportsEvaluateExpressions =
200
+ manifest.debugger?.capabilities?.evaluateExpressions === true;
201
+ const manifestSupportsReadMemory = manifest.debugger?.capabilities?.readMemory === true;
202
+ const manifestSupportsWriteMemory = manifest.debugger?.capabilities?.writeMemory === true;
203
+ this.supportsReadMemory = false;
204
+ this.supportsWriteMemory = false;
205
+ const manifestSupportsDataBreakpoints = manifest.debugger?.capabilities?.dataBreakpoints === true;
206
+ if (lifecycleVersion !== this.lifecycleVersion)
207
+ return completion;
208
+ const artifactCompiler = this.options.artifact.descriptor?.compiler;
209
+ if (artifactCompiler?.name === 'clang' &&
210
+ artifactCompiler.revision &&
211
+ artifactCompiler.revision !== manifest.debugger.lldb.llvmRevision) {
212
+ throw new Error(`Compiler/LLDB revision mismatch: artifact ${artifactCompiler.revision}, runtime ${manifest.debugger.lldb.llvmRevision}.`);
213
+ }
214
+ if (artifactCompiler?.name === 'rustc' &&
215
+ artifactCompiler.llvmVersion &&
216
+ artifactCompiler.llvmVersion !== manifest.debugger.lldb.llvmVersion) {
217
+ throw new Error(`Rust LLVM/LLDB version mismatch: artifact ${artifactCompiler.llvmVersion}, runtime ${manifest.debugger.lldb.llvmVersion}.`);
218
+ }
219
+ let session;
220
+ const sourceBreakpoints = Array.from(this.breakpointsBySource, ([sourcePath, lines]) => ({
221
+ sourcePath,
222
+ lines: [...lines]
223
+ }));
224
+ const configuredBreakpointVersion = this.breakpointVersion;
225
+ session = createBrowserLldbSession({
226
+ manifest,
227
+ runtimeBaseUrl: this.options.runtimeBaseUrl,
228
+ module: this.options.artifact.bytes,
229
+ moduleSha256: this.options.artifact.descriptor?.moduleSha256,
230
+ sources: this.options.artifact.sources,
231
+ breakpoints: sourceBreakpoints.map(({ sourcePath, lines }) => ({
232
+ source: { path: sourcePath },
233
+ lines
234
+ })),
235
+ launch: {
236
+ program: '/workspace/program.wasm',
237
+ stopOnEntry: this.options.pauseOnEntry,
238
+ args: this.options.programArgs
239
+ },
240
+ fetchImpl: this.options.fetchImpl,
241
+ onOutput: (_channel, output) => this.options.onOutput(output),
242
+ onLifecycle: (event) => {
243
+ if (lifecycleVersion !== this.lifecycleVersion || this.session !== session) {
244
+ return;
245
+ }
246
+ if (event.type === 'worker-error') {
247
+ this.fail(new Error(`${event.worker} debug worker failed: ${event.message}`));
248
+ }
249
+ else {
250
+ this.finish(event.exitCode ?? this.dapExitCode);
251
+ }
252
+ }
253
+ });
254
+ if (lifecycleVersion !== this.lifecycleVersion) {
255
+ await session.dispose();
256
+ return completion;
257
+ }
258
+ this.session = session;
259
+ let resolveEntrySetup;
260
+ this.entrySetup = {
261
+ ready: new Promise((resolve) => {
262
+ resolveEntrySetup = resolve;
263
+ }),
264
+ resolve: () => resolveEntrySetup()
265
+ };
266
+ session.onEvent((event) => {
267
+ if (lifecycleVersion === this.lifecycleVersion && this.session === session) {
268
+ try {
269
+ this.handleDapEvent(event);
270
+ }
271
+ catch (error) {
272
+ if (!(error instanceof ProtocolError))
273
+ throw error;
274
+ this.fail(error);
275
+ }
276
+ }
277
+ });
278
+ try {
279
+ const capabilities = await session.initialize();
280
+ if (lifecycleVersion !== this.lifecycleVersion || this.session !== session) {
281
+ await session.dispose();
282
+ return completion;
283
+ }
284
+ this.supportsReadMemory =
285
+ manifestSupportsReadMemory && capabilities.supportsReadMemoryRequest === true;
286
+ this.supportsWriteMemory =
287
+ manifestSupportsWriteMemory && capabilities.supportsWriteMemoryRequest === true;
288
+ this.supportsDataBreakpoints =
289
+ manifestSupportsDataBreakpoints && capabilities.supportsDataBreakpoints === true;
290
+ this.supportsValueFormatting = capabilities.supportsValueFormattingOptions === true;
291
+ this.initialized = true;
292
+ if (configuredBreakpointVersion === this.breakpointVersion) {
293
+ for (const { sourcePath, lines } of sourceBreakpoints) {
294
+ this.publishResolvedBreakpoints(session.getResolvedBreakpoints(sourcePath), lines, sourcePath);
295
+ }
296
+ }
297
+ else {
298
+ for (const [sourcePath, lines] of this.breakpointsBySource) {
299
+ await this.setBreakpoints(lines, sourcePath);
300
+ }
301
+ }
302
+ // Startup breakpoint edits must reach LLDB before automatic source entry. Do not
303
+ // wait for stdin to drain: a full input queue needs the guest to run first.
304
+ resolveEntrySetup();
305
+ this.inputReady = true;
306
+ if (this.options.stdin !== undefined) {
307
+ this.pendingInput.push(this.options.stdin);
308
+ this.pendingEof = true;
309
+ }
310
+ await this.flushInput(session, lifecycleVersion);
311
+ }
312
+ catch (error) {
313
+ if (lifecycleVersion === this.lifecycleVersion &&
314
+ this.stopped &&
315
+ this.session !== session) {
316
+ return completion;
317
+ }
318
+ if (lifecycleVersion !== this.lifecycleVersion) {
319
+ await session.dispose();
320
+ return completion;
321
+ }
322
+ if (this.session === session) {
323
+ this.fail(this.asProtocolError(error) ??
324
+ (error instanceof Error
325
+ ? error
326
+ : new Error('Unable to initialize the LLDB debug session.')));
327
+ return completion;
328
+ }
329
+ await session.dispose();
330
+ throw error;
331
+ }
332
+ finally {
333
+ resolveEntrySetup();
334
+ }
335
+ return completion;
336
+ }
337
+ write(input) {
338
+ this.pendingInput.push(input);
339
+ this.pendingEof = false;
340
+ const session = this.session;
341
+ const lifecycleVersion = this.lifecycleVersion;
342
+ return this.observeInputFlush(this.flushInput(session, lifecycleVersion), session, lifecycleVersion);
343
+ }
344
+ eof() {
345
+ this.pendingEof = true;
346
+ const session = this.session;
347
+ const lifecycleVersion = this.lifecycleVersion;
348
+ return this.observeInputFlush(this.flushInput(session, lifecycleVersion), session, lifecycleVersion);
349
+ }
350
+ async debugCommand(command) {
351
+ const session = this.requireSession();
352
+ this.targetStopped = false;
353
+ this.command = command;
354
+ this.pauseRequested = false;
355
+ const dapCommand = command === 'stepInto'
356
+ ? 'stepIn'
357
+ : command === 'nextLine'
358
+ ? 'next'
359
+ : command === 'stepOut'
360
+ ? 'stepOut'
361
+ : 'continue';
362
+ const stateVersion = ++this.stateVersion;
363
+ const request = session.request(dapCommand, { threadId: this.activeThreadId }, { responseTimeoutMs: null });
364
+ this.publishActiveDebugEvent({ type: 'resume', command });
365
+ void request.catch((error) => {
366
+ if (this.session !== session || this.stateVersion !== stateVersion)
367
+ return;
368
+ this.fail(error instanceof Error
369
+ ? error
370
+ : new Error(`Unable to send the LLDB ${dapCommand} request.`));
371
+ });
372
+ }
373
+ async pause() {
374
+ const session = this.requireSession();
375
+ const requestVersion = ++this.pauseRequestVersion;
376
+ this.pauseRequested = true;
377
+ try {
378
+ await session.request('pause', {
379
+ threadId: this.activeThreadId
380
+ });
381
+ }
382
+ catch (error) {
383
+ if (this.session !== session ||
384
+ this.pauseRequestVersion !== requestVersion ||
385
+ !this.pauseRequested) {
386
+ return;
387
+ }
388
+ this.pauseRequested = false;
389
+ throw error;
390
+ }
391
+ }
392
+ async setBreakpoints(lines, sourcePath = this.options.sourcePath) {
393
+ const requestedLines = snapshotBreakpointLines(lines);
394
+ this.breakpointsBySource.set(sourcePath, requestedLines);
395
+ this.breakpointVersion += 1;
396
+ const requestVersion = (this.breakpointRequestVersions.get(sourcePath) ?? 0) + 1;
397
+ this.breakpointRequestVersions.set(sourcePath, requestVersion);
398
+ if (!this.session || !this.initialized)
399
+ return;
400
+ const session = this.requireSession();
401
+ let breakpoints;
402
+ try {
403
+ breakpoints = await session.setBreakpoints({ path: sourcePath }, requestedLines);
404
+ }
405
+ catch (error) {
406
+ if (this.session !== session ||
407
+ this.breakpointRequestVersions.get(sourcePath) !== requestVersion) {
408
+ return;
409
+ }
410
+ this.rethrowProtocolError(error);
411
+ throw error;
412
+ }
413
+ if (this.session !== session ||
414
+ this.breakpointRequestVersions.get(sourcePath) !== requestVersion) {
415
+ return;
416
+ }
417
+ this.publishResolvedBreakpoints(breakpoints, requestedLines, sourcePath);
418
+ }
419
+ async evaluate(expression) {
420
+ if (!this.supportsEvaluateExpressions || !this.activeFrameId)
421
+ return '?';
422
+ const session = this.requireSession();
423
+ const stateVersion = this.stateVersion;
424
+ const scopeRequestVersion = this.scopeRequestVersion;
425
+ const frameId = this.activeFrameId;
426
+ try {
427
+ const response = await session.request('evaluate', {
428
+ expression,
429
+ frameId,
430
+ context: 'watch'
431
+ });
432
+ if (!this.isCurrentValueRequest(session, stateVersion, scopeRequestVersion)) {
433
+ return '?';
434
+ }
435
+ assertDapRecord(response, 'evaluate', 'body');
436
+ assertDapString(response.result, 'evaluate', 'result');
437
+ assertDapNonNegativeSafeInteger(response.variablesReference, 'evaluate', 'variablesReference');
438
+ return response.result;
439
+ }
440
+ catch (error) {
441
+ if (!this.isCurrentValueRequest(session, stateVersion, scopeRequestVersion)) {
442
+ return '?';
443
+ }
444
+ this.rethrowProtocolError(error);
445
+ return '?';
446
+ }
447
+ }
448
+ async variables(variablesReference, start, count) {
449
+ assertPositiveSafeIntegerArgument(variablesReference, 'variablesReference');
450
+ if (start !== undefined)
451
+ assertNonNegativeSafeIntegerArgument(start, 'start');
452
+ if (count !== undefined)
453
+ assertNonNegativeSafeIntegerArgument(count, 'count');
454
+ const session = this.requireSession();
455
+ const stateVersion = this.stateVersion;
456
+ const scopeRequestVersion = this.scopeRequestVersion;
457
+ try {
458
+ const response = await session.request('variables', {
459
+ variablesReference,
460
+ ...(start === undefined ? {} : { start }),
461
+ ...(count === undefined ? {} : { count })
462
+ });
463
+ if (!this.isCurrentValueRequest(session, stateVersion, scopeRequestVersion)) {
464
+ return [];
465
+ }
466
+ return dapResponseCollection(response, 'variables', 'variables').map((variable, index) => {
467
+ const path = `variables[${index}]`;
468
+ assertDapRecord(variable, 'variables', path);
469
+ assertDapString(variable.name, 'variables', `${path}.name`);
470
+ assertDapString(variable.value, 'variables', `${path}.value`);
471
+ assertDapNonNegativeSafeInteger(variable.variablesReference, 'variables', `${path}.variablesReference`);
472
+ const type = variable.type;
473
+ if (type !== undefined)
474
+ assertDapString(type, 'variables', `${path}.type`);
475
+ const evaluateName = variable.evaluateName;
476
+ if (evaluateName !== undefined) {
477
+ assertDapString(evaluateName, 'variables', `${path}.evaluateName`);
478
+ }
479
+ const memoryReference = variable.memoryReference;
480
+ if (memoryReference !== undefined) {
481
+ assertDapString(memoryReference, 'variables', `${path}.memoryReference`);
482
+ }
483
+ const namedVariables = dapOptionalNonNegativeSafeInteger(variable, 'namedVariables', 'variables', path);
484
+ const indexedVariables = dapOptionalNonNegativeSafeInteger(variable, 'indexedVariables', 'variables', path);
485
+ return {
486
+ name: variable.name,
487
+ value: variable.value,
488
+ type,
489
+ ...(evaluateName === undefined ? {} : { evaluateName }),
490
+ variablesReference: variable.variablesReference,
491
+ memoryReference,
492
+ ...(namedVariables === undefined ? {} : { namedVariables }),
493
+ ...(indexedVariables === undefined ? {} : { indexedVariables })
494
+ };
495
+ });
496
+ }
497
+ catch (error) {
498
+ if (!this.isCurrentValueRequest(session, stateVersion, scopeRequestVersion)) {
499
+ return [];
500
+ }
501
+ this.rethrowProtocolError(error);
502
+ throw error;
503
+ }
504
+ }
505
+ /** Ask the adapter to format one stopped frame, without changing evaluation selection. */
506
+ async formattedFrameName(frameId) {
507
+ assertPositiveSafeIntegerArgument(frameId, 'frameId');
508
+ if (!this.targetStopped || !this.supportsValueFormatting || !this.activeThreadId)
509
+ return null;
510
+ const index = this.stoppedFrames.findIndex((frame) => frame.id === frameId);
511
+ if (index < 0)
512
+ return null;
513
+ const session = this.requireSession();
514
+ const version = this.stateVersion;
515
+ try {
516
+ const response = await session.request('stackTrace', {
517
+ threadId: this.activeThreadId,
518
+ startFrame: index,
519
+ levels: 1,
520
+ format: {
521
+ parameters: true,
522
+ parameterNames: true,
523
+ parameterValues: true,
524
+ parameterTypes: false,
525
+ line: false,
526
+ module: false
527
+ }
528
+ });
529
+ if (!this.isCurrentValueRequest(session, version))
530
+ return null;
531
+ const frames = dapResponseCollection(response, 'stackTrace', 'stackFrames');
532
+ if (!frames.length)
533
+ return null;
534
+ const frame = frames[0];
535
+ assertDapRecord(frame, 'stackTrace', 'stackFrames[0]');
536
+ assertDapPositiveSafeInteger(frame.id, 'stackTrace', 'stackFrames[0].id');
537
+ assertDapString(frame.name, 'stackTrace', 'stackFrames[0].name');
538
+ if (frame.id !== frameId || frame.name === this.stoppedFrames[index]?.name)
539
+ return null;
540
+ return frame.name.length > 512 ? frame.name.slice(0, 511) + '…' : frame.name;
541
+ }
542
+ catch (error) {
543
+ if (!this.isCurrentValueRequest(session, version))
544
+ return null;
545
+ this.rethrowProtocolError(error);
546
+ throw error;
547
+ }
548
+ }
549
+ /** Scope metadata lookup does not select a frame or retire other value requests. */
550
+ async frameScopes(frameId) {
551
+ assertPositiveSafeIntegerArgument(frameId, 'frameId');
552
+ const session = this.requireSession();
553
+ const stateVersion = this.stateVersion;
554
+ try {
555
+ const scopes = await this.requestScopes(session, frameId);
556
+ return this.isCurrentValueRequest(session, stateVersion) ? scopes : [];
557
+ }
558
+ catch (error) {
559
+ if (!this.isCurrentValueRequest(session, stateVersion))
560
+ return [];
561
+ this.rethrowProtocolError(error);
562
+ throw error;
563
+ }
564
+ }
565
+ /** Select the evaluation frame, keeping the existing public debugScopes contract. */
566
+ async scopes(frameId) {
567
+ assertPositiveSafeIntegerArgument(frameId, 'frameId');
568
+ const session = this.requireSession();
569
+ const stateVersion = this.stateVersion;
570
+ const requestVersion = ++this.scopeRequestVersion;
571
+ try {
572
+ const scopes = await this.requestScopes(session, frameId);
573
+ if (this.session === session &&
574
+ this.stateVersion === stateVersion &&
575
+ this.scopeRequestVersion === requestVersion) {
576
+ this.activeFrameId = frameId;
577
+ }
578
+ return scopes;
579
+ }
580
+ catch (error) {
581
+ if (this.session !== session ||
582
+ this.stateVersion !== stateVersion ||
583
+ this.scopeRequestVersion !== requestVersion) {
584
+ throw error;
585
+ }
586
+ this.rethrowProtocolError(error);
587
+ throw error;
588
+ }
589
+ }
590
+ async readMemory(memoryReference, offset, count) {
591
+ if (!this.targetStopped || !this.supportsReadMemory)
592
+ return null;
593
+ assertBoundedNonEmptyStringArgument(memoryReference, 'memoryReference');
594
+ if (!Number.isSafeInteger(offset)) {
595
+ throw new RangeError('offset must be a safe integer.');
596
+ }
597
+ assertNonNegativeSafeIntegerArgument(count, 'count');
598
+ if (count > MAX_DEBUG_MEMORY_BYTES) {
599
+ throw new RangeError(`count must not exceed ${MAX_DEBUG_MEMORY_BYTES}.`);
600
+ }
601
+ const session = this.requireSession();
602
+ const stateVersion = this.stateVersion;
603
+ try {
604
+ const response = await session.request('readMemory', {
605
+ memoryReference,
606
+ offset,
607
+ count
608
+ });
609
+ if (!this.isCurrentValueRequest(session, stateVersion))
610
+ return null;
611
+ assertDapRecord(response, 'readMemory', 'body');
612
+ assertDapString(response.address, 'readMemory', 'address');
613
+ const encodedData = response.data;
614
+ if (encodedData !== undefined)
615
+ assertDapString(encodedData, 'readMemory', 'data');
616
+ const unreadableBytes = response.unreadableBytes;
617
+ if (unreadableBytes !== undefined) {
618
+ assertDapNonNegativeSafeInteger(unreadableBytes, 'readMemory', 'unreadableBytes');
619
+ }
620
+ const maximumEncodedDataLength = Math.ceil(count / 3) * 4;
621
+ if (encodedData !== undefined && encodedData.length > maximumEncodedDataLength) {
622
+ invalidDapResponse('readMemory', 'data', `encoded data exceeds the ${maximumEncodedDataLength}-character limit for a ${count}-byte request`);
623
+ }
624
+ let binary;
625
+ try {
626
+ binary = globalThis.atob(encodedData ?? '');
627
+ }
628
+ catch {
629
+ invalidDapResponse('readMemory', 'data', 'expected valid Base64');
630
+ }
631
+ if (binary.length > count) {
632
+ invalidDapResponse('readMemory', 'data', `decoded ${binary.length} bytes for a ${count}-byte request`);
633
+ }
634
+ if (binary.length + (unreadableBytes ?? 0) > count) {
635
+ invalidDapResponse('readMemory', 'unreadableBytes', `reported ${binary.length} readable and ${unreadableBytes ?? 0} unreadable bytes for a ${count}-byte request`);
636
+ }
637
+ const data = new Uint8Array(binary.length);
638
+ for (let index = 0; index < binary.length; index += 1) {
639
+ data[index] = binary.charCodeAt(index);
640
+ }
641
+ return {
642
+ address: response.address,
643
+ data,
644
+ unreadableBytes: unreadableBytes ?? 0
645
+ };
646
+ }
647
+ catch (error) {
648
+ if (!this.isCurrentValueRequest(session, stateVersion))
649
+ return null;
650
+ this.rethrowProtocolError(error);
651
+ throw error;
652
+ }
653
+ }
654
+ async writeMemory(memoryReference, offset, data, allowPartial = false) {
655
+ if (!this.targetStopped || !this.supportsWriteMemory)
656
+ return null;
657
+ assertBoundedNonEmptyStringArgument(memoryReference, 'memoryReference');
658
+ if (!Number.isSafeInteger(offset)) {
659
+ throw new RangeError('offset must be a safe integer.');
660
+ }
661
+ if (!(data instanceof Uint8Array)) {
662
+ throw new TypeError('data must be a Uint8Array.');
663
+ }
664
+ if (data.byteLength > MAX_DEBUG_MEMORY_BYTES) {
665
+ throw new RangeError(`data must not exceed ${MAX_DEBUG_MEMORY_BYTES} bytes.`);
666
+ }
667
+ assertOptionalBooleanArgument(allowPartial, 'allowPartial');
668
+ const chunks = [];
669
+ for (let start = 0; start < data.byteLength; start += 0x8000) {
670
+ chunks.push(String.fromCharCode(...data.subarray(start, start + 0x8000)));
671
+ }
672
+ const session = this.requireSession();
673
+ const stateVersion = this.stateVersion;
674
+ try {
675
+ const response = await session.request('writeMemory', {
676
+ memoryReference,
677
+ offset,
678
+ allowPartial,
679
+ data: globalThis.btoa(chunks.join(''))
680
+ });
681
+ if (!this.isCurrentValueRequest(session, stateVersion))
682
+ return null;
683
+ if (response !== undefined)
684
+ assertDapRecord(response, 'writeMemory', 'body');
685
+ const responseBody = response ?? {};
686
+ const responseBytesWritten = responseBody.bytesWritten;
687
+ if (responseBytesWritten !== undefined) {
688
+ assertDapNonNegativeSafeInteger(responseBytesWritten, 'writeMemory', 'bytesWritten');
689
+ }
690
+ const bytesWritten = responseBytesWritten ?? data.byteLength;
691
+ if (bytesWritten > data.byteLength) {
692
+ invalidDapResponse('writeMemory', 'bytesWritten', `reported ${bytesWritten} bytes written for ${data.byteLength} input bytes`);
693
+ }
694
+ if (!allowPartial && bytesWritten !== data.byteLength) {
695
+ invalidDapResponse('writeMemory', 'bytesWritten', `reported a partial write of ${bytesWritten} bytes for a required ${data.byteLength}-byte write`);
696
+ }
697
+ const responseOffset = responseBody.offset;
698
+ if (responseOffset !== undefined &&
699
+ (typeof responseOffset !== 'number' || !Number.isSafeInteger(responseOffset))) {
700
+ invalidDapResponse('writeMemory', 'offset', 'expected a safe integer');
701
+ }
702
+ return {
703
+ ...(responseOffset === undefined ? {} : { offset: responseOffset }),
704
+ bytesWritten
705
+ };
706
+ }
707
+ catch (error) {
708
+ if (!this.isCurrentValueRequest(session, stateVersion))
709
+ return null;
710
+ this.rethrowProtocolError(error);
711
+ throw error;
712
+ }
713
+ }
714
+ async dataBreakpointInfo(arguments_) {
715
+ if (!this.targetStopped || !this.supportsDataBreakpoints)
716
+ return null;
717
+ if (typeof arguments_ !== 'object' || arguments_ === null || Array.isArray(arguments_)) {
718
+ throw new TypeError('arguments must be an object.');
719
+ }
720
+ assertBoundedNonEmptyStringArgument(arguments_.name, 'name');
721
+ if (arguments_.variablesReference !== undefined) {
722
+ assertNonNegativeSafeIntegerArgument(arguments_.variablesReference, 'variablesReference');
723
+ }
724
+ if (arguments_.frameId !== undefined) {
725
+ assertPositiveSafeIntegerArgument(arguments_.frameId, 'frameId');
726
+ }
727
+ if (arguments_.bytes !== undefined) {
728
+ assertPositiveSafeIntegerArgument(arguments_.bytes, 'bytes');
729
+ if (arguments_.bytes > MAX_DEBUG_MEMORY_BYTES) {
730
+ throw new RangeError(`bytes must not exceed ${MAX_DEBUG_MEMORY_BYTES}.`);
731
+ }
732
+ }
733
+ assertOptionalBooleanArgument(arguments_.asAddress, 'asAddress');
734
+ const session = this.requireSession();
735
+ const stateVersion = this.stateVersion;
736
+ try {
737
+ const response = await session.request('dataBreakpointInfo', {
738
+ name: arguments_.name,
739
+ ...(arguments_.variablesReference === undefined
740
+ ? {}
741
+ : { variablesReference: arguments_.variablesReference }),
742
+ ...(arguments_.frameId === undefined ? {} : { frameId: arguments_.frameId }),
743
+ ...(arguments_.asAddress === undefined ? {} : { asAddress: arguments_.asAddress }),
744
+ ...(arguments_.bytes === undefined ? {} : { bytes: arguments_.bytes })
745
+ });
746
+ if (!this.isCurrentValueRequest(session, stateVersion))
747
+ return null;
748
+ assertDapRecord(response, 'dataBreakpointInfo', 'body');
749
+ assertDapString(response.description, 'dataBreakpointInfo', 'description');
750
+ let dataId;
751
+ if (response.dataId !== undefined && response.dataId !== null) {
752
+ assertDapString(response.dataId, 'dataBreakpointInfo', 'dataId');
753
+ if (response.dataId.length === 0) {
754
+ invalidDapResponse('dataBreakpointInfo', 'dataId', 'expected a non-empty string');
755
+ }
756
+ if (response.dataId.length > MAX_DEBUG_IDENTIFIER_CODE_UNITS) {
757
+ invalidDapResponse('dataBreakpointInfo', 'dataId', `expected at most ${MAX_DEBUG_IDENTIFIER_CODE_UNITS} UTF-16 code units`);
758
+ }
759
+ dataId = response.dataId;
760
+ }
761
+ let accessTypes;
762
+ if (response.accessTypes !== undefined) {
763
+ if (!Array.isArray(response.accessTypes)) {
764
+ invalidDapResponse('dataBreakpointInfo', 'accessTypes', 'expected an array');
765
+ }
766
+ if (response.accessTypes.length > 3) {
767
+ invalidDapResponse('dataBreakpointInfo', 'accessTypes', 'expected at most 3 entries');
768
+ }
769
+ const seenAccessTypes = new Set();
770
+ accessTypes = response.accessTypes.map((accessType, index) => {
771
+ if (accessType !== 'read' &&
772
+ accessType !== 'write' &&
773
+ accessType !== 'readWrite') {
774
+ invalidDapResponse('dataBreakpointInfo', `accessTypes[${index}]`, 'expected read, write, or readWrite');
775
+ }
776
+ if (seenAccessTypes.has(accessType)) {
777
+ invalidDapResponse('dataBreakpointInfo', `accessTypes[${index}]`, 'expected a unique access type');
778
+ }
779
+ seenAccessTypes.add(accessType);
780
+ return accessType;
781
+ });
782
+ }
783
+ let canPersist;
784
+ if (response.canPersist !== undefined) {
785
+ assertDapBoolean(response.canPersist, 'dataBreakpointInfo', 'canPersist');
786
+ canPersist = response.canPersist;
787
+ }
788
+ return {
789
+ ...(dataId === undefined ? {} : { dataId }),
790
+ description: response.description,
791
+ ...(accessTypes === undefined ? {} : { accessTypes }),
792
+ ...(canPersist === undefined ? {} : { canPersist })
793
+ };
794
+ }
795
+ catch (error) {
796
+ if (!this.isCurrentValueRequest(session, stateVersion))
797
+ return null;
798
+ this.rethrowProtocolError(error);
799
+ throw error;
800
+ }
801
+ }
802
+ async setDataBreakpoints(breakpoints) {
803
+ if (!this.targetStopped || !this.supportsDataBreakpoints)
804
+ return [];
805
+ if (!Array.isArray(breakpoints)) {
806
+ throw new TypeError('breakpoints must be an array.');
807
+ }
808
+ if (breakpoints.length > MAX_DEBUG_DATA_BREAKPOINTS) {
809
+ throw new RangeError(`breakpoints must not contain more than ${MAX_DEBUG_DATA_BREAKPOINTS} entries.`);
810
+ }
811
+ for (let index = 0; index < breakpoints.length; index += 1) {
812
+ const breakpoint = breakpoints[index];
813
+ if (typeof breakpoint !== 'object' ||
814
+ breakpoint === null ||
815
+ Array.isArray(breakpoint)) {
816
+ throw new TypeError(`breakpoints[${index}] must be an object.`);
817
+ }
818
+ if (typeof breakpoint.dataId !== 'string' || breakpoint.dataId.length === 0) {
819
+ throw new TypeError(`breakpoints[${index}].dataId must be a non-empty string.`);
820
+ }
821
+ if (breakpoint.dataId.length > MAX_DEBUG_IDENTIFIER_CODE_UNITS) {
822
+ throw new RangeError(`breakpoints[${index}].dataId must not exceed ${MAX_DEBUG_IDENTIFIER_CODE_UNITS} UTF-16 code units.`);
823
+ }
824
+ if (breakpoint.accessType !== undefined &&
825
+ breakpoint.accessType !== 'read' &&
826
+ breakpoint.accessType !== 'write' &&
827
+ breakpoint.accessType !== 'readWrite') {
828
+ throw new TypeError(`breakpoints[${index}].accessType must be read, write, or readWrite.`);
829
+ }
830
+ }
831
+ const requestBreakpoints = breakpoints.map((breakpoint) => {
832
+ return {
833
+ dataId: breakpoint.dataId,
834
+ ...(breakpoint.accessType === undefined
835
+ ? {}
836
+ : { accessType: breakpoint.accessType })
837
+ };
838
+ });
839
+ const session = this.requireSession();
840
+ const stateVersion = this.stateVersion;
841
+ try {
842
+ const response = await session.request('setDataBreakpoints', {
843
+ breakpoints: requestBreakpoints
844
+ });
845
+ if (!this.isCurrentValueRequest(session, stateVersion))
846
+ return [];
847
+ const responseBreakpoints = dapResponseCollection(response, 'setDataBreakpoints', 'breakpoints');
848
+ if (responseBreakpoints.length !== requestBreakpoints.length) {
849
+ invalidDapResponse('setDataBreakpoints', 'breakpoints', `expected ${requestBreakpoints.length} entries`);
850
+ }
851
+ return responseBreakpoints.map((breakpoint, index) => {
852
+ const path = `breakpoints[${index}]`;
853
+ assertDapRecord(breakpoint, 'setDataBreakpoints', path);
854
+ assertDapBoolean(breakpoint.verified, 'setDataBreakpoints', `${path}.verified`);
855
+ const id = dapOptionalNonNegativeSafeInteger(breakpoint, 'id', 'setDataBreakpoints', path);
856
+ let message;
857
+ if (breakpoint.message !== undefined) {
858
+ assertDapString(breakpoint.message, 'setDataBreakpoints', `${path}.message`);
859
+ message = breakpoint.message;
860
+ }
861
+ return {
862
+ ...(id === undefined ? {} : { id }),
863
+ verified: breakpoint.verified,
864
+ ...(message === undefined ? {} : { message })
865
+ };
866
+ });
867
+ }
868
+ catch (error) {
869
+ if (!this.isCurrentValueRequest(session, stateVersion))
870
+ return [];
871
+ const failure = this.asProtocolError(error) ??
872
+ (error instanceof Error
873
+ ? error
874
+ : new Error('Unable to replace the LLDB data breakpoints.'));
875
+ this.fail(failure);
876
+ throw failure;
877
+ }
878
+ }
879
+ async disconnect() {
880
+ const completionResolve = this.completionResolve;
881
+ const completionReject = this.completionReject;
882
+ this.lifecycleVersion += 1;
883
+ this.entrySetup?.resolve();
884
+ this.entrySetup = undefined;
885
+ const startupAbortController = this.startupAbortController;
886
+ this.startupAbortController = undefined;
887
+ startupAbortController?.abort(new Error('LLDB sandbox session disconnected during startup.'));
888
+ this.stateVersion += 1;
889
+ this.targetStopped = false;
890
+ this.retireInput();
891
+ this.initialized = false;
892
+ this.supportsEvaluateExpressions = false;
893
+ this.supportsReadMemory = false;
894
+ this.supportsWriteMemory = false;
895
+ this.supportsDataBreakpoints = false;
896
+ this.dapExitCode = null;
897
+ const session = this.session;
898
+ this.session = undefined;
899
+ const shouldPublishStop = !this.stopped;
900
+ this.stopped = true;
901
+ const disposal = session
902
+ ? this.trackSessionDisposal(session.disconnect({ terminateTarget: true }))
903
+ : this.sessionDisposal;
904
+ let disposalFailure;
905
+ try {
906
+ await disposal;
907
+ }
908
+ catch (error) {
909
+ disposalFailure =
910
+ error instanceof Error
911
+ ? error
912
+ : new Error('Unable to disconnect the LLDB debug session.');
913
+ }
914
+ if (disposalFailure) {
915
+ completionReject?.(disposalFailure);
916
+ if (shouldPublishStop)
917
+ this.publishStop();
918
+ throw disposalFailure;
919
+ }
920
+ completionResolve?.(true);
921
+ if (shouldPublishStop)
922
+ this.publishStop();
923
+ }
924
+ handleDapEvent(event) {
925
+ if (event.event === 'output') {
926
+ const body = event.body;
927
+ if (typeof body?.output === 'string')
928
+ this.options.onOutput(body.output);
929
+ return;
930
+ }
931
+ if (event.event === 'stopped') {
932
+ this.targetStopped = false;
933
+ if (typeof event.body !== 'object' ||
934
+ event.body === null ||
935
+ Array.isArray(event.body)) {
936
+ invalidDapPayload('stopped event', 'body', 'expected an object');
937
+ }
938
+ const body = event.body;
939
+ if (typeof body.reason !== 'string') {
940
+ invalidDapPayload('stopped event', 'reason', 'expected a string');
941
+ }
942
+ const threadId = body.threadId;
943
+ if (threadId !== undefined) {
944
+ assertDapPositiveSafeInteger(threadId, 'stopped event', 'threadId');
945
+ }
946
+ if (body.allThreadsStopped !== undefined &&
947
+ typeof body.allThreadsStopped !== 'boolean') {
948
+ invalidDapPayload('stopped event', 'allThreadsStopped', 'expected a boolean');
949
+ }
950
+ const reason = this.pauseRequested && body.reason === 'exception' ? 'pause' : body.reason;
951
+ this.pauseRequested = false;
952
+ const session = this.requireSession();
953
+ const version = ++this.stateVersion;
954
+ void this.resolveStoppedState(threadId, reason, version).catch((error) => {
955
+ if (version !== this.stateVersion || this.session !== session)
956
+ return;
957
+ this.fail(error instanceof Error ? error : new Error('Unable to read LLDB stopped state.'));
958
+ });
959
+ return;
960
+ }
961
+ if (event.event === 'continued') {
962
+ this.targetStopped = false;
963
+ if (typeof event.body !== 'object' ||
964
+ event.body === null ||
965
+ Array.isArray(event.body)) {
966
+ invalidDapPayload('continued event', 'body', 'expected an object');
967
+ }
968
+ const body = event.body;
969
+ assertDapPositiveSafeInteger(body.threadId, 'continued event', 'threadId');
970
+ if (body.allThreadsContinued !== undefined &&
971
+ typeof body.allThreadsContinued !== 'boolean') {
972
+ invalidDapPayload('continued event', 'allThreadsContinued', 'expected a boolean');
973
+ }
974
+ this.stateVersion += 1;
975
+ return;
976
+ }
977
+ if (event.event === 'breakpoint') {
978
+ const body = event.body;
979
+ const breakpointId = body?.breakpoint?.id;
980
+ const sourcePath = body?.breakpoint?.source?.path;
981
+ for (const [trackedSourcePath, requestedLines] of this.breakpointsBySource) {
982
+ const resolved = this.requireSession().getResolvedBreakpoints(trackedSourcePath);
983
+ if (breakpointId !== undefined) {
984
+ if (!resolved.some((breakpoint) => breakpoint.id === breakpointId))
985
+ continue;
986
+ }
987
+ else {
988
+ if (sourcePath && sourcePath !== trackedSourcePath)
989
+ continue;
990
+ }
991
+ this.publishResolvedBreakpoints(resolved, requestedLines, trackedSourcePath);
992
+ }
993
+ return;
994
+ }
995
+ if (event.event === 'exited') {
996
+ if (typeof event.body !== 'object' ||
997
+ event.body === null ||
998
+ Array.isArray(event.body)) {
999
+ invalidDapPayload('exited event', 'body', 'expected an object');
1000
+ }
1001
+ const exitCode = event.body.exitCode;
1002
+ if (typeof exitCode !== 'number' || !Number.isSafeInteger(exitCode)) {
1003
+ invalidDapPayload('exited event', 'exitCode', 'expected a safe integer');
1004
+ }
1005
+ this.dapExitCode = exitCode;
1006
+ return;
1007
+ }
1008
+ if (event.event === 'terminated')
1009
+ return;
1010
+ }
1011
+ async resolveStoppedState(requestedThreadId, reason, version) {
1012
+ const session = this.requireSession();
1013
+ let threadId = requestedThreadId;
1014
+ if (threadId === undefined) {
1015
+ const response = await session.request('threads');
1016
+ const threads = dapResponseCollection(response, 'threads', 'threads').map((thread, index) => {
1017
+ const path = `threads[${index}]`;
1018
+ assertDapRecord(thread, 'threads', path);
1019
+ assertDapPositiveSafeInteger(thread.id, 'threads response', `${path}.id`);
1020
+ assertDapString(thread.name, 'threads', `${path}.name`);
1021
+ return { id: thread.id, name: thread.name };
1022
+ });
1023
+ threadId = threads[0]?.id;
1024
+ }
1025
+ if (!threadId)
1026
+ throw new Error('LLDB stopped without a WebAssembly thread.');
1027
+ const response = await session.request('stackTrace', {
1028
+ threadId,
1029
+ startFrame: 0,
1030
+ levels: 100
1031
+ });
1032
+ const frames = dapResponseCollection(response, 'stackTrace', 'stackFrames').map((frame, index) => {
1033
+ const path = `stackFrames[${index}]`;
1034
+ assertDapRecord(frame, 'stackTrace', path);
1035
+ assertDapPositiveSafeInteger(frame.id, 'stackTrace response', `${path}.id`);
1036
+ assertDapString(frame.name, 'stackTrace', `${path}.name`);
1037
+ assertDapNonNegativeSafeInteger(frame.line, 'stackTrace', `${path}.line`);
1038
+ assertDapNonNegativeSafeInteger(frame.column, 'stackTrace', `${path}.column`);
1039
+ let source;
1040
+ if (frame.source !== undefined) {
1041
+ assertDapRecord(frame.source, 'stackTrace', `${path}.source`);
1042
+ const sourcePath = frame.source.path;
1043
+ if (sourcePath !== undefined) {
1044
+ assertDapString(sourcePath, 'stackTrace', `${path}.source.path`);
1045
+ }
1046
+ source = sourcePath === undefined ? {} : { path: sourcePath };
1047
+ }
1048
+ return {
1049
+ id: frame.id,
1050
+ name: frame.name,
1051
+ source,
1052
+ line: frame.line,
1053
+ column: frame.column
1054
+ };
1055
+ });
1056
+ const selectedFrame = frames[0];
1057
+ if (!selectedFrame)
1058
+ throw new Error('LLDB stopped without a stack frame.');
1059
+ const isWorkspaceFrame = this.options.artifact.sources.some((source) => source.path === selectedFrame.source?.path);
1060
+ if (!this.isCurrentValueRequest(session, version))
1061
+ return;
1062
+ if (this.entryPhase === 'initial') {
1063
+ await this.entrySetup?.ready;
1064
+ if (!this.isCurrentValueRequest(session, version))
1065
+ return;
1066
+ this.entryPhase = 'done';
1067
+ if (reason === 'entry' && selectedFrame.name === '_start' && !isWorkspaceFrame) {
1068
+ // configurationDone has already installed all user source breakpoints. Function
1069
+ // breakpoints occupy a separate DAP registry owned by this product session.
1070
+ this.entryPhase = 'seeking-main';
1071
+ const verified = await this.setMainEntryBreakpoint(session, true);
1072
+ if (!this.isCurrentValueRequest(session, version))
1073
+ return;
1074
+ if (verified && !this.pauseRequested) {
1075
+ this.activeThreadId = threadId;
1076
+ await this.debugCommand('continue');
1077
+ return;
1078
+ }
1079
+ await this.setMainEntryBreakpoint(session, false);
1080
+ if (!this.isCurrentValueRequest(session, version))
1081
+ return;
1082
+ this.entryPhase = 'done';
1083
+ if (this.pauseRequested) {
1084
+ this.pauseRequested = false;
1085
+ reason = 'pause';
1086
+ }
1087
+ else {
1088
+ this.options.onOutput('LLDB could not resolve main; paused at runtime entry.\n');
1089
+ }
1090
+ }
1091
+ }
1092
+ else if (this.entryPhase === 'seeking-main') {
1093
+ // Honor any earlier user breakpoint, trap, or Pause, and never leave a hidden
1094
+ // main breakpoint behind for a later Continue.
1095
+ this.entryPhase = 'done';
1096
+ await this.setMainEntryBreakpoint(session, false);
1097
+ if (!this.isCurrentValueRequest(session, version))
1098
+ return;
1099
+ if (reason === 'breakpoint' && selectedFrame.name === 'main' && isWorkspaceFrame) {
1100
+ reason = 'entry';
1101
+ }
1102
+ }
1103
+ const scopes = isWorkspaceFrame ? await this.requestScopes(session, selectedFrame.id) : [];
1104
+ if (version !== this.stateVersion || this.session !== session)
1105
+ return;
1106
+ this.activeThreadId = threadId;
1107
+ this.activeFrameId = selectedFrame.id;
1108
+ this.stoppedFrames = frames;
1109
+ this.targetStopped = true;
1110
+ const callStack = frames.map((frame) => {
1111
+ const sourcePath = frame.source?.path;
1112
+ const sourceContentSha256 = this.sourceContentSha256ByPath.get(sourcePath || '');
1113
+ return {
1114
+ id: frame.id,
1115
+ functionName: frame.name,
1116
+ line: frame.line,
1117
+ column: frame.column,
1118
+ sourcePath,
1119
+ ...(sourceContentSha256 ? { sourceContentSha256 } : {})
1120
+ };
1121
+ });
1122
+ const sourceContentSha256 = this.sourceContentSha256ByPath.get(selectedFrame.source?.path || '');
1123
+ this.options.onDebugEvent({
1124
+ type: 'pause',
1125
+ capabilities: {
1126
+ readMemory: this.supportsReadMemory,
1127
+ writeMemory: this.supportsWriteMemory,
1128
+ dataBreakpoints: this.supportsDataBreakpoints
1129
+ },
1130
+ line: selectedFrame.line,
1131
+ sourcePath: selectedFrame.source?.path,
1132
+ ...(sourceContentSha256 ? { sourceContentSha256 } : {}),
1133
+ reason: pauseReason(reason, this.command),
1134
+ stoppedReason: reason,
1135
+ threadId,
1136
+ frameId: selectedFrame.id,
1137
+ locals: [],
1138
+ callStack,
1139
+ scopes
1140
+ });
1141
+ this.command = null;
1142
+ }
1143
+ async setMainEntryBreakpoint(session, enabled) {
1144
+ const response = await session.request('setFunctionBreakpoints', {
1145
+ breakpoints: enabled ? [{ name: 'main' }] : []
1146
+ });
1147
+ const breakpoints = dapResponseCollection(response, 'setFunctionBreakpoints', 'breakpoints');
1148
+ if (breakpoints.length !== (enabled ? 1 : 0)) {
1149
+ invalidDapResponse('setFunctionBreakpoints', 'breakpoints', 'unexpected breakpoint count');
1150
+ }
1151
+ if (!enabled)
1152
+ return false;
1153
+ const breakpoint = breakpoints[0];
1154
+ assertDapRecord(breakpoint, 'setFunctionBreakpoints', 'breakpoints[0]');
1155
+ assertDapBoolean(breakpoint.verified, 'setFunctionBreakpoints', 'breakpoints[0].verified');
1156
+ return breakpoint.verified;
1157
+ }
1158
+ async requestScopes(session, frameId) {
1159
+ const response = await session.request('scopes', { frameId });
1160
+ return dapResponseCollection(response, 'scopes', 'scopes').map((scope, index) => {
1161
+ const path = `scopes[${index}]`;
1162
+ assertDapRecord(scope, 'scopes', path);
1163
+ assertDapString(scope.name, 'scopes', `${path}.name`);
1164
+ assertDapNonNegativeSafeInteger(scope.variablesReference, 'scopes', `${path}.variablesReference`);
1165
+ assertDapBoolean(scope.expensive, 'scopes', `${path}.expensive`);
1166
+ const presentationHint = scope.presentationHint;
1167
+ if (presentationHint !== undefined) {
1168
+ assertDapString(presentationHint, 'scopes', `${path}.presentationHint`);
1169
+ }
1170
+ const namedVariables = dapOptionalNonNegativeSafeInteger(scope, 'namedVariables', 'scopes', path);
1171
+ const indexedVariables = dapOptionalNonNegativeSafeInteger(scope, 'indexedVariables', 'scopes', path);
1172
+ return {
1173
+ name: scope.name,
1174
+ ...(presentationHint === undefined ? {} : { presentationHint }),
1175
+ variablesReference: scope.variablesReference,
1176
+ ...(namedVariables === undefined ? {} : { namedVariables }),
1177
+ ...(indexedVariables === undefined ? {} : { indexedVariables }),
1178
+ expensive: scope.expensive,
1179
+ variables: []
1180
+ };
1181
+ });
1182
+ }
1183
+ isCurrentValueRequest(session, stateVersion, scopeRequestVersion) {
1184
+ return (this.session === session &&
1185
+ this.stateVersion === stateVersion &&
1186
+ (scopeRequestVersion === undefined || this.scopeRequestVersion === scopeRequestVersion));
1187
+ }
1188
+ rethrowProtocolError(error) {
1189
+ const protocolError = this.asProtocolError(error);
1190
+ if (!protocolError)
1191
+ return;
1192
+ this.fail(protocolError);
1193
+ throw protocolError;
1194
+ }
1195
+ asProtocolError(error) {
1196
+ if (error instanceof ProtocolError)
1197
+ return error;
1198
+ if (error instanceof DapProtocolError) {
1199
+ return new ProtocolError(error.message, { cause: error });
1200
+ }
1201
+ return null;
1202
+ }
1203
+ finish(exitCode) {
1204
+ if (this.stopped)
1205
+ return;
1206
+ this.entrySetup?.resolve();
1207
+ this.entrySetup = undefined;
1208
+ this.stopped = true;
1209
+ this.stateVersion += 1;
1210
+ this.targetStopped = false;
1211
+ this.retireInput();
1212
+ this.initialized = false;
1213
+ this.supportsEvaluateExpressions = false;
1214
+ this.supportsReadMemory = false;
1215
+ this.supportsWriteMemory = false;
1216
+ this.supportsDataBreakpoints = false;
1217
+ this.dapExitCode = null;
1218
+ const session = this.session;
1219
+ this.session = undefined;
1220
+ const completionResolve = this.completionResolve;
1221
+ const completionReject = this.completionReject;
1222
+ const disposal = session
1223
+ ? this.trackSessionDisposal(session.dispose())
1224
+ : (this.sessionDisposal ?? Promise.resolve());
1225
+ void disposal.then(() => {
1226
+ if (exitCode !== null && exitCode !== 0) {
1227
+ completionReject?.(new Error(`Debug target exited with code ${exitCode}.`));
1228
+ }
1229
+ else {
1230
+ completionResolve?.(true);
1231
+ }
1232
+ }, (error) => completionReject?.(error instanceof Error
1233
+ ? error
1234
+ : new Error('Unable to dispose the LLDB debug session.')));
1235
+ this.publishStop();
1236
+ }
1237
+ fail(error) {
1238
+ if (this.stopped)
1239
+ return;
1240
+ this.entrySetup?.resolve();
1241
+ this.entrySetup = undefined;
1242
+ this.stopped = true;
1243
+ this.stateVersion += 1;
1244
+ this.targetStopped = false;
1245
+ this.retireInput();
1246
+ this.initialized = false;
1247
+ this.supportsEvaluateExpressions = false;
1248
+ this.supportsReadMemory = false;
1249
+ this.supportsWriteMemory = false;
1250
+ this.supportsDataBreakpoints = false;
1251
+ this.dapExitCode = null;
1252
+ const session = this.session;
1253
+ this.session = undefined;
1254
+ const completionReject = this.completionReject;
1255
+ const disposal = session
1256
+ ? this.trackSessionDisposal(session.dispose())
1257
+ : (this.sessionDisposal ?? Promise.resolve());
1258
+ void disposal.then(() => completionReject?.(error), () => completionReject?.(error));
1259
+ this.publishStop();
1260
+ }
1261
+ publishStop() {
1262
+ try {
1263
+ this.options.onDebugEvent({ type: 'stop' });
1264
+ }
1265
+ catch {
1266
+ // Consumer callbacks cannot interrupt target teardown or completion settlement.
1267
+ }
1268
+ }
1269
+ publishActiveDebugEvent(event) {
1270
+ try {
1271
+ this.options.onDebugEvent(event);
1272
+ }
1273
+ catch (error) {
1274
+ const failure = error instanceof Error
1275
+ ? error
1276
+ : new Error('Unable to publish the LLDB debug session state.');
1277
+ this.fail(failure);
1278
+ throw failure;
1279
+ }
1280
+ }
1281
+ trackSessionDisposal(disposal) {
1282
+ this.sessionDisposal = disposal;
1283
+ void disposal.then(() => {
1284
+ if (this.sessionDisposal === disposal)
1285
+ this.sessionDisposal = undefined;
1286
+ }, () => {
1287
+ if (this.sessionDisposal === disposal)
1288
+ this.sessionDisposal = undefined;
1289
+ });
1290
+ return disposal;
1291
+ }
1292
+ requireSession() {
1293
+ if (!this.session)
1294
+ throw new Error('LLDB sandbox session is not running.');
1295
+ return this.session;
1296
+ }
1297
+ publishResolvedBreakpoints(breakpoints, requestedLines, sourcePath = this.options.sourcePath) {
1298
+ const sourceContentSha256 = this.sourceContentSha256ByPath.get(sourcePath);
1299
+ this.publishActiveDebugEvent({
1300
+ type: 'breakpoints',
1301
+ sourcePath,
1302
+ ...(sourceContentSha256 ? { sourceContentSha256 } : {}),
1303
+ breakpoints: requestedLines.map((requestedLine, index) => ({
1304
+ requestedLine,
1305
+ line: breakpoints[index]?.line ?? requestedLine,
1306
+ verified: breakpoints[index]?.verified === true,
1307
+ message: breakpoints[index]?.message
1308
+ }))
1309
+ });
1310
+ }
1311
+ observeInputFlush(flush, session, lifecycleVersion) {
1312
+ void flush.catch((error) => {
1313
+ if (this.stopped ||
1314
+ this.lifecycleVersion !== lifecycleVersion ||
1315
+ this.session !== session) {
1316
+ return;
1317
+ }
1318
+ this.fail(error instanceof Error ? error : new Error('Unable to write LLDB target input.'));
1319
+ });
1320
+ return flush;
1321
+ }
1322
+ retireInput() {
1323
+ this.inputReady = false;
1324
+ this.pendingInput.length = 0;
1325
+ this.pendingEof = false;
1326
+ }
1327
+ async flushInput(session, lifecycleVersion) {
1328
+ if (!this.inputReady ||
1329
+ !session ||
1330
+ this.lifecycleVersion !== lifecycleVersion ||
1331
+ this.session !== session) {
1332
+ return;
1333
+ }
1334
+ while (this.pendingInput.length > 0) {
1335
+ await session.writeStdin(this.pendingInput.shift() || '');
1336
+ if (!this.inputReady ||
1337
+ this.lifecycleVersion !== lifecycleVersion ||
1338
+ this.session !== session) {
1339
+ return;
1340
+ }
1341
+ }
1342
+ if (this.pendingEof) {
1343
+ this.pendingEof = false;
1344
+ await session.closeStdin();
1345
+ }
1346
+ }
1347
+ }