warpo 3.0.0 → 3.1.1

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 (86) hide show
  1. package/dist/debug_server/debugSession.d.ts +17 -1
  2. package/dist/debug_server/debugSession.js +169 -7
  3. package/dist/debug_server/debugSession.js.map +1 -1
  4. package/dist/debug_server/debugger.d.ts +25 -0
  5. package/dist/debug_server/debugger.js +4 -0
  6. package/dist/debug_server/debugger.js.map +1 -0
  7. package/dist/debug_server/debuggerWasmModule.d.ts +28 -0
  8. package/dist/debug_server/debuggerWasmModule.js +75 -0
  9. package/dist/debug_server/debuggerWasmModule.js.map +1 -0
  10. package/dist/debug_server/nodeDebugger.d.ts +27 -0
  11. package/dist/debug_server/nodeDebugger.js +240 -0
  12. package/dist/debug_server/nodeDebugger.js.map +1 -0
  13. package/dist/debug_server/tests/debugSession.test.js +45 -1
  14. package/dist/debug_server/tests/debugSession.test.js.map +1 -1
  15. package/dist/debug_server/tests/testModule/debugger_basic.d.ts +1 -0
  16. package/dist/debug_server/tests/testModule/debugger_basic.js +6 -0
  17. package/dist/debug_server/tests/testModule/debugger_basic.js.map +1 -0
  18. package/dist/debug_server/wasmEntry.js +36 -0
  19. package/dist/debug_server/wasmEntry.js.map +1 -0
  20. package/dist/heap_analyzer/cli.d.ts +1 -0
  21. package/dist/heap_analyzer/cli.js +172 -0
  22. package/dist/heap_analyzer/cli.js.map +1 -0
  23. package/dist/heap_analyzer/src/comparison.d.ts +2 -0
  24. package/dist/heap_analyzer/src/comparison.js +77 -0
  25. package/dist/heap_analyzer/src/comparison.js.map +1 -0
  26. package/dist/heap_analyzer/src/constants.d.ts +1 -1
  27. package/dist/heap_analyzer/src/constants.js +1 -1
  28. package/dist/heap_analyzer/src/debugInfoResolver.d.ts +30 -0
  29. package/dist/heap_analyzer/src/debugInfoResolver.js +334 -0
  30. package/dist/heap_analyzer/src/debugInfoResolver.js.map +1 -0
  31. package/dist/heap_analyzer/src/dumpReader.js +11 -2
  32. package/dist/heap_analyzer/src/dumpReader.js.map +1 -1
  33. package/dist/heap_analyzer/src/dwarfParser.d.ts +30 -9
  34. package/dist/heap_analyzer/src/dwarfParser.js +54 -20
  35. package/dist/heap_analyzer/src/dwarfParser.js.map +1 -1
  36. package/dist/heap_analyzer/src/index.d.ts +7 -0
  37. package/dist/heap_analyzer/src/index.js +16 -0
  38. package/dist/heap_analyzer/src/index.js.map +1 -0
  39. package/dist/heap_analyzer/src/referenceScanner.d.ts +4 -4
  40. package/dist/heap_analyzer/src/referenceScanner.js +52 -21
  41. package/dist/heap_analyzer/src/referenceScanner.js.map +1 -1
  42. package/dist/heap_analyzer/src/roots.d.ts +3 -6
  43. package/dist/heap_analyzer/src/roots.js +12 -5
  44. package/dist/heap_analyzer/src/roots.js.map +1 -1
  45. package/dist/heap_analyzer/src/snapshot.d.ts +2 -2
  46. package/dist/heap_analyzer/src/snapshot.js +36 -88
  47. package/dist/heap_analyzer/src/snapshot.js.map +1 -1
  48. package/dist/heap_analyzer/src/types.d.ts +54 -11
  49. package/dist/heap_analyzer/src/types.js +22 -1
  50. package/dist/heap_analyzer/src/types.js.map +1 -1
  51. package/dist/heap_analyzer/tests/comparison.test.d.ts +1 -0
  52. package/dist/heap_analyzer/tests/comparison.test.js +121 -0
  53. package/dist/heap_analyzer/tests/comparison.test.js.map +1 -0
  54. package/dist/heap_analyzer/tests/debugInfoResolver.test.d.ts +1 -0
  55. package/dist/heap_analyzer/tests/debugInfoResolver.test.js +205 -0
  56. package/dist/heap_analyzer/tests/debugInfoResolver.test.js.map +1 -0
  57. package/dist/heap_analyzer/tests/dumpReader.test.js +12 -2
  58. package/dist/heap_analyzer/tests/dumpReader.test.js.map +1 -1
  59. package/dist/heap_analyzer/tests/dwarfParser.test.js +40 -28
  60. package/dist/heap_analyzer/tests/dwarfParser.test.js.map +1 -1
  61. package/dist/heap_analyzer/tests/roots.test.js +21 -4
  62. package/dist/heap_analyzer/tests/roots.test.js.map +1 -1
  63. package/dist/heap_analyzer/tests/snapshot.test.js +58 -54
  64. package/dist/heap_analyzer/tests/snapshot.test.js.map +1 -1
  65. package/dist/heap_analyzer/tests/testHelper.js +1 -1
  66. package/dist/heap_analyzer/tests/testHelper.js.map +1 -1
  67. package/dist/heap_analyzer/tests/wasmExecutor.js +2 -1
  68. package/dist/heap_analyzer/tests/wasmExecutor.js.map +1 -1
  69. package/dist/scripts/lib.d.ts +5 -1
  70. package/dist/scripts/lib.js +171 -24
  71. package/dist/scripts/lib.js.map +1 -1
  72. package/dist/test_runner/core/compiler.js +0 -1
  73. package/dist/test_runner/core/compiler.js.map +1 -1
  74. package/dist/warpo.d.ts +12 -1
  75. package/dist/warpo.js +32 -7
  76. package/dist/warpo.js.map +1 -1
  77. package/dist/warpo_internal.d.ts +1 -1
  78. package/dist/warpo_internal.js +23 -14
  79. package/dist/warpo_internal.js.map +1 -1
  80. package/package.json +11 -2
  81. package/dist/heap_analyzer/src/classResolver.d.ts +0 -34
  82. package/dist/heap_analyzer/src/classResolver.js +0 -206
  83. package/dist/heap_analyzer/src/classResolver.js.map +0 -1
  84. package/dist/heap_analyzer/tests/classResolver.test.js +0 -110
  85. package/dist/heap_analyzer/tests/classResolver.test.js.map +0 -1
  86. /package/dist/{heap_analyzer/tests/classResolver.test.d.ts → debug_server/wasmEntry.d.ts} +0 -0
