xbintsc 0.3.81 → 0.5.6

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 (188) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +16 -5
  3. package/README.zh-CN.md +14 -6
  4. package/dist/src/ast/common.d.ts +23 -0
  5. package/dist/src/cli/main.js +68 -24
  6. package/dist/src/cli/main.js.map +1 -1
  7. package/dist/src/codegen/generator/calls/access.js +6 -2
  8. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  9. package/dist/src/codegen/generator/calls/closures.js +4 -0
  10. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  11. package/dist/src/codegen/generator/calls/invocation.js +9 -4
  12. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  13. package/dist/src/codegen/generator/context.d.ts +50 -0
  14. package/dist/src/codegen/generator/context.js +124 -13
  15. package/dist/src/codegen/generator/context.js.map +1 -1
  16. package/dist/src/codegen/generator/debug.d.ts +33 -0
  17. package/dist/src/codegen/generator/debug.js +97 -0
  18. package/dist/src/codegen/generator/debug.js.map +1 -0
  19. package/dist/src/codegen/generator/expressions/assignment.js +9 -5
  20. package/dist/src/codegen/generator/expressions/assignment.js.map +1 -1
  21. package/dist/src/codegen/generator/expressions/operators.js +35 -9
  22. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  23. package/dist/src/codegen/generator/expressions/primary.js +11 -3
  24. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  25. package/dist/src/codegen/generator/generator.d.ts +3 -1
  26. package/dist/src/codegen/generator/generator.js +3 -1
  27. package/dist/src/codegen/generator/generator.js.map +1 -1
  28. package/dist/src/codegen/generator/module.d.ts +1 -1
  29. package/dist/src/codegen/generator/module.js +82 -12
  30. package/dist/src/codegen/generator/module.js.map +1 -1
  31. package/dist/src/codegen/generator/numeric.d.ts +26 -0
  32. package/dist/src/codegen/generator/numeric.js +127 -0
  33. package/dist/src/codegen/generator/numeric.js.map +1 -0
  34. package/dist/src/codegen/generator/state.d.ts +17 -0
  35. package/dist/src/codegen/generator/state.js +9 -0
  36. package/dist/src/codegen/generator/state.js.map +1 -1
  37. package/dist/src/codegen/generator/statements/control-flow.js +2 -4
  38. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  39. package/dist/src/codegen/generator/statements/dispatch.js +3 -0
  40. package/dist/src/codegen/generator/statements/dispatch.js.map +1 -1
  41. package/dist/src/codegen/generator/statements/variables.js +8 -2
  42. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  43. package/dist/src/codegen/generator/tables.d.ts +16 -0
  44. package/dist/src/codegen/generator/tables.js +99 -2
  45. package/dist/src/codegen/generator/tables.js.map +1 -1
  46. package/dist/src/driver/bundler/merge.js +41 -5
  47. package/dist/src/driver/bundler/merge.js.map +1 -1
  48. package/dist/src/driver/compiler.d.ts +23 -4
  49. package/dist/src/driver/compiler.js +46 -57
  50. package/dist/src/driver/compiler.js.map +1 -1
  51. package/dist/src/driver/fingerprint.d.ts +27 -0
  52. package/dist/src/driver/fingerprint.js +88 -0
  53. package/dist/src/driver/fingerprint.js.map +1 -0
  54. package/dist/src/driver/toolchain-provider.d.ts +9 -2
  55. package/dist/src/driver/toolchain-provider.js +15 -15
  56. package/dist/src/driver/toolchain-provider.js.map +1 -1
  57. package/dist/src/driver/toolchain.d.ts +58 -1
  58. package/dist/src/driver/toolchain.js +169 -22
  59. package/dist/src/driver/toolchain.js.map +1 -1
  60. package/dist/src/parser/expressions.js +20 -1
  61. package/dist/src/parser/expressions.js.map +1 -1
  62. package/dist/tests/cli/main.test.js +41 -1
  63. package/dist/tests/cli/main.test.js.map +1 -1
  64. package/dist/tests/codegen/closures.test.js +8 -0
  65. package/dist/tests/codegen/closures.test.js.map +1 -1
  66. package/dist/tests/codegen/expressions.test.js +14 -3
  67. package/dist/tests/codegen/expressions.test.js.map +1 -1
  68. package/dist/tests/codegen/llvm.test.js +23 -0
  69. package/dist/tests/codegen/llvm.test.js.map +1 -1
  70. package/dist/tests/driver/toolchain-provider.test.js +49 -2
  71. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  72. package/dist/tests/driver/toolchain.test.js +62 -3
  73. package/dist/tests/driver/toolchain.test.js.map +1 -1
  74. package/dist/tests/e2e/async-await.test.d.ts +10 -0
  75. package/dist/tests/e2e/async-await.test.js +247 -0
  76. package/dist/tests/e2e/async-await.test.js.map +1 -0
  77. package/dist/tests/e2e/child-process.test.d.ts +10 -0
  78. package/dist/tests/e2e/child-process.test.js +59 -0
  79. package/dist/tests/e2e/child-process.test.js.map +1 -0
  80. package/dist/tests/e2e/compile-objects-classes.test.js +47 -0
  81. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  82. package/dist/tests/e2e/error-stack.test.d.ts +9 -0
  83. package/dist/tests/e2e/error-stack.test.js +94 -0
  84. package/dist/tests/e2e/error-stack.test.js.map +1 -0
  85. package/dist/tests/e2e/runtime-coverage-globals.test.js +46 -0
  86. package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
  87. package/dist/tests/e2e/string-concat.test.d.ts +9 -0
  88. package/dist/tests/e2e/string-concat.test.js +102 -0
  89. package/dist/tests/e2e/string-concat.test.js.map +1 -0
  90. package/dist/tests/e2e/string-utf16.test.d.ts +6 -0
  91. package/dist/tests/e2e/string-utf16.test.js +133 -0
  92. package/dist/tests/e2e/string-utf16.test.js.map +1 -0
  93. package/dist/tests/helpers.d.ts +9 -0
  94. package/dist/tests/helpers.js +26 -3
  95. package/dist/tests/helpers.js.map +1 -1
  96. package/dist/tests/parser/expressions.test.js +7 -0
  97. package/dist/tests/parser/expressions.test.js.map +1 -1
  98. package/dist/tests/version.test.d.ts +1 -0
  99. package/dist/tests/version.test.js +24 -0
  100. package/dist/tests/version.test.js.map +1 -0
  101. package/doc/DESIGN.md +20 -12
  102. package/doc/ai/cli.md +2 -0
  103. package/doc/ai/contributing.md +16 -8
  104. package/doc/ai/extensions.md +3 -2
  105. package/doc/ai/language-support.md +15 -12
  106. package/doc/ai/troubleshooting.md +43 -5
  107. package/doc/ai/zh-CN/cli.md +2 -0
  108. package/doc/ai/zh-CN/contributing.md +11 -7
  109. package/doc/ai/zh-CN/extensions.md +2 -1
  110. package/doc/ai/zh-CN/language-support.md +15 -12
  111. package/doc/ai/zh-CN/troubleshooting.md +38 -4
  112. package/doc/implemented.md +16 -13
  113. package/doc/requirements.md +13 -4
  114. package/doc/unimplemented.md +20 -18
  115. package/doc/zh-CN/DESIGN.md +15 -9
  116. package/doc/zh-CN/implemented.md +15 -12
  117. package/doc/zh-CN/requirements.md +12 -3
  118. package/doc/zh-CN/unimplemented.md +19 -17
  119. package/package.json +3 -1
  120. package/runtime/ext_node/buffer/parts/construction.inc +2 -2
  121. package/runtime/ext_node/buffer/parts/methods.inc +1 -1
  122. package/runtime/ext_node/buffer/parts/search.inc +1 -1
  123. package/runtime/ext_node/child_process/child_process.c +25 -0
  124. package/runtime/ext_node/fs/fd_ops.c +1 -1
  125. package/runtime/rt.h +49 -1
  126. package/runtime/rt_internal.h +136 -4
  127. package/runtime/xt_alloc.c +20 -2
  128. package/runtime/xt_async.c +197 -0
  129. package/runtime/xt_bigint/conversions.inc +1 -1
  130. package/runtime/xt_builtins.c +169 -43
  131. package/runtime/xt_constructors.c +389 -0
  132. package/runtime/xt_containers/access.inc +61 -24
  133. package/runtime/xt_containers/arrays.inc +26 -2
  134. package/runtime/xt_containers/objects.inc +206 -8
  135. package/runtime/xt_coroutine.c +212 -0
  136. package/runtime/xt_generator.c +31 -162
  137. package/runtime/xt_io/exception.inc +171 -2
  138. package/runtime/xt_io/inspect.inc +48 -13
  139. package/runtime/xt_io.c +5 -0
  140. package/runtime/xt_promise.c +62 -17
  141. package/runtime/xt_stdlib/arrays.inc +2 -2
  142. package/runtime/xt_stdlib/dispatch.inc +20 -4
  143. package/runtime/xt_stdlib/strings.inc +98 -29
  144. package/runtime/xt_stdlib2/array-statics.inc +3 -2
  145. package/runtime/xt_stdlib2/arrays.inc +1 -1
  146. package/runtime/xt_stdlib2/error.inc +33 -6
  147. package/runtime/xt_stdlib2/json.inc +46 -16
  148. package/runtime/xt_stdlib2/number-string-statics.inc +24 -13
  149. package/runtime/xt_stdlib2/objects.inc +1 -1
  150. package/runtime/xt_stdlib2/regexp-match.inc +50 -35
  151. package/runtime/xt_stdlib2/set.inc +6 -0
  152. package/runtime/xt_stdlib2/strings.inc +81 -42
  153. package/runtime/xt_symbol.c +1 -1
  154. package/runtime/xt_typed_array/construction.inc +43 -2
  155. package/runtime/xt_typed_array.c +4 -0
  156. package/runtime/xt_values/comparison.inc +2 -2
  157. package/runtime/xt_values/constructors.inc +18 -5
  158. package/runtime/xt_values/conversions.inc +4 -3
  159. package/runtime/xt_values/strings.inc +94 -4
  160. package/runtime/xt_values/utf16.inc +340 -0
  161. package/runtime/xt_values.c +1 -0
  162. package/scripts/bench.ts +172 -0
  163. package/scripts/build-runtime.ts +2 -1
  164. package/scripts/check-version.ts +53 -0
  165. package/src/ast/common.ts +23 -0
  166. package/src/cli/main.ts +68 -26
  167. package/src/codegen/generator/calls/access.ts +7 -2
  168. package/src/codegen/generator/calls/closures.ts +3 -0
  169. package/src/codegen/generator/calls/invocation.ts +9 -3
  170. package/src/codegen/generator/context.ts +129 -18
  171. package/src/codegen/generator/debug.ts +132 -0
  172. package/src/codegen/generator/expressions/assignment.ts +9 -5
  173. package/src/codegen/generator/expressions/operators.ts +47 -8
  174. package/src/codegen/generator/expressions/primary.ts +11 -3
  175. package/src/codegen/generator/generator.ts +18 -2
  176. package/src/codegen/generator/module.ts +83 -13
  177. package/src/codegen/generator/numeric.ts +158 -0
  178. package/src/codegen/generator/state.ts +26 -0
  179. package/src/codegen/generator/statements/control-flow.ts +2 -3
  180. package/src/codegen/generator/statements/dispatch.ts +3 -0
  181. package/src/codegen/generator/statements/variables.ts +8 -2
  182. package/src/codegen/generator/tables.ts +110 -2
  183. package/src/driver/bundler/merge.ts +39 -5
  184. package/src/driver/compiler.ts +65 -55
  185. package/src/driver/fingerprint.ts +85 -0
  186. package/src/driver/toolchain-provider.ts +17 -16
  187. package/src/driver/toolchain.ts +210 -21
  188. package/src/parser/expressions.ts +20 -1
