xbintsc 0.3.87 → 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.
- package/AGENTS.md +8 -4
- package/README.md +4 -3
- package/README.zh-CN.md +2 -2
- package/dist/src/codegen/generator/calls/access.js +6 -2
- package/dist/src/codegen/generator/calls/access.js.map +1 -1
- package/dist/src/codegen/generator/calls/closures.js +4 -0
- package/dist/src/codegen/generator/calls/closures.js.map +1 -1
- package/dist/src/codegen/generator/calls/invocation.js +4 -3
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
- package/dist/src/codegen/generator/expressions/primary.js +6 -1
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
- package/dist/src/codegen/generator/module.d.ts +0 -1
- package/dist/src/codegen/generator/module.js +10 -10
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.js +4 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.js +1 -3
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +9 -0
- package/dist/src/codegen/generator/tables.js +74 -2
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +2 -2
- package/dist/src/driver/compiler.js +4 -1
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/tests/codegen/closures.test.js +8 -0
- package/dist/tests/codegen/closures.test.js.map +1 -1
- package/dist/tests/e2e/async-await.test.d.ts +10 -0
- package/dist/tests/e2e/async-await.test.js +247 -0
- package/dist/tests/e2e/async-await.test.js.map +1 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js +46 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
- package/dist/tests/e2e/string-utf16.test.d.ts +6 -0
- package/dist/tests/e2e/string-utf16.test.js +133 -0
- package/dist/tests/e2e/string-utf16.test.js.map +1 -0
- package/doc/ai/contributing.md +9 -7
- package/doc/ai/extensions.md +3 -2
- package/doc/ai/language-support.md +11 -8
- package/doc/ai/troubleshooting.md +4 -3
- package/doc/ai/zh-CN/contributing.md +5 -5
- package/doc/ai/zh-CN/extensions.md +2 -1
- package/doc/ai/zh-CN/language-support.md +11 -8
- package/doc/ai/zh-CN/troubleshooting.md +3 -2
- package/doc/implemented.md +15 -12
- package/doc/unimplemented.md +11 -10
- package/doc/zh-CN/implemented.md +14 -11
- package/doc/zh-CN/unimplemented.md +11 -10
- package/package.json +1 -1
- package/runtime/rt.h +32 -0
- package/runtime/rt_internal.h +99 -10
- package/runtime/xt_alloc.c +6 -0
- package/runtime/xt_async.c +197 -0
- package/runtime/xt_builtins.c +40 -36
- package/runtime/xt_constructors.c +389 -0
- package/runtime/xt_containers/access.inc +47 -11
- package/runtime/xt_containers/arrays.inc +26 -2
- package/runtime/xt_containers/objects.inc +202 -5
- package/runtime/xt_coroutine.c +212 -0
- package/runtime/xt_generator.c +31 -162
- package/runtime/xt_io/inspect.inc +35 -2
- package/runtime/xt_promise.c +62 -17
- package/runtime/xt_stdlib/dispatch.inc +18 -2
- package/runtime/xt_stdlib/strings.inc +73 -16
- package/runtime/xt_stdlib2/array-statics.inc +3 -3
- package/runtime/xt_stdlib2/error.inc +11 -0
- package/runtime/xt_stdlib2/json.inc +44 -15
- package/runtime/xt_stdlib2/number-string-statics.inc +24 -15
- package/runtime/xt_stdlib2/objects.inc +1 -1
- package/runtime/xt_stdlib2/regexp-match.inc +2 -2
- package/runtime/xt_stdlib2/set.inc +6 -0
- package/runtime/xt_stdlib2/strings.inc +70 -40
- package/runtime/xt_typed_array/construction.inc +43 -2
- package/runtime/xt_typed_array.c +4 -0
- package/runtime/xt_values/constructors.inc +8 -0
- package/runtime/xt_values/strings.inc +19 -3
- package/runtime/xt_values/utf16.inc +340 -0
- package/runtime/xt_values.c +1 -0
- package/src/codegen/generator/calls/access.ts +7 -2
- package/src/codegen/generator/calls/closures.ts +3 -0
- package/src/codegen/generator/calls/invocation.ts +4 -3
- package/src/codegen/generator/expressions/primary.ts +6 -1
- package/src/codegen/generator/module.ts +10 -12
- package/src/codegen/generator/state.ts +4 -0
- package/src/codegen/generator/statements/control-flow.ts +1 -2
- package/src/codegen/generator/tables.ts +84 -2
- package/src/driver/compiler.ts +4 -1
package/doc/zh-CN/implemented.md
CHANGED
|
@@ -190,7 +190,7 @@ xt_value fn(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
|
|
|
190
190
|
|
|
191
191
|
- `thisValue` 作为首个 ABI 参数线程化(异常安全、支持嵌套);箭头函数从环境额外槽位词法继承 `this`。
|
|
192
192
|
- 闭包通过 `env` 线程化捕获变量(引用传递,box 包装),直接调用与闭包调用共用同一代码路径。
|
|
193
|
-
- `xt_object` 带原型字段,属性查找沿原型链;`xt_function` 带 `prototype`
|
|
193
|
+
- `xt_object` 带原型字段,属性查找沿原型链;`xt_function` 带 `prototype` 与属性包(静态成员)。`xt_array` 也带 `[[Prototype]]`(Array.prototype)。`Object.prototype` 是普通对象的原型根,提供 `hasOwnProperty` / `toString` / `valueOf` / `isPrototypeOf` / `propertyIsEnumerable` / `__proto__`;`Object.getPrototypeOf({}) === Object.prototype`。
|
|
194
194
|
|
|
195
195
|
---
|
|
196
196
|
|
|
@@ -211,12 +211,13 @@ xt_value fn(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
|
|
|
211
211
|
- 数组字面量(含展开 `[...]`)、对象字面量(含简写 / 方法 / 对象展开 `{...obj}`)
|
|
212
212
|
- 类型化数组(`Uint8Array`、`Int8Array`、`Uint8ClampedArray`、`Uint16Array`、`Int16Array`、`Uint32Array`、`Int32Array`、`Float32Array`、`Float64Array`):构造(`new X(n)` / `new X(可迭代)` / `X.from` / `X.of`)、`length` / `byteLength` / `byteOffset` / `BYTES_PER_ELEMENT`、按元素类型强制的读写(`ToIntN` / `ToUintN`、`Uint8ClampedArray` 舍入、`Float32` 单精度舍入)以及原型方法 `fill` / `set` / `slice` / `subarray` / `join` / `toString` / `indexOf` / `lastIndexOf` / `includes` / `forEach` / `map` / `filter` / `every` / `some` / `find` / `findIndex` / `reduce` / `reverse` / `sort` / `copyWithin` / `at` / `keys` / `values` / `entries`。有意保留的差异见未实现文档(`subarray` 返回副本、迭代器方法返回数组、无 `ArrayBuffer`/`DataView`)。
|
|
213
213
|
- 属性访问(含 `length` 特判、`Math` 常量)、元素访问、调用
|
|
214
|
+
- 一等公民内建构造器(`const A = Array`、`const M = Map`、`const E = TypeError`、类型化数组):裸引用下降为 `xt_builtin_constructor`,得到带 `name` / `length`、`prototype` 与静态成员(`A.isArray`、`A.from`、`M.prototype` 等)的缓存函数。通过别名调用或 `new` 会分派到同一运行时构造器,`x instanceof A` 沿共享原型链判断。
|
|
214
215
|
- 可选链 `?.` / `?.[]` / `?.()`:以空值判断短路到 `undefined`
|
|
215
216
|
- `delete`、`in`、`instanceof`
|
|
216
217
|
- `this`(保存到函数 `%saved.this`;箭头函数从环境槽读)、`super`(`super.x` / `super(...)`)、`new`、`await`
|
|
217
218
|
- 闭包(箭头函数 / 函数表达式)与捕获环境构建
|
|
218
219
|
- 类:构造器闭包 + 原型对象,存入 LLVM 全局(`@class.<id>`);实例字段在构造器体前初始化;`static` 成员存于构造器属性包;`extends` 设置原型链;`super(...)` 通过原型上的隐藏 `__ctor` 调用。
|
|
219
|
-
- `async
|
|
220
|
+
- `async`:闭包用 `xt_function_set_async` 标记;调用时在栈式协程(`xt_coroutine.c`、`xt_async.c`)上运行函数体并立即返回 promise。函数体同步执行到第一个等待**未 settle** promise 的 `await` 后挂起;promise settle 时排入微任务恢复协程。逃出函数体的异常会让该 promise reject,而不是同步抛出。`await` 非 promise 或已 settle 的值仍走同步快路径,rejection 触发异常。
|
|
220
221
|
- 标准库调用:`console.*`、`Math.*`、`Object.*`、数组 / 字符串方法统一走 `xt_call_method` / `xt_math_call` / `xt_object_*`;`JSON`/`Date`/`Map`/`Set`/`RegExp`/`Promise` 静态与构造走对应 `xt_*`;全局函数(`parseInt` 等)走 `xt_parse_int` 等。
|
|
221
222
|
- 全局字符串池(`@.str.N` 私有常量,UTF-8 转义)。
|
|
222
223
|
- 内置调用:`console.log` / `info` / `warn` / `error`、`Math.*`、`Object.*`、数组 / 字符串方法、全局函数、扩展 builtins(统一 `(argc, argv)` ABI)。
|
|
@@ -228,18 +229,19 @@ xt_value fn(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
|
|
|
228
229
|
## 8. C 运行时(Runtime,已实现)
|
|
229
230
|
|
|
230
231
|
实现位置:`runtime/xt_alloc.c`、`runtime/xt_values.c`、`runtime/xt_containers.c`、
|
|
231
|
-
`runtime/xt_stdlib.c`、`runtime/xt_stdlib2.c`、`runtime/xt_promise.c`、`runtime/
|
|
232
|
+
`runtime/xt_stdlib.c`、`runtime/xt_stdlib2.c`、`runtime/xt_promise.c`、`runtime/xt_async.c`、
|
|
233
|
+
`runtime/xt_coroutine.c`、`runtime/xt_builtins.c`、
|
|
232
234
|
`runtime/xt_io.c`,共享私有头 `runtime/rt_internal.h`;公开 ABI 见 `runtime/rt.h`。
|
|
233
235
|
|
|
234
236
|
- 分配器:`xt_alloc` 背后的非移动标记-清扫回收器(显式根、子系统根提供者与保守 C 栈扫描)。
|
|
235
237
|
- 值构造:`xt_undefined/xt_null/xt_bool/xt_number/xt_string_new/xt_string_from_cstr`。
|
|
236
|
-
- 字符串:UTF-8
|
|
238
|
+
- 字符串:UTF-8 存储,对外呈现 JavaScript 的 UTF-16 视图(`length`、索引、`slice`、`indexOf`、`split`、`padStart`、`codePointAt` 按码元计数;`for...of` 与 `Array.from` 按码点计数;孤立代理项以 WTF-8 保存,并在拼接时重新组合)、惰性 cons 节点拼接(首次观察时才扁平化,因此循环追加保持线性复杂度)、相等比较、格式化数字转字符串。`xt_string_length` 供 I/O 使用,返回字节数;`xt_string_utf16_length` 返回 JavaScript 长度。
|
|
237
239
|
- 类型转换:`xt_truthy`、`xt_to_number`、`xt_to_string`、`xt_typeof`。
|
|
238
240
|
- 算术:`add/sub/mul/div/mod/pow/neg/pos`。
|
|
239
241
|
- 位运算:`and/or/xor/not/shl/shr/ushr`(含 `ToInt32` 语义)。
|
|
240
242
|
- 比较:`lt/le/gt/ge`、宽松 / 严格相等、`not`、`is_nullish`。
|
|
241
243
|
- 对象:线性属性列表,`object_new/get/set/has/keys/values/entries/assign/spread`。
|
|
242
|
-
- 数组:`array_new/get/set/push/length/spread`;对 `arr.length` 赋值会截断 / 扩展(与 JS 一致);`iter_length` / `iter_value`
|
|
244
|
+
- 数组:`array_new/get/set/push/length/spread`;对 `arr.length` 赋值会截断 / 扩展(与 JS 一致);`iter_length` / `iter_value` 为数组、字符串(按码点)、`Map`、`Set` 提供统一迭代视图。
|
|
243
245
|
- 类型化数组(`xt_typed_array.c`):以属性包对象表示,每种元素类型一个原型;读取返回已存值,写入按元素类型强制转换;提供 `from` / `of` 静态方法与完整原型方法集;`subarray` 返回副本。
|
|
244
246
|
- Symbol(`xt_symbol.c`):`Symbol(description)` 原始值(`XT_OBJECT_KIND_SYMBOL`)、13 个著名符号(`Symbol.iterator`、`Symbol.asyncIterator`、`Symbol.match` 等)、`Symbol.for` / `Symbol.keyFor` 全局注册表、`symbol.description` / `toString()` / `valueOf()`;symbol 可作为属性键(`Object.getOwnPropertySymbols`,symbol 键的 `get`/`set`/`in`/`delete`),会被 `Object.keys` / `values` / `entries` / `for...in` / `JSON.stringify` 跳过,打印为 `Symbol(desc)`。
|
|
245
247
|
- 通用成员访问:`xt_get` / `xt_set`(对数组 / 对象 / 字符串分发)。
|
|
@@ -249,10 +251,11 @@ xt_value fn(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
|
|
|
249
251
|
- 函数与闭包:`arg`、`closure_new/call/env/arity`。
|
|
250
252
|
- 异常:`xt_try_enter` / `xt_try_exception` / `xt_try_leave` 维护 `_setjmp` 帧栈;`xt_throw` 在存在帧时长跳到最近 `try`,否则打印 `Uncaught ...` 后退出。codegen 还会维护一条影子调用栈(函数名、源文件、行号):`Error.stack` 用它生成堆栈,原生崩溃时致命信号处理器也会打印同一组帧。`--debug` 还会生成 `!DICompileUnit` / `!DISubprogram` / `!DILocation` 元数据,并用 `-g -fno-omit-frame-pointer` 编译,因此 gdb/lldb/WinDbg 可以把指令映射回源码行。
|
|
251
253
|
- 输出:`xt_print/xt_println/xt_console_log/info/warn/error`(Node 风格 inspect:数组 `[ a, b ]`、对象 `{ k: v }`;`info`/`log` 到 stdout,`warn`/`error` 到 stderr),以及 `dir/trace/assert/count/countReset/group/groupEnd/table/time/timeEnd/timeLog`。
|
|
252
|
-
- 对象 / 函数:`xt_object` 带原型链,`xt_function` 带属性包(静态成员与 `prototype`);`xt_new`(实例化)、`xt_instance_of`(原型链)、`xt_object_freeze/is_frozen/from_entries
|
|
254
|
+
- 对象 / 函数:`xt_object` 带原型链,`xt_function` 带属性包(静态成员与 `prototype`);`xt_new`(实例化)、`xt_instance_of`(原型链)、`xt_object_freeze/is_frozen/from_entries`;`xt_constructors.c` 保存一等公民构造器缓存、构造器原型与静态值分派。
|
|
253
255
|
- 标准库扩展(`xt_stdlib2.c`):数组 / 字符串 / 数字 / 对象的扩展方法;`Object` / `Array` / `Number` / `String` 静态方法;`JSON.parse` / `JSON.stringify`;`Map` / `Set`;`Date`(`gmtime_r`);`RegExp`(POSIX ERE `regcomp`/`regexec` 的 `test`/`exec`)。
|
|
254
|
-
- Promise(`xt_promise.c
|
|
255
|
-
-
|
|
256
|
+
- Promise(`xt_promise.c`):微任务队列(`xt_microtasks`);`xt_promise_ctor/resolve/reject/static`、实例 `then/catch/finally`;`xt_drain_microtasks` 在程序结束时清空队列,事件循环也会在回调之间清空它。`xt_await`(位于 `xt_async.c`)对已 settle 的值同步返回,对 pending promise 则挂起当前 async 协程并登记等待者。
|
|
257
|
+
- 异步协程(`xt_async.c`)复用共享的栈式协程运行时(`xt_coroutine.c`,POSIX `ucontext` / Windows fiber):每次 `async` 调用拥有私有栈,切换异常帧栈与 GC 栈区间,因此 `await` 可跨越 `try`/`finally`、循环与闭包。由定时器、套接字回调或另一个协程 settle 的 promise 会在微任务队列上恢复挂起的函数体。
|
|
258
|
+
- Fetch(`xt_fetch.c`):全局 `fetch(input, init)` 是阻塞式 HTTP/1.1 客户端,返回的 promise 已经 settle(交换同步完成,不经过 reactor 调度)。只接受 `http://` URL——由于未链接 TLS 后端,`https://` 会以 `TypeError` 拒绝——支持 `method`、`headers`(普通对象或 `Headers`)、`body` 与 `redirect`(`follow` / `manual` / `error`),最多跟随 20 次重定向,并在 301/302/303 时将 POST 改为 GET。解析出的 `Response` 形状对象暴露 `ok` / `status` / `statusText` / `url` / `headers` 以及 `text()` / `json()` / `arrayBuffer()` / `bytes()` / `clone()`;`Headers` 大小写不敏感,提供 `get` / `has` / `set` / `append` / `delete` / `keys` / `values` / `entries` / `forEach` / `getSetCookie`。非法 URL 与网络失败会以 `TypeError` 拒绝。
|
|
256
259
|
|
|
257
260
|
---
|
|
258
261
|
|
|
@@ -338,7 +341,7 @@ const result = build("program.ts", { emit: "exe", outDir: "build" });
|
|
|
338
341
|
实现位置:`tests/`(`lexer` / `parser` / `binder` / `codegen` / `driver` / `extensions` / `cli` / `e2e`)
|
|
339
342
|
|
|
340
343
|
- 各模块单元测试;e2e 在存在 `clang` 时真正编译并运行二进制,否则自动跳过。
|
|
341
|
-
- e2e 覆盖:算术与打印、递归函数、循环 / 数组 / 字符串拼接、闭包按引用捕获、对象 / 数组 JS 风格打印、Node `fs` 扩展(经 `import`)、`switch` 穿透、数组 / 字符串方法、`Math` 与全局函数与 `console` 各等级、默认 / 剩余参数与 `arguments`、`Object` 助手与展开与 `in`/`delete`、`for...in` 对象键枚举、`try/catch/finally`、可选链、类与 `new`/`this`/`static`/`extends`/`super`/`instanceof`、`async`/`await` 与 `Promise
|
|
344
|
+
- e2e 覆盖:算术与打印、递归函数、循环 / 数组 / 字符串拼接、闭包按引用捕获、对象 / 数组 JS 风格打印、Node `fs` 扩展(经 `import`)、`switch` 穿透、数组 / 字符串方法、`Math` 与全局函数与 `console` 各等级、默认 / 剩余参数与 `arguments`、`Object` 助手与展开与 `in`/`delete`、`for...in` 对象键枚举、`try/catch/finally`、可选链、类与 `new`/`this`/`static`/`extends`/`super`/`instanceof`、`async`/`await` 与 `Promise`、真实 await 挂起(定时器、TCP 套接字与 `fs/promises` 跨事件循环轮次、恢复后的 rejection 与 `finally`)、`Map`/`Set`/`JSON` 与扩展标准库、`Map`/`Set` 的 `for...of`、数组 `length` 赋值与可迭代展开、多文件 `import`/`export`、类型化数组(元素强制转换、`from`/`of`、迭代与原型方法)、对象 rest 解构与内建 `instanceof`,一等公民内建构造器与 `Object.prototype`(别名、静态成员、`getPrototypeOf`、`hasOwnProperty.call`),以及全局 `fetch`(HTTP GET/POST、请求头、重定向、JSON/文本/二进制响应体与 `TypeError` 拒绝)。
|
|
342
345
|
|
|
343
346
|
---
|
|
344
347
|
|
|
@@ -352,11 +355,11 @@ const result = build("program.ts", { emit: "exe", outDir: "build" });
|
|
|
352
355
|
| 运算符 | 算术、比较、相等、逻辑、位运算、移位、一元(含 `typeof`/`void`)、前后缀增减、复合赋值、逻辑赋值、`in`、`delete`、`instanceof` |
|
|
353
356
|
| 函数 | 默认参数、剩余参数、捕获闭包、`this` 绑定、箭头函数词法 `this`、`call`/`apply`/`bind`、`name`/`length` |
|
|
354
357
|
| 类 / OO | 构造函数、实例字段、方法、`static`、继承 `extends`/`super`、原型链、`instanceof` |
|
|
355
|
-
| 异步 | `async`/`await
|
|
358
|
+
| 异步 | `async`/`await` 具备真实的栈式协程挂起(pending promise 会暂停函数体,直到定时器/套接字/其他协程将其 settle)、`Promise`(`then/catch/finally`、`resolve/reject/all/allSettled/race`) |
|
|
356
359
|
| 模块 | `import`/`export`(具名 / 默认 / 再导出 / `export *`),相对路径多文件打包(`.js` 系列说明符解析到对应 `.ts` 源码,省略后缀时优先 TypeScript 后缀而非同名的 JavaScript 文件;纯 `.js` / `.jsx` / `.mjs` / `.cjs` 源码也可直接打包)与 `node_modules` 包(`exports` / `module` / `main`、作用域包与子路径),裸说明符解析到扩展模块;`node_modules` 内的 CommonJS 包会被降级(`require` / `module.exports` / `exports`),用户代码中的 `require()` 报错并提示改用 `import` |
|
|
357
360
|
| 标准库 | 数组 / 字符串 / 数字 / 对象扩展方法、类型化数组、`Math`、`JSON`、`Date`、`RegExp`、`Map`、`Set`、`Symbol`、`Error` 家族、`Object/Array/Number/String/Symbol` 静态、`console.*` |
|
|
358
361
|
| 值模型 | 64 位 NaN-boxing、统一函数 ABI(含 `this`)、闭包环境、对象原型链 |
|
|
359
|
-
| 运行时 | 字符串 / 对象 / 数组 / 类型化数组 / 闭包 / 算术 / 比较 / 可捕获异常 / Promise / 集合 / symbol / 生成器 / `fetch` / `console` |
|
|
362
|
+
| 运行时 | 字符串 / 对象 / 数组 / 类型化数组 / 闭包 / 算术 / 比较 / 可捕获异常 / Promise / 异步协程 / 集合 / symbol / 生成器 / `fetch` / `console` |
|
|
360
363
|
| 扩展 | 扩展注册表、`core`(print)、`node`(fs / path / os / process / buffer / stream / net / dgram / http,按说明符导入) |
|
|
361
364
|
| GUI(`gui` 扩展) | 自托管 HTML/CSS 渲染器窗口(SDL3 + SDL_GPU):DOM/CSS/布局、CSS `transform`/`transform-origin`、`<img>`/SVG、`<video>`/`<audio>`、`<canvas>` 2D、事件、transition(含 `transform`) |
|
|
362
365
|
| 工具链 | clang 编译 IR/C、链接、增量缓存 |
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
- `JSON.parse` / `JSON.stringify`
|
|
73
73
|
- `Date`、`RegExp`(POSIX ERE 子集,支持捕获组)、`Map`、`Set`、`Promise`、`BigInt`
|
|
74
74
|
- `Array` 静态(`isArray/of/from`)、`Object` 静态、`Number` 静态、`String` 静态(`fromCharCode` / `fromCodePoint` / `raw`)
|
|
75
|
+
- 一等公民内建构造器(`const A = Array`、`new A(...)`、`A.isArray`、`x instanceof A`)与 `Object.prototype`(`hasOwnProperty`、`toString`、`valueOf`、`isPrototypeOf`、`propertyIsEnumerable`、`__proto__`),且 `Object.getPrototypeOf({}) === Object.prototype`
|
|
75
76
|
- `Error` 家族(`Error`、`TypeError`、`RangeError`、`SyntaxError`、`ReferenceError`、`EvalError`、`URIError`、`AggregateError`):支持 `new`、`instanceof`、`extends`、`String(err)` / `err.toString()` 与 `.stack`
|
|
76
77
|
|
|
77
78
|
### 3.3 仍未实现
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
| `AggregateError` 构造器 | ✓ `new AggregateError(errors, message)`;`Promise.any` 现以其作为 rejection |
|
|
86
87
|
| 迭代器协议 / `Symbol.iterator` / `for...of` 自定义可迭代 | ✓ 数组、字符串、`Map`、`Set`、生成器以及任何暴露 `[Symbol.iterator]()` 的对象均可在 `for...of` / 展开中使用 |
|
|
87
88
|
| 生成器(`function*`、`yield`、`yield*`、`next`/`throw`/`return`) | ✓ 基于有栈协程实现;支持 `for...of`、展开与委托。`return()` 直接结束,不执行 `finally` |
|
|
88
|
-
| 定时器 | ✓ 核心事件循环提供 `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval`(返回数字 id,无 `Timeout` 对象;无 `setImmediate` / `queueMicrotask
|
|
89
|
+
| 定时器 | ✓ 核心事件循环提供 `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval`(返回数字 id,无 `Timeout` 对象;无 `setImmediate` / `queueMicrotask`)。定时器 settle 的 promise 可以被 await:async 函数体在 pending promise 上挂起,定时器触发时恢复 |
|
|
89
90
|
| I/O / 进程等宿主 API | 仅通过扩展(如 Node `fs`)提供 |
|
|
90
91
|
|
|
91
92
|
### 3.4 类型化数组
|
|
@@ -104,7 +105,7 @@
|
|
|
104
105
|
| `keys` / `values` / `entries` | ~ 返回数组,而非迭代器对象 |
|
|
105
106
|
| `ArrayBuffer` / `DataView` / `.buffer` / `.byteOffset` 语义 | ✗ 无底层缓冲区类型;`.byteOffset` 恒为 0 |
|
|
106
107
|
| `BigInt64Array` / `BigUint64Array` | ✗ 未实现 |
|
|
107
|
-
| `instanceof` 内建构造器 | ✓ `instanceof Array` / `Object` / `Map` / `Set` / `Date` / `RegExp` / `Promise` / `Error` 家族 /
|
|
108
|
+
| `instanceof` 内建构造器 | ✓ `instanceof Array` / `Object` / `Map` / `Set` / `Date` / `RegExp` / `Promise` / `Error` 家族 / 类型化数组都能按名字识别,**也能通过一等公民构造器值判断**(`const A = Array; x instanceof A`);构造器可保存、传参、取别名、调用与 `new` |
|
|
108
109
|
| 基于 `Buffer` / `ArrayBuffer` 的类型化数组视图 | ✗ 构造器仅能从长度 / 数组样 / 类型化数组复制 |
|
|
109
110
|
|
|
110
111
|
---
|
|
@@ -137,13 +138,14 @@
|
|
|
137
138
|
| 解构参数 / 解构绑定 | ✓ | ✓ 已实现 |
|
|
138
139
|
| `arguments` 对象 | ✓(隐式) | ✓ 已实现(箭头函数取的是自身参数,而非外层函数的 `arguments`,与 JS 不同) |
|
|
139
140
|
| `this` 绑定 / 方法调用语义 | ✓ | ✓ 已实现(`this` 作为函数首个 ABI 参数线程化;箭头函数词法继承) |
|
|
140
|
-
| `async` / `await` / Promise | ✓ | ✓
|
|
141
|
+
| `async` / `await` / Promise | ✓ | ✓ 已实现:基于栈式协程的真实挂起;等待 pending promise 会暂停函数体并由事件循环恢复(剩余差异见偏差表) |
|
|
141
142
|
| `new.target` | ✗ | 已解析,但以 `UnsupportedFeature` 明确拒绝(无 `new.target` 语义) |
|
|
142
143
|
| 生成器 / 迭代器 / `yield` | ✓ 已实现 | `function*`、`yield`、`yield*`、`.next/.throw/.return`;异步生成器以 `UnsupportedFeature` 拒绝 |
|
|
143
144
|
| 闭包 `arity` | — | `xt_closure_arity` 恒为 -1,未填充 |
|
|
144
145
|
| `fn.call` / `fn.apply` / `fn.bind` | ✓ | ✓ 已实现(绑定闭包不跟踪部分参数的 `length`) |
|
|
145
146
|
| `fn.name` / `fn.length` | ✓ | ✓ 已实现(从声明 / 赋值 / 属性键推断;绑定函数为 `"bound ..."` 并调整 arity) |
|
|
146
147
|
| 内置方法一等公民(`typeof arr.map`、`const f = arr.push`、`obj.method?.()`) | ✓ | ✓ 作为**未绑定**方法值实现:读取 `arr.map` 得到函数,`arr.map?.(cb)` 与 `obj.method?.()` 会把接收者作为 `this` 绑定,脱离接收者调用(`const f = arr.map; f(cb)`)会像 JavaScript 一样抛错。方法的 `name`/`length` 也一并暴露 |
|
|
148
|
+
| 内建构造器一等公民(`const A = Array`、`new A(...)`、`typeof Map`) | ✓ | ✓ 构造器是普通函数值,带 `name`/`length`、`prototype`、静态成员(`A.isArray`)与完整的 `instanceof` 协议 |
|
|
147
149
|
| `fn.toString()` | ~ | 返回原生占位字符串(`function name() { [native code] }`),而非原始源码文本 |
|
|
148
150
|
|
|
149
151
|
---
|
|
@@ -189,8 +191,7 @@
|
|
|
189
191
|
|
|
190
192
|
| 项 | 偏差 |
|
|
191
193
|
| --- | --- |
|
|
192
|
-
|
|
|
193
|
-
| `Object.getPrototypeOf({})` | 返回 `undefined`,而非 `Object.prototype` 对象 |
|
|
194
|
+
| 正则按字节匹配 | 引擎按 UTF-8 字节匹配:多字节字面量仍可匹配,但 `.` 与字符类每次只消费一个字节(`\d`/`\w` 仍是 ASCII)。`exec` / `search` / 替换回调返回的偏移会转换为 UTF-16 码元 |
|
|
194
195
|
| 全局正则 `lastIndex` | `/g`、`/y` 正则的 `test` / `exec` 不推进也不读取调用方设置的 `lastIndex` |
|
|
195
196
|
| `String.normalize` / `structuredClone` | 未实现 |
|
|
196
197
|
| 内置方法一等公民 | 以未绑定方法值实现(见第 5 节);`fn.toString()` 返回占位字符串而非源码文本 |
|
|
@@ -198,9 +199,9 @@
|
|
|
198
199
|
| 数组越界 / 稀疏 | 越界访问返回 `undefined`;对 `arr.length` 赋值会截断 / 扩展,但不区分稀疏空洞 |
|
|
199
200
|
| 内存管理 | 非移动标记-清扫回收器(在 `xt_alloc` 之后):显式根、子系统根提供者与保守 C 栈扫描。单线程、stop-the-world;无移动/压缩与分代 |
|
|
200
201
|
| 函数 `arity` / 调用参数个数 | 无参数个数校验;`fn.length` 报告声明的 arity,但调用不做校验 |
|
|
201
|
-
| `async` / `await` |
|
|
202
|
+
| `async` / `await` | 已在栈式协程上真实挂起;但对**已 settle** 的值 `await` 会同步继续,而不是像规范要求那样排入微任务,因此与 pending `.then` 回调的交错顺序可能不同。顶层 `await` 会阻塞事件循环等待,而不是让出模块主体。`fs/promises` 仍在 settle 前同步完成 I/O;`fetch` 是阻塞的;不支持 `async` 生成器 |
|
|
202
203
|
| `super` | `super.x` / `super(...)` 取 `this` 原型的原型;单级继承正确,继承深度 > 1 时可能不准确 |
|
|
203
|
-
| `Error.stack` | 仅函数级帧:每帧为 `at 名称 (文件:行)
|
|
204
|
+
| `Error.stack` | 仅函数级帧:每帧为 `at 名称 (文件:行)`,行号取自函数声明(最内层帧会更新为错误构造处);没有列号,生成器 / `async` 函数体不产生帧(它们会切换栈) |
|
|
204
205
|
| 模块实时绑定 | 命名空间导入与导入绑定为快照(见第 4 节) |
|
|
205
206
|
| `import.meta` | ✓ `import.meta.url` / `.dirname` / `.filename`,由可执行文件路径解析 |
|
|
206
207
|
|
|
@@ -217,7 +218,7 @@
|
|
|
217
218
|
| 类型检查器 | ✗ 仅定义诊断码,无 checker |
|
|
218
219
|
| 完整标准库 | 部分:Math / JSON / Date / Map / Set / RegExp / `Error` / `BigInt` / `Symbol` 已实现;String.normalize / structuredClone 缺失 |
|
|
219
220
|
| 多文件模块打包 | 部分:相对路径 `.ts` 打包、ESM `node_modules` 包、命名空间导入、裸说明符扩展模块导入已实现;循环依赖 / CommonJS / 实时绑定未实现 |
|
|
220
|
-
|
|
|
221
|
+
| 异步运行时 | ✓ `async`/`await` 在 `select(2)` reactor 上对 pending promise 挂起:定时器、TCP 套接字与 promise 回调都能恢复协程。仍缺:真正的异步 I/O 调度(`fs/promises` 会先阻塞完成 I/O 再 settle)、非阻塞 `fetch` 与 worker 线程(worker 是子进程) |
|
|
221
222
|
| Windows 二进制产物验证 | 构建层已适配(`.exe` 后缀、链接参数分支),并在 CI 中验证 |
|
|
222
223
|
| 精确的 ECMAScript 数值 / 字符串 / 比较语义 | 部分,见第 8 节 |
|
|
223
224
|
|
|
@@ -241,8 +242,8 @@
|
|
|
241
242
|
|
|
242
243
|
未实现(类型系统):类型检查、泛型实例化、断言语义、可选链类型窄化
|
|
243
244
|
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
未实现(运行时):异步 I/O 调度、
|
|
246
|
+
全局正则 lastIndex
|
|
246
247
|
|
|
247
248
|
未实现(工程):类型检查器
|
|
248
249
|
```
|
package/package.json
CHANGED
package/runtime/rt.h
CHANGED
|
@@ -96,7 +96,10 @@ xt_value xt_string_from_cstr(const char *data);
|
|
|
96
96
|
* Materialises a lazily concatenated string, so the returned pointer is stable
|
|
97
97
|
* until the string is collected. */
|
|
98
98
|
const char *xt_string_data(xt_value value);
|
|
99
|
+
/** Byte length of the UTF-8 storage (what I/O and C extensions consume). */
|
|
99
100
|
int32_t xt_string_length_value(xt_value value);
|
|
101
|
+
/** JavaScript `String.prototype.length`: UTF-16 code units. */
|
|
102
|
+
int32_t xt_string_utf16_length_value(xt_value value);
|
|
100
103
|
|
|
101
104
|
/* -- bigint -------------------------------------------------------------- */
|
|
102
105
|
xt_value xt_bigint_from_string(const char *data, size_t len);
|
|
@@ -125,6 +128,10 @@ xt_value xt_instance_of(xt_value value, xt_value ctor);
|
|
|
125
128
|
xt_value xt_instance_of_builtin(xt_value value, int32_t id);
|
|
126
129
|
xt_value xt_function_set_prototype(xt_value fn, xt_value proto);
|
|
127
130
|
xt_value xt_function_get_prototype(xt_value fn);
|
|
131
|
+
/** Mark a closure as a generator so calling it creates a suspended generator. */
|
|
132
|
+
xt_value xt_function_set_generator(xt_value fn);
|
|
133
|
+
/** Mark a closure as an `async` function so calling it starts a coroutine. */
|
|
134
|
+
xt_value xt_function_set_async(xt_value fn);
|
|
128
135
|
|
|
129
136
|
/* -- conversions ---------------------------------------------------------- */
|
|
130
137
|
int xt_truthy(xt_value v);
|
|
@@ -163,6 +170,10 @@ xt_value xt_not(xt_value a);
|
|
|
163
170
|
/* -- objects -------------------------------------------------------------- */
|
|
164
171
|
xt_value xt_object_new(void);
|
|
165
172
|
xt_value xt_object_new_with_proto(xt_value proto);
|
|
173
|
+
/** The shared `Object.prototype` object (root of the ordinary object chain). */
|
|
174
|
+
xt_value xt_object_prototype(void);
|
|
175
|
+
/** The shared `Function.prototype` object. */
|
|
176
|
+
xt_value xt_function_prototype(void);
|
|
166
177
|
xt_value xt_object_get(xt_value obj, xt_value key);
|
|
167
178
|
xt_value xt_object_get_prototype(xt_value obj);
|
|
168
179
|
xt_value xt_object_set_prototype(xt_value obj, xt_value proto);
|
|
@@ -193,6 +204,17 @@ xt_value xt_symbol_static(xt_value name, int32_t argc, xt_value *argv);
|
|
|
193
204
|
xt_value xt_symbol_get(xt_value name);
|
|
194
205
|
|
|
195
206
|
/* -- standard library dispatch -------------------------------------------- */
|
|
207
|
+
/* -- built-in constructors as first-class values -------------------------- */
|
|
208
|
+
/** The first-class value of a built-in constructor (`Array`, `Map`, ...). */
|
|
209
|
+
xt_value xt_builtin_constructor(xt_value name);
|
|
210
|
+
/** A static method/value of a first-class constructor (`A.isArray`, ...). */
|
|
211
|
+
xt_value xt_builtin_static_value(xt_value ctor, xt_value key);
|
|
212
|
+
/** The constructor prototype for a runtime object kind (`Map` -> Map.prototype). */
|
|
213
|
+
xt_value xt_builtin_prototype_for_kind(int32_t kind);
|
|
214
|
+
/** `Array(...)` / `new Array(...)`. */
|
|
215
|
+
xt_value xt_array_ctor(int32_t argc, xt_value *argv);
|
|
216
|
+
/** `Object(...)` / `new Object(...)`. */
|
|
217
|
+
xt_value xt_object_ctor(int32_t argc, xt_value *argv);
|
|
196
218
|
/** Call `target[name](...)`, falling back to built-in Array/String methods. */
|
|
197
219
|
xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *argv);
|
|
198
220
|
/** Implements `Math.<name>(...)`; the name is interned by the compiler. */
|
|
@@ -207,6 +229,14 @@ xt_value xt_object_static(xt_value name, int32_t argc, xt_value *argv);
|
|
|
207
229
|
/** Implements `Number.<name>(...)` / `String.<name>(...)` statics. */
|
|
208
230
|
xt_value xt_number_static(xt_value name, int32_t argc, xt_value *argv);
|
|
209
231
|
xt_value xt_string_static(xt_value name, int32_t argc, xt_value *argv);
|
|
232
|
+
/** Typed-array constructor/static/prototype dispatch by constructor name. */
|
|
233
|
+
xt_value xt_typed_array_ctor_by_name(xt_value name, int32_t argc, xt_value *argv);
|
|
234
|
+
xt_value xt_typed_array_static_by_name(xt_value name, xt_value method, int32_t argc, xt_value *argv);
|
|
235
|
+
xt_value xt_typed_array_prototype(xt_value name);
|
|
236
|
+
/** Error-family construction and prototype lookup by constructor name. */
|
|
237
|
+
xt_value xt_error_ctor_by_name(xt_value name, int32_t argc, xt_value *argv);
|
|
238
|
+
xt_value xt_error_prototype(xt_value name);
|
|
239
|
+
xt_value xt_error_constructor(xt_value name);
|
|
210
240
|
/** Map / Set constructors and dispatch. */
|
|
211
241
|
xt_value xt_map_ctor(int32_t argc, xt_value *argv);
|
|
212
242
|
xt_value xt_set_ctor(int32_t argc, xt_value *argv);
|
|
@@ -314,6 +344,8 @@ extern char **xt_program_argv;
|
|
|
314
344
|
|
|
315
345
|
/* -- arrays --------------------------------------------------------------- */
|
|
316
346
|
xt_value xt_array_new(int32_t count, xt_value *items);
|
|
347
|
+
/** The shared `Array.prototype` array. */
|
|
348
|
+
xt_value xt_array_prototype(void);
|
|
317
349
|
xt_value xt_array_get(xt_value arr, xt_value index);
|
|
318
350
|
xt_value xt_array_set(xt_value arr, xt_value index, xt_value value);
|
|
319
351
|
xt_value xt_array_push(xt_value arr, xt_value value);
|
package/runtime/rt_internal.h
CHANGED
|
@@ -21,12 +21,15 @@
|
|
|
21
21
|
* code free of write barriers and makes the first implementation small and
|
|
22
22
|
* predictable. Replacing it with a precise/conservative collector is an
|
|
23
23
|
* isolated change behind `xt_alloc` plus root registration.
|
|
24
|
-
* * Strings are UTF-8
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
24
|
+
* * Strings are stored as UTF-8 (with lone surrogate halves kept as WTF-8) but
|
|
25
|
+
* expose JavaScript's UTF-16 view: `length`, indexing, slicing, searching
|
|
26
|
+
* and splitting all count UTF-16 code units. `xt_string_length` is the raw
|
|
27
|
+
* byte length (what extensions and I/O need), while
|
|
28
|
+
* `xt_string_utf16_length` is the JavaScript `.length`. Concatenation is
|
|
29
|
+
* lazy: a `+` between two non-empty strings builds an immutable cons node
|
|
30
|
+
* (`flat == NULL`) and the bytes are materialised once, on first
|
|
31
|
+
* observation, by `xt_string_bytes`. This keeps `s += x` in a loop linear
|
|
32
|
+
* instead of copying the accumulated prefix every iteration.
|
|
30
33
|
* * Objects use a small linear property list. Fine for the language subset
|
|
31
34
|
* xbintsc targets today; swap for a hash map when the profile demands it.
|
|
32
35
|
*/
|
|
@@ -55,6 +58,7 @@
|
|
|
55
58
|
#define XT_OBJECT_KIND_ERROR 12
|
|
56
59
|
#define XT_OBJECT_KIND_GENERATOR 13
|
|
57
60
|
#define XT_OBJECT_KIND_ITERATOR 14
|
|
61
|
+
#define XT_OBJECT_KIND_ASYNC 15
|
|
58
62
|
|
|
59
63
|
/* Common header for every heap object. `flags` bit 0 is the collector's mark
|
|
60
64
|
* bit; it is cleared on every surviving object at the end of a sweep. */
|
|
@@ -70,13 +74,18 @@ typedef struct xt_header {
|
|
|
70
74
|
|
|
71
75
|
/* A string is either *flat* (`flat` points at `capacity` bytes, the last one
|
|
72
76
|
* NUL) or a *cons* node (`flat == NULL`, `left`/`right` name the operands).
|
|
73
|
-
* `length` is
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
+
* `length` is the raw UTF-8 byte length; `utf16_length` (cached, 0 means
|
|
78
|
+
* "not computed yet" and is also the length of the empty string) is the same
|
|
79
|
+
* text measured in UTF-16 code units, which is what JavaScript observes.
|
|
80
|
+
* `code_point_count` is the number of Unicode scalar values (used by
|
|
81
|
+
* `for...of` and `Array.from`). `xt_string_bytes` turns a cons node into a flat
|
|
82
|
+
* one in place; treat the result as immutable and never write through a pointer
|
|
83
|
+
* obtained from it. */
|
|
77
84
|
typedef struct xt_string {
|
|
78
85
|
xt_header header;
|
|
79
86
|
uint32_t length;
|
|
87
|
+
uint32_t utf16_length;
|
|
88
|
+
uint32_t code_point_count;
|
|
80
89
|
uint32_t capacity;
|
|
81
90
|
char *flat;
|
|
82
91
|
struct xt_string *left;
|
|
@@ -125,6 +134,10 @@ typedef struct {
|
|
|
125
134
|
/* Named (non-index) properties such as `raw` on template strings or
|
|
126
135
|
* `index`/`input` on RegExp match results, stored in an `xt_object`. */
|
|
127
136
|
xt_value extra;
|
|
137
|
+
/* The array's [[Prototype]] (`Array.prototype` for ordinary arrays). Arrays
|
|
138
|
+
* are a distinct allocation kind, so this field is what lets
|
|
139
|
+
* `Object.getPrototypeOf([])` and `x instanceof <Array alias>` work. */
|
|
140
|
+
xt_value prototype;
|
|
128
141
|
} xt_array;
|
|
129
142
|
|
|
130
143
|
typedef struct {
|
|
@@ -139,6 +152,13 @@ typedef struct {
|
|
|
139
152
|
/* Set on generator function objects: calling the closure does not run the
|
|
140
153
|
* body, it creates a suspended generator (see xt_generator.c). */
|
|
141
154
|
uint8_t is_generator;
|
|
155
|
+
/* Set on `async` function objects: calling the closure starts a coroutine
|
|
156
|
+
* (see xt_async.c) and immediately returns the promise it resolves. */
|
|
157
|
+
uint8_t is_async;
|
|
158
|
+
/* Non-NULL for the first-class value of a built-in constructor ("Array",
|
|
159
|
+
* "Map", ...). It lets property access resolve the constructor's statics
|
|
160
|
+
* (`const A = Array; A.isArray(x)`). Points at a static string. */
|
|
161
|
+
const char *builtin_name;
|
|
142
162
|
} xt_function;
|
|
143
163
|
|
|
144
164
|
/* Allocation and garbage collection (xt_alloc.c).
|
|
@@ -201,6 +221,19 @@ void xt_promise_gc_trace(xt_header *header);
|
|
|
201
221
|
void xt_promise_gc_release(xt_header *header);
|
|
202
222
|
void xt_generator_gc_trace(xt_header *header);
|
|
203
223
|
void xt_generator_gc_release(xt_header *header);
|
|
224
|
+
void xt_async_gc_trace(xt_header *header);
|
|
225
|
+
void xt_async_gc_release(xt_header *header);
|
|
226
|
+
|
|
227
|
+
/* Stackful coroutines (xt_coroutine.c). A coroutine owns a private C stack and
|
|
228
|
+
* switches to it with `ucontext`/fibers; `enter` runs until the body calls
|
|
229
|
+
* `leave`. Exception frames and GC stack regions are swapped alongside the C
|
|
230
|
+
* stack. Generators and async functions own one each. */
|
|
231
|
+
typedef struct xt_coroutine xt_coroutine;
|
|
232
|
+
xt_coroutine *xt_coroutine_create(void (*entry)(void *), void *arg);
|
|
233
|
+
void xt_coroutine_enter(xt_coroutine *co);
|
|
234
|
+
void xt_coroutine_leave(xt_coroutine *co);
|
|
235
|
+
void xt_coroutine_gc_trace(xt_coroutine *co);
|
|
236
|
+
void xt_coroutine_release(xt_coroutine *co);
|
|
204
237
|
|
|
205
238
|
/* Value / string helpers shared across translation units (xt_values.c). */
|
|
206
239
|
xt_string *xt_string_alloc(size_t length);
|
|
@@ -210,6 +243,42 @@ int xt_string_equals(xt_string *a, xt_string *b);
|
|
|
210
243
|
/* Contiguous UTF-8 bytes of a string, flattening a cons node in place on first
|
|
211
244
|
* use. The result is NUL-terminated at `s->length`; never write through it. */
|
|
212
245
|
const char *xt_string_bytes(xt_string *s);
|
|
246
|
+
|
|
247
|
+
/* UTF-8 <-> UTF-16 helpers (xt_values/utf16.inc). Decoding accepts WTF-8, so
|
|
248
|
+
* lone surrogate halves produced by indexing survive a round trip. */
|
|
249
|
+
uint32_t xt_utf8_decode(const char *data, size_t length, size_t *width);
|
|
250
|
+
size_t xt_utf8_encode(uint32_t code, char *out);
|
|
251
|
+
uint32_t xt_utf8_utf16_length(const char *data, size_t length);
|
|
252
|
+
void xt_utf8_measure(const char *data, size_t length, uint32_t *units, uint32_t *points);
|
|
253
|
+
/* Combine an adjacent WTF-8 high/low surrogate pair into one four-byte
|
|
254
|
+
* sequence, in place. Returns the resulting byte length. */
|
|
255
|
+
size_t xt_utf8_normalize_surrogates(char *data, size_t length);
|
|
256
|
+
|
|
257
|
+
/* Publish a manually filled buffer (`xt_string_alloc` + `xt_string_mutable`):
|
|
258
|
+
* normalises surrogate pairs, records the byte length and caches the UTF-16 and
|
|
259
|
+
* code-point counts. */
|
|
260
|
+
void xt_string_finish(xt_string *s);
|
|
261
|
+
uint32_t xt_string_utf16_length(xt_string *s);
|
|
262
|
+
uint32_t xt_string_code_point_count(xt_string *s);
|
|
263
|
+
/* UTF-16 code unit at `index`, or -1 when out of range. */
|
|
264
|
+
int32_t xt_string_code_unit(xt_string *s, int32_t index);
|
|
265
|
+
/* Unicode code point beginning at UTF-16 index `index` (combining a surrogate
|
|
266
|
+
* pair), or -1 when out of range. */
|
|
267
|
+
int32_t xt_string_code_point_at(xt_string *s, int32_t index);
|
|
268
|
+
/* A one-code-unit string (a lone surrogate when `index` points into a pair). */
|
|
269
|
+
xt_value xt_string_unit_value(xt_string *s, int32_t index);
|
|
270
|
+
xt_value xt_string_from_code_point(uint32_t code);
|
|
271
|
+
xt_value xt_string_from_units(const uint16_t *units, size_t count);
|
|
272
|
+
/* Copy UTF-16 range [start, end), splitting a surrogate pair when needed. */
|
|
273
|
+
xt_value xt_string_slice_units(xt_string *s, int32_t start, int32_t end);
|
|
274
|
+
/* Byte offset / UTF-16 index conversions; both clamp to the string bounds. */
|
|
275
|
+
int32_t xt_string_byte_offset(xt_string *s, int32_t unit_index);
|
|
276
|
+
int32_t xt_string_unit_offset(xt_string *s, int32_t byte_offset);
|
|
277
|
+
/* True when `unit_index` sits on a code-point boundary (not between the two
|
|
278
|
+
* halves of a surrogate pair). */
|
|
279
|
+
int xt_string_is_boundary(xt_string *s, int32_t unit_index);
|
|
280
|
+
/* The `index`-th Unicode code point (for `for...of` and `Array.from`). */
|
|
281
|
+
xt_value xt_string_code_point_value(xt_string *s, int32_t index);
|
|
213
282
|
/* Mutable bytes of a string just created with `xt_string_alloc` (never a cons
|
|
214
283
|
* node). Used by the constructors that fill a buffer before publishing it. */
|
|
215
284
|
char *xt_string_mutable(xt_string *s);
|
|
@@ -299,6 +368,26 @@ xt_value xt_yield_star(xt_value delegate);
|
|
|
299
368
|
int xt_generator_has_next(xt_value generator);
|
|
300
369
|
xt_value xt_generator_iter_value(xt_value generator);
|
|
301
370
|
|
|
371
|
+
/* Async coroutines (xt_async.c). Calling an `async` function runs its body on
|
|
372
|
+
* a coroutine that suspends at a pending `await` and resumes when the awaited
|
|
373
|
+
* promise settles, so the event loop can make progress in between. */
|
|
374
|
+
#define XT_PROMISE_PENDING 0
|
|
375
|
+
#define XT_PROMISE_FULFILLED 1
|
|
376
|
+
#define XT_PROMISE_REJECTED 2
|
|
377
|
+
xt_value xt_async_call(xt_value function, xt_value thisValue, int32_t argc, xt_value *argv);
|
|
378
|
+
/* Resume `async` with the settlement of the promise it awaited. Called by the
|
|
379
|
+
* microtask runner when the promise settles. */
|
|
380
|
+
void xt_async_wake(void *async, xt_value value, int rejected);
|
|
381
|
+
/* Create a pending promise / settle an existing one (used by xt_async.c). */
|
|
382
|
+
xt_value xt_promise_create(void);
|
|
383
|
+
void xt_promise_fulfill(xt_value promise, xt_value value);
|
|
384
|
+
void xt_promise_reject_value(xt_value promise, xt_value value);
|
|
385
|
+
/* `-1` when `value` is not a promise, otherwise PENDING / FULFILLED / REJECTED. */
|
|
386
|
+
int xt_promise_state_of(xt_value value);
|
|
387
|
+
xt_value xt_promise_value_of(xt_value value);
|
|
388
|
+
/* Register a coroutine to resume when `promise` settles (it must be pending). */
|
|
389
|
+
void xt_promise_add_async_waiter(xt_value promise, void *async);
|
|
390
|
+
|
|
302
391
|
/* Exception-frame plumbing shared with the generator runtime. The struct is
|
|
303
392
|
* public so a coroutine can `_setjmp` its own boundary directly (a `setjmp`
|
|
304
393
|
* must run in the frame it returns to, never in a helper). */
|
package/runtime/xt_alloc.c
CHANGED
|
@@ -389,6 +389,9 @@ static void xt_gc_process(xt_header *header) {
|
|
|
389
389
|
case XT_OBJECT_KIND_GENERATOR:
|
|
390
390
|
xt_generator_gc_trace(header);
|
|
391
391
|
return;
|
|
392
|
+
case XT_OBJECT_KIND_ASYNC:
|
|
393
|
+
xt_async_gc_trace(header);
|
|
394
|
+
return;
|
|
392
395
|
default:
|
|
393
396
|
/* Symbols, regexps, iterators and any future kind whose references live
|
|
394
397
|
* inline: the payload scan covers them. */
|
|
@@ -432,6 +435,9 @@ static void xt_gc_release(xt_header *header) {
|
|
|
432
435
|
case XT_OBJECT_KIND_GENERATOR:
|
|
433
436
|
xt_generator_gc_release(header);
|
|
434
437
|
break;
|
|
438
|
+
case XT_OBJECT_KIND_ASYNC:
|
|
439
|
+
xt_async_gc_release(header);
|
|
440
|
+
break;
|
|
435
441
|
default:
|
|
436
442
|
break;
|
|
437
443
|
}
|