xbintsc 0.3.1 → 0.3.4

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 (144) hide show
  1. package/dist/src/ast/expressions.d.ts +8 -0
  2. package/dist/src/binder/binder.js +1 -0
  3. package/dist/src/binder/binder.js.map +1 -1
  4. package/dist/src/binder/references.d.ts +1 -1
  5. package/dist/src/binder/references.js +34 -5
  6. package/dist/src/binder/references.js.map +1 -1
  7. package/dist/src/binder/types.d.ts +4 -0
  8. package/dist/src/binder/types.js.map +1 -1
  9. package/dist/src/cli/main.js.map +1 -1
  10. package/dist/src/codegen/generator/calls/access.d.ts +9 -1
  11. package/dist/src/codegen/generator/calls/access.js +146 -13
  12. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  13. package/dist/src/codegen/generator/calls/closures.d.ts +1 -0
  14. package/dist/src/codegen/generator/calls/closures.js +25 -0
  15. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  16. package/dist/src/codegen/generator/calls/invocation.js +3 -1
  17. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  18. package/dist/src/codegen/generator/calls/literals.js +12 -4
  19. package/dist/src/codegen/generator/calls/literals.js.map +1 -1
  20. package/dist/src/codegen/generator/calls/super.js +4 -7
  21. package/dist/src/codegen/generator/calls/super.js.map +1 -1
  22. package/dist/src/codegen/generator/context.d.ts +6 -1
  23. package/dist/src/codegen/generator/context.js +13 -1
  24. package/dist/src/codegen/generator/context.js.map +1 -1
  25. package/dist/src/codegen/generator/expressions/assignment.js +1 -3
  26. package/dist/src/codegen/generator/expressions/assignment.js.map +1 -1
  27. package/dist/src/codegen/generator/expressions/primary.d.ts +3 -1
  28. package/dist/src/codegen/generator/expressions/primary.js +99 -1
  29. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  30. package/dist/src/codegen/generator/generator.js.map +1 -1
  31. package/dist/src/codegen/generator/module.js +25 -15
  32. package/dist/src/codegen/generator/module.js.map +1 -1
  33. package/dist/src/codegen/generator/state.d.ts +15 -0
  34. package/dist/src/codegen/generator/state.js +28 -1
  35. package/dist/src/codegen/generator/state.js.map +1 -1
  36. package/dist/src/codegen/generator/statements/control-flow.d.ts +3 -1
  37. package/dist/src/codegen/generator/statements/control-flow.js +85 -0
  38. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  39. package/dist/src/codegen/generator/statements/dispatch.js +15 -6
  40. package/dist/src/codegen/generator/statements/dispatch.js.map +1 -1
  41. package/dist/src/codegen/generator/statements/loops.d.ts +3 -0
  42. package/dist/src/codegen/generator/statements/loops.js +25 -11
  43. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  44. package/dist/src/codegen/generator/tables.d.ts +7 -0
  45. package/dist/src/codegen/generator/tables.js +41 -1
  46. package/dist/src/codegen/generator/tables.js.map +1 -1
  47. package/dist/src/driver/compiler.d.ts +1 -1
  48. package/dist/src/driver/compiler.js +33 -1
  49. package/dist/src/driver/compiler.js.map +1 -1
  50. package/dist/src/driver/modules.d.ts +4 -3
  51. package/dist/src/driver/modules.js +61 -4
  52. package/dist/src/driver/modules.js.map +1 -1
  53. package/dist/src/driver/toolchain.js +1 -1
  54. package/dist/src/driver/toolchain.js.map +1 -1
  55. package/dist/src/lexer/scanner.js.map +1 -1
  56. package/dist/src/parser/declarations/classes.js +4 -0
  57. package/dist/src/parser/declarations/classes.js.map +1 -1
  58. package/dist/src/parser/declarations/type-members.js.map +1 -1
  59. package/dist/src/parser/expressions.d.ts +2 -1
  60. package/dist/src/parser/expressions.js +10 -1
  61. package/dist/src/parser/expressions.js.map +1 -1
  62. package/dist/src/parser/helpers.js +2 -2
  63. package/dist/src/parser/helpers.js.map +1 -1
  64. package/dist/src/parser/literals.js +79 -6
  65. package/dist/src/parser/literals.js.map +1 -1
  66. package/dist/src/parser/modules.js.map +1 -1
  67. package/dist/src/parser/parser.js +0 -1
  68. package/dist/src/parser/parser.js.map +1 -1
  69. package/dist/src/parser/statements.d.ts +1 -0
  70. package/dist/src/parser/statements.js +13 -1
  71. package/dist/src/parser/statements.js.map +1 -1
  72. package/dist/src/parser/types.js +2 -2
  73. package/dist/src/parser/types.js.map +1 -1
  74. package/dist/tests/driver/toolchain.test.js +11 -1
  75. package/dist/tests/driver/toolchain.test.js.map +1 -1
  76. package/dist/tests/e2e/compile-node.test.js +3 -1
  77. package/dist/tests/e2e/compile-node.test.js.map +1 -1
  78. package/dist/tests/e2e/compile.test.js +465 -2
  79. package/dist/tests/e2e/compile.test.js.map +1 -1
  80. package/dist/tests/e2e/differential.test.d.ts +7 -0
  81. package/dist/tests/e2e/differential.test.js +581 -0
  82. package/dist/tests/e2e/differential.test.js.map +1 -0
  83. package/dist/tests/e2e/harness.d.ts +21 -0
  84. package/dist/tests/e2e/harness.js +26 -0
  85. package/dist/tests/e2e/harness.js.map +1 -1
  86. package/package.json +6 -1
  87. package/runtime/ext_node/fs/fs_ops.c +36 -1
  88. package/runtime/rt.h +17 -0
  89. package/runtime/rt_internal.h +88 -2
  90. package/runtime/xt_builtins.c +174 -6
  91. package/runtime/xt_containers.c +234 -42
  92. package/runtime/xt_generator.c +304 -0
  93. package/runtime/xt_io.c +170 -30
  94. package/runtime/xt_promise.c +6 -1
  95. package/runtime/xt_regex.h +105 -35
  96. package/runtime/xt_stdlib/dispatch.inc +255 -4
  97. package/runtime/xt_stdlib/strings.inc +17 -13
  98. package/runtime/xt_stdlib2/arrays.inc +126 -19
  99. package/runtime/xt_stdlib2/date.inc +9 -2
  100. package/runtime/xt_stdlib2/error.inc +162 -12
  101. package/runtime/xt_stdlib2/helpers.inc +4 -0
  102. package/runtime/xt_stdlib2/json.inc +19 -6
  103. package/runtime/xt_stdlib2/number-string-statics.inc +1 -1
  104. package/runtime/xt_stdlib2/numbers.inc +4 -5
  105. package/runtime/xt_stdlib2/objects.inc +29 -0
  106. package/runtime/xt_stdlib2/regexp-match.inc +293 -51
  107. package/runtime/xt_stdlib2/set.inc +58 -2
  108. package/runtime/xt_stdlib2/strings.inc +38 -0
  109. package/runtime/xt_symbol.c +149 -0
  110. package/runtime/xt_values.c +221 -15
  111. package/scripts/build-runtime.ts +1 -1
  112. package/src/ast/expressions.ts +8 -0
  113. package/src/binder/binder.ts +1 -1
  114. package/src/binder/references.ts +47 -4
  115. package/src/binder/types.ts +4 -0
  116. package/src/cli/main.ts +1 -2
  117. package/src/codegen/generator/calls/access.ts +158 -13
  118. package/src/codegen/generator/calls/closures.ts +24 -0
  119. package/src/codegen/generator/calls/invocation.ts +3 -1
  120. package/src/codegen/generator/calls/literals.ts +10 -4
  121. package/src/codegen/generator/calls/super.ts +6 -9
  122. package/src/codegen/generator/context.ts +14 -3
  123. package/src/codegen/generator/expressions/assignment.ts +1 -3
  124. package/src/codegen/generator/expressions/primary.ts +108 -2
  125. package/src/codegen/generator/generator.ts +0 -1
  126. package/src/codegen/generator/module.ts +24 -18
  127. package/src/codegen/generator/state.ts +44 -1
  128. package/src/codegen/generator/statements/control-flow.ts +86 -0
  129. package/src/codegen/generator/statements/dispatch.ts +18 -6
  130. package/src/codegen/generator/statements/loops.ts +29 -11
  131. package/src/codegen/generator/tables.ts +44 -1
  132. package/src/driver/compiler.ts +32 -2
  133. package/src/driver/modules.ts +64 -4
  134. package/src/driver/toolchain.ts +1 -1
  135. package/src/lexer/scanner.ts +0 -1
  136. package/src/parser/declarations/classes.ts +4 -0
  137. package/src/parser/declarations/type-members.ts +0 -2
  138. package/src/parser/expressions.ts +13 -1
  139. package/src/parser/helpers.ts +2 -2
  140. package/src/parser/literals.ts +82 -7
  141. package/src/parser/modules.ts +0 -1
  142. package/src/parser/parser.ts +0 -1
  143. package/src/parser/statements.ts +14 -0
  144. package/src/parser/types.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../tests/e2e/harness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../tests/e2e/harness.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xbintsc",