@@ -0,0 +1,247 @@
1
+ /**
2
+ * End-to-end tests for *real* `async`/`await` suspension.
3
+ *
4
+ * An `async` function runs its body on a stackful coroutine. When it awaits a
5
+ * promise that has not settled yet, the coroutine suspends and the event loop
6
+ * (timers, sockets, ...) takes over; the promise's settlement resumes the
7
+ * coroutine exactly where it stopped. These tests therefore depend on work that
8
+ * can only complete after the program body returns.
9
+ */
10
+ import { expect, it } from "vitest";
11
+ import { describeE2E } from "./harness.js";
12
+ import { makeDifferential } from "./differential-helpers.js";
13
+ const prelude = `
14
+ function sleep(ms: number): Promise<void> {
15
+ return new Promise<void>((resolve) => setTimeout(resolve, ms));
16
+ }
17
+ `;
18
+ describeE2E("end-to-end real async/await", (harness) => {
19
+ const { runProgram } = harness;
20
+ const { diff } = makeDifferential(harness);
21
+ diff("resumes an async function after a timer settles its promise", `${prelude}
22
+ const order: string[] = [];
23
+ async function main(): Promise<void> {
24
+ order.push("start");
25
+ await sleep(5);
26
+ order.push("timer");
27
+ const value = await new Promise<number>((resolve) => setTimeout(() => resolve(7), 1));
28
+ order.push("value:" + value);
29
+ }
30
+ main().then(() => {
31
+ order.push("done");
32
+ console.log(order.join(","));
33
+ });
34
+ console.log("body");`);
35
+ it("keeps the program alive until an awaited timer resolves", () => {
36
+ const source = `${prelude}
37
+ async function main(): Promise<void> {
38
+ await sleep(10);
39
+ console.log("after");
40
+ }
41
+ main();
42
+ console.log("before");`;
43
+ expect(runProgram(source)).toBe("before\nafter");
44
+ });
45
+ it("runs independent async functions concurrently", () => {
46
+ /* Do not assert which timer fires first: Windows timer granularity can
47
+ * batch 1ms and 8ms deadlines into the same reactor turn. Instead observe
48
+ * that both bodies reach their `await` before either resumes (peak 2),
49
+ * and that `Promise.all` keeps the array order regardless of completion
50
+ * order. */
51
+ const source = `${prelude}
52
+ let active = 0;
53
+ let peak = 0;
54
+ async function task(ms: number): Promise<number> {
55
+ active++;
56
+ if (active > peak) peak = active;
57
+ await sleep(ms);
58
+ active--;
59
+ return ms;
60
+ }
61
+ async function main(): Promise<void> {
62
+ const results = await Promise.all([task(8), task(1)]);
63
+ console.log("peak", peak, "results", results.join(","));
64
+ }
65
+ main();`;
66
+ expect(runProgram(source)).toBe("peak 2 results 8,1");
67
+ });
68
+ it("finishes independent async functions in delay order with long timers", () => {
69
+ /* The timers are far enough apart (50ms vs 200ms) that even a platform
70
+ * with ~15ms timer granularity cannot merge them into one reactor turn, so
71
+ * completion order is observable and deterministic. */
72
+ const source = `${prelude}
73
+ const order: string[] = [];
74
+ async function task(name: string, ms: number): Promise<void> {
75
+ await sleep(ms);
76
+ order.push(name);
77
+ }
78
+ async function main(): Promise<void> {
79
+ await Promise.all([task("slow", 200), task("fast", 50)]);
80
+ console.log(order.join(","));
81
+ }
82
+ main();`;
83
+ expect(runProgram(source)).toBe("fast,slow");
84
+ });
85
+ it("rejects when an awaited timer promise rejects and is catchable", () => {
86
+ const source = `${prelude}
87
+ function fail(ms: number): Promise<number> {
88
+ return new Promise<number>((_resolve, reject) => setTimeout(() => reject("boom"), ms));
89
+ }
90
+ async function main(): Promise<void> {
91
+ try {
92
+ await fail(2);
93
+ console.log("unreachable");
94
+ } catch (error) {
95
+ console.log("caught", error);
96
+ }
97
+ try {
98
+ await fail(1);
99
+ } finally {
100
+ console.log("finally");
101
+ }
102
+ }
103
+ main();`;
104
+ expect(runProgram(source)).toBe("caught boom\nfinally");
105
+ });
106
+ it("rejects the returned promise when the body throws after resuming", () => {
107
+ const source = `${prelude}
108
+ async function boom(): Promise<void> {
109
+ await sleep(1);
110
+ throw new Error("late");
111
+ }
112
+ boom().catch((error: any) => console.log("rejected", error.message));`;
113
+ expect(runProgram(source)).toBe("rejected late");
114
+ });
115
+ it("suspends across loops, closures and nested async calls", () => {
116
+ const source = `${prelude}
117
+ async function twice(n: number): Promise<number> {
118
+ await sleep(1);
119
+ return n * 2;
120
+ }
121
+ async function sum(limit: number): Promise<number> {
122
+ let total = 0;
123
+ for (let i = 0; i < limit; i++) {
124
+ total += await twice(i);
125
+ }
126
+ return total;
127
+ }
128
+ async function main(): Promise<void> {
129
+ const total = await sum(4);
130
+ console.log("total", total);
131
+ }
132
+ main();`;
133
+ expect(runProgram(source)).toBe("total 12");
134
+ });
135
+ it("resumes two coroutines waiting on the same promise", () => {
136
+ const source = `${prelude}
137
+ async function main(): Promise<void> {
138
+ const shared = new Promise<string>((resolve) => setTimeout(() => resolve("shared"), 3));
139
+ const results = await Promise.all([
140
+ (async () => "a:" + (await shared))(),
141
+ (async () => "b:" + (await shared))(),
142
+ ]);
143
+ console.log(results.join(" "));
144
+ }
145
+ main();`;
146
+ expect(runProgram(source)).toBe("a:shared b:shared");
147
+ });
148
+ it("awaits a promise resolved by a socket callback", () => {
149
+ const source = `
150
+ import net from "node:net";
151
+
152
+ function once(socket: any, event: string): Promise<any> {
153
+ return new Promise<any>((resolve) => socket.on(event, resolve));
154
+ }
155
+
156
+ async function main(): Promise<void> {
157
+ const server = net.createServer((socket: any) => {
158
+ socket.on("data", (data: any) => {
159
+ socket.write("echo:" + data);
160
+ socket.end();
161
+ });
162
+ });
163
+ server.listen(0, () => {});
164
+ await new Promise<void>((resolve) => server.on("listening", resolve));
165
+ const client = net.connect(server.address().port, "127.0.0.1");
166
+ client.write("ping");
167
+ const data = await once(client, "data");
168
+ await once(client, "end");
169
+ server.close();
170
+ console.log("client", data);
171
+ }
172
+ main();`;
173
+ expect(runProgram(source, { extensions: true })).toBe("client echo:ping");
174
+ });
175
+ it("awaits fs/promises across an event-loop turn", () => {
176
+ const base = `${JSON.stringify(harness.workdir)} + "/async-fs-" + Math.random().toString(36).slice(2)`;
177
+ const source = `
178
+ import { promises as fsp } from "fs";
179
+
180
+ async function main(): Promise<void> {
181
+ const base = ${base};
182
+ await fsp.mkdir(base, { recursive: true });
183
+ const order: string[] = [];
184
+ setTimeout(() => order.push("timer"), 1);
185
+ await fsp.writeFile(base + "/a.txt", "hello");
186
+ order.push("write");
187
+ const text = await fsp.readFile(base + "/a.txt", "utf8");
188
+ order.push("read:" + text);
189
+ await new Promise<void>((resolve) => setTimeout(resolve, 5));
190
+ order.push("waited");
191
+ console.log(order.join(","));
192
+ await fsp.rm(base, { recursive: true, force: true });
193
+ }
194
+ main();`;
195
+ expect(runProgram(source, { extensions: true })).toBe("write,read:hello,timer,waited");
196
+ });
197
+ it("keeps a pending await alive while unrelated timers fire", () => {
198
+ const source = `${prelude}
199
+ const log: string[] = [];
200
+ async function main(): Promise<void> {
201
+ setTimeout(() => log.push("early"), 1);
202
+ await sleep(6);
203
+ log.push("late");
204
+ console.log(log.join(","));
205
+ }
206
+ main();`;
207
+ expect(runProgram(source)).toBe("early,late");
208
+ });
209
+ it("runs async callbacks scheduled by then() and setTimeout()", () => {
210
+ const source = `${prelude}
211
+ Promise.resolve().then(async () => {
212
+ await sleep(1);
213
+ console.log("then");
214
+ });
215
+ setTimeout(async () => {
216
+ await sleep(1);
217
+ console.log("timer");
218
+ }, 2);`;
219
+ expect(runProgram(source)).toBe("then\ntimer");
220
+ });
221
+ it("awaits a top-level promise by blocking on the event loop", () => {
222
+ const source = `${prelude}
223
+ await sleep(50);
224
+ console.log("top-level");`;
225
+ expect(runProgram(source)).toBe("top-level");
226
+ });
227
+ it("keeps suspended coroutines reachable across collections", () => {
228
+ const source = `${prelude}
229
+ async function worker(id: number): Promise<number> {
230
+ let total = 0;
231
+ for (let i = 0; i < 20; i++) {
232
+ const junk: any[] = [];
233
+ for (let j = 0; j < 10; j++) junk.push({ id, i, j, text: "x".repeat(40) + j });
234
+ await sleep(i % 2);
235
+ total += junk.length;
236
+ }
237
+ return total;
238
+ }
239
+ async function main(): Promise<void> {
240
+ const results = await Promise.all([worker(1), worker(2)]);
241
+ console.log("alive", results.join(","));
242
+ }
243
+ main();`;
244
+ expect(runProgram(source, { env: { XT_GC_THRESHOLD: "1048576" }, timeout: 60000 })).toBe("alive 200,200");
245
+ });
246
+ });
247
+ //# sourceMappingURL=async-await.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-await.test.js","sourceRoot":"","sources":["../../../tests/e2e/async-await.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Regression: `spawnSync` with a command path that contains spaces.
3
+ *
4
+ * MSVC's `_spawnvp` builds the child command line without quoting argv[0], so a
5
+ * compiler installed under "C:\Program Files" reached the child as several
6
+ * arguments ("Files\Microsoft", "Visual", …). It only showed up with a real
7
+ * compile (an argument list long enough that clang did not short-circuit on
8
+ * `--version`), which is exactly what a self-hosted `xbintsc` does on Windows.
9
+ */
10
+ export {};
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Regression: `spawnSync` with a command path that contains spaces.
3
+ *
4
+ * MSVC's `_spawnvp` builds the child command line without quoting argv[0], so a
5
+ * compiler installed under "C:\Program Files" reached the child as several
6
+ * arguments ("Files\Microsoft", "Visual", …). It only showed up with a real
7
+ * compile (an argument list long enough that clang did not short-circuit on
8
+ * `--version`), which is exactly what a self-hosted `xbintsc` does on Windows.
9
+ */
10
+ import { execFileSync } from "node:child_process";
11
+ import { expect, it } from "vitest";
12
+ import { resolveToolchain } from "../../src/driver/toolchain-provider.js";
13
+ import { describeE2E } from "./harness.js";
14
+ /** The resolved clang absolute path, or a `where clang` hit, when it has a space. */
15
+ function clangPathWithSpace() {
16
+ if (process.platform !== "win32")
17
+ return undefined;
18
+ try {
19
+ const resolved = resolveToolchain().clang;
20
+ if (resolved.includes(" "))
21
+ return resolved;
22
+ }
23
+ catch {
24
+ // Fall through to `where`.
25
+ }
26
+ try {
27
+ const output = execFileSync("where", ["clang"], { encoding: "utf8" });
28
+ return output
29
+ .split(/\r?\n/)
30
+ .map((line) => line.trim())
31
+ .find((line) => line.length > 0 && line.includes(" "));
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ const spacedClang = clangPathWithSpace();
38
+ describeE2E("child_process.spawnSync", (harness) => {
39
+ it.skipIf(spacedClang === undefined)("runs a command whose path contains spaces", () => {
40
+ const directory = harness.workdir.replace(/\\/g, "/");
41
+ const clang = spacedClang.replace(/\\/g, "/");
42
+ const source = `
43
+ import { existsSync, writeFileSync } from "node:fs";
44
+ import { spawnSync } from "node:child_process";
45
+
46
+ const directory = ${JSON.stringify(directory)};
47
+ writeFileSync(directory + "/probe.c", "int probe(void) { return 7; }\\n");
48
+ const result = spawnSync(
49
+ ${JSON.stringify(clang)},
50
+ ["-x", "c", "-c", directory + "/probe.c", "-o", directory + "/probe.o"],
51
+ { encoding: "utf8" },
52
+ );
53
+ console.log(result.status, existsSync(directory + "/probe.o"));
54
+ `;
55
+ const output = harness.runProgram(source, { extensions: true });
56
+ expect(output).toBe("0 true");
57
+ });
58
+ });
59
+ //# sourceMappingURL=child-process.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-process.test.js","sourceRoot":"","sources":["../../../tests/e2e/child-process.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,qFAAqF;AACrF,SAAS,kBAAkB;IACzB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC,KAAK,CAAC;QAC1C,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,OAAO,MAAM;aACV,KAAK,CAAC,OAAO,CAAC;aACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;AAEzC,WAAW,CAAC,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE;IACjD,EAAE,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACrF,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,WAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG;;;;oBAIC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;IAGzC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;;;;;CAKxB,CAAC;QACE,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -358,5 +358,52 @@ describeE2E("end-to-end objects, functions and classes", (harness) => {
358
358
  "true shared undefined\n" +
359
359
  "1,2,3\n10,11,12\n5,6");
360
360
  });
