xbintsc 0.3.81 → 0.3.87

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 (157) hide show
  1. package/README.md +12 -2
  2. package/README.zh-CN.md +12 -4
  3. package/dist/src/ast/common.d.ts +23 -0
  4. package/dist/src/cli/main.js +68 -24
  5. package/dist/src/cli/main.js.map +1 -1
  6. package/dist/src/codegen/generator/calls/invocation.js +5 -1
  7. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  8. package/dist/src/codegen/generator/context.d.ts +50 -0
  9. package/dist/src/codegen/generator/context.js +124 -13
  10. package/dist/src/codegen/generator/context.js.map +1 -1
  11. package/dist/src/codegen/generator/debug.d.ts +33 -0
  12. package/dist/src/codegen/generator/debug.js +97 -0
  13. package/dist/src/codegen/generator/debug.js.map +1 -0
  14. package/dist/src/codegen/generator/expressions/assignment.js +9 -5
  15. package/dist/src/codegen/generator/expressions/assignment.js.map +1 -1
  16. package/dist/src/codegen/generator/expressions/operators.js +35 -9
  17. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  18. package/dist/src/codegen/generator/expressions/primary.js +5 -2
  19. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  20. package/dist/src/codegen/generator/generator.d.ts +3 -1
  21. package/dist/src/codegen/generator/generator.js +3 -1
  22. package/dist/src/codegen/generator/generator.js.map +1 -1
  23. package/dist/src/codegen/generator/module.d.ts +1 -0
  24. package/dist/src/codegen/generator/module.js +76 -6
  25. package/dist/src/codegen/generator/module.js.map +1 -1
  26. package/dist/src/codegen/generator/numeric.d.ts +26 -0
  27. package/dist/src/codegen/generator/numeric.js +127 -0
  28. package/dist/src/codegen/generator/numeric.js.map +1 -0
  29. package/dist/src/codegen/generator/state.d.ts +17 -0
  30. package/dist/src/codegen/generator/state.js +5 -0
  31. package/dist/src/codegen/generator/state.js.map +1 -1
  32. package/dist/src/codegen/generator/statements/control-flow.js +1 -1
  33. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  34. package/dist/src/codegen/generator/statements/dispatch.js +3 -0
  35. package/dist/src/codegen/generator/statements/dispatch.js.map +1 -1
  36. package/dist/src/codegen/generator/statements/variables.js +8 -2
  37. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  38. package/dist/src/codegen/generator/tables.d.ts +7 -0
  39. package/dist/src/codegen/generator/tables.js +25 -0
  40. package/dist/src/codegen/generator/tables.js.map +1 -1
  41. package/dist/src/driver/bundler/merge.js +41 -5
  42. package/dist/src/driver/bundler/merge.js.map +1 -1
  43. package/dist/src/driver/compiler.d.ts +22 -3
  44. package/dist/src/driver/compiler.js +43 -57
  45. package/dist/src/driver/compiler.js.map +1 -1
  46. package/dist/src/driver/fingerprint.d.ts +27 -0
  47. package/dist/src/driver/fingerprint.js +88 -0
  48. package/dist/src/driver/fingerprint.js.map +1 -0
  49. package/dist/src/driver/toolchain-provider.d.ts +9 -2
  50. package/dist/src/driver/toolchain-provider.js +15 -15
  51. package/dist/src/driver/toolchain-provider.js.map +1 -1
  52. package/dist/src/driver/toolchain.d.ts +58 -1
  53. package/dist/src/driver/toolchain.js +169 -22
  54. package/dist/src/driver/toolchain.js.map +1 -1
  55. package/dist/src/parser/expressions.js +20 -1
  56. package/dist/src/parser/expressions.js.map +1 -1
  57. package/dist/tests/cli/main.test.js +41 -1
  58. package/dist/tests/cli/main.test.js.map +1 -1
  59. package/dist/tests/codegen/expressions.test.js +14 -3
  60. package/dist/tests/codegen/expressions.test.js.map +1 -1
  61. package/dist/tests/codegen/llvm.test.js +23 -0
  62. package/dist/tests/codegen/llvm.test.js.map +1 -1
  63. package/dist/tests/driver/toolchain-provider.test.js +49 -2
  64. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  65. package/dist/tests/driver/toolchain.test.js +62 -3
  66. package/dist/tests/driver/toolchain.test.js.map +1 -1
  67. package/dist/tests/e2e/child-process.test.d.ts +10 -0
  68. package/dist/tests/e2e/child-process.test.js +59 -0
  69. package/dist/tests/e2e/child-process.test.js.map +1 -0
  70. package/dist/tests/e2e/compile-objects-classes.test.js +47 -0
  71. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  72. package/dist/tests/e2e/error-stack.test.d.ts +9 -0
  73. package/dist/tests/e2e/error-stack.test.js +94 -0
  74. package/dist/tests/e2e/error-stack.test.js.map +1 -0
  75. package/dist/tests/e2e/string-concat.test.d.ts +9 -0
  76. package/dist/tests/e2e/string-concat.test.js +102 -0
  77. package/dist/tests/e2e/string-concat.test.js.map +1 -0
  78. package/dist/tests/helpers.d.ts +9 -0
  79. package/dist/tests/helpers.js +26 -3
  80. package/dist/tests/helpers.js.map +1 -1
  81. package/dist/tests/parser/expressions.test.js +7 -0
  82. package/dist/tests/parser/expressions.test.js.map +1 -1
  83. package/dist/tests/version.test.d.ts +1 -0
  84. package/dist/tests/version.test.js +24 -0
  85. package/dist/tests/version.test.js.map +1 -0
  86. package/doc/DESIGN.md +20 -12
  87. package/doc/ai/cli.md +2 -0
  88. package/doc/ai/contributing.md +7 -1
  89. package/doc/ai/language-support.md +4 -4
  90. package/doc/ai/troubleshooting.md +39 -2
  91. package/doc/ai/zh-CN/cli.md +2 -0
  92. package/doc/ai/zh-CN/contributing.md +6 -2
  93. package/doc/ai/zh-CN/language-support.md +4 -4
  94. package/doc/ai/zh-CN/troubleshooting.md +35 -2
  95. package/doc/implemented.md +3 -3
  96. package/doc/requirements.md +13 -4
  97. package/doc/unimplemented.md +11 -10
  98. package/doc/zh-CN/DESIGN.md +15 -9
  99. package/doc/zh-CN/implemented.md +3 -3
  100. package/doc/zh-CN/requirements.md +12 -3
  101. package/doc/zh-CN/unimplemented.md +10 -9
  102. package/package.json +3 -1
  103. package/runtime/ext_node/buffer/parts/construction.inc +2 -2
  104. package/runtime/ext_node/buffer/parts/methods.inc +1 -1
  105. package/runtime/ext_node/buffer/parts/search.inc +1 -1
  106. package/runtime/ext_node/child_process/child_process.c +25 -0
  107. package/runtime/ext_node/fs/fd_ops.c +1 -1
  108. package/runtime/rt.h +17 -1
  109. package/runtime/rt_internal.h +47 -4
  110. package/runtime/xt_alloc.c +14 -2
  111. package/runtime/xt_bigint/conversions.inc +1 -1
  112. package/runtime/xt_builtins.c +136 -14
  113. package/runtime/xt_containers/access.inc +17 -16
  114. package/runtime/xt_containers/objects.inc +4 -3
  115. package/runtime/xt_io/exception.inc +171 -2
  116. package/runtime/xt_io/inspect.inc +15 -13
  117. package/runtime/xt_io.c +5 -0
  118. package/runtime/xt_stdlib/arrays.inc +2 -2
  119. package/runtime/xt_stdlib/dispatch.inc +2 -2
  120. package/runtime/xt_stdlib/strings.inc +33 -21
  121. package/runtime/xt_stdlib2/array-statics.inc +2 -1
  122. package/runtime/xt_stdlib2/arrays.inc +1 -1
  123. package/runtime/xt_stdlib2/error.inc +22 -6
  124. package/runtime/xt_stdlib2/json.inc +3 -2
  125. package/runtime/xt_stdlib2/number-string-statics.inc +3 -1
  126. package/runtime/xt_stdlib2/regexp-match.inc +48 -33
  127. package/runtime/xt_stdlib2/strings.inc +23 -14
  128. package/runtime/xt_symbol.c +1 -1
  129. package/runtime/xt_values/comparison.inc +2 -2
  130. package/runtime/xt_values/constructors.inc +10 -5
  131. package/runtime/xt_values/conversions.inc +4 -3
  132. package/runtime/xt_values/strings.inc +78 -4
  133. package/scripts/bench.ts +172 -0
  134. package/scripts/build-runtime.ts +2 -1
  135. package/scripts/check-version.ts +53 -0
  136. package/src/ast/common.ts +23 -0
  137. package/src/cli/main.ts +68 -26
  138. package/src/codegen/generator/calls/invocation.ts +5 -0
  139. package/src/codegen/generator/context.ts +129 -18
  140. package/src/codegen/generator/debug.ts +132 -0
  141. package/src/codegen/generator/expressions/assignment.ts +9 -5
  142. package/src/codegen/generator/expressions/operators.ts +47 -8
  143. package/src/codegen/generator/expressions/primary.ts +5 -2
  144. package/src/codegen/generator/generator.ts +18 -2
  145. package/src/codegen/generator/module.ts +78 -6
  146. package/src/codegen/generator/numeric.ts +158 -0
  147. package/src/codegen/generator/state.ts +22 -0
  148. package/src/codegen/generator/statements/control-flow.ts +1 -1
  149. package/src/codegen/generator/statements/dispatch.ts +3 -0
  150. package/src/codegen/generator/statements/variables.ts +8 -2
  151. package/src/codegen/generator/tables.ts +26 -0
  152. package/src/driver/bundler/merge.ts +39 -5
  153. package/src/driver/compiler.ts +62 -55
  154. package/src/driver/fingerprint.ts +85 -0
  155. package/src/driver/toolchain-provider.ts +17 -16
  156. package/src/driver/toolchain.ts +210 -21
  157. package/src/parser/expressions.ts +20 -1