@@ -1,206 +0,0 @@
1
- // Copyright (C) 2026 wasm-ecosystem
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { DW_AT, DW_TAG, buildOffsetMap, findDIEsByTag, getAttr, parseDwarf } from "./dwarfParser.js";
4
- /**
5
- * Resolves class layouts from DWARF debug information embedded in a
6
- * WebAssembly binary and provides helper queries for reference scanning.
7
- *
8
- * Only classes with a runtime ID (`DW_AT_signature`) are included.
9
- */
10
- export class ClassResolver {
11
- layoutMap;
12
- constructor(layouts) {
13
- this.layoutMap = new Map(layouts.map((l) => [l.rtid, l]));
14
- }
15
- static fromWasm(wasmBinary) {
16
- const dwarf = parseDwarf(wasmBinary);
17
- const classes = [];
18
- for (const unit of dwarf.compilationUnits) {
19
- const resolver = new CompilationUnitResolver(unit.rootDIE);
20
- for (const layout of resolver.resolve(unit.rootDIE)) {
21
- classes.push(layout);
22
- }
23
- }
24
- flattenInheritedFields(classes);
25
- return new ClassResolver(classes);
26
- }
27
- getLayouts() {
28
- return Array.from(this.layoutMap.values());
29
- }
30
- /** Returns class name, or "Class#<id>" if not found in debug info */
31
- getClassName(classId) {
32
- const layout = this.layoutMap.get(classId);
33
- return layout ? layout.name : `Class#${classId}`;
34
- }
35
- /** Returns ClassDef or undefined */
36
- getClassDef(classId) {
37
- return this.layoutMap.get(classId);
38
- }
39
- /**
40
- * Check if a type has no managed references (no reference fields, no reference elements).
41
- * Derived from field layout and elementIsReference rather than flags.
42
- */
43
- isPointerfree(classId) {
44
- const layout = this.layoutMap.get(classId);
45
- if (!layout) {
46
- return false;
47
- }
48
- if (layout.elementIsReference === true) {
49
- return false;
50
- }
51
- for (const field of layout.fields) {
52
- if (field.isReference) {
53
- return false;
54
- }
55
- }
56
- return true;
57
- }
58
- /**
59
- * Returns all reference fields (isReference == true) for this class,
60
- * walking the full inheritance chain via base.
61
- */
62
- getReferenceFields(classId) {
63
- const layout = this.layoutMap.get(classId);
64
- if (!layout) {
65
- return [];
66
- }
67
- return layout.fields.filter((f) => f.isReference);
68
- }
69
- }
70
- class CompilationUnitResolver {
71
- offsetMap;
72
- baseTypeNames;
73
- constructor(root) {
74
- this.offsetMap = buildOffsetMap(root);
75
- this.baseTypeNames = new Set();
76
- for (const die of findDIEsByTag(root, DW_TAG.base_type)) {
77
- const name = getAttr(die, DW_AT.name)?.value;
78
- if (name) {
79
- this.baseTypeNames.add(name);
80
- }
81
- }
82
- }
83
- resolve(root) {
84
- const layouts = [];
85
- for (const classDie of findDIEsByTag(root, DW_TAG.class_type)) {
86
- const layout = this.resolveClassLayout(classDie);
87
- if (layout) {
88
- layouts.push(layout);
89
- }
90
- }
91
- return layouts;
92
- }
93
- resolveTypeInfo(typeRef) {
94
- const typeDie = this.offsetMap.get(typeRef);
95
- if (!typeDie) {
96
- return { size: 4, isReference: false };
97
- }
98
- const name = getAttr(typeDie, DW_AT.name)?.value;
99
- const isReference = name === undefined ? false : !this.baseTypeNames.has(name);
100
- const byteSize = getAttr(typeDie, DW_AT.byte_size);
101
- const size = byteSize === undefined ? 4 : byteSize.value;
102
- return { name, size, isReference };
103
- }
104
- resolveField(memberDie) {
105
- const nameAttr = getAttr(memberDie, DW_AT.name);
106
- const offsetAttr = getAttr(memberDie, DW_AT.data_member_location);
107
- const typeAttr = getAttr(memberDie, DW_AT.type);
108
- if (!nameAttr || offsetAttr === undefined || !typeAttr) {
109
- return null;
110
- }
111
- const { size, isReference } = this.resolveTypeInfo(typeAttr.value);
112
- return {
113
- name: nameAttr.value,
114
- offset: offsetAttr.value,
115
- size,
116
- isReference,
117
- };
118
- }
119
- resolveTemplateType(classDie) {
120
- const templateParam = classDie.children.find((c) => c.tag === DW_TAG.template_type_parameter);
121
- if (!templateParam) {
122
- return undefined;
123
- }
124
- const typeAttr = getAttr(templateParam, DW_AT.type);
125
- if (!typeAttr) {
126
- return undefined;
127
- }
128
- return this.resolveTypeInfo(typeAttr.value).name;
129
- }
130
- resolveBaseName(classDie) {
131
- const inheritanceDie = classDie.children.find((c) => c.tag === DW_TAG.inheritance);
132
- if (!inheritanceDie) {
133
- return null;
134
- }
135
- const typeAttr = getAttr(inheritanceDie, DW_AT.type);
136
- if (!typeAttr) {
137
- return null;
138
- }
139
- const parentDie = this.offsetMap.get(typeAttr.value);
140
- if (!parentDie) {
141
- return null;
142
- }
143
- return getAttr(parentDie, DW_AT.name)?.value ?? null;
144
- }
145
- resolveClassLayout(classDie) {
146
- const nameAttr = getAttr(classDie, DW_AT.name);
147
- if (!nameAttr) {
148
- return null;
149
- }
150
- const sigAttr = getAttr(classDie, DW_AT.signature);
151
- if (sigAttr === undefined) {
152
- return null;
153
- }
154
- const members = classDie.children.filter((c) => c.tag === DW_TAG.member);
155
- const fields = [];
156
- for (const member of members) {
157
- const field = this.resolveField(member);
158
- if (field) {
159
- fields.push(field);
160
- }
161
- }
162
- const layout = {
163
- rtid: sigAttr.value,
164
- name: nameAttr.value,
165
- base: this.resolveBaseName(classDie),
166
- fields,
167
- };
168
- const templateType = this.resolveTemplateType(classDie);
169
- if (templateType !== undefined) {
170
- layout.templateType = templateType;
171
- }
172
- return layout;
173
- }
174
- }
175
- /**
176
- * Resolve all class layouts from DWARF debug information embedded in a
177
- * WebAssembly binary.
178
- *
179
- * Only classes with a runtime ID (`DW_AT_signature`) are included.
180
- */
181
- export function resolveClassLayouts(wasmBinary) {
182
- return ClassResolver.fromWasm(wasmBinary).getLayouts();
183
- }
184
- function flattenInheritedFields(classes) {
185
- const byName = new Map(classes.map((c) => [c.name, c]));
186
- const flattened = new Set();
187
- function flatten(cls) {
188
- if (flattened.has(cls.name)) {
189
- return;
190
- }
191
- flattened.add(cls.name);
192
- if (!cls.base) {
193
- return;
194
- }
195
- const parent = byName.get(cls.base);
196
- if (!parent) {
197
- return;
198
- }
199
- flatten(parent);
200
- cls.fields = [...parent.fields, ...cls.fields];
201
- }
202
- for (const cls of classes) {
203
- flatten(cls);
204
- }
205
- }
206
- //# sourceMappingURL=classResolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"classResolver.js","sourceRoot":"","sources":["../../../tools/heap_analyzer/src/classResolver.ts"],"names":[],"mappings":"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"}
@@ -1,110 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { before, describe, it } from "node:test";
3
- import { resolveClassLayouts } from "../src/classResolver.js";
4
- import { CLASS_PREFIX, describeIntegration } from "./testHelper.js";
5
- describeIntegration("class-resolver", (ctx) => {
6
- let classes;
7
- let classMap;
8
- before(() => {
9
- ctx.compileFixture();
10
- classes = resolveClassLayouts(ctx.loadFixtureWasm());
11
- classMap = new Map(classes.map((c) => [c.name, c]));
12
- });
13
- it("contains user-defined classes", () => {
14
- const userClasses = ["Vector2", "Item", "Entity", "Character", "Player", "NPC", "TreeNode", "ListNode", "KVPair"];
15
- for (const name of userClasses) {
16
- assert.ok(classMap.has(CLASS_PREFIX + name), `missing class ${name}`);
17
- }
18
- });
19
- it("contains stdlib classes with rtid", () => {
20
- assert.ok(classMap.has("~lib/string/String"));
21
- assert.ok(classMap.has("~lib/arraybuffer/ArrayBuffer"));
22
- });
23
- it("every class has a numeric rtid", () => {
24
- for (const cls of classes) {
25
- assert.strictEqual(typeof cls.rtid, "number");
26
- }
27
- });
28
- it("non-zero rtIds are unique", () => {
29
- const nonZeroRtIds = classes.filter((c) => c.rtid !== 0).map((c) => c.rtid);
30
- assert.strictEqual(new Set(nonZeroRtIds).size, nonZeroRtIds.length);
31
- });
32
- describe("Vector2 layout", () => {
33
- it("has two f32 fields at correct offsets", () => {
34
- const vec2 = classMap.get(CLASS_PREFIX + "Vector2");
35
- assert.strictEqual(vec2.fields.length, 2);
36
- const x = vec2.fields.find((f) => f.name === "x");
37
- assert.strictEqual(x.offset, 0);
38
- assert.strictEqual(x.size, 4);
39
- assert.strictEqual(x.isReference, false);
40
- const y = vec2.fields.find((f) => f.name === "y");
41
- assert.strictEqual(y.offset, 4);
42
- assert.strictEqual(y.size, 4);
43
- assert.strictEqual(y.isReference, false);
44
- });
45
- });
46
- describe("Character layout", () => {
47
- it("has inherited fields from Entity and own fields", () => {
48
- const character = classMap.get(CLASS_PREFIX + "Character");
49
- const fieldNames = character.fields.map((f) => f.name);
50
- assert.deepStrictEqual(fieldNames, ["id", "position", "name", "hp"]);
51
- });
52
- it("has base set to Entity", () => {
53
- const character = classMap.get(CLASS_PREFIX + "Character");
54
- assert.strictEqual(character.base, CLASS_PREFIX + "Entity");
55
- });
56
- it("name field is a reference", () => {
57
- const character = classMap.get(CLASS_PREFIX + "Character");
58
- const name = character.fields.find((f) => f.name === "name");
59
- assert.strictEqual(name.isReference, true);
60
- });
61
- it("hp field is not a reference", () => {
62
- const character = classMap.get(CLASS_PREFIX + "Character");
63
- const hp = character.fields.find((f) => f.name === "hp");
64
- assert.strictEqual(hp.isReference, false);
65
- });
66
- });
67
- describe("Player layout (deep inheritance)", () => {
68
- it("has all inherited fields from Entity→Character plus own fields", () => {
69
- const player = classMap.get(CLASS_PREFIX + "Player");
70
- const fieldNames = player.fields.map((f) => f.name);
71
- assert.deepStrictEqual(fieldNames, ["id", "position", "name", "hp", "inventory", "score"]);
72
- });
73
- it("has base set to Character", () => {
74
- const player = classMap.get(CLASS_PREFIX + "Player");
75
- assert.strictEqual(player.base, CLASS_PREFIX + "Character");
76
- });
77
- it("inherited fields have correct offsets", () => {
78
- const player = classMap.get(CLASS_PREFIX + "Player");
79
- assert.strictEqual(player.fields.find((f) => f.name === "id").offset, 0);
80
- assert.strictEqual(player.fields.find((f) => f.name === "position").offset, 4);
81
- assert.strictEqual(player.fields.find((f) => f.name === "name").offset, 8);
82
- assert.strictEqual(player.fields.find((f) => f.name === "hp").offset, 12);
83
- assert.strictEqual(player.fields.find((f) => f.name === "inventory").offset, 16);
84
- assert.strictEqual(player.fields.find((f) => f.name === "score").offset, 20);
85
- });
86
- });
87
- describe("TreeNode layout", () => {
88
- it("has self-referencing fields", () => {
89
- const treeNode = classMap.get(CLASS_PREFIX + "TreeNode");
90
- const left = treeNode.fields.find((f) => f.name === "left");
91
- const right = treeNode.fields.find((f) => f.name === "right");
92
- assert.strictEqual(left.isReference, true);
93
- assert.strictEqual(right.isReference, true);
94
- });
95
- });
96
- describe("template types", () => {
97
- it("resolves template type for Array<Item>", () => {
98
- const arrayItem = classes.find((c) => c.name === `~lib/array/Array<${CLASS_PREFIX}Item>`);
99
- if (arrayItem) {
100
- assert.notStrictEqual(arrayItem.templateType, undefined);
101
- }
102
- });
103
- });
104
- it("excludes classes without rtid", () => {
105
- for (const cls of classes) {
106
- assert.notStrictEqual(cls.rtid, undefined);
107
- }
108
- });
109
- });
110
- //# sourceMappingURL=classResolver.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"classResolver.test.js","sourceRoot":"","sources":["../../../tools/heap_analyzer/tests/classResolver.test.ts"],"names":[],"mappings":"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"}