361
+ it("supports object rest destructuring in bindings, parameters and assignments", () => {
362
+ const source = `
363
+ const source = { a: 1, b: 2, c: 3 };
364
+ const { a, ...rest } = source;
365
+ console.log(a, JSON.stringify(rest));
366
+ const { b: renamed, ...others } = source;
367
+ console.log(renamed, JSON.stringify(others));
368
+ const { missing = 42, ...tail } = source;
369
+ console.log(missing, JSON.stringify(tail));
370
+ function pick({ b, ...rest }: { b: number }) { return JSON.stringify(rest); }
371
+ console.log(pick(source));
372
+ const nested = { outer: { x: 1, y: 2 } };
373
+ const { outer: { x, ...inner } } = nested;
374
+ console.log(x, JSON.stringify(inner));
375
+ const key = Symbol("tag");
376
+ const withSymbol = { [key]: 7, keep: 1 };
377
+ const { keep, ...symbols } = withSymbol;
378
+ console.log(keep, symbols[key]);
379
+ const array = [10, 20, 30];
380
+ const { ...arrayRest } = array;
381
+ console.log(JSON.stringify(arrayRest));
382
+ const getter = { get value() { return 5; }, other: 6 };
383
+ const { value, ...restWithGetter } = getter;
384
+ console.log(value, JSON.stringify(restWithGetter));
385
+ let assigned: any = {};
386
+ ({ b: assigned.b, ...assigned.rest } = source);
387
+ console.log(assigned.b, JSON.stringify(assigned.rest));
388
+ `;
389
+ harness.expectSameOutputAsNode(source, { name: "object_rest" });
390
+ });
391
+ it("supports instanceof against built-in constructors", () => {
392
+ const source = `
393
+ console.log([] instanceof Array, {} instanceof Object, [] instanceof Object, (() => {}) instanceof Function);
394
+ console.log(new Map() instanceof Map, new Set() instanceof Set, new Date() instanceof Date, /x/ instanceof RegExp);
395
+ console.log(Promise.resolve(1) instanceof Promise);
396
+ console.log(new TypeError("x") instanceof TypeError, new TypeError("x") instanceof Error, new Error("x") instanceof TypeError);
397
+ console.log(new Uint8Array(4) instanceof Uint8Array, new Uint8Array(4) instanceof Int8Array);
398
+ class C {}
399
+ console.log(new C() instanceof C, new C() instanceof Object);
400
+ `;
401
+ expect(runProgram(source)).toBe("true true true true\n" +
402
+ "true true true true\n" +
403
+ "true\n" +
404
+ "true true false\n" +
405
+ "true false\n" +
406
+ "true true");
407
+ });
361
408
  });