@@ -0,0 +1,102 @@
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
+ import { expect, it } from "vitest";
10
+ import { describeE2E } from "./harness.js";
11
+ describeE2E("lazy string concatenation", (harness) => {
12
+ const { runProgram, runProgramFull } = harness;
13
+ it("matches Node for append and prepend chains", () => {
14
+ const source = `
15
+ function build(n: number): string {
16
+ let text = "";
17
+ for (let i = 0; i < n; i++) text = text + "abcdefghijklmnopqrstuvwxyz".charAt(i % 26);
18
+ return text;
19
+ }
20
+ const text = build(2000);
21
+ console.log(text.length);
22
+ console.log(text.slice(0, 26));
23
+ console.log(text.slice(-26));
24
+ console.log(text.indexOf("xyz"));
25
+ console.log(text.lastIndexOf("abc"));
26
+ console.log(text.includes("mnop"));
27
+ console.log(text.split("def").length);
28
+ console.log(text.toUpperCase().slice(0, 26));
29
+ console.log(text.replace("abc", "ABC").slice(0, 26));
30
+ console.log(text.replaceAll("a", "!").slice(0, 26));
31
+ console.log(text === build(2000));
32
+ console.log(text.startsWith("abc"), text.endsWith("xyz"));
33
+ console.log(JSON.stringify(text.slice(0, 10)));
34
+ console.log(text.charCodeAt(5), text.at(-1));
35
+
36
+ let prepended = "";
37
+ for (let i = 0; i < 2000; i++) prepended = "x" + prepended;
38
+ console.log(prepended.length, prepended.slice(0, 3), prepended.slice(-3));
39
+
40
+ let mixed = "";
41
+ for (let i = 0; i < 200; i++) mixed += i;
42
+ console.log(mixed.length, mixed.slice(0, 12));
43
+
44
+ let templated = "";
45
+ for (let i = 0; i < 2000; i++) templated = \`\${templated}\${i % 10}\`;
46
+ console.log(templated.length, templated.slice(0, 12));
47
+
48
+ let key = "";
49
+ for (let i = 0; i < 40; i++) key += "k";
50
+ const holder: any = {};
51
+ holder[key] = "v";
52
+ console.log(holder[key], Object.keys(holder)[0].length);
53
+ console.log([text, prepended].join("|").length);
54
+ `;
55
+ harness.expectSameOutputAsNode(source, { name: "string_concat_chains" });
56
+ });
57
+ it("keeps cons nodes reachable across collections", () => {
58
+ const source = `
59
+ let text = "";
60
+ for (let i = 0; i < 2000; i++) text += "z";
61
+ const holder: any = { text: text };
62
+ const list: any[] = [text];
63
+ text = "";
64
+
65
+ /* Allocate and drop many objects to force collections while the rope is
66
+ reachable only through the object property and the array element. */
67
+ let junk: any = {};
68
+ for (let i = 0; i < 40000; i++) junk = { value: i };
69
+ junk = {};
70
+ const trigger = "x" + "y";
71
+
72
+ /* Reuse the freed memory before the rope is ever flattened. */
73
+ const reuse: any[] = [];
74
+ for (let i = 0; i < 5000; i++) reuse.push("a" + "b");
75
+
76
+ console.log(holder.text.length, holder.text === "z".repeat(2000));
77
+ console.log(list[0].length, list[0] === holder.text, reuse.length, trigger);
78
+ console.log(holder.text.slice(0, 2), holder.text.slice(-2), holder.text.toUpperCase().slice(0, 3));
79
+ `;
80
+ const result = runProgramFull(source, {
81
+ name: "string_concat_gc",
82
+ env: { XT_GC_THRESHOLD: "1048576" },
83
+ timeout: 60000,
84
+ });
85
+ expect(result.status).toBe(0);
86
+ expect(result.stdout.trim()).toBe("2000 true\n2000 true 5000 xy\nzz zz ZZZ");
87
+ });
88
+ it("flattens reused chains without mutating earlier results", () => {
89
+ const source = `
90
+ let prefix = "start-";
91
+ for (let i = 0; i < 200; i++) prefix += "p";
92
+ const first = prefix + "-first";
93
+ const second = prefix + "-second";
94
+ const prefixCopy = prefix.slice(0);
95
+ console.log(first.slice(-6), second.slice(-7));
96
+ console.log(prefix.length, first.length, second.length);
97
+ console.log(prefix === prefixCopy, prefix === first.slice(0, prefix.length));
98
+ `;
99
+ expect(runProgram(source)).toBe("-first -second\n206 212 213\ntrue true");
100
+ });
101
+ });
102
+ //# sourceMappingURL=string-concat.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-concat.test.js","sourceRoot":"","sources":["../../../tests/e2e/string-concat.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,2BAA2B,EAAE,CAAC,OAAO,EAAE,EAAE;IACnD,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAE/C,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwClB,CAAC;QACE,OAAO,CAAC,sBAAsB,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBlB,CAAC;QACE,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE;YACpC,IAAI,EAAE,kBAAkB;YACxB,GAAG,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE;YACnC,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,MAAM,GAAG;;;;;;;;;CASlB,CAAC;QACE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -18,9 +18,18 @@ export declare function bindSource(text: string): {
18
18
  export declare function compileToIr(text: string, extensions?: ExtensionRegistry, target?: {
19
19
  platform: string;
20
20
  arch: string;
21
+ }, options?: {
22
+ readonly debug?: boolean;
21
23
  }): {
22
24
  ir: string;
23
25
  binding: BindResult;
24
26
  diagnostics: readonly Diagnostic[];
25
27
  };
