xbintsc 0.3.46 → 0.3.49
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 +95 -0
- package/README.md +25 -0
- package/README.zh-CN.md +23 -0
- package/dist/src/cli/hints.d.ts +54 -0
- package/dist/src/cli/hints.js +165 -0
- package/dist/src/cli/hints.js.map +1 -0
- package/dist/src/cli/main.js +73 -9
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +26 -0
- package/dist/src/codegen/generator/tables.js +64 -12
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/diagnostics/source-text.d.ts +22 -0
- package/dist/src/diagnostics/source-text.js +76 -0
- package/dist/src/diagnostics/source-text.js.map +1 -0
- package/dist/src/driver/bundler/graph.js +2 -1
- package/dist/src/driver/bundler/graph.js.map +1 -1
- package/dist/src/driver/compiler.js +3 -2
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/lexer/scanner/strings.js +16 -3
- package/dist/src/lexer/scanner/strings.js.map +1 -1
- package/dist/tests/cli/hints.test.d.ts +9 -0
- package/dist/tests/cli/hints.test.js +143 -0
- package/dist/tests/cli/hints.test.js.map +1 -0
- package/dist/tests/cli/main.test.js +6 -4
- package/dist/tests/cli/main.test.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +17 -2
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/helpers.js +3 -2
- package/dist/tests/helpers.js.map +1 -1
- package/dist/tests/lexer/strings.test.js +14 -2
- package/dist/tests/lexer/strings.test.js.map +1 -1
- package/doc/DESIGN.md +117 -0
- package/doc/ai/README.md +63 -0
- package/doc/ai/build-recipe.md +137 -0
- package/doc/ai/cli.md +142 -0
- package/doc/ai/contributing.md +196 -0
- package/doc/ai/extensions.md +148 -0
- package/doc/ai/language-support.md +152 -0
- package/doc/ai/troubleshooting.md +163 -0
- package/doc/ai/zh-CN/README.md +56 -0
- package/doc/ai/zh-CN/build-recipe.md +132 -0
- package/doc/ai/zh-CN/cli.md +127 -0
- package/doc/ai/zh-CN/contributing.md +173 -0
- package/doc/ai/zh-CN/extensions.md +139 -0
- package/doc/ai/zh-CN/language-support.md +147 -0
- package/doc/ai/zh-CN/troubleshooting.md +150 -0
- package/doc/gui-scripts.md +350 -0
- package/doc/gui.md +646 -0
- package/doc/icon.md +265 -0
- package/doc/implemented.md +373 -0
- package/doc/node-implemented.md +588 -0
- package/doc/node-unimplemented.md +167 -0
- package/doc/post/announce.md +43 -0
- package/doc/requirements.md +145 -0
- package/doc/unimplemented.md +286 -0
- package/doc/xbintsc.config.schema.json +67 -0
- package/doc/zh-CN/DESIGN.md +104 -0
- package/doc/zh-CN/gui-scripts.md +329 -0
- package/doc/zh-CN/gui.md +588 -0
- package/doc/zh-CN/icon.md +241 -0
- package/doc/zh-CN/implemented.md +365 -0
- package/doc/zh-CN/node-implemented.md +533 -0
- package/doc/zh-CN/node-unimplemented.md +141 -0
- package/doc/zh-CN/plan-require-node-modules.md +284 -0
- package/doc/zh-CN/post/announce.md +47 -0
- package/doc/zh-CN/requirements.md +134 -0
- package/doc/zh-CN/unimplemented.md +247 -0
- package/llms.txt +45 -0
- package/package.json +4 -1
- package/runtime/ext_gui/gui.cpp +3 -1
- package/runtime/ext_gui/renderer.cpp +13 -11
- package/runtime/ext_gui/renderer_image.cpp +12 -8
- package/runtime/ext_gui/renderer_shaders.h +131 -4
- package/runtime/ext_gui/renderer_shaders_data.h +1809 -0
- package/runtime/ext_gui/renderer_text.cpp +12 -8
- package/runtime/ext_gui/shaders.hlsl +98 -0
- package/runtime/ext_gui/spirv/fill.frag +19 -0
- package/runtime/ext_gui/spirv/fill.vert +42 -0
- package/runtime/ext_gui/spirv/image.frag +16 -0
- package/runtime/ext_gui/spirv/quad.vert +30 -0
- package/runtime/ext_gui/spirv/text.frag +16 -0
- package/scripts/build-gui-shaders.mjs +204 -0
- package/scripts/build-gui.ts +35 -0
- package/scripts/check-file-length.ts +5 -1
- package/src/cli/hints.ts +194 -0
- package/src/cli/main.ts +82 -9
- package/src/codegen/generator/tables.ts +60 -14
- package/src/diagnostics/source-text.ts +78 -0
- package/src/driver/bundler/graph.ts +2 -1
- package/src/driver/compiler.ts +3 -2
- package/src/lexer/scanner/strings.ts +16 -3
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# xbintsc 未实现语法与功能
|
|
2
|
+
|
|
3
|
+
> 语言 / Language:[English](../unimplemented.md) | **简体中文**
|
|
4
|
+
|
|
5
|
+
本文档基于对源码(`src/`、`runtime/`)与测试(`tests/`)的逐文件核对整理,列出**当前未实现 / 仅部分实现 / 语义与标准不符**的语法与功能。
|
|
6
|
+
|
|
7
|
+
判定标准(按严重程度):
|
|
8
|
+
|
|
9
|
+
1. **未解析**:解析器直接报语法错误,无法进入代码生成。
|
|
10
|
+
2. **解析但代码生成报错**:AST / 绑定能建立,但 `codegen` 报 `UnsupportedFeature`。
|
|
11
|
+
3. **解析且能编译,但语义未实现或有偏差**:能产出二进制,但运行结果不符合 ECMAScript / TypeScript 语义。
|
|
12
|
+
|
|
13
|
+
> 近期已补齐:**ECMAScript 语义 + 差分测试** —— 数字格式化 / 强制转换(`toFixed` / `toPrecision` / `toExponential`、十六 / 八 / 二进制解析、完整的 `+` 与关系运算 `ToPrimitive`)、`JSON.stringify` 省略规则、`Array.prototype.sort` 默认稳定字符串序、整数键插入序、整链可选链短路、`finally` 在提前 `return` / `break` / `continue` 时执行、对象键插入序、感知 UTF-8 且能展示循环引用的 `console` 输出、`Array.prototype.splice`、`String.prototype.match` / `lastIndexOf` / 带 limit 的 `split`、正则捕获组(`exec` / `match` / `replace` / `split` / `search`)、不可变数组方法(`toReversed` / `toSorted` / `toSpliced` / `with`)、`Object.getOwnPropertyNames` / `groupBy`、全局 URI 函数、标签语句、`#private` 字段 / 方法 / 静态成员、标记模板(含 raw 字符串与 `String.raw`)、相对模块的 `import * as ns`。测试套件新增了**差分测试脚手架**:每个用例同时经 xbintsc 与 Node 运行并逐字节比较输出。
|
|
14
|
+
|
|
15
|
+
> 更早已补齐:`class` 声明 / 类表达式、`new` / `this`、继承 `extends` / `super`、`instanceof`、方法 / 静态成员 / 实例字段 / getter 与 setter / 构造器参数属性、`async` / `await` + `Promise`、`import` / `export` 多文件打包(含 `.js` → `.ts` 说明符解析与命名空间导入)、`Map` / `Set` / `Date` / `RegExp` / `JSON` / `BigInt`、解构绑定与解构参数、`enum` / `const enum`,以及**自举**(产出的 LLVM IR 达到逐字节不动点)。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. 语句层未实现
|
|
20
|
+
|
|
21
|
+
### 1.1 解析但代码生成报 `UnsupportedFeature`
|
|
22
|
+
|
|
23
|
+
| 语法 | 现状 | 说明 |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `namespace` / `module` 声明 | 解析 ✓,代码生成 ✗ | → "does not yet support this statement (module declaration)" |
|
|
26
|
+
|
|
27
|
+
> 标签语句(`label: statement`、`break label`、`continue label`)已实现,包括非循环语句上的标签。
|
|
28
|
+
|
|
29
|
+
### 1.2 解析器不支持(直接语法错误)
|
|
30
|
+
|
|
31
|
+
目前未知有语句级别的缺口。解析器有意保持宽松,接受绝大多数 TypeScript 语句语法;不支持的形式会在代码生成阶段报错(见上)。
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. 表达式层未实现
|
|
36
|
+
|
|
37
|
+
### 2.1 解析但代码生成报 `UnsupportedFeature`
|
|
38
|
+
|
|
39
|
+
无——生成器已实现。
|
|
40
|
+
|
|
41
|
+
> 标记模板已实现,含 raw 字符串与 `String.raw`。生成器(`function*`、`yield`、`yield*`)
|
|
42
|
+
> 基于有栈协程实现,支持 `next`/`throw`/`return`、`for...of`、展开与委托;
|
|
43
|
+
> `import.meta` 可解析,但无运行时取值;异步生成器尚未支持。
|
|
44
|
+
|
|
45
|
+
### 2.2 解析器不支持
|
|
46
|
+
|
|
47
|
+
目前未知有表达式级别的缺口。
|
|
48
|
+
|
|
49
|
+
### 2.3 运算符未实现
|
|
50
|
+
|
|
51
|
+
| 运算符 | 现状 | 说明 |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `new.target` | ✗ | 未实现 |
|
|
54
|
+
| `typeof` / `void` / `in` / `delete` / `instanceof` | ✓ | 映射到运行时辅助函数(`xt_typeof`、`xt_in`、`xt_delete`、`xt_instance_of`) |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 3. 标准库未实现
|
|
59
|
+
|
|
60
|
+
### 3.1 已实现(概要)
|
|
61
|
+
|
|
62
|
+
- 数组:`push` `pop` `shift` `unshift` `join` `slice` `splice` `indexOf` `lastIndexOf` `includes` `concat` `reverse` `forEach` `map` `filter` `reduce` `reduceRight` `find` `findIndex` `findLast` `findLastIndex` `some` `every` `sort` `flat` `flatMap` `fill` `copyWithin` `at` `keys` `values` `entries`,以及不可变的 `toReversed` / `toSorted` / `toSpliced` / `with`
|
|
63
|
+
- 字符串:`charAt` `charCodeAt` `codePointAt` `indexOf` `lastIndexOf` `includes` `startsWith` `endsWith` `slice` `substring` `substr` `split` `match` `replace` `replaceAll` `search` `toUpperCase` `toLowerCase` `trim` `trimStart` `trimEnd` `padStart` `padEnd` `repeat` `concat` `at` `localeCompare` `valueOf`
|
|
64
|
+
- `Math`:完整函数与常量
|
|
65
|
+
- `Object.keys` / `values` / `entries` / `assign` / `getOwnPropertyNames` / `groupBy`,对象展开 `{...obj}`
|
|
66
|
+
- 全局函数:`parseInt` `parseFloat` `isNaN` `isFinite` `Number` `String` `Boolean` `encodeURI` `decodeURI` `encodeURIComponent` `decodeURIComponent`
|
|
67
|
+
- `console.log` / `info` / `warn` / `error` / `dir` / `trace` / `assert` / `count` / `group` / `table` / `time`
|
|
68
|
+
|
|
69
|
+
### 3.2 已补齐
|
|
70
|
+
|
|
71
|
+
- `JSON.parse` / `JSON.stringify`
|
|
72
|
+
- `Date`、`RegExp`(POSIX ERE 子集,支持捕获组)、`Map`、`Set`、`Promise`、`BigInt`
|
|
73
|
+
- `Array` 静态(`isArray/of/from`)、`Object` 静态、`Number` 静态、`String` 静态(`fromCharCode` / `fromCodePoint` / `raw`)
|
|
74
|
+
- `Error` 家族(`Error`、`TypeError`、`RangeError`、`SyntaxError`、`ReferenceError`、`EvalError`、`URIError`、`AggregateError`):支持 `new`、`instanceof`、`extends`、`String(err)` / `err.toString()` 与 `.stack`
|
|
75
|
+
|
|
76
|
+
### 3.3 仍未实现
|
|
77
|
+
|
|
78
|
+
| 类别 | 现状 |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `Symbol` 构造器与 symbol 原始值 | ✓ `Symbol(description)`、著名符号、`Symbol.for` / `Symbol.keyFor`、symbol 属性键与 `Object.getOwnPropertySymbols` |
|
|
81
|
+
| `String.prototype.normalize` | ✗ 未实现 |
|
|
82
|
+
| `structuredClone` | ✗ 未实现 |
|
|
83
|
+
| 内置错误子类(`TypeError`、`RangeError` 等) | ✓ 一等公民构造器与原型;整个家族 `instanceof Error` 成立 |
|
|
84
|
+
| `AggregateError` 构造器 | ✓ `new AggregateError(errors, message)`;`Promise.any` 现以其作为 rejection |
|
|
85
|
+
| 迭代器协议 / `Symbol.iterator` / `for...of` 自定义可迭代 | ✓ 数组、字符串、`Map`、`Set`、生成器以及任何暴露 `[Symbol.iterator]()` 的对象均可在 `for...of` / 展开中使用 |
|
|
86
|
+
| 生成器(`function*`、`yield`、`yield*`、`next`/`throw`/`return`) | ✓ 基于有栈协程实现;支持 `for...of`、展开与委托。`return()` 直接结束,不执行 `finally` |
|
|
87
|
+
| 定时器 | ✓ 核心事件循环提供 `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval`(返回数字 id,无 `Timeout` 对象;无 `setImmediate` / `queueMicrotask`) |
|
|
88
|
+
| I/O / 进程等宿主 API | 仅通过扩展(如 Node `fs`)提供 |
|
|
89
|
+
|
|
90
|
+
### 3.4 类型化数组
|
|
91
|
+
|
|
92
|
+
已实现:`Uint8Array`、`Int8Array`、`Uint8ClampedArray`、`Uint16Array`、
|
|
93
|
+
`Int16Array`、`Uint32Array`、`Int32Array`、`Float32Array`、`Float64Array`,支持
|
|
94
|
+
`new X(n)` / `new X(数组样)`、`X.from` / `X.of`、`BYTES_PER_ELEMENT`、按类型强制的
|
|
95
|
+
元素写入,以及 `fill` / `set` / `slice` / `subarray` / `join` / `toString` /
|
|
96
|
+
`indexOf` / `lastIndexOf` / `includes` / `forEach` / `map` / `filter` / `every` /
|
|
97
|
+
`some` / `find` / `findIndex` / `reduce` / `reverse` / `sort` / `copyWithin` /
|
|
98
|
+
`at` / `keys` / `values` / `entries`。已知差异:
|
|
99
|
+
|
|
100
|
+
| 功能 | 现状 |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `subarray` | ~ 返回副本,而非共享缓冲区上的视图 |
|
|
103
|
+
| `keys` / `values` / `entries` | ~ 返回数组,而非迭代器对象 |
|
|
104
|
+
| `ArrayBuffer` / `DataView` / `.buffer` / `.byteOffset` 语义 | ✗ 无底层缓冲区类型;`.byteOffset` 恒为 0 |
|
|
105
|
+
| `BigInt64Array` / `BigUint64Array` | ✗ 未实现 |
|
|
106
|
+
| `instanceof Uint8Array` | ✗ 全局构造器不是一等公民值,`x instanceof Uint8Array` 会报 `Cannot find name 'Uint8Array'` |
|
|
107
|
+
| 基于 `Buffer` / `ArrayBuffer` 的类型化数组视图 | ✗ 构造器仅能从长度 / 数组样 / 类型化数组复制 |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 4. 模块系统
|
|
112
|
+
|
|
113
|
+
| 功能 | 现状 |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| 多文件 / 模块解析与链接 | ✓ 驱动层 AST 打包(`src/driver/modules.ts`):解析每个模块、按模块前缀重命名顶层符号、改写引用后合并为单文件重新绑定 |
|
|
116
|
+
| 具名导入导出 | ✓ `import { a, b as c }` / `export { a as b }` / `export const/let/var/function/class` |
|
|
117
|
+
| 默认导入导出 | ✓ `export default` / `import d from` |
|
|
118
|
+
| 再导出 `export { x } from` / `export * from` | ✓(`export *` 复制依赖模块的导出) |
|
|
119
|
+
| 命名空间导入 `import * as ns` | ✓ 降级为持有全部导出的合成对象字面量 |
|
|
120
|
+
| 循环依赖 | ✗ 直接报错(不做循环初始化语义) |
|
|
121
|
+
| 实时绑定(live bindings) | ✗ 命名空间对象与导入绑定是模块求值时的快照 |
|
|
122
|
+
| ESM `node_modules` 包 | ✓ 裸说明符沿目录树解析,支持 `exports` / `module` / `main`、作用域包与子路径;包源码与相对模块一样被打包 |
|
|
123
|
+
| CommonJS `require` / `module.exports` | ✓ 仅限 `node_modules` 内:打包器为每个 CommonJS 包注入合成的 `module` / `exports`,将 `require("x")` 降级为依赖的导出对象,并把外部/内置 `require` 提升为 ESM `import`。用户代码(`node_modules` 之外)的 `require()` 仍会报错并提示改用 ESM `import` |
|
|
124
|
+
|
|
125
|
+
> 扩展模块(如 `fs`)可通过裸名称或 `node:` 前缀的 `import` 引入 —— `import { readFileSync } from "fs"` / `import path from "path"` —— 并解析到运行时入口(具名、默认与命名空间形式均可)。相对模块与 `node_modules` 中的 ESM/CJS 包均在驱动层打包;CJS 包内的 `require` 会静态解析并内联。
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 5. 函数特性未实现(或语义缺失)
|
|
130
|
+
|
|
131
|
+
| 特性 | 解析 | 语义 |
|
|
132
|
+
| --- | --- | --- |
|
|
133
|
+
| 默认参数 `function f(a = 5)` | ✓ | ✓ 已实现 |
|
|
134
|
+
| 剩余参数 `function f(...args)` | ✓ | ✓ 已实现 |
|
|
135
|
+
| 调用参数展开 `f(...args)` | ✓ | ✓ 已实现 |
|
|
136
|
+
| 解构参数 / 解构绑定 | ✓ | ✓ 已实现 |
|
|
137
|
+
| `arguments` 对象 | ✓(隐式) | ✓ 已实现(箭头函数取的是自身参数,而非外层函数的 `arguments`,与 JS 不同) |
|
|
138
|
+
| `this` 绑定 / 方法调用语义 | ✓ | ✓ 已实现(`this` 作为函数首个 ABI 参数线程化;箭头函数词法继承) |
|
|
139
|
+
| `async` / `await` / Promise | ✓ | ✓ 已实现(同步微任务模型) |
|
|
140
|
+
| `new.target` | ✗ | 未实现 |
|
|
141
|
+
| 生成器 / 迭代器 / `yield` | ✓ 已实现 | `function*`、`yield`、`yield*`、`.next/.throw/.return`;不支持异步生成器 |
|
|
142
|
+
| 闭包 `arity` | — | `xt_closure_arity` 恒为 -1,未填充 |
|
|
143
|
+
| `fn.call` / `fn.apply` / `fn.bind` | ✓ | ✓ 已实现(绑定闭包不跟踪部分参数的 `length`) |
|
|
144
|
+
| `fn.name` / `fn.length` | ✓ | ✓ 已实现(从声明 / 赋值 / 属性键推断;绑定函数为 `"bound ..."` 并调整 arity) |
|
|
145
|
+
| 内置方法一等公民(`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` 也一并暴露 |
|
|
146
|
+
| `fn.toString()` | ~ | 返回原生占位字符串(`function name() { [native code] }`),而非原始源码文本 |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 6. 类与面向对象
|
|
151
|
+
|
|
152
|
+
| 特性 | 现状 |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `class` 声明 / 类表达式 | ✓ 已实现 |
|
|
155
|
+
| 构造函数 `constructor` | ✓ |
|
|
156
|
+
| 实例字段 / 属性声明 | ✓ |
|
|
157
|
+
| 方法 | ✓ |
|
|
158
|
+
| `static` 字段 / 方法 | ✓ |
|
|
159
|
+
| 继承 `extends` / `super` | ✓(单级正确;`super` 取 `this` 原型的原型,理论缺陷见第 8 节) |
|
|
160
|
+
| 原型链 / 方法查找 | ✓ |
|
|
161
|
+
| `instanceof` | ✓ |
|
|
162
|
+
| `new` / 实例化 | ✓ |
|
|
163
|
+
| `get` / `set` 访问器 | ✓ 已实现 |
|
|
164
|
+
| 参数属性 `constructor(public x: T)` | ✓ 已实现 |
|
|
165
|
+
| 私有字段 `#x` | ✓ 已实现(以字面量 `#x` 作为键存储;无访问控制强制) |
|
|
166
|
+
| `enum` / `const enum` | ✓ 已实现(正向 + 反向映射) |
|
|
167
|
+
| `private` / `protected` / `public` / `readonly` 修饰符 | ✗ 无访问控制(擦除) |
|
|
168
|
+
| `abstract` / `implements` | ✗(擦除) |
|
|
169
|
+
| 父子类 `#x` 同名 | ✗ 可能混用(同一字面量键) |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 7. 类型系统未实现(仅解析、不检查)
|
|
174
|
+
|
|
175
|
+
类型语法被解析为 AST 后在绑定 / 代码生成阶段**整体擦除**,不做任何类型检查:
|
|
176
|
+
|
|
177
|
+
- 类型注解、返回类型、类型参数、类型别名、接口、泛型约束等:解析 ✓,检查 ✗。
|
|
178
|
+
- 检查器诊断码(`TypeMismatch` `NotCallable` `PropertyNotFound` `ArgumentCountMismatch`)已定义但**未使用**。
|
|
179
|
+
- `as` / `satisfies` / 非空断言 `!`:直接擦除,不做任何断言语义。
|
|
180
|
+
- 泛型:无运行时实例化,类型参数被忽略。
|
|
181
|
+
- 可选链 `?.` 的类型窄化:无(运行时短路已实现,但无类型层面的窄化)。
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 8. 运行时 / 语义与标准不符(已知偏差)
|
|
186
|
+
|
|
187
|
+
这些特性**能编译、能运行**,但结果不完全符合 ECMAScript:
|
|
188
|
+
|
|
189
|
+
| 项 | 偏差 |
|
|
190
|
+
| --- | --- |
|
|
191
|
+
| 字符串 `length` | 按 UTF-8 字节计数,而非 UTF-16 码元(`"\u00e9".length` 报 1 而非 2;`"\u{1F600}".length` 报 4 而非 2;`codePointAt` 同样有偏差) |
|
|
192
|
+
| `Object.getPrototypeOf({})` | 返回 `undefined`,而非 `Object.prototype` 对象 |
|
|
193
|
+
| 全局正则 `lastIndex` | `/g`、`/y` 正则的 `test` / `exec` 不推进也不读取调用方设置的 `lastIndex` |
|
|
194
|
+
| `String.normalize` / `structuredClone` | 未实现 |
|
|
195
|
+
| 内置方法一等公民 | 以未绑定方法值实现(见第 5 节);`fn.toString()` 返回占位字符串而非源码文本 |
|
|
196
|
+
| `for...in` | 枚举对象 / 数组 / 字符串的自身键;不含原型链属性 |
|
|
197
|
+
| 数组越界 / 稀疏 | 越界访问返回 `undefined`;对 `arr.length` 赋值会截断 / 扩展,但不区分稀疏空洞 |
|
|
198
|
+
| 内存管理 | 非移动标记-清扫回收器(在 `xt_alloc` 之后):显式根、子系统根提供者与保守 C 栈扫描。单线程、stop-the-world;无移动/压缩与分代 |
|
|
199
|
+
| 函数 `arity` / 调用参数个数 | 无参数个数校验;`fn.length` 报告声明的 arity,但调用不做校验 |
|
|
200
|
+
| `async` / `await` | **同步微任务模型**:`await` 在已 settle 的 promise 上同步继续。定时器与套接字仅在程序主体执行完后由事件循环运行,因此无法等待由定时器回调 settle 的 promise |
|
|
201
|
+
| `super` | `super.x` / `super(...)` 取 `this` 原型的原型;单级继承正确,继承深度 > 1 时可能不准确 |
|
|
202
|
+
| `Error.stack` | 未捕获 |
|
|
203
|
+
| 模块实时绑定 | 命名空间导入与导入绑定为快照(见第 4 节) |
|
|
204
|
+
| `import.meta` | 可解析但无取值 |
|
|
205
|
+
|
|
206
|
+
> 数字格式化、宽松相等、`+` / 关系运算 `ToPrimitive`、整链可选链、`finally` 提前退出、对象键顺序等均已对齐 Node,并由差分测试覆盖,故不再列为偏差。
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 9. 工具链 / 平台 / 工程未实现
|
|
211
|
+
|
|
212
|
+
| 项 | 现状 |
|
|
213
|
+
| --- | --- |
|
|
214
|
+
| GC(垃圾回收) | ✓ `xt_alloc.c` 中的非移动标记-清扫,按存活堆阈值(`XT_GC_THRESHOLD`)或 `xt_gc_collect()` 触发;显式根 + 根提供者 + 保守活动栈扫描。无压缩、弱引用或后台回收 |
|
|
215
|
+
| 自举(self-hosting) | ✓ 编译器已能自编译:`xbintsc build src/cli/main.ts` 可产出可用二进制,且从第 1 代起产出的 IR 保持稳定。运行时仍为 C |
|
|
216
|
+
| 类型检查器 | ✗ 仅定义诊断码,无 checker |
|
|
217
|
+
| 完整标准库 | 部分:Math / JSON / Date / Map / Set / RegExp / `Error` / `BigInt` / `Symbol` 已实现;String.normalize / structuredClone 缺失 |
|
|
218
|
+
| 多文件模块打包 | 部分:相对路径 `.ts` 打包、ESM `node_modules` 包、命名空间导入、裸说明符扩展模块导入已实现;循环依赖 / CommonJS / 实时绑定未实现 |
|
|
219
|
+
| 真正的异步运行时 / 事件循环 | ✗(Promise 为同步微任务模型) |
|
|
220
|
+
| Windows 二进制产物验证 | 构建层已适配(`.exe` 后缀、链接参数分支),并在 CI 中验证 |
|
|
221
|
+
| 精确的 ECMAScript 数值 / 字符串 / 比较语义 | 部分,见第 8 节 |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 10. 速查:未实现 / 部分实现清单
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
未实现(语句):namespace/module 声明
|
|
229
|
+
|
|
230
|
+
未实现(表达式):new.target、import.meta 取值
|
|
231
|
+
|
|
232
|
+
未实现(函数):`fn.toString()` 源码文本、异步生成器
|
|
233
|
+
|
|
234
|
+
未实现(类/面向对象):abstract/implements、访问控制、父子类 #x 同名
|
|
235
|
+
|
|
236
|
+
未实现(标准库):String.normalize、structuredClone
|
|
237
|
+
|
|
238
|
+
未实现(模块):循环依赖、实时绑定、动态 `require(expr)`、
|
|
239
|
+
`require.resolve` / `require.cache`、`__dirname` / `__filename`
|
|
240
|
+
|
|
241
|
+
未实现(类型系统):类型检查、泛型实例化、断言语义、可选链类型窄化
|
|
242
|
+
|
|
243
|
+
未实现(运行时):真正的异步事件循环、UTF-16 length、
|
|
244
|
+
Object.prototype 身份、全局正则 lastIndex
|
|
245
|
+
|
|
246
|
+
未实现(工程):类型检查器
|
|
247
|
+
```
|
package/llms.txt
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# xbintsc
|
|
2
|
+
|
|
3
|
+
> xbintsc compiles a subset of TypeScript directly to native binaries: it parses
|
|
4
|
+
> TypeScript itself, lowers the program to LLVM IR text, and drives clang to
|
|
5
|
+
> produce a standalone executable linked against a small C runtime. There is no
|
|
6
|
+
> Node.js, V8 or TypeScript compiler inside the produced binary. It runs on
|
|
7
|
+
> macOS, Linux and Windows (x64 and arm64), compiles itself, and ships prebuilt
|
|
8
|
+
> archives per platform. A clang 16+ toolchain is required to link binaries;
|
|
9
|
+
> `xbintsc emit` (LLVM IR only) needs nothing.
|
|
10
|
+
|
|
11
|
+
## Start here
|
|
12
|
+
|
|
13
|
+
- [AGENTS.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/AGENTS.md): entry point for an agent working in the repository — what xbintsc is, the repository map, the build gate and the rules
|
|
14
|
+
- [doc/ai/README.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/README.md): task-oriented AI guide — the three facts that decide everything, and which page to read for your task
|
|
15
|
+
- [README.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/README.md): the project's human overview
|
|
16
|
+
|
|
17
|
+
## Using the compiler
|
|
18
|
+
|
|
19
|
+
- [doc/ai/build-recipe.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/build-recipe.md): exact commands to run, build, inspect IR and configure a project, with the program shape that compiles
|
|
20
|
+
- [doc/ai/cli.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/cli.md): every CLI flag and its parsing quirks, project config fields, environment variables, incremental-cache behaviour, diagnostic codes, programmatic API
|
|
21
|
+
- [doc/ai/language-support.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/language-support.md): the supported TypeScript subset as tables — statements, expressions, classes, async, the erased type system, standard library gaps, modules, runtime deviations
|
|
22
|
+
- [doc/ai/extensions.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/extensions.md): Node built-in modules and the `--ext node` rule, the GUI extension, bundling third-party packages, C++/Rust native extensions via manifest
|
|
23
|
+
- [doc/ai/troubleshooting.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/troubleshooting.md): the clang version requirement and every frequent error message with its cause and fix
|
|
24
|
+
- [doc/requirements.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/requirements.md): per-platform toolchain prerequisites
|
|
25
|
+
- [doc/xbintsc.config.schema.json](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/xbintsc.config.schema.json): JSON schema for `xbintsc.config.json`
|
|
26
|
+
|
|
27
|
+
## Changing the compiler
|
|
28
|
+
|
|
29
|
+
- [doc/ai/contributing.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/ai/contributing.md): test suites, the self-hosting fixpoint invariant, the runtime ABI and value model, adding extensions or diagnostics, documentation duties
|
|
30
|
+
- [doc/DESIGN.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/DESIGN.md): architecture and design rationale
|
|
31
|
+
- [doc/implemented.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/implemented.md): everything implemented, by compiler stage — the canonical reference
|
|
32
|
+
- [doc/unimplemented.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/unimplemented.md): unsupported syntax, missing semantics and known deviations, with a quick-reference list
|
|
33
|
+
- [doc/node-implemented.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/node-implemented.md): Node module coverage of the `node` extension
|
|
34
|
+
- [doc/node-unimplemented.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/node-unimplemented.md): what the `node` extension is still missing
|
|
35
|
+
- [doc/gui.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/gui.md): the self-hosted GPU HTML/CSS renderer
|
|
36
|
+
- [doc/gui-scripts.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/gui-scripts.md): the GUI scripting surface
|
|
37
|
+
- [doc/icon.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/icon.md): application icons and project config packaging
|
|
38
|
+
- [examples/extensions/README.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/examples/extensions/README.md): authoring C++ and Rust native extensions
|
|
39
|
+
|
|
40
|
+
## Optional
|
|
41
|
+
|
|
42
|
+
- [doc/zh-CN/](https://github.com/zy445566/xbintsc/tree/main/doc/zh-CN): Chinese translations of the canonical documents
|
|
43
|
+
- [doc/ai/zh-CN/](https://github.com/zy445566/xbintsc/tree/main/doc/ai/zh-CN): Chinese translations of the AI guide
|
|
44
|
+
- [doc/post/announce.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/doc/post/announce.md): announcement / project write-up
|
|
45
|
+
- [README.zh-CN.md](https://raw.githubusercontent.com/zy445566/xbintsc/main/README.zh-CN.md): the project overview in Chinese
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xbintsc",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.49",
|
|
4
4
|
"description": "xbintsc - a TypeScript binary compiler (TypeScript -> LLVM IR -> native binary)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
"runtime",
|
|
28
28
|
"scripts",
|
|
29
29
|
"bin",
|
|
30
|
+
"doc",
|
|
31
|
+
"AGENTS.md",
|
|
32
|
+
"llms.txt",
|
|
30
33
|
"README.md"
|
|
31
34
|
],
|
|
32
35
|
"scripts": {
|
package/runtime/ext_gui/gui.cpp
CHANGED
|
@@ -73,7 +73,9 @@ static int ensure_init(void) {
|
|
|
73
73
|
return 0;
|
|
74
74
|
}
|
|
75
75
|
/* Accept every shader format so the same code runs on Metal, Vulkan and
|
|
76
|
-
* D3D12; the backend only needs the one it supports.
|
|
76
|
+
* D3D12; the backend only needs the one it supports. The engine ships MSL,
|
|
77
|
+
* SPIR-V and DXIL shaders accordingly, and picks the matching one in
|
|
78
|
+
* `renderer_shaders.h`. */
|
|
77
79
|
SDL_GPUShaderFormat formats =
|
|
78
80
|
SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_DXIL;
|
|
79
81
|
g_device = SDL_CreateGPUDevice(formats, false, NULL);
|
|
@@ -130,30 +130,32 @@ bool xt_gui_renderer_ensure(SDL_GPUDevice *device, SDL_Window *reference) {
|
|
|
130
130
|
using namespace xtgui::renderer_detail;
|
|
131
131
|
if (g_pipeline != nullptr) return true;
|
|
132
132
|
if (g_renderer_failed) return false;
|
|
133
|
-
|
|
133
|
+
const ShaderSource fill_vs = selectShader(device, ShaderProgram::Fill, false);
|
|
134
|
+
const ShaderSource fill_fs = selectShader(device, ShaderProgram::Fill, true);
|
|
135
|
+
if (!fill_vs.valid() || !fill_fs.valid()) {
|
|
134
136
|
fprintf(stderr,
|
|
135
|
-
"xt_gui: backend
|
|
136
|
-
"(Vulkan
|
|
137
|
+
"xt_gui: backend supports neither Metal nor D3D12 shaders; shape/text painting "
|
|
138
|
+
"disabled (Vulkan SPIR-V blobs are a TODO)\n");
|
|
137
139
|
g_renderer_failed = 1;
|
|
138
140
|
return false;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
SDL_GPUShaderCreateInfo vs_info;
|
|
142
144
|
memset(&vs_info, 0, sizeof(vs_info));
|
|
143
|
-
vs_info.code_size =
|
|
144
|
-
vs_info.code =
|
|
145
|
-
vs_info.entrypoint =
|
|
146
|
-
vs_info.format =
|
|
145
|
+
vs_info.code_size = fill_vs.size;
|
|
146
|
+
vs_info.code = fill_vs.code;
|
|
147
|
+
vs_info.entrypoint = fill_vs.entry;
|
|
148
|
+
vs_info.format = fill_vs.format;
|
|
147
149
|
vs_info.stage = SDL_GPU_SHADERSTAGE_VERTEX;
|
|
148
150
|
vs_info.num_uniform_buffers = 1;
|
|
149
151
|
SDL_GPUShader *vs = SDL_CreateGPUShader(device, &vs_info);
|
|
150
152
|
|
|
151
153
|
SDL_GPUShaderCreateInfo fs_info;
|
|
152
154
|
memset(&fs_info, 0, sizeof(fs_info));
|
|
153
|
-
fs_info.code_size =
|
|
154
|
-
fs_info.code =
|
|
155
|
-
fs_info.entrypoint =
|
|
156
|
-
fs_info.format =
|
|
155
|
+
fs_info.code_size = fill_fs.size;
|
|
156
|
+
fs_info.code = fill_fs.code;
|
|
157
|
+
fs_info.entrypoint = fill_fs.entry;
|
|
158
|
+
fs_info.format = fill_fs.format;
|
|
157
159
|
fs_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
|
|
158
160
|
SDL_GPUShader *fs = SDL_CreateGPUShader(device, &fs_info);
|
|
159
161
|
|
|
@@ -17,22 +17,26 @@ namespace xtgui {
|
|
|
17
17
|
namespace renderer_detail {
|
|
18
18
|
|
|
19
19
|
SDL_GPUGraphicsPipeline *createImagePipeline(SDL_GPUDevice *device, SDL_Window *reference) {
|
|
20
|
+
const ShaderSource image_vs = selectShader(device, ShaderProgram::Image, false);
|
|
21
|
+
const ShaderSource image_fs = selectShader(device, ShaderProgram::Image, true);
|
|
22
|
+
if (!image_vs.valid() || !image_fs.valid()) return nullptr;
|
|
23
|
+
|
|
20
24
|
SDL_GPUShaderCreateInfo vs_info;
|
|
21
25
|
memset(&vs_info, 0, sizeof(vs_info));
|
|
22
|
-
vs_info.code_size =
|
|
23
|
-
vs_info.code =
|
|
24
|
-
vs_info.entrypoint =
|
|
25
|
-
vs_info.format =
|
|
26
|
+
vs_info.code_size = image_vs.size;
|
|
27
|
+
vs_info.code = image_vs.code;
|
|
28
|
+
vs_info.entrypoint = image_vs.entry;
|
|
29
|
+
vs_info.format = image_vs.format;
|
|
26
30
|
vs_info.stage = SDL_GPU_SHADERSTAGE_VERTEX;
|
|
27
31
|
vs_info.num_uniform_buffers = 1;
|
|
28
32
|
SDL_GPUShader *vs = SDL_CreateGPUShader(device, &vs_info);
|
|
29
33
|
|
|
30
34
|
SDL_GPUShaderCreateInfo fs_info;
|
|
31
35
|
memset(&fs_info, 0, sizeof(fs_info));
|
|
32
|
-
fs_info.code_size =
|
|
33
|
-
fs_info.code =
|
|
34
|
-
fs_info.entrypoint =
|
|
35
|
-
fs_info.format =
|
|
36
|
+
fs_info.code_size = image_fs.size;
|
|
37
|
+
fs_info.code = image_fs.code;
|
|
38
|
+
fs_info.entrypoint = image_fs.entry;
|
|
39
|
+
fs_info.format = image_fs.format;
|
|
36
40
|
fs_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
|
|
37
41
|
fs_info.num_samplers = 1;
|
|
38
42
|
SDL_GPUShader *fs = SDL_CreateGPUShader(device, &fs_info);
|
|
@@ -1,13 +1,39 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* xbintsc GUI engine —
|
|
2
|
+
* xbintsc GUI engine — shader sources.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* `renderer.cpp` (fills), `renderer_text.cpp` (glyphs) and `renderer_image.cpp`
|
|
5
|
+
* (images) each build one SDL_GPU graphics pipeline. Three shader families back
|
|
6
|
+
* them, one per SDL_GPU backend:
|
|
7
|
+
*
|
|
8
|
+
* - Metal: the MSL string literals below, which SDL_GPU compiles at runtime.
|
|
9
|
+
* - Vulkan: SPIR-V blobs in `renderer_shaders_data.h`, compiled from
|
|
10
|
+
* `spirv/*.{vert,frag}` by `scripts/build-gui-shaders.mjs`.
|
|
11
|
+
* - Direct3D 12: DXIL blobs from the same header, compiled from `shaders.hlsl`.
|
|
12
|
+
*
|
|
13
|
+
* `selectShader` resolves a logical program and stage to whichever of those the
|
|
14
|
+
* device accepts. The backend rejects any other format, so a missing blob means
|
|
15
|
+
* "no pipeline", never a mismatched one.
|
|
16
|
+
*
|
|
17
|
+
* Text and image quads share the vertex program; only the fragment entry point
|
|
18
|
+
* differs (`fs_text` vs `fs_image`).
|
|
19
|
+
*
|
|
20
|
+
* Note the entry-point names differ per format: MSL/DXIL keep the descriptive
|
|
21
|
+
* names from their sources, while glslc emits the GLSL `main`.
|
|
7
22
|
*/
|
|
8
23
|
#ifndef XT_GUI_RENDERER_SHADERS_H
|
|
9
24
|
#define XT_GUI_RENDERER_SHADERS_H
|
|
10
25
|
|
|
26
|
+
#include <SDL3/SDL.h>
|
|
27
|
+
#include <cstring>
|
|
28
|
+
|
|
29
|
+
#include "renderer_shaders_data.h"
|
|
30
|
+
|
|
31
|
+
namespace xtgui {
|
|
32
|
+
namespace renderer_detail {
|
|
33
|
+
|
|
34
|
+
/** The three pipeline programs the engine builds. */
|
|
35
|
+
enum class ShaderProgram { Fill, Text, Image };
|
|
36
|
+
|
|
11
37
|
/* Rounded-rectangle fill. Vertex attributes (matching SDL_GPUVertexAttribute):
|
|
12
38
|
* 0 -> position (pixels, viewport-relative)
|
|
13
39
|
* 1 -> local (pixels, relative to the rectangle centre)
|
|
@@ -105,4 +131,105 @@ fragment float4 fs_image(TextOut in [[stage_in]],
|
|
|
105
131
|
}
|
|
106
132
|
)MSL";
|
|
107
133
|
|
|
134
|
+
/** One stage of one pipeline program, in whichever format the device accepts. */
|
|
135
|
+
struct ShaderSource {
|
|
136
|
+
SDL_GPUShaderFormat format = 0;
|
|
137
|
+
const unsigned char *code = nullptr;
|
|
138
|
+
size_t size = 0;
|
|
139
|
+
const char *entry = nullptr;
|
|
140
|
+
|
|
141
|
+
bool valid() const { return code != nullptr; }
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/** The MSL text backing `program` (one literal covers both stages). */
|
|
145
|
+
inline const char *mslSource(ShaderProgram program) {
|
|
146
|
+
return program == ShaderProgram::Fill ? kFillMSL : kTextMSL;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** MSL entry point names for `program`, matching the literals below. */
|
|
150
|
+
inline const char *vertexEntry(ShaderProgram program) {
|
|
151
|
+
return program == ShaderProgram::Fill ? "vs_main" : "vs_text";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
inline const char *fragmentEntry(ShaderProgram program) {
|
|
155
|
+
if (program == ShaderProgram::Fill) return "fs_main";
|
|
156
|
+
return program == ShaderProgram::Text ? "fs_text" : "fs_image";
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** A blob pair for one shader format: bytes plus the entry-point names it uses.
|
|
160
|
+
* The names are stored in `ShaderSource` rather than resolved at the call site
|
|
161
|
+
* because cross-compilers rename entry points (glslc emits `main`, dxc keeps the
|
|
162
|
+
* HLSL name, MSL keeps the Metal name). */
|
|
163
|
+
struct ShaderBlobs {
|
|
164
|
+
const unsigned char *vertex;
|
|
165
|
+
size_t vertex_size;
|
|
166
|
+
const char *vertex_entry;
|
|
167
|
+
const unsigned char *fragment;
|
|
168
|
+
size_t fragment_size;
|
|
169
|
+
const char *fragment_entry;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/** SPIR-V blobs for `program` (Vulkan). glslc names every entry point `main`. */
|
|
173
|
+
inline ShaderBlobs spirvBlobs(ShaderProgram program) {
|
|
174
|
+
switch (program) {
|
|
175
|
+
case ShaderProgram::Fill:
|
|
176
|
+
return {kFillSpirvVs, kFillSpirvVsSize, "main", kFillSpirvFs, kFillSpirvFsSize, "main"};
|
|
177
|
+
case ShaderProgram::Text:
|
|
178
|
+
return {kTextSpirvVs, kTextSpirvVsSize, "main", kTextSpirvFs, kTextSpirvFsSize, "main"};
|
|
179
|
+
case ShaderProgram::Image:
|
|
180
|
+
return {kTextSpirvVs, kTextSpirvVsSize, "main", kImageSpirvFs, kImageSpirvFsSize, "main"};
|
|
181
|
+
}
|
|
182
|
+
return {nullptr, 0, nullptr, nullptr, 0, nullptr};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** DXIL blobs for `program` (Direct3D 12); one blob per entry point. */
|
|
186
|
+
inline ShaderBlobs dxilBlobs(ShaderProgram program) {
|
|
187
|
+
switch (program) {
|
|
188
|
+
case ShaderProgram::Fill:
|
|
189
|
+
return {kFillDxilVs, kFillDxilVsSize, "vs_main", kFillDxilFs, kFillDxilFsSize, "fs_main"};
|
|
190
|
+
case ShaderProgram::Text:
|
|
191
|
+
return {kTextDxilVs, kTextDxilVsSize, "vs_text", kTextDxilFs, kTextDxilFsSize, "fs_text"};
|
|
192
|
+
case ShaderProgram::Image:
|
|
193
|
+
return {kTextDxilVs, kTextDxilVsSize, "vs_text", kImageDxilFs, kImageDxilFsSize, "fs_image"};
|
|
194
|
+
}
|
|
195
|
+
return {nullptr, 0, nullptr, nullptr, 0, nullptr};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** MSL for `program`: a single source holds both stages, so it is expressed as a
|
|
199
|
+
* blob pair sharing one buffer. */
|
|
200
|
+
inline ShaderBlobs mslBlobs(ShaderProgram program) {
|
|
201
|
+
const char *msl = mslSource(program);
|
|
202
|
+
const size_t size = strlen(msl);
|
|
203
|
+
const unsigned char *code = (const unsigned char *)msl;
|
|
204
|
+
return {code, size, vertexEntry(program), code, size, fragmentEntry(program)};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Resolve `program`'s vertex and fragment stages to shaders the device accepts.
|
|
208
|
+
* Returns an invalid source when the backend supports none of the formats the
|
|
209
|
+
* engine ships. */
|
|
210
|
+
inline ShaderSource selectShader(SDL_GPUDevice *device, ShaderProgram program, bool fragment) {
|
|
211
|
+
ShaderSource source;
|
|
212
|
+
const SDL_GPUShaderFormat formats = SDL_GetGPUShaderFormats(device);
|
|
213
|
+
ShaderBlobs blobs;
|
|
214
|
+
if ((formats & SDL_GPU_SHADERFORMAT_MSL) != 0) {
|
|
215
|
+
source.format = SDL_GPU_SHADERFORMAT_MSL;
|
|
216
|
+
blobs = mslBlobs(program);
|
|
217
|
+
} else if ((formats & SDL_GPU_SHADERFORMAT_SPIRV) != 0) {
|
|
218
|
+
source.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
|
219
|
+
blobs = spirvBlobs(program);
|
|
220
|
+
} else if ((formats & SDL_GPU_SHADERFORMAT_DXIL) != 0) {
|
|
221
|
+
source.format = SDL_GPU_SHADERFORMAT_DXIL;
|
|
222
|
+
blobs = dxilBlobs(program);
|
|
223
|
+
} else {
|
|
224
|
+
return source;
|
|
225
|
+
}
|
|
226
|
+
source.code = fragment ? blobs.fragment : blobs.vertex;
|
|
227
|
+
source.size = fragment ? blobs.fragment_size : blobs.vertex_size;
|
|
228
|
+
source.entry = fragment ? blobs.fragment_entry : blobs.vertex_entry;
|
|
229
|
+
return source;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
} // namespace renderer_detail
|
|
233
|
+
} // namespace xtgui
|
|
234
|
+
|
|
108
235
|
#endif /* XT_GUI_RENDERER_SHADERS_H */
|