362
409
  //# sourceMappingURL=compile-objects-classes.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compile-objects-classes.test.js","sourceRoot":"","sources":["../../../tests/e2e/compile-objects-classes.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compile-objects-classes.test.js","sourceRoot":"","sources":["../../../tests/e2e/compile-objects-classes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `Error.stack` and the shadow call stack that backs it.
3
+ *
4
+ * The frames come from codegen: every non-generator function pushes a frame
5
+ * (display name, source file, line) on entry and pops it before returning.
6
+ * Assertions check structure rather than exact formatting so the tests keep
7
+ * working across platforms (path separators) and small formatting changes.
8
+ */
9
+ export {};
@@ -0,0 +1,94 @@
1
+ /**
2
+ * `Error.stack` and the shadow call stack that backs it.
3
+ *
4
+ * The frames come from codegen: every non-generator function pushes a frame
5
+ * (display name, source file, line) on entry and pops it before returning.
6
+ * Assertions check structure rather than exact formatting so the tests keep
7
+ * working across platforms (path separators) and small formatting changes.
8
+ */
9
+ import { expect, it } from "vitest";
10
+ import { describeE2E } from "./harness.js";
11
+ describeE2E("error stacks", (harness) => {
12
+ it("captures a stack with function names, files and lines", () => {
13
+ const source = `
14
+ function inner(): never { throw new Error("boom"); }
15
+ function middle(): void { inner(); }
16
+ try {
17
+ middle();
18
+ } catch (e) {
19
+ const stack = (e as Error).stack;
20
+ console.log(stack.split("\\n")[0]);
21
+ console.log(stack.includes("at inner"));
22
+ console.log(stack.includes("at middle"));
23
+ console.log(stack.includes("at module"));
24
+ console.log(stack.includes("error_stack"));
25
+ }
26
+ `;
27
+ expect(harness.runProgram(source, { name: "error_stack" })).toBe("Error: boom\ntrue\ntrue\ntrue\ntrue");
28
+ });
29
+ it("keeps stack out of enumeration and JSON and reports it as a string", () => {
30
+ const source = `
31
+ const plain = new Error("plain");
32
+ console.log(typeof plain.stack);
33
+ console.log(Object.keys(plain).includes("stack"));
34
+ console.log(JSON.stringify(plain).includes("stack"));
35
+ console.log(plain.stack.split("\\n")[0]);
36
+ console.log(plain.stack.includes("at module"));
37
+ `;
38
+ expect(harness.runProgram(source)).toBe("string\nfalse\nfalse\nError: plain\ntrue");
39
+ });
40
+ it("captures stacks for Error subclasses", () => {
41
+ const source = `
42
+ class MyError extends Error {
43
+ constructor(message: string) { super(message); this.name = "MyError"; }
44
+ }
45
+ try {
46
+ throw new MyError("custom");
47
+ } catch (e) {
48
+ const stack = (e as Error).stack;
49
+ console.log(e instanceof MyError, (e as Error).name);
50
+ console.log(stack.split("\\n")[0]);
51
+ console.log(stack.includes("at new MyError"));
52
+ }
53
+ `;
54
+ expect(harness.runProgram(source)).toBe("true MyError\nError: custom\ntrue");
55
+ });
56
+ it("prints the stack for an uncaught error", () => {
57
+ const result = harness.runProgramFull(`
58
+ function inner(): never { throw new Error("boom"); }
59
+ inner();
60
+ `);
61
+ expect(result.status).not.toBe(0);
62
+ expect(result.stderr).toContain("Uncaught Error: boom");
63
+ expect(result.stderr).toContain("at inner");
64
+ expect(result.stderr).toContain("at module");
65
+ expect(result.stderr).toContain(":1");
66
+ });
67
+ it("names bundled functions without the bundler's module prefix", () => {
68
+ const output = harness.runProgram(`
69
+ import { fail } from "./failure.ts";
70
+ try { fail(); } catch (e) { console.log((e as Error).stack); }
71
+ `, {
72
+ name: "bundled_stack",
73
+ files: {
74
+ "failure.ts": 'export function fail(): never { throw new Error("from helper"); }\n',
75
+ },
76
+ });
77
+ expect(output).toContain("Error: from helper");
78
+ expect(output).toContain("at fail (");
79
+ expect(output).toContain("failure.ts:");
80
+ expect(output).not.toContain("_fail (");
81
+ });
82
+ it("does not leak frames from a call unwound by catch", () => {
83
+ const source = `
84
+ function inner(): never { throw new Error("boom"); }
85
+ try { inner(); } catch (e) { console.log((e as Error).message); }
86
+ const after = new Error("after");
87
+ console.log(after.stack.includes("inner"));
88
+ console.log(after.stack.includes("middle"));
89
+ console.log(after.stack.includes("at module"));
90
+ `;
91
+ expect(harness.runProgram(source)).toBe("boom\nfalse\nfalse\ntrue");
92
+ });
93
+ });
94
+ //# sourceMappingURL=error-stack.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-stack.test.js","sourceRoot":"","sources":["../../../tests/e2e/error-stack.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,WAAW,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE;IACtC,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG;;;;;;;;;;;;;KAad,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAC1G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG;;;;;;;KAOd,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG;;;;;;;;;;;;KAYd,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;;;KAGrC,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAC/B;;;OAGC,EACD;YACE,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE;gBACL,YAAY,EAAE,qEAAqE;aACpF;SACF,CACF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG;;;;;;;KAOd,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -42,6 +42,52 @@ describeE2E("runtime coverage: globals", (h) => {
42
42
  "b 2",