28
+ /**
29
+ * True when a *supported* clang is available. The end-to-end suites really
30
+ * compile and link native binaries, and the emitted IR needs clang >= 16, so a
31
+ * missing or too-old toolchain skips them instead of failing every case with an
32
+ * opaque-pointer error. `resolveToolchain` applies the same selection (and
33
+ * version gate) the driver uses, so the tests and the compiler agree.
34
+ */
26
35
  export declare function hasClang(): boolean;
@@ -7,7 +7,8 @@ import { Parser } from "../src/parser/parser.js";
7
7
  import { bind } from "../src/binder/binder.js";
8
8
  import { generate } from "../src/codegen/llvm.js";
9
9
  import { createDefaultRegistry } from "../src/extensions/registry.js";
10
- import { realRunner } from "../src/driver/toolchain.js";
10
+ import { MINIMUM_CLANG_MAJOR } from "../src/driver/toolchain.js";
11
+ import { resolveToolchain } from "../src/driver/toolchain-provider.js";
11
12
  export function lex(text) {
12
13
  const source = new SourceFile("test.ts", sourceTextBytes(text));
13
14
  const diagnostics = new DiagnosticBag();
@@ -28,7 +29,7 @@ export function bindSource(text) {
28
29
  const result = bind(file);
29
30
  return { result, diagnostics: bag.diagnostics };
30
31
  }
31
- export function compileToIr(text, extensions, target) {
32
+ export function compileToIr(text, extensions, target, options = {}) {
32
33
  const { file, diagnostics: parseDiagnostics } = parse(text);
33
34
  const diagnostics = new DiagnosticBag();
34
35
  diagnostics.addAll(parseDiagnostics);
@@ -37,10 +38,32 @@ export function compileToIr(text, extensions, target) {
37
38
  builtins: registry.builtins(),
38
39
  modules: registry.modules(),
39
40
  ...(target ? { target } : {}),
41
+ debug: options.debug === true,
40
42
  });
41
43
  return { ir, binding, diagnostics: diagnostics.diagnostics };
42
44
  }
45
+ let cachedClangSupport;
46
+ /**
47
+ * True when a *supported* clang is available. The end-to-end suites really
48
+ * compile and link native binaries, and the emitted IR needs clang >= 16, so a
49
+ * missing or too-old toolchain skips them instead of failing every case with an
50
+ * opaque-pointer error. `resolveToolchain` applies the same selection (and
51
+ * version gate) the driver uses, so the tests and the compiler agree.
52
+ */
43
53
  export function hasClang() {
44
- return realRunner.run(process.env.xbintsc_CLANG ?? "clang", ["--version"]).status === 0;
54
+ if (cachedClangSupport === undefined) {
55
+ try {
56
+ const version = resolveToolchain().version;
57
+ cachedClangSupport = version === undefined || version.major >= MINIMUM_CLANG_MAJOR;
58
+ }
59
+ catch {
60
+ cachedClangSupport = false;
61
+ }
62
+ if (!cachedClangSupport) {
63
+ console.warn(`xbintsc: skipping end-to-end tests — clang ${MINIMUM_CLANG_MAJOR}+ was not found ` +
64
+ "(see doc/requirements.md, or set xbintsc_CLANG)");
65
+ }
66
+ }
67
+ return cachedClangSupport;
45
68
  }
46
69
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../tests/helpers.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAErD,OAAO,EAAE,aAAa,EAAmB,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAmB,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAA0B,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAGxD,MAAM,UAAU,GAAG,CAAC,IAAY;IAC9B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,aAAa,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,aAAa,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,aAAa,EAAE,CAAC;IAChC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,UAA8B,EAC9B,MAA2C;IAE3C,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,IAAI,aAAa,EAAE,CAAC;IACxC,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,UAAU,IAAI,qBAAqB,EAAE,CAAC;IACvD,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE;QAClD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;QAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE;QAC3B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1F,CAAC"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../tests/helpers.ts"],"names":[],"mappings":"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"}
@@ -44,4 +44,11 @@ describe("assignment validation", () => {
44
44
  expect(diagnostics.some((d) => d.code === DiagnosticCode.InvalidAssignmentTarget)).toBe(true);
45
45
  });