3
- "version": "0.3.1",
3
+ "version": "0.3.4",
4
4
  "description": "xbintsc - a TypeScript binary compiler (TypeScript -> LLVM IR -> native binary)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,15 +38,20 @@
38
38
  "runtime:clean": "node -e \"require('fs').rmSync('build/runtime-obj',{recursive:true,force:true});require('fs').rmSync('runtime/lib',{recursive:true,force:true})\"",
39
39
  "xbintsc": "tsx src/cli/main.ts",
40
40
  "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "lint": "eslint .",
41
42
  "test": "vitest run",
42
43
  "test:watch": "vitest",
43
44
  "test:e2e": "vitest run tests/e2e",
44
45
  "coverage": "vitest run --coverage"
45
46
  },
46
47
  "devDependencies": {
48
+ "@eslint/js": "^9.39.5",
47
49
  "@types/node": "^22.20.4",
50
+ "@vitest/coverage-v8": "^2.1.9",
51
+ "eslint": "^9.39.5",
48
52
  "tsx": "^4.19.2",
49
53
  "typescript": "^5.7.2",
54
+ "typescript-eslint": "^8.70.1",
50
55
  "vitest": "^2.1.8"
51
56
  },
52
57
  "engines": {
@@ -131,11 +131,46 @@ xt_value xt_node_exists(int32_t argc, xt_value *argv) {
131
131
  /* readdirSync */
132
132
  /* ------------------------------------------------------------------------- */
133
133
 
134
+ /* Defined alongside `statSync` further down; the `Dirent` objects built for
135
+ `readdirSync(path, { withFileTypes: true })` reuse the same closures. */
136
+ static void xt_fs_define_stat_method(xt_value object, const char *name, unsigned int mode);
137
+
138
+ /* Build the Node `Dirent`-shaped object (`name` plus stat predicates) for a
139
+ single directory entry. Types come from `lstat`, matching Node's `d_type`
140
+ based `Dirent` (a symlink reports `isSymbolicLink()` true). */
141
+ static xt_value xt_node_dirent_result(const char *dir, const char *name) {
142
+ size_t size = strlen(dir) + strlen(name) + 2;
143
+ char *full = (char *)malloc(size);
144
+ unsigned int mode = 0;
145
+ if (full) {
146
+ snprintf(full, size, "%s/%s", dir, name);
147
+ xt_fs_stat_t info;
148
+ if (xt_fs_lstat_fn(full, &info) == 0) mode = (unsigned int)info.st_mode;
149
+ free(full);
150
+ }
151
+
152
+ xt_value object = xt_object_new();
153
+ xt_object_set(object, xt_string_from_cstr("name"), xt_string_from_cstr(name));
154
+ xt_fs_define_stat_method(object, "isFile", mode);
155
+ xt_fs_define_stat_method(object, "isDirectory", mode);
156
+ xt_fs_define_stat_method(object, "isSymbolicLink", mode);
157
+ xt_fs_define_stat_method(object, "isFIFO", mode);
158
+ xt_fs_define_stat_method(object, "isSocket", mode);
159
+ xt_fs_define_stat_method(object, "isBlockDevice", mode);
160
+ xt_fs_define_stat_method(object, "isCharacterDevice", mode);
161
+ return object;
162
+ }
163
+
134
164
  xt_value xt_node_read_dir(int32_t argc, xt_value *argv) {
135
165
  if (argc < 1) return xt_undefined();
136
166
  const char *path = xt_string_data(xt_to_string(argv[0]));
137
167
  if (!path) return xt_undefined();
138
168
 
169
+ /* `readdirSync(path, { withFileTypes: true })` yields `Dirent` objects;
170
+ without the option the result is a plain array of entry names. */
171
+ int withFileTypes =
172
+ argc > 1 && XT_IS_OBJECT(argv[1]) && xt_truthy(xt_object_get_cstr(argv[1], "withFileTypes"));
173
+
139
174
  xt_fs_dir dir;
140
175
  if (!xt_fs_dir_open(&dir, path)) {
141
176
  xt_fs_error("open directory", path);
@@ -159,7 +194,7 @@ xt_value xt_node_read_dir(int32_t argc, xt_value *argv) {
159
194
  if (!grown) break;
160
195
  items = grown;
161
196
  }
162
- items[count++] = xt_string_from_cstr(name);
197
+ items[count++] = withFileTypes ? xt_node_dirent_result(path, name) : xt_string_from_cstr(name);
163
198
  }
164
199
  xt_fs_dir_close(&dir);
165
200
 
package/runtime/rt.h CHANGED
@@ -107,6 +107,7 @@ xt_value xt_closure_call(xt_value fn, int32_t argc, xt_value *argv);
107
107
  xt_value xt_call_with_this(xt_value fn, xt_value thisValue, int32_t argc, xt_value *argv);
108
108
  xt_value xt_closure_env(xt_value fn, int32_t index);
109
109
  int32_t xt_closure_arity(xt_value fn);
110
+ xt_value xt_function_set_metadata(xt_value fn, xt_value name, int32_t arity);
110
111
  xt_value xt_this(void);
111
112
  xt_value xt_new(xt_value ctor, int32_t argc, xt_value *argv);
112
113
  xt_value xt_instance_of(xt_value value, xt_value ctor);
@@ -169,6 +170,14 @@ xt_value xt_object_entries(xt_value obj);
169
170
  xt_value xt_object_assign(int32_t argc, xt_value *argv);
170
171
  xt_value xt_object_spread(xt_value target, xt_value source);
171
172
 
173
+ /* -- symbols -------------------------------------------------------------- */
174
+ /** Implements `Symbol(description)`. */
175
+ xt_value xt_symbol(int32_t argc, xt_value *argv);
176
+ /** Implements `Symbol.<name>(...)` statics (`for`, `keyFor`). */
177
+ xt_value xt_symbol_static(xt_value name, int32_t argc, xt_value *argv);
178
+ /** Reads a well-known symbol (`Symbol.iterator`, ...). */
179
+ xt_value xt_symbol_get(xt_value name);
180
+
172
181
  /* -- standard library dispatch -------------------------------------------- */
173
182
  /** Call `target[name](...)`, falling back to built-in Array/String methods. */
174
183
  xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *argv);
@@ -229,6 +238,10 @@ xt_value xt_parse_int(int32_t argc, xt_value *argv);
229
238
  xt_value xt_parse_float(int32_t argc, xt_value *argv);
230
239
  xt_value xt_is_nan(int32_t argc, xt_value *argv);
231
240
  xt_value xt_is_finite(int32_t argc, xt_value *argv);
241
+ xt_value xt_encode_uri_component(int32_t argc, xt_value *argv);
242
+ xt_value xt_encode_uri(int32_t argc, xt_value *argv);
243
+ xt_value xt_decode_uri_component(int32_t argc, xt_value *argv);
244
+ xt_value xt_decode_uri(int32_t argc, xt_value *argv);
232
245
  xt_value xt_number_ctor(int32_t argc, xt_value *argv);
233
246
  xt_value xt_string_ctor(int32_t argc, xt_value *argv);
234
247
  xt_value xt_boolean_ctor(int32_t argc, xt_value *argv);
@@ -263,6 +276,10 @@ xt_value xt_iter_value(xt_value value, xt_value index);
263
276
  /* -- generic member access ------------------------------------------------ */
264
277
  xt_value xt_get(xt_value target, xt_value key);
265
278
  xt_value xt_set(xt_value target, xt_value key, xt_value value);
279
+ /* Materialise a first-class runtime method value (`arr.map`) as an unbound
280
+ * closure that expects the receiver through `this`. Returns `XT_UNDEFINED` when
281
+ * `name` is not a method of `target`, so it can be used as a property fallback. */
282
+ xt_value xt_method_value(xt_value target, xt_value name);
266
283
 
267
284
  /* -- boxes (used for captured variables) ---------------------------------- */
268
285
  xt_value xt_box_new(xt_value value);
@@ -32,6 +32,7 @@
32
32
 
33
33
  #include "rt.h"
34
34
 
35
+ #include <setjmp.h>
35
36
  #include <stddef.h>
36
37
  #include <stdint.h>
37
38
 
@@ -47,6 +48,9 @@
47
48
  #define XT_OBJECT_KIND_REGEXP 9
48
49
  #define XT_OBJECT_KIND_SYMBOL 10
49
50
  #define XT_OBJECT_KIND_BIGINT 11
51
+ #define XT_OBJECT_KIND_ERROR 12
52
+ #define XT_OBJECT_KIND_GENERATOR 13
53
+ #define XT_OBJECT_KIND_ITERATOR 14
50
54
 
51
55
  /* Common header for every heap object. */
52
56
  typedef struct xt_header {
@@ -74,7 +78,8 @@ typedef struct {
74
78
  } xt_bigint;
75
79
 
76
80
  typedef struct {
77
- xt_string *key;
81
+ /* String or Symbol value (see `xt_to_property_key`). */
82
+ xt_value key;
78
83
  xt_value value;
79
84
  /* Accessor properties (`get x()` / `set x(v)`) store the functions here;
80
85
  * when set, `value` is ignored and property access invokes the getter. */
@@ -98,6 +103,9 @@ typedef struct {
98
103
  uint32_t length;
99
104
  uint32_t capacity;
100
105
  xt_value *items;
106
+ /* Named (non-index) properties such as `raw` on template strings or
107
+ * `index`/`input` on RegExp match results, stored in an `xt_object`. */
108
+ xt_value extra;
101
109
  } xt_array;
102
110
 
103
111
  typedef struct {
@@ -109,6 +117,9 @@ typedef struct {
109
117
  xt_string *name;
110
118
  xt_object *properties;
111
119
  xt_value prototype;
120
+ /* Set on generator function objects: calling the closure does not run the
121
+ * body, it creates a suspended generator (see xt_generator.c). */
122
+ uint8_t is_generator;
112
123
  } xt_function;
113
124
 
114
125
  /* Allocation (xt_alloc.c). */
@@ -121,6 +132,12 @@ int32_t xt_string_length(xt_string *s);
121
132
  int xt_string_equals(xt_string *a, xt_string *b);
122
133
  int32_t xt_to_int32(xt_value v);
123
134
 
135
+ /* ECMAScript number formatting (xt_values.c). */
136
+ void xt_number_to_js_string(double d, char *buffer, size_t size);
137
+ void xt_number_to_exponential(double d, int precision, char *buffer, size_t size);
138
+ void xt_number_to_precision(double d, int precision, char *buffer, size_t size);
139
+ void xt_number_to_fixed(double d, int precision, char *buffer, size_t size);
140
+
124
141
  /* BigInt runtime (xt_bigint.c). */
125
142
  int xt_is_bigint(xt_value value);
126
143
  double xt_bigint_to_double_value(xt_value value);
@@ -150,7 +167,19 @@ void xt_array_reserve(xt_array *array, uint32_t needed);
150
167
 
151
168
  /* Object helpers used by the standard library. */
152
169
  xt_object *xt_as_object(xt_value value);
153
- xt_property *xt_object_find_property(xt_object *obj, xt_string *key);
170
+ xt_property *xt_object_find_property(xt_object *obj, xt_value key);
171
+
172
+ /* Property keys are either strings or symbols. */
173
+ xt_value xt_to_property_key(xt_value key);
174
+ int xt_property_key_equals(xt_value a, xt_value b);
175
+
176
+ /* Symbols (xt_symbol.c). */
177
+ int xt_is_symbol(xt_value value);
178
+ xt_value xt_symbol_new(xt_value description);
179
+ xt_value xt_symbol_description(xt_value value);
180
+ xt_value xt_symbol_to_string(xt_value value);
181
+ xt_value xt_symbol_well_known(const char *name);
182
+ xt_value xt_object_own_property_symbols(xt_value value);
154
183
 
155
184
  /* Map / Set / Promise / Date / RegExp live in xt_stdlib.c and xt_promise.c. */
156
185
  int xt_is_promise(xt_value value);
@@ -160,13 +189,66 @@ int xt_is_date(xt_value value);
160
189
  int xt_is_regexp(xt_value value);
161
190
  int xt_regexp_find(xt_value regexp, xt_value input, int32_t start, int32_t *matchStart, int32_t *matchEnd);
162
191
  xt_value xt_regexp_exec(xt_value regexp, xt_value input);
192
+ xt_value xt_regexp_match(xt_value input, xt_value regexp);
163
193
  xt_value xt_regexp_replace(xt_value value, xt_value regexp, xt_value replacement);
194
+ xt_value xt_regexp_split(xt_value value, xt_value regexp, xt_value limit);
164
195
  xt_value xt_regexp_get_property(xt_value regexp, xt_value key);
165
196
  int32_t xt_map_size(xt_value value);
166
197
  int32_t xt_set_size(xt_value value);
167
198
  /* `for...of` iteration: dispatch over arrays, strings, Maps and Sets. */
168
199
  xt_value xt_iter_length(xt_value value);
169
200
  xt_value xt_iter_value(xt_value value, xt_value index);
201
+ /* Per-step iteration check. Generators pull the next value here; the index is
202
+ * ignored because the value is cached until `xt_iter_value` reads it. */
203
+ xt_value xt_iter_has(xt_value value, xt_value index);
204
+ /* Resolve the iteration protocol once: returns `value` for the built-in index
205
+ * protocols, or a wrapper around `value[Symbol.iterator]()` otherwise. */
206
+ xt_value xt_iter_open(xt_value value);
207
+
208
+ /* Stackful generators (xt_generator.c). */
209
+ int xt_is_generator(xt_value value);
210
+ xt_value xt_generator_new(xt_value function, xt_value thisValue, int32_t argc, xt_value *argv);
211
+ xt_value xt_generator_next(xt_value generator, xt_value sent);
212
+ xt_value xt_generator_return(xt_value generator, xt_value value);
213
+ xt_value xt_generator_throw(xt_value generator, xt_value error);
214
+ xt_value xt_yield(xt_value value);
215
+ xt_value xt_yield_star(xt_value delegate);
216
+ int xt_generator_has_next(xt_value generator);
217
+ xt_value xt_generator_iter_value(xt_value generator);
218
+
219
+ /* Exception-frame plumbing shared with the generator runtime. The struct is
220
+ * public so a coroutine can `_setjmp` its own boundary directly (a `setjmp`
221
+ * must run in the frame it returns to, never in a helper). */
222
+ typedef struct xt_try_frame {
223
+ jmp_buf buf;
224
+ struct xt_try_frame *prev;
225
+ xt_value exception;
226
+ } xt_try_frame;
227
+ /* Call `_setjmp` the way the active `<setjmp.h>` declares it. The two Windows
228
+ * C runtimes differ:
229
+ *
230
+ * - MSVC/UCRT declares `_setjmp(jmp_buf)` with one visible argument and lets
231
+ * clang treat it as a built-in that injects the caller's frame address
232
+ * (`@llvm.frameaddress(0)`) as a hidden second argument. Writing the frame
233
+ * by hand is a compile error ("too many arguments to function call").
234
+ * - MinGW-w64 (the vendored llvm-mingw toolchain) declares
235
+ * `_setjmp(jmp_buf, void *frame)` itself, so the frame must be passed
236
+ * explicitly -- exactly what its own `setjmp` macro does.
237
+ *
238
+ * The generated IR always emits the two-argument form, because it is already
239
+ * IR and clang will not rewrite it. `_setjmp` (rather than the `setjmp` macro)
240
+ * is used so it pairs with the plain `longjmp` in `xt_throw`. */
241
+ #if defined(_WIN32) && !defined(__MINGW32__)
242
+ #define xt_try_setjmp(framePtr) _setjmp(((xt_try_frame *)(framePtr))->buf)
243
+ #elif defined(_WIN32) && defined(__aarch64__)
244
+ #define xt_try_setjmp(framePtr) _setjmpex(((xt_try_frame *)(framePtr))->buf, __builtin_sponentry())
245
+ #elif defined(_WIN32)
246
+ #define xt_try_setjmp(framePtr) _setjmp(((xt_try_frame *)(framePtr))->buf, __builtin_frame_address(0))
247
+ #else
248
+ #define xt_try_setjmp(framePtr) _setjmp(((xt_try_frame *)(framePtr))->buf)
249
+ #endif
250
+ void *xt_try_mark(void);
251
+ void xt_try_restore(void *mark);
170
252
 
171
253
  /* -- collection / date / regexp representations --------------------------- */
172
254
  typedef struct {
@@ -201,6 +283,10 @@ xt_value xt_ext_array_method(xt_value target, const char *method, int32_t argc,
201
283
  xt_value xt_ext_string_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
202
284
  xt_value xt_ext_number_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
203
285
  xt_value xt_ext_object_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
286
+
287
+ /* Error family helpers (xt_stdlib2.c). */
288
+ xt_value xt_error_to_string(xt_value error);
289
+ xt_value xt_aggregate_error_ctor(int32_t argc, xt_value *argv);
204
290
  xt_value xt_ext_container_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
205
291
  xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
206
292
 
@@ -8,6 +8,7 @@
8
8
  #include "rt_internal.h"
9
9
 
10
10
  #include <math.h>
11
+ #include <stdio.h>
11
12
  #include <stdlib.h>
12
13
  #include <string.h>
13
14
 
@@ -19,7 +20,9 @@ xt_value xt_object_values(xt_value value) {
19
20
  xt_value result = xt_array_new(0, NULL);
20
21
  if (!XT_IS_OBJECT(value)) return result;
21
22
  xt_object *obj = (xt_object *)XT_GET_PTR(value);
22
- for (uint32_t i = 0; i < obj->count; i++) xt_array_push(result, obj->properties[i].value);
23
+ for (uint32_t i = 0; i < obj->count; i++) {
24
+ if (XT_IS_STRING(obj->properties[i].key)) xt_array_push(result, obj->properties[i].value);
25
+ }
23
26
  return result;
24
27
  }
25
28
 
@@ -28,8 +31,9 @@ xt_value xt_object_entries(xt_value value) {
28
31
  if (!XT_IS_OBJECT(value)) return result;
29
32
  xt_object *obj = (xt_object *)XT_GET_PTR(value);
30
33
  for (uint32_t i = 0; i < obj->count; i++) {
34
+ if (!XT_IS_STRING(obj->properties[i].key)) continue;
31
35
  xt_value pair = xt_array_new(0, NULL);
32
- xt_array_push(pair, XT_FROM_PTR(XT_TAG_STRING, obj->properties[i].key));
36
+ xt_array_push(pair, obj->properties[i].key);
33
37
  xt_array_push(pair, obj->properties[i].value);
34
38
  xt_array_push(result, pair);
35
39
  }
@@ -44,7 +48,7 @@ xt_value xt_object_assign(int32_t argc, xt_value *argv) {
44
48
  if (!XT_IS_OBJECT(argv[i])) continue;
45
49
  xt_object *source = (xt_object *)XT_GET_PTR(argv[i]);
46
50
  for (uint32_t j = 0; j < source->count; j++) {
47
- xt_object_set(target, XT_FROM_PTR(XT_TAG_STRING, source->properties[j].key), source->properties[j].value);
51
+ xt_object_set(target, source->properties[j].key, source->properties[j].value);
48
52
  }
49
53
  }
50
54
  return target;
@@ -119,6 +123,140 @@ xt_value xt_is_finite(int32_t argc, xt_value *argv) {
119
123
  return xt_bool(!isnan(value) && !isinf(value));
120
124
  }
121
125
 
126
+ /* ------------------------------------------------------------------------- */
127
+ /* URI encoding / decoding (ECMAScript 19.2.6) */
128
+ /* ------------------------------------------------------------------------- */
129
+
130
+ static _Noreturn void xt_throw_uri_error(const char *message) {
131
+ char buffer[96];
132
+ snprintf(buffer, sizeof(buffer), "URIError: %s", message);
133
+ xt_throw(xt_string_from_cstr(buffer));
134
+ abort();
135
+ }
136
+
137
+ static int xt_uri_is_kept(const char *allowed, unsigned char c) {
138
+ return c < 0x80 && c != 0 && strchr(allowed, (int)c) != NULL;
139
+ }
140
+
141
+ static xt_value xt_uri_encode(xt_value input, const char *allowed) {
142
+ xt_string *s = xt_as_string(xt_to_string(input));
143
+ static const char hex[] = "0123456789ABCDEF";
144
+ char *out = (char *)malloc((size_t)s->length * 3 + 1);
145
+ if (!out) {
146
+ fprintf(stderr, "xbintsc: out of memory\n");
147
+ abort();
148
+ }
149
+ size_t written = 0;
150
+ for (uint32_t i = 0; i < s->length; i++) {
151
+ unsigned char c = (unsigned char)s->data[i];
152
+ if (xt_uri_is_kept(allowed, c)) {
153
+ out[written++] = (char)c;
154
+ } else {
155
+ out[written++] = '%';
156
+ out[written++] = hex[(c >> 4) & 0xF];
157
+ out[written++] = hex[c & 0xF];
158
+ }
159
+ }
160
+ xt_value result = xt_string_new(out, written);
161
+ free(out);
162
+ return result;
163
+ }
164
+
165
+ static int xt_hex_value(int c) {
166
+ if (c >= '0' && c <= '9') return c - '0';
167
+ if (c >= 'A' && c <= 'F') return c - 'A' + 10;
168
+ if (c >= 'a' && c <= 'f') return c - 'a' + 10;
169
+ return -1;
170
+ }
171
+
172
+ /* Decode percent-escapes as UTF-8. When `component` is false (`decodeURI`),
173
+ * escapes for reserved characters are copied through unchanged. */
174
+ static xt_value xt_uri_decode(xt_value input, int component) {
175
+ xt_string *s = xt_as_string(xt_to_string(input));
176
+ char *out = (char *)malloc((size_t)s->length + 1);
177
+ if (!out) {
178
+ fprintf(stderr, "xbintsc: out of memory\n");
179
+ abort();
180
+ }
181
+ size_t written = 0;
182
+ uint32_t i = 0;
183
+ while (i < s->length) {
184
+ unsigned char c = (unsigned char)s->data[i];
185
+ if (c != '%') {
186
+ out[written++] = (char)c;
187
+ i++;
188
+ continue;
189
+ }
190
+ if (i + 2 >= s->length) xt_throw_uri_error("URI malformed");
191
+ int h1 = xt_hex_value((unsigned char)s->data[i + 1]);
192
+ int h2 = xt_hex_value((unsigned char)s->data[i + 2]);
193
+ if (h1 < 0 || h2 < 0) xt_throw_uri_error("URI malformed");
194
+ unsigned char b = (unsigned char)((h1 << 4) | h2);
195
+ if (b < 0x80) {
196
+ if (!component && xt_uri_is_kept(";/?:@&=+$,#", b)) {
197
+ out[written++] = s->data[i];
198
+ out[written++] = s->data[i + 1];
199
+ out[written++] = s->data[i + 2];
200
+ } else {
201
+ out[written++] = (char)b;
202
+ }
203
+ i += 3;
204
+ continue;
205
+ }
206
+ int extra;
207
+ if (b >= 0xC2 && b <= 0xDF) extra = 1;
208
+ else if (b >= 0xE0 && b <= 0xEF) extra = 2;
209
+ else if (b >= 0xF0 && b <= 0xF4) extra = 3;
210
+ else xt_throw_uri_error("URI malformed");
211
+ char seq[4];
212
+ seq[0] = (char)b;
213
+ for (int k = 1; k <= extra; k++) {
214
+ uint32_t pos = i + (uint32_t)k * 3;
215
+ if (pos + 2 >= s->length) xt_throw_uri_error("URI malformed");
216
+ if (s->data[pos] != '%') xt_throw_uri_error("URI malformed");
217
+ int c1 = xt_hex_value((unsigned char)s->data[pos + 1]);
218
+ int c2 = xt_hex_value((unsigned char)s->data[pos + 2]);
219
+ if (c1 < 0 || c2 < 0) xt_throw_uri_error("URI malformed");
220
+ unsigned char cb = (unsigned char)((c1 << 4) | c2);
221
+ if ((cb & 0xC0) != 0x80) xt_throw_uri_error("URI malformed");
222
+ seq[k] = (char)cb;
223
+ }
224
+ uint32_t codePoint;
225
+ if (extra == 1) codePoint = ((uint32_t)(b & 0x1F) << 6) | ((uint32_t)seq[1] & 0x3F);
226
+ else if (extra == 2)
227
+ codePoint = ((uint32_t)(b & 0x0F) << 12) | (((uint32_t)seq[1] & 0x3F) << 6) | ((uint32_t)seq[2] & 0x3F);
228
+ else
229
+ codePoint = ((uint32_t)(b & 0x07) << 18) | (((uint32_t)seq[1] & 0x3F) << 12) |
230
+ (((uint32_t)seq[2] & 0x3F) << 6) | ((uint32_t)seq[3] & 0x3F);
231
+ uint32_t minimum = extra == 1 ? 0x80u : (extra == 2 ? 0x800u : 0x10000u);
232
+ if (codePoint < minimum || codePoint > 0x10FFFF || (codePoint >= 0xD800 && codePoint <= 0xDFFF))
233
+ xt_throw_uri_error("URI malformed");
234
+ for (int k = 0; k <= extra; k++) out[written++] = seq[k];
235
+ i += (uint32_t)(extra + 1) * 3;
236
+ }
237
+ xt_value result = xt_string_new(out, written);
238
+ free(out);
239
+ return result;
240
+ }
241
+
242
+ xt_value xt_encode_uri_component(int32_t argc, xt_value *argv) {
243
+ return xt_uri_encode(xt_arg_at(argc, argv, 0),
244
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()");
245
+ }
246
+
247
+ xt_value xt_encode_uri(int32_t argc, xt_value *argv) {
248
+ return xt_uri_encode(xt_arg_at(argc, argv, 0),
249
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'();,/?:@&=+$#");
250
+ }
251
+
252
+ xt_value xt_decode_uri_component(int32_t argc, xt_value *argv) {
253
+ return xt_uri_decode(xt_arg_at(argc, argv, 0), /* component */ 1);
254
+ }
255
+
256
+ xt_value xt_decode_uri(int32_t argc, xt_value *argv) {
257
+ return xt_uri_decode(xt_arg_at(argc, argv, 0), /* component */ 0);
258
+ }
259
+
122
260
  xt_value xt_number_ctor(int32_t argc, xt_value *argv) {
123
261
  if (argc == 0) return xt_number(0);
124
262
  return xt_number(xt_to_number(argv[0]));
@@ -126,6 +264,7 @@ xt_value xt_number_ctor(int32_t argc, xt_value *argv) {
126
264
 
127
265
  xt_value xt_string_ctor(int32_t argc, xt_value *argv) {
128
266
  if (argc == 0) return xt_string_from_cstr("");
267
+ if (xt_is_symbol(argv[0])) return xt_symbol_to_string(argv[0]);
129
268
  return xt_to_string(argv[0]);
130
269
  }
131
270
 
@@ -153,18 +292,29 @@ XT_BUILTIN_TRAMPOLINE(xt_builtin_value_boolean, xt_boolean_ctor)
153
292
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_number, xt_number_ctor)
154
293
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_bigint, xt_bigint_ctor)
155
294
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_string, xt_string_ctor)
295
+ XT_BUILTIN_TRAMPOLINE(xt_builtin_value_symbol, xt_symbol)
156
296
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_parseInt, xt_parse_int)
157
297
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_parseFloat, xt_parse_float)
158
298
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_isNaN, xt_is_nan)
159
299
  XT_BUILTIN_TRAMPOLINE(xt_builtin_value_isFinite, xt_is_finite)
300
+ XT_BUILTIN_TRAMPOLINE(xt_builtin_value_encodeURIComponent, xt_encode_uri_component)
301
+ XT_BUILTIN_TRAMPOLINE(xt_builtin_value_encodeURI, xt_encode_uri)
302
+ XT_BUILTIN_TRAMPOLINE(xt_builtin_value_decodeURIComponent, xt_decode_uri_component)
303
+ XT_BUILTIN_TRAMPOLINE(xt_builtin_value_decodeURI, xt_decode_uri)
160
304
 
161
305
  xt_value xt_in(xt_value key, xt_value value) {
162
306
  if (XT_IS_OBJECT(value)) return xt_object_has(value, key);
163
307
  if (XT_IS_ARRAY(value)) {
308
+ if (xt_is_symbol(key)) {
309
+ xt_array *array = (xt_array *)XT_GET_PTR(value);
310
+ if (!XT_IS_OBJECT(array->extra)) return XT_FALSE;
311
+ return xt_object_has_own(array->extra, key);
312
+ }
164
313
  int32_t index = xt_to_int32(key);
165
314
  return xt_bool(index >= 0 && (uint32_t)index < xt_as_array(value)->length);
166
315
  }
167
316
  if (XT_IS_STRING(value)) {
317
+ if (xt_is_symbol(key)) return XT_FALSE;
168
318
  xt_string *s = xt_as_string(value);
169
319
  xt_string *k = xt_as_string(xt_to_string(key));
170
320
  if (k->length == 6 && memcmp(k->data, "length", 6) == 0) return XT_TRUE;
@@ -177,9 +327,9 @@ xt_value xt_in(xt_value key, xt_value value) {
177
327
  xt_value xt_delete(xt_value value, xt_value key) {
178
328
  if (XT_IS_OBJECT(value)) {
179
329
  xt_object *obj = (xt_object *)XT_GET_PTR(value);
180
- xt_string *k = xt_as_string(xt_to_string(key));
330
+ xt_value k = xt_to_property_key(key);
181
331
  for (uint32_t i = 0; i < obj->count; i++) {
182
- if (xt_string_equals(obj->properties[i].key, k)) {
332
+ if (xt_property_key_equals(obj->properties[i].key, k)) {
183
333
  for (uint32_t j = i + 1; j < obj->count; j++) obj->properties[j - 1] = obj->properties[j];
184
334
  obj->count--;
185
335
  break;
@@ -188,7 +338,7 @@ xt_value xt_delete(xt_value value, xt_value key) {
188
338
  return XT_TRUE;
189
339
  }
190
340
  if (XT_IS_ARRAY(value)) {
191
- xt_array_set(value, key, XT_UNDEFINED);
341
+ if (!xt_is_symbol(key)) xt_array_set(value, key, XT_UNDEFINED);
192
342
  return XT_TRUE;
193
343
  }
194
344
  return XT_TRUE;
@@ -216,6 +366,7 @@ xt_value xt_closure_new(void *fn, int32_t env_count, xt_value *env) {
216
366
  function->code = (xt_code_fn)fn;
217
367
  function->environment_count = env_count;
218
368
  function->arity = -1;
369
+ function->name = NULL;
219
370
  function->properties = NULL;
220
371
  function->environment = NULL;
221
372
  function->prototype = XT_UNDEFINED;
@@ -236,6 +387,9 @@ xt_value xt_call_with_this(xt_value value, xt_value thisValue, int32_t argc, xt_
236
387
  return XT_UNDEFINED;
237
388
  }
238
389
  xt_function *function = (xt_function *)XT_GET_PTR(value);
390
+ /* Calling a generator function returns a suspended generator instead of
391
+ * running the body. */
392
+ if (function->is_generator) return xt_generator_new(value, thisValue, argc, argv);
239
393
  /* The closure value itself is threaded through as `env` so the callee can
240
394
  * read its captures with xt_closure_env(env, i). */
241
395
  return function->code(thisValue, value, argc, argv);
@@ -248,6 +402,11 @@ xt_value xt_function_set_prototype(xt_value value, xt_value proto) {
248
402
  return value;
249
403
  }
250
404
 
405
+ xt_value xt_function_set_generator(xt_value value) {
406
+ if (XT_IS_FUNCTION(value)) ((xt_function *)XT_GET_PTR(value))->is_generator = 1;
407
+ return value;
408
+ }
409
+
251
410
  xt_value xt_function_get_prototype(xt_value value) {
252
411
  if (XT_IS_FUNCTION(value)) return ((xt_function *)XT_GET_PTR(value))->prototype;
253
412
  return XT_UNDEFINED;
@@ -294,3 +453,12 @@ int32_t xt_closure_arity(xt_value value) {
294
453
  return ((xt_function *)XT_GET_PTR(value))->arity;
295
454
  }
296
455
 
456
+ xt_value xt_function_set_metadata(xt_value value, xt_value name, int32_t arity) {
457
+ if (XT_IS_FUNCTION(value)) {
458
+ xt_function *function = (xt_function *)XT_GET_PTR(value);
459
+ function->arity = arity;
460
+ function->name = XT_IS_STRING(name) ? xt_as_string(name) : NULL;
461
+ }
462
+ return value;
463
+ }
464
+