43
43
  ]);
44
44
  });
45
+ it("exposes first-class built-in constructors and Object.prototype", () => {
46
+ const source = `
47
+ const A = Array;
48
+ console.log(typeof A, A === Array, A.name, A.length);
49
+ const a = new A(1, 2, 3);
50
+ console.log(a.length, a.join(","), a instanceof A, A.isArray(a));
51
+ console.log(Object.getPrototypeOf({}) === Object.prototype);
52
+ console.log(Object.prototype.hasOwnProperty.call({x:1}, "x"), Object.prototype.hasOwnProperty.call({x:1}, "y"));
53
+ const F = Function;
54
+ function f() {}
55
+ console.log(f instanceof F, Object.getPrototypeOf([]) === Array.prototype);
56
+ const M = Map;
57
+ const m = new M();
58
+ m.set("k", 1);
59
+ console.log(m instanceof M, m.get("k"), Object.getPrototypeOf(m) === M.prototype);
60
+ const E = TypeError;
61
+ const e = new E("bad");
62
+ console.log(e instanceof E, e instanceof Error, e.name, e.message);
63
+ const U = Uint8Array;
64
+ const u = new U(2);
65
+ u[0] = 300;
66
+ console.log(u instanceof U, u[0], U.BYTES_PER_ELEMENT);
67
+ const S = String;
68
+ const N = Number;
69
+ console.log(S.fromCharCode(65), S(42), N.isInteger(3), N.MAX_SAFE_INTEGER);
70
+ const Sym = Symbol;
71
+ console.log(Sym.prototype.constructor === Sym, Sym.iterator === Symbol.iterator);
72
+ console.log(Array.isArray(Array.prototype), ({}).constructor === Object, [].constructor === Array);
73
+ console.log(Object.getPrototypeOf(Object.prototype) === null);
74
+ `;
75
+ const stdout = h.runProgram(source, { extensions: true, timeout: TIMEOUT });
76
+ expect(stdout.split("\n")).toEqual([
77
+ "function true Array 1",
78
+ "3 1,2,3 true true",
79
+ "true",
80
+ "true false",
81
+ "true true",
82
+ "true 1 true",
83
+ "true true TypeError bad",
84
+ "true 44 1",
85
+ "A 42 true 9007199254740991",
86
+ "true true",
87
+ "true true true",
88
+ "true",
89
+ ]);
90
+ });
45
91
  it("uses the console surface, inspect and base64 helpers", () => {
46
92
  const source = `
47
93
  console.count("x");
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-coverage-globals.test.js","sourceRoot":"","sources":["../../../tests/e2e/runtime-coverage-globals.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,OAAO,GAAG,MAAM,CAAC;AAEvB,WAAW,CACT,2BAA2B,EAC3B,CAAC,CAAC,EAAE,EAAE;IACJ,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;OAkBd,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YACjC,eAAe;YACf,uBAAuB;YACvB,KAAK;YACL,YAAY;YACZ,YAAY;YACZ,uBAAuB;YACvB,SAAS;YACT,SAAS;YACT,GAAG;YACH,6BAA6B;YAC7B,iBAAiB;YACjB,eAAe;YACf,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;OAwBd,CAAC;QACF,MAAM,MAAM,GAAG,CAAC;aACb,UAAU,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;aAC1D,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YACjC,MAAM;YACN,MAAM;YACN,MAAM;YACN,GAAG;YACH,UAAU;YACV,WAAW;YACX,WAAW;YACX,wBAAwB;YACxB,MAAM;YACN,gBAAgB;YAChB,+BAA+B;YAC/B,gBAAgB;YAChB,yCAAyC;YACzC,oBAAoB;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;OAyBd,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;YACjC,qBAAqB;YACrB,uBAAuB;YACvB,wBAAwB;YACxB,2BAA2B;YAC3B,gCAAgC;YAChC,gCAAgC;YAChC,qBAAqB;YACrB,aAAa;YACb,YAAY;YACZ,6BAA6B;YAC7B,OAAO;YACP,kBAAkB;YAClB,+CAA+C;YAC/C,gBAAgB;YAChB,iMAAiM;YACjM,6BAA6B;YAC7B,iBAAiB;YACjB,cAAc;YACd,cAAc;YACd,uBAAuB;YACvB,yBAAyB;YACzB,2BAA2B;YAC3B,QAAQ;YACR,qCAAqC;SACtC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,EACD,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAC3C,CAAC"}
1
+ {"version":3,"file":"runtime-coverage-globals.test.js","sourceRoot":"","sources":["../../../tests/e2e/runtime-coverage-globals.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * End-to-end tests for the lazy (rope/cons) string model.
3
+ *
4
+ * Concatenation above the eager-copy threshold produces an immutable cons node
5
+ * whose bytes are materialised on first observation. These tests exercise every
6
+ * kind of observation (length, slicing, searching, case changes, JSON, property
7
+ * keys) and keep chains reachable across a garbage collection.
8
+ */
9
+ export {};