46
46
  });
47
+ describe("unsupported syntax", () => {
48
+ it("reports new.target as an unsupported feature, not a syntax error", () => {
49
+ const { diagnostics } = parse("function F() { return new.target; }");
50
+ expect(diagnostics.map((d) => d.code)).toContain(DiagnosticCode.UnsupportedFeature);
51
+ expect(diagnostics.map((d) => d.code)).not.toContain(DiagnosticCode.UnexpectedToken);
52
+ });
53
+ });
47
54
  //# sourceMappingURL=expressions.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"expressions.test.js","sourceRoot":"","sources":["../../../tests/parser/expressions.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"expressions.test.js","sourceRoot":"","sources":["../../../tests/parser/expressions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { describe, expect, it } from "vitest";
3
+ import { COMPILER_VERSION } from "../src/driver/compiler.js";
4
+ const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
5
+ describe("compiler version", () => {
6
+ it("matches package.json", () => {
7
+ expect(COMPILER_VERSION).toBe(packageJson.version);
8
+ });
9
+ it("is part of the incremental cache key", () => {
10
+ const source = readFileSync(new URL("../src/driver/compiler.ts", import.meta.url), "utf8");
11
+ expect(source).toMatch(/hashParts\(\[\s*COMPILER_VERSION,/);
12
+ });
13
+ it("is printed by `xbintsc version`", async () => {
14
+ const { run } = await import("../src/cli/main.js");
15
+ const lines = [];
16
+ const code = run(["version"], {
17
+ stdout: (text) => lines.push(text),
18
+ stderr: (text) => lines.push(text),
19
+ });
20
+ expect(code).toBe(0);
21
+ expect(lines.join("")).toContain(COMPILER_VERSION);
22
+ });
23
+ });
24
+ //# sourceMappingURL=version.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.test.js","sourceRoot":"","sources":["../../tests/version.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAC3C,CAAC;AAEzB,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3F,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE;YAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;YAClC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/doc/DESIGN.md CHANGED
@@ -41,16 +41,21 @@ xt_value fn(xt_value env, int32_t argc, xt_value *argv);
41
41
 
42
42
  `env` threads captured variables by reference through boxes, so direct calls and
43
43
  closure calls share a single code path. JavaScript semantics that are awkward to
44
- inline (`+` coercion, relational comparison, property access, inspection) are
45
- delegated to `@xt_*` runtime calls.
44
+ inline (`+` coercion, property access, inspection) are delegated to `@xt_*`
45
+ runtime calls. Numeric arithmetic and comparison are the exception: codegen emits
46
+ the double fast path inline (`numeric.ts`) and calls the runtime for the coercing
47
+ cases.
46
48
 
47
49
  ### Runtime
48
50
 
49
- `runtime/xt_runtime.c` implements strings, objects, arrays, closures, arithmetic,
50
- comparison, exceptions and Node-like `console.log` inspection. It uses a
51
- non-moving mark-sweep collector behind `xt_alloc` (explicit roots, subsystem
52
- root providers and a conservative C-stack scan), so the collector's internals
53
- stay isolated from the compiler.
51
+ `runtime/` implements strings, objects, arrays, closures, arithmetic, comparison,
52
+ exceptions and Node-like `console.log` inspection. It is split by concern into
53
+ translation units (`xt_values.c`, `xt_containers.c`, `xt_stdlib.c`,
54
+ `xt_builtins.c`, `xt_io.c`, `xt_alloc.c`, …), each `#include`-ing its
55
+ implementation fragments (`.inc`) so files stay small without changing the link
56
+ surface. It uses a non-moving mark-sweep collector behind `xt_alloc` (explicit
57
+ roots, subsystem root providers and a conservative C-stack scan), so the
58
+ collector's internals stay isolated from the compiler.
54
59
 
55
60
  ### Replacing llc
56
61
 
@@ -103,15 +108,18 @@ found on `PATH` (the MSVC ABI when LLVM + the Visual Studio C++ build tools are
103
108
  installed), and each manifest declares any platform-specific linker flags. See
104
109
  `examples/extensions/` and `runtime/xt_ext.h` / `runtime/xt_ext.rs`.
105
110
 
106
- ## Self-hosting roadmap
111
+ ## Self-hosting
107
112
 
108
- The compiler itself is written in TypeScript and emits IR text, and `runtime` is
109
- already decoupled from the compiler. Later, the runtime can be rewritten in TS
110
- and the compiler can compile itself, gradually reaching self-hosting.
113
+ The compiler compiles itself: `xbintsc build src/cli/main.ts --ext node` produces
114
+ a working `xbintsc` binary, and the emitted IR is a fixpoint from the first
115
+ generation onward. CI builds those binaries for every supported platform and
116
+ checks the fixpoint. The runtime stays in C; rewriting it in TypeScript is an
117
+ option for later, not a prerequisite for self-hosting.
111
118
 
112
119
  ## Tests
113
120
 
114
121
  Organised by module: `tests/lexer`, `tests/parser`, `tests/binder`,
115
122
  `tests/codegen`, `tests/driver`, `tests/extensions`, `tests/cli`, `tests/e2e`.
116
- When `clang` is present, e2e tests really compile and run binaries; otherwise
123
+ When a supported clang (16+, the same version gate `build` applies) is present,
124
+ e2e tests really compile and run binaries; otherwise
117
125
  they are skipped automatically.
package/doc/ai/cli.md CHANGED
@@ -36,6 +36,8 @@ unknown command prints an error plus the help text and exits 1.
36
36
  --app-id <id> macOS bundle identifier (e.g. com.example.demo)
37
37
  --force Ignore the incremental cache
38
38
  --verbose Print progress information
39
+ --time Print per-phase build timings
40
+ --debug Emit debug info (DWARF/CodeView) and keep frame pointers
39
41
  ```
40
42
 
41
43
  Parsing details that occasionally surprise:
@@ -38,6 +38,7 @@ it. Release tags are created by `release.yml`, never by the hook.
38
38
  | `npm run test:watch` | vitest in watch mode |
39
39
  | `npm run coverage` | V8 coverage of the TypeScript compiler (`src/`) |
40
40
  | `npm run coverage:runtime` | LLVM coverage of the C runtime (`runtime/`) |
41
+ | `npm run bench` | build and time the fixed benchmark suite (optionally vs Node) |
41
42
 
42
43
  Unit tests live one directory per module under `tests/` (`lexer`, `parser`,
43
44
  `binder`, `codegen`, `driver`, `extensions`, `cli`, `e2e`) and mirror the source
@@ -103,7 +104,12 @@ diff scratch/ref.ll scratch/gen2.ll
103
104
  in [../../src/codegen/values.ts](../../src/codegen/values.ts) and
104
105
  [../../runtime/rt.h](../../runtime/rt.h); change both together or not at all.
105
106
  - Awkward JS semantics (`+` coercion, relational comparison, property access,
106
- inspection) are delegated to `@xt_*` runtime calls rather than inlined.
107
+ inspection) are delegated to `@xt_*` runtime calls. Numeric arithmetic and
108
+ comparison are the exception: codegen inlines the two-double fast path
109
+ (`src/codegen/generator/numeric.ts`) and calls the runtime for everything else.
110
+ - String literals are interned: each distinct literal is materialised once in
111
+ `main`, stored in a GC-rooted global, and loaded at each use. Property names
112
+ therefore never allocate per access.
107
113
  - The GC is a non-moving mark-sweep collector: new heap objects go through
108
114
  `xt_alloc`, and a value must be reachable from an explicit root slot, a
109
115
  registered root provider (the event loop, the microtask queue) or the
@@ -45,8 +45,8 @@ Canonical detail (always current, much longer):
45
45
  | Destructuring (bindings, parameters, nested) | ✅ | defaults + rest supported |
46
46
  | `delete`, `in`, `instanceof`, `typeof` | ✅ | |
47
47
  | Comma operator, `void` | ✅ | |
48
- | `new.target` | 🚫 | not implemented |
49
- | `import.meta` | 🚫 | parsed but has no value |
48
+ | `new.target` | 🚫 | parsed, then rejected with a clear `UnsupportedFeature` |
49
+ | `import.meta` | ✅ | `url`, `dirname`, `filename` (resolved from the executable path) |
50
50
  | `super` | ⚠️ | single-level inheritance correct; depth > 1 may be inaccurate |
51
51
 
52
52
  ## Functions, classes, objects
@@ -103,7 +103,7 @@ URI functions.
103
103
  | Missing or different | Status |
104
104
  | --- | --- |
105
105
  | `String.prototype.normalize`, `structuredClone` | 🚫 |
106
- | `Error.stack` capture | 🚫 (not captured) |
106
+ | `Error.stack` capture | ⚠️ function-level frames (name/file/line), no columns; generator bodies are omitted |
107
107
  | `Object.getPrototypeOf({})` | ⚠️ returns `undefined`, not `Object.prototype` |
108
108
  | Global RegExp `lastIndex` | ⚠️ `test`/`exec` ignore it for `/g` and `/y` |
109
109
  | Sparse array holes, array out-of-bounds | ⚠️ holes are not tracked distinctly; out-of-bounds reads give `undefined` |
@@ -122,7 +122,7 @@ See section 3 of [../unimplemented.md](../unimplemented.md) for the full list.
122
122
  | `require()` / CommonJS | 🚫 | rejected with a hint to use `import` |
123
123
  | Circular dependencies | 🚫 | |
124
124
  | Live bindings | ⚠️ | imports and namespace members are snapshots |
125
- | `import.meta`, `__dirname`, `__filename` | 🚫 | |
125
+ | `__dirname`, `__filename` | 🚫 | use `import.meta.dirname` / `import.meta.filename` |
126
126
 
127
127
  ## Strings, numbers, memory
128
128
 
@@ -22,8 +22,12 @@ D:\...\build\app.ll:382:37: error: '@.str.0' defined with type '[6 x i8]*' but e
22
22
 
23
23
  The compiler emits LLVM IR that relies on opaque pointers; typed pointers were
24
24
  removed in LLVM 16 ([LLVM release notes](https://github.com/llvm/llvm-project/blob/release/15.x/llvm/docs/ReleaseNotes.rst#changes-to-the-llvm-ir)).
25
- Confirm with `clang --version`; if the machine has an old system clang, install a
26
- newer LLVM and point xbintsc at it:
25
+ `xbintsc build`/`run` check the version up front and stop with "reports clang
26
+ 15.0.2, but xbintsc requires clang 16 or newer", and `xbintsc doctor` prints
27
+ `status : ok` or `status : too old` (exiting non-zero in the latter case). The
28
+ search prefers a supported clang — including the LLVM bundled with Visual Studio
29
+ on Windows — so an old `/usr/bin/clang` is skipped when a newer one is installed.
30
+ To choose one explicitly:
27
31
 
28
32
  ```bash
29
33
  export xbintsc_CLANG=/usr/lib/llvm-18/bin/clang # PowerShell: $env:xbintsc_CLANG = "C:\Program Files\LLVM\bin\clang.exe"
@@ -118,6 +122,39 @@ described in [../gui.md](../gui.md).
118
122
  Windows, embedding a PE icon needs `llvm-rc` or `windres`; `doctor` reports which
119
123
  one was found, and a missing one is only fatal when an icon was requested.
120
124
 
125
+ ## Reading a stack trace
126
+
127
+ `Error.stack` is captured by codegen, not from the C runtime's native frames:
128
+ every non-generator function pushes `{name, file, line}` on entry and pops it
129
+ before returning. Frames look like
130
+
131
+ ```
132
+ Error: boom
133
+ at inner (app.ts:12)
134
+ at module (app.ts:3)
135
+ ```
136
+
137
+ Lines are function declaration lines, except that the innermost frame is moved
138
+ to the `new Error(...)` line; there are no column numbers. Generator bodies are
139
+ not tracked because they switch stacks. A fatal native signal prints
140
+ `xbintsc: fatal signal …` followed by the same frames, so a crash without a
141
+ debugger still shows which JavaScript functions were running.
142
+
143
+ ## Debugging with gdb / lldb / WinDbg
144
+
145
+ `xbintsc build app.ts --debug` emits LLVM debug metadata and passes `-g
146
+ -fno-omit-frame-pointer` to clang, so the object carries DWARF (Linux/macOS) or
147
+ CodeView (Windows) line tables. Function symbols keep their source names
148
+ (`xt_fn_3_add`) and every statement has a line location:
149
+
150
+ ```bash
151
+ xbintsc build app.ts --debug
152
+ gdb ./build/app # or: lldb ./build/app, or open the .exe in WinDbg
153
+ ```
154
+
155
+ The binary is larger and is cached separately from a normal build (the debug
156
+ flag is part of the cache key). `Error.stack` works without `--debug`.
157
+
121
158
  ## Build behaviour that looks wrong but is not
122
159
 
123
160
  ### The build printed `(cached)` and did nothing
@@ -33,6 +33,8 @@
33
33
  --app-id <id> macOS bundle 标识(如 com.example.demo)
34
34
  --force 忽略增量缓存
35
35
  --verbose 打印进度信息
36
+ --time 打印各构建阶段耗时
37
+ --debug 生成调试信息(DWARF/CodeView)并保留帧指针
36
38
  ```
37
39
 
38
40
  少数容易踩的解析细节:
@@ -35,6 +35,7 @@ git config core.hooksPath .githooks
35
35
  | `npm run test:watch` | vitest 监听模式 |
36
36
  | `npm run coverage` | TypeScript 编译器(`src/`)的 V8 覆盖率 |
37
37
  | `npm run coverage:runtime` | C 运行时(`runtime/`)的 LLVM 覆盖率 |
38
+ | `npm run bench` | 构建并计时固定基准套件(可与 Node 对比) |
38
39
 
39
40
  单元测试在 `tests/` 下按模块一个目录(`lexer`、`parser`、`binder`、`codegen`、
40
41
  `driver`、`extensions`、`cli`、`e2e`),与源码树镜像对应。边界用例放在它覆盖的模块
@@ -90,8 +91,11 @@ diff scratch/ref.ll scratch/gen2.ll
90
91
  - 每个值都是一个 64 位字:double 不装箱,其余都是带标签指针(16 位标签 + 48 位载荷)。
91
92
  该表示只定义一次:[../../../src/codegen/values.ts](../../../src/codegen/values.ts) 与
92
93
  [../../../runtime/rt.h](../../../runtime/rt.h);要改就一起改,否则别动。
93
- - 别扭的 JS 语义(`+` 强转、关系比较、属性访问、打印)委托给 `@xt_*` 运行时调用,而
94
- 不是内联。
94
+ - 别扭的 JS 语义(`+` 强转、关系比较、属性访问、打印)委托给 `@xt_*` 运行时调用。
95
+ 数值算术与比较是例外:codegen 内联双 double 快路径
96
+ (`src/codegen/generator/numeric.ts`),其余情况调用运行时。
97
+ - 字符串字面量会被驻留:每个不同字面量只在 `main` 中创建一次,存入 GC 根全局,
98
+ 每次使用只做一次 load;属性名因此不再逐次分配。
95
99
  - GC 是非移动标记清扫:新堆对象走 `xt_alloc`;值存活期间必须能从显式根槽、已注册的
96
100
  根提供者(事件循环、微任务队列)或 C 栈保守扫描到达。只存在于未被扫描的 C 局部
97
101
  变量里的值就是 bug。
@@ -42,8 +42,8 @@ xbintsc 编译 TypeScript 的一个**实用子集**。本页用来判断你能
42
42
  | 解构(绑定、参数、嵌套) | ✅ | 支持默认值与剩余 |
43
43
  | `delete`、`in`、`instanceof`、`typeof` | ✅ | |
44
44
  | 逗号运算符、`void` | ✅ | |
45
- | `new.target` | 🚫 | 未实现 |
46
- | `import.meta` | 🚫 | 能解析,但没有值 |
45
+ | `new.target` | 🚫 | 能解析,但会给出明确的 `UnsupportedFeature` |
46
+ | `import.meta` | ✅ | `url`、`dirname`、`filename`(由可执行文件路径解析) |
47
47
  | `super` | ⚠️ | 单层继承正确;继承深度 > 1 可能不准 |
48
48
 
49
49
  ## 函数、类与对象
@@ -98,7 +98,7 @@ xbintsc 编译 TypeScript 的一个**实用子集**。本页用来判断你能
98
98
  | 缺失或行为不同 | 状态 |
99
99
  | --- | --- |
100
100
  | `String.prototype.normalize`、`structuredClone` | 🚫 |
101
- | `Error.stack` 采集 | 🚫(不采集) |
101
+ | `Error.stack` 采集 | ⚠️ 函数级帧(名称/文件/行号),没有列号;生成器函数体不产生帧 |
102
102
  | `Object.getPrototypeOf({})` | ⚠️ 返回 `undefined`,而非 `Object.prototype` |
103
103
  | 全局 RegExp `lastIndex` | ⚠️ `/g`、`/y` 下 `test`/`exec` 忽略它 |
104
104
  | 稀疏数组空洞、数组越界 | ⚠️ 不区分空洞;越界读得 `undefined` |
@@ -117,7 +117,7 @@ xbintsc 编译 TypeScript 的一个**实用子集**。本页用来判断你能
117
117
  | `require()` / CommonJS | 🚫 | 被拒绝,并提示改用 `import` |
118
118
  | 循环依赖 | 🚫 | |
119
119
  | 实时绑定 | ⚠️ | 导入与命名空间成员都是快照 |
120
- | `import.meta`、`__dirname`、`__filename` | 🚫 | |
120
+ | `__dirname`、`__filename` | 🚫 | 请使用 `import.meta.dirname` / `import.meta.filename` |
121
121
 
122
122
  ## 字符串、数字与内存
123
123
 
@@ -21,8 +21,11 @@ D:\...\build\app.ll:382:37: error: '@.str.0' defined with type '[6 x i8]*' but e
21
21
 
22
22
  编译器生成的 LLVM IR 依赖不透明指针(opaque pointers),而有类型指针在 LLVM 16
23
23
  中被移除([LLVM 发布说明](https://github.com/llvm/llvm-project/blob/release/15.x/llvm/docs/ReleaseNotes.rst#changes-to-the-llvm-ir))。
24
- 用 `clang --version` 确认;如果机器上的系统 clang 太旧,装一个新版 LLVM 并让 xbintsc
25
- 用它:
24
+ `xbintsc build`/`run` 现在会先检查版本,直接停止并提示 "reports clang 15.0.2,
25
+ but xbintsc requires clang 16 or newer";`xbintsc doctor` 会打印
26
+ `status : ok` 或 `status : too old`(后者以非零码退出)。搜索工具链时会优先选择受支持
27
+ 的 clang——包括 Windows 上 Visual Studio 自带的 LLVM——所以装了新版时旧的
28
+ `/usr/bin/clang` 会被跳过。也可以显式指定:
26
29
 
27
30
  ```powershell
28
31
  $env:xbintsc_CLANG = "C:\Program Files\LLVM\bin\clang.exe"
@@ -110,6 +113,36 @@ clang 自身失败。抛出的消息包含完整的 clang 命令与 stderr——
110
113
  `llvm-rc` 或 `windres`;`doctor` 会报告找到了哪个,只有在确实请求了图标时缺失才是
111
114
  致命错误。
112
115
 
116
+ ## 怎么看堆栈
117
+
118
+ `Error.stack` 由 codegen 采集,而不是依赖 C 运行时的原生帧:每个非生成器函数
119
+ 在入口压入 `{名称, 文件, 行号}`,返回前弹出。帧形如
120
+
121
+ ```
122
+ Error: boom
123
+ at inner (app.ts:12)
124
+ at module (app.ts:3)
125
+ ```
126
+
127
+ 行号取函数声明行;最内层帧会更新为 `new Error(...)` 所在行。没有列号;生成器
128
+ 函数体因为会切换栈而不记录。原生致命信号会先打印 `xbintsc: fatal signal …`,
129
+ 再打印同一组帧,所以即使没有调试器也能看出崩溃时正在运行哪些 JS 函数。
130
+
131
+ ## 用 gdb / lldb / WinDbg 调试
132
+
133
+ `xbintsc build app.ts --debug` 会生成 LLVM 调试元数据,并把 `-g
134
+ -fno-omit-frame-pointer` 传给 clang,因此目标文件带有 DWARF(Linux/macOS)或
135
+ CodeView(Windows)行号表。函数符号保留源码名(如 `xt_fn_3_add`),每条语句都有
136
+ 对应的行位置:
137
+
138
+ ```bash
139
+ xbintsc build app.ts --debug
140
+ gdb ./build/app # 或 lldb ./build/app,Windows 用 WinDbg 打开 .exe
141
+ ```
142
+
143
+ 调试版二进制更大,并且与普通构建分开缓存(debug 标志参与缓存键)。`Error.stack`
144
+ 不需要 `--debug` 也能工作。
145
+
113
146
  ## 看起来不对、其实正常的构建行为
114
147
 
115
148
  ### 构建打印了 `(cached)` 并什么都没做
@@ -241,7 +241,7 @@ Location: `runtime/xt_alloc.c`, `runtime/xt_values.c`, `runtime/xt_containers.c`
241
241
 
242
242
  - Allocator: non-moving mark-sweep collector behind `xt_alloc` (explicit roots, subsystem root providers and a conservative C-stack scan).
243
243
  - Value construction: `xt_undefined/xt_null/xt_bool/xt_number/xt_string_new/xt_string_from_cstr`.
244
- - Strings: UTF-8 storage, concatenation, equality comparison, formatted number-to-string.
244
+ - Strings: UTF-8 storage, lazy cons-node concatenation (bytes are flattened on first observation, so append loops stay linear), equality comparison, formatted number-to-string.
245
245
  - Type conversion: `xt_truthy`, `xt_to_number`, `xt_to_string`, `xt_typeof`.
246
246
  - Arithmetic: `add/sub/mul/div/mod/pow/neg/pos`.
247
247
  - Bitwise: `and/or/xor/not/shl/shr/ushr` (including `ToInt32` semantics).
@@ -255,7 +255,7 @@ Location: `runtime/xt_alloc.c`, `runtime/xt_values.c`, `runtime/xt_containers.c`
255
255
  - Operator helpers: `xt_in` (`in`), `xt_delete` (`delete`), `xt_rest_args` (rest parameters / `arguments`).
256
256
  - Box: `box_new/get/set` (for closure-captured variables).
257
257
  - Functions and closures: `arg`, `closure_new/call/env/arity`.
258
- - Exceptions: `xt_try_enter` / `xt_try_exception` / `xt_try_leave` maintain the `_setjmp` frame stack; `xt_throw` long-jumps to the nearest `try` when a frame exists, otherwise prints `Uncaught ...` and exits.
258
+ - Exceptions: `xt_try_enter` / `xt_try_exception` / `xt_try_leave` maintain the `_setjmp` frame stack; `xt_throw` long-jumps to the nearest `try` when a frame exists, otherwise prints `Uncaught ...` and exits. Codegen also maintains a shadow call stack (function name, source file and line): `Error.stack` captures it, and a fatal-signal handler dumps the same frames on a native crash. `--debug` additionally emits `!DICompileUnit` / `!DISubprogram` / `!DILocation` metadata and compiles with `-g -fno-omit-frame-pointer`, so gdb/lldb/WinDbg map instructions back to source lines.
259
259
  - Output: `xt_print/xt_println/xt_console_log/info/warn/error` (Node-style inspect: arrays `[ a, b ]`, objects `{ k: v }`; `info`/`log` to stdout, `warn`/`error` to stderr), plus `dir/trace/assert/count/countReset/group/groupEnd/table/time/timeEnd/timeLog`.
260
260
  - Objects / functions: `xt_object` with a prototype chain, `xt_function` with a property bag (static members and `prototype`); `xt_new` (instantiation), `xt_instance_of` (prototype chain), `xt_object_freeze/is_frozen/from_entries`.
261
261
  - Standard library extensions (`xt_stdlib2.c`): extended array / string / number / object methods; `Object` / `Array` / `Number` / `String` statics; `JSON.parse` / `JSON.stringify`; `Map` / `Set`; `Date` (`gmtime_r`); `RegExp` (POSIX ERE `regcomp`/`regexec` `test`/`exec`).
@@ -346,7 +346,7 @@ const result = build("program.ts", { emit: "exe", outDir: "build" });
346
346
  Location: `tests/` (`lexer` / `parser` / `binder` / `codegen` / `driver` / `extensions` / `cli` / `e2e`)
347
347
 
348
348
  - Per-module unit tests; when `clang` is present, e2e really compiles and runs binaries, otherwise it is skipped automatically.
349
- - e2e coverage: arithmetic and printing, recursive functions, loops / arrays / string concatenation, closures capturing by reference, JS-style printing of objects / arrays, the Node `fs` extension via `import`, `switch` fall-through, array / string methods, `Math` and global functions and all `console` levels, default / rest parameters and `arguments`, `Object` helpers and spread and `in`/`delete`, `for...in` object key enumeration, `try/catch/finally`, optional chaining, classes and `new`/`this`/`static`/`extends`/`super`/`instanceof`, `async`/`await` and `Promise`, `Map`/`Set`/`JSON` and extended standard library, `for...of` over `Map`/`Set`, array `length` assignment and iterable spread, multi-file `import`/`export` (including `.js` specifiers and plain JavaScript sources), destructuring bindings and assignments, `enum`/`const enum`, regular-expression literals and `new Error(...)`, the `Error` family and `AggregateError`, generators and `Symbol` with custom `Symbol.iterator` iterables, typed arrays (element coercion, `from`/`of`, iteration and the prototype methods), and the global `fetch` (HTTP GET/POST, headers, redirects, JSON/text/binary bodies and `TypeError` rejection).
349
+ - e2e coverage: arithmetic and printing, recursive functions, loops / arrays / string concatenation, closures capturing by reference, JS-style printing of objects / arrays, the Node `fs` extension via `import`, `switch` fall-through, array / string methods, `Math` and global functions and all `console` levels, default / rest parameters and `arguments`, `Object` helpers and spread and `in`/`delete`, `for...in` object key enumeration, `try/catch/finally`, optional chaining, classes and `new`/`this`/`static`/`extends`/`super`/`instanceof`, `async`/`await` and `Promise`, `Map`/`Set`/`JSON` and extended standard library, `for...of` over `Map`/`Set`, array `length` assignment and iterable spread, multi-file `import`/`export` (including `.js` specifiers and plain JavaScript sources), destructuring bindings and assignments (including object rest), built-in `instanceof`, `enum`/`const enum`, regular-expression literals and `new Error(...)`, the `Error` family and `AggregateError`, generators and `Symbol` with custom `Symbol.iterator` iterables, typed arrays (element coercion, `from`/`of`, iteration and the prototype methods), and the global `fetch` (HTTP GET/POST, headers, redirects, JSON/text/binary bodies and `TypeError` rejection).
350
350
 
351
351
  ---
352
352
 
@@ -20,10 +20,19 @@ build/app.ll:382:37: error: '@.str.0' defined with type '[6 x i8]*' but expected
20
20
  ```
21
21
 
22
22
  Typed pointers were removed in LLVM 16 ([release notes](https://github.com/llvm/llvm-project/blob/release/15.x/llvm/docs/ReleaseNotes.rst#changes-to-the-llvm-ir)),
23
- so check `clang --version` before anything else, and point xbintsc at a newer
24
- build with `xbintsc_CLANG` when the system clang is older. `xbintsc doctor`
25
- reports the resolved toolchain and its version. Working around the limitation by
26
- compiling the IR elsewhere is not supported.
23
+ so xbintsc now **checks the version before it compiles anything**:
24
+
25
+ - `xbintsc build` / `run` stop immediately with an actionable error when the
26
+ resolved driver is older than 16, instead of emitting IR that cannot compile.
27
+ - `xbintsc doctor` prints `status : ok` or `status : too old` and exits non-zero
28
+ when the toolchain cannot build binaries, so scripts and CI can preflight it.
29
+ - The search prefers a clang >= 16: on Windows the LLVM bundled with Visual
30
+ Studio (`<VS install>\VC\Tools\Llvm\x64\bin\clang.exe`) is found even when an
31
+ older `clang` comes first on `PATH`. Set `xbintsc_CLANG` to override the
32
+ choice; an explicit older binary is rejected with a "too old" error rather
33
+ than silently ignored.
34
+
35
+ Working around the limitation by compiling the IR elsewhere is not supported.
27
36
 
28
37
  ## Summary
29
38