quickwin 3.0.0 → 3.0.2

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 (253) hide show
  1. package/README.en.md +3 -0
  2. package/README.md +2 -0
  3. package/lib/abort.d.ts +21 -0
  4. package/lib/assert.d.ts +2 -0
  5. package/lib/bitmap.d.ts +7 -0
  6. package/lib/cache-utils.d.ts +6 -0
  7. package/lib/certs.d.ts +1 -0
  8. package/lib/dpi.d.ts +9 -0
  9. package/lib/dumpRects.d.ts +2 -0
  10. package/lib/exec-log.d.ts +23 -0
  11. package/lib/fetch.d.ts +4 -0
  12. package/lib/ffi/bind.d.ts +70 -0
  13. package/lib/ffi/ctype.d.ts +117 -0
  14. package/lib/ffi/index.d.ts +2 -0
  15. package/lib/ffi/struct.d.ts +174 -0
  16. package/lib/http-common.d.ts +143 -0
  17. package/lib/http-server.d.ts +59 -0
  18. package/lib/polyfill.d.ts +22 -0
  19. package/lib/react-qw/components/Button.d.ts +9 -0
  20. package/lib/react-qw/components/CheckBox.d.ts +11 -0
  21. package/lib/react-qw/components/ComboBox.d.ts +11 -0
  22. package/lib/react-qw/components/DateTimePicker.d.ts +15 -0
  23. package/lib/react-qw/components/Input.d.ts +15 -0
  24. package/lib/react-qw/components/Link.d.ts +12 -0
  25. package/lib/react-qw/components/ListBox.d.ts +13 -0
  26. package/lib/react-qw/components/ListView.d.ts +37 -0
  27. package/lib/react-qw/components/PathPicker.d.ts +23 -0
  28. package/lib/react-qw/components/ProgressBar.d.ts +9 -0
  29. package/lib/react-qw/components/RadioButton.d.ts +11 -0
  30. package/lib/react-qw/components/ScrollView.d.ts +9 -0
  31. package/lib/react-qw/components/Slider.d.ts +12 -0
  32. package/lib/react-qw/components/Tab.d.ts +14 -0
  33. package/lib/react-qw/components/Tooltip.d.ts +7 -0
  34. package/lib/react-qw/components/TreeView.d.ts +18 -0
  35. package/lib/react-qw/components/index.d.ts +16 -0
  36. package/lib/react-qw/index.d.ts +24 -0
  37. package/lib/react-qw/layout.d.ts +29 -0
  38. package/lib/react-qw/nmhdr.d.ts +1 -0
  39. package/lib/react-qw/props.d.ts +2 -0
  40. package/lib/react-qw/reconciler.d.ts +21 -0
  41. package/lib/stream.d.ts +20 -0
  42. package/lib/text-codec.d.ts +39 -0
  43. package/lib/text-measure.d.ts +14 -0
  44. package/lib/url.d.ts +54 -0
  45. package/lib/websocket.d.ts +73 -0
  46. package/lib/windows/{advapi32.ts → advapi32.d.ts} +6 -21
  47. package/lib/windows/comctl32.d.ts +14 -0
  48. package/lib/windows/comdlg32.d.ts +4 -0
  49. package/lib/windows/{gdi32.ts → gdi32.d.ts} +161 -98
  50. package/lib/windows/{kernel32.ts → kernel32.d.ts} +138 -115
  51. package/lib/windows/{msimg32.ts → msimg32.d.ts} +11 -14
  52. package/lib/windows/ntdll.d.ts +5 -0
  53. package/lib/windows/ole32.d.ts +3 -0
  54. package/lib/windows/{psapi.ts → psapi.d.ts} +9 -18
  55. package/lib/windows/{shell32.ts → shell32.d.ts} +25 -24
  56. package/lib/windows/structs.d.ts +3141 -0
  57. package/lib/windows/{user32.ts → user32.d.ts} +196 -193
  58. package/lib/windows/version.d.ts +27 -0
  59. package/lib/windows/{winspool.ts → winspool.d.ts} +18 -32
  60. package/package.json +15 -8
  61. package/qwin-nowasm-x86.exe +0 -0
  62. package/qwin-nowasm.exe +0 -0
  63. package/qwin-x86.exe +0 -0
  64. package/qwin.exe +0 -0
  65. package/examples/PdfCanvas.js +0 -38
  66. package/examples/PdfCanvas.tsx +0 -54
  67. package/examples/execd/main.js +0 -23379
  68. package/examples/execd/tray.js +0 -192
  69. package/examples/execd/worker.js +0 -122
  70. package/examples/pdf_preview2.js +0 -398
  71. package/examples/pdf_preview2.ts +0 -353
  72. package/examples/pdf_viewer.js +0 -22515
  73. package/examples/pdf_viewer.tsx +0 -228
  74. package/examples/test_gallery.js +0 -18692
  75. package/examples/test_gallery.tsx +0 -291
  76. package/examples/test_react_lazy.js +0 -18560
  77. package/examples/test_react_lazy.tsx +0 -65
  78. package/examples/test_react_listbox.js +0 -18562
  79. package/examples/test_react_listbox.tsx +0 -73
  80. package/examples/test_root_window.js +0 -18532
  81. package/examples/test_root_window.tsx +0 -41
  82. package/examples/test_tab.js +0 -18563
  83. package/examples/test_tab.tsx +0 -77
  84. package/examples/tray_demo.js +0 -86
  85. package/examples/tray_demo.tsx +0 -89
  86. package/lib/abort.ts +0 -69
  87. package/lib/assert.ts +0 -7
  88. package/lib/bitmap.ts +0 -39
  89. package/lib/cache-utils.ts +0 -40
  90. package/lib/certs.ts +0 -258
  91. package/lib/dpi.ts +0 -31
  92. package/lib/dumpRects.ts +0 -34
  93. package/lib/exec-log.ts +0 -30
  94. package/lib/fetch.ts +0 -589
  95. package/lib/ffi/bind.ts +0 -540
  96. package/lib/ffi/ctype.ts +0 -371
  97. package/lib/ffi/index.ts +0 -6
  98. package/lib/ffi/struct.ts +0 -780
  99. package/lib/http-common.ts +0 -441
  100. package/lib/http-server.ts +0 -604
  101. package/lib/polyfill.ts +0 -171
  102. package/lib/react-qw/components/index.ts +0 -17
  103. package/lib/react-qw/index.ts +0 -96
  104. package/lib/react-qw/layout.ts +0 -111
  105. package/lib/react-qw/nmhdr.ts +0 -7
  106. package/lib/react-qw/props.ts +0 -41
  107. package/lib/react-qw/reconciler.ts +0 -379
  108. package/lib/stream.ts +0 -22
  109. package/lib/text-codec.ts +0 -171
  110. package/lib/text-measure.ts +0 -44
  111. package/lib/url.ts +0 -201
  112. package/lib/websocket.ts +0 -600
  113. package/lib/windows/comctl32.ts +0 -20
  114. package/lib/windows/comdlg32.ts +0 -10
  115. package/lib/windows/ntdll.ts +0 -11
  116. package/lib/windows/ole32.ts +0 -9
  117. package/lib/windows/structs.ts +0 -807
  118. package/lib/windows/version.ts +0 -35
  119. package/test/add.wasm +0 -0
  120. package/test/bench_ffi_callraw.js +0 -235
  121. package/test/bench_ffi_callraw.ts +0 -235
  122. package/test/bench_ffi_overhead.js +0 -139
  123. package/test/bench_ffi_overhead.ts +0 -141
  124. package/test/bench_sendmessage.js +0 -104
  125. package/test/bench_sendmessage.ts +0 -100
  126. package/test/bench_sendmessage_nonnull.js +0 -187
  127. package/test/bench_sendmessage_nonnull.ts +0 -188
  128. package/test/complex.wasm +0 -0
  129. package/test/complex_imports.wasm +0 -0
  130. package/test/debug/http_server_e2e.js +0 -31
  131. package/test/debug/minwasm.js +0 -52
  132. package/test/debug/mupdf_debug.js +0 -86
  133. package/test/debug/wasm.js +0 -122
  134. package/test/debug/wasm_export_debug.js +0 -54
  135. package/test/debug/wasm_names.js +0 -36
  136. package/test/example.pdf +0 -0
  137. package/test/global_imports.wasm +0 -0
  138. package/test/import_func.wasm +0 -0
  139. package/test/imports.wasm +0 -0
  140. package/test/mupdf-cdn.js +0 -40
  141. package/test/mupdf-cdn.ts +0 -43
  142. package/test/run.js +0 -111
  143. package/test/run.ts +0 -116
  144. package/test/sjlj.wasm +0 -0
  145. package/test/test_basic.js +0 -7
  146. package/test/test_basic.ts +0 -9
  147. package/test/test_basic_fetch.js +0 -63
  148. package/test/test_basic_fetch.ts +0 -59
  149. package/test/test_brotli.js +0 -48
  150. package/test/test_brotli.ts +0 -52
  151. package/test/test_fetch_cache.js +0 -169
  152. package/test/test_fetch_cache.ts +0 -187
  153. package/test/test_ffi.js +0 -157
  154. package/test/test_ffi.ts +0 -170
  155. package/test/test_ffi_abi.js +0 -290
  156. package/test/test_ffi_abi.ts +0 -274
  157. package/test/test_ffi_array.js +0 -116
  158. package/test/test_ffi_array.ts +0 -141
  159. package/test/test_ffi_bind.js +0 -656
  160. package/test/test_ffi_bind.ts +0 -670
  161. package/test/test_ffi_struct.js +0 -779
  162. package/test/test_ffi_struct.ts +0 -828
  163. package/test/test_ffi_struct_layout.js +0 -495
  164. package/test/test_ffi_struct_layout.ts +0 -543
  165. package/test/test_ffi_user32.js +0 -103
  166. package/test/test_ffi_user32.ts +0 -113
  167. package/test/test_ffi_windows.js +0 -172
  168. package/test/test_ffi_windows.ts +0 -187
  169. package/test/test_files.js +0 -102
  170. package/test/test_files.ts +0 -121
  171. package/test/test_frame_encoding.js +0 -128
  172. package/test/test_frame_encoding.ts +0 -132
  173. package/test/test_gdi_draw.js +0 -681
  174. package/test/test_gdi_draw.ts +0 -725
  175. package/test/test_helper.js +0 -91
  176. package/test/test_helper.ts +0 -88
  177. package/test/test_http_import.js +0 -96
  178. package/test/test_http_import.ts +0 -93
  179. package/test/test_http_server.js +0 -214
  180. package/test/test_http_server.ts +0 -211
  181. package/test/test_import_dir.js +0 -4
  182. package/test/test_import_dir.ts +0 -5
  183. package/test/test_ipv6.js +0 -134
  184. package/test/test_ipv6.ts +0 -130
  185. package/test/test_jsx.js +0 -1314
  186. package/test/test_meta_url.js +0 -3
  187. package/test/test_meta_url.ts +0 -4
  188. package/test/test_mupdf_render.js +0 -51
  189. package/test/test_mupdf_render.ts +0 -55
  190. package/test/test_mupdf_twice.js +0 -62
  191. package/test/test_mupdf_twice.ts +0 -65
  192. package/test/test_mupdf_wasm.js +0 -39
  193. package/test/test_mupdf_wasm.ts +0 -32
  194. package/test/test_net_event.js +0 -57
  195. package/test/test_net_event.ts +0 -56
  196. package/test/test_net_fetch.js +0 -384
  197. package/test/test_net_fetch.ts +0 -373
  198. package/test/test_net_websocket.js +0 -180
  199. package/test/test_net_websocket.ts +0 -164
  200. package/test/test_polyfill.js +0 -144
  201. package/test/test_polyfill.ts +0 -159
  202. package/test/test_printer.js +0 -137
  203. package/test/test_printer.ts +0 -148
  204. package/test/test_proc.js +0 -141
  205. package/test/test_proc.ts +0 -163
  206. package/test/test_react_complex.js +0 -18678
  207. package/test/test_react_counter.js +0 -18555
  208. package/test/test_react_flex.js +0 -18871
  209. package/test/test_react_hidden.js +0 -18560
  210. package/test/test_react_listview_link.js +0 -18590
  211. package/test/test_react_notify.js +0 -18797
  212. package/test/test_react_render.js +0 -18550
  213. package/test/test_registry.js +0 -74
  214. package/test/test_registry.ts +0 -95
  215. package/test/test_sysinfo.js +0 -122
  216. package/test/test_sysinfo.ts +0 -141
  217. package/test/test_url.js +0 -173
  218. package/test/test_url.ts +0 -183
  219. package/test/test_wasm_basic.js +0 -85
  220. package/test/test_wasm_basic.ts +0 -73
  221. package/test/test_wasm_import_global.js +0 -41
  222. package/test/test_wasm_import_global.ts +0 -45
  223. package/test/test_wasm_sjlj.js +0 -145
  224. package/test/test_wasm_sjlj.ts +0 -125
  225. package/test/test_wasm_types.js +0 -97
  226. package/test/test_wasm_types.ts +0 -124
  227. package/test/test_wolfssl_read.js +0 -203
  228. package/test/test_wolfssl_read.ts +0 -184
  229. package/test/test_worker.js +0 -21
  230. package/test/test_worker.ts +0 -24
  231. package/test/test_worker_concurrent.js +0 -45
  232. package/test/test_worker_concurrent.ts +0 -56
  233. package/test/test_worker_data_url.js +0 -46
  234. package/test/test_worker_data_url.ts +0 -51
  235. package/test/test_worker_fetch.js +0 -26
  236. package/test/test_worker_fetch.ts +0 -27
  237. package/test/test_worker_net.js +0 -69
  238. package/test/test_worker_net.ts +0 -66
  239. package/test/test_worker_wasm_concurrent.js +0 -44
  240. package/test/test_worker_wasm_concurrent.ts +0 -45
  241. package/test/types.wasm +0 -0
  242. package/test/worker_fetch.js +0 -13
  243. package/test/worker_fetch.ts +0 -13
  244. package/test/worker_helper.js +0 -1
  245. package/test/worker_helper.ts +0 -1
  246. package/test/worker_http.js +0 -18
  247. package/test/worker_http.ts +0 -20
  248. package/test/worker_import_lib.js +0 -12
  249. package/test/worker_import_lib.ts +0 -13
  250. package/test/worker_module.js +0 -16
  251. package/test/worker_module.ts +0 -17
  252. package/test/worker_wasm_concurrent.js +0 -22
  253. package/test/worker_wasm_concurrent.ts +0 -22
package/lib/ffi/ctype.ts DELETED
@@ -1,371 +0,0 @@
1
- import { bufferPtr } from 'ffi'
2
- import * as os from 'os'
3
-
4
- // ============================================================
5
- // 语法词汇 —— struct/bind 共用的 C 类型描述。标量直接写规范 token 字符串('i32'/'u32'),
6
- // 指针写 '<>ptr'(裸地址)或 '<NAME>ptr'(带名);对象值一律带 '#' 声明键(见 §4)。
7
- // 只描述「C 声明怎么写」(unit/length/encoding 等意图);内存布局与读写视图由
8
- // struct.ts 的 computeStructLayout/lower 单独 lower 成 layout IR。
9
- //
10
- // 叶子模块:刻意不依赖 win/std/text-codec,可被 struct 直接引用,
11
- // 避免「只用 struct」的调用方被动加载整个 bind 运行时。
12
- // 四段按依赖序:§1 kind 词汇表 → §2 指针布局与品牌 → §3 token 词表与白名单(normToken) → §4 值词汇。
13
- // ============================================================
14
-
15
- // ============================================================
16
- // §1 kind 词汇表 —— C_BASIC_TYPE 是唯一手写清单,下列集合全从它派生
17
- // C_BasicType(12) bind 签名 token / lower 后 IR 共用
18
- // C_Number(10) 结构体字段的数字档
19
- // C_Integer(8) C_Number 去浮点 —— 位域存储单元只能是整数档
20
- // Token(11+指针) C_BasicType_Token / Arg·Ret JsTypeOfToken 的操作面(见 §3)
21
- // 排除项:'void' 无大小;裸 'ptr' 用户面禁写(须写 '<>ptr'),内部保留 ——
22
- // 唯一随架构变宽的标量档。lower 后所有指针归一为 kind 'ptr',名字被擦掉。
23
- // ============================================================
24
- const C_BASIC_TYPE = [
25
- 'void', 'u8', 'i8', 'u16', 'i16', 'u32', 'i32',
26
- 'u64', 'i64', 'f32', 'f64', 'ptr',
27
- ] as const
28
-
29
- export type C_BasicType = (typeof C_BASIC_TYPE)[number]
30
- export type C_BasicType_No_Void = Exclude<C_BasicType, 'void'>
31
-
32
- // '!' / '*' 形随 token 走(normToken 只剥运行时不理解的 '@',运行时要执法的 '!'(0 检查)
33
- // 与 '*'(数组分派)保留在 token 上——token 即契约,callPacked 按尾缀执法,无独立 flag
34
- // 可丢)。'<N*>ptr' 数组位无需新词形:品牌段含 '*',整 token 仍在 <${string}>ptr 模板内。
35
- export type C_BasicType_Token = Exclude<C_BasicType, 'ptr'> | `<${string}>ptr` | `<${string}>ptr!` | `<${string}>`
36
- export type C_BasicType_Token_No_Void = Exclude<C_BasicType_Token, 'void'>
37
-
38
- // 尾缀修饰:'!' = 非空担保(见 Arg/RetJsTypeOfToken 的 ! 分支与 callPacked 的运行时 0 检查),
39
- // '@Name' = 枚举值域标注(类型层启用前先由 Norm 归一剥掉)。两者语义正交但作用面不相交
40
- // (! 主品牌位、@ 主裸档整数位,@ 枚举不含 0 时已蕴含 !),故每 token 至多一个修饰。
41
- // 组 1 恒为名字(归一名),组 2 为修饰;槽宽/ABI 只看归一形式。
42
- // 名字形收紧为标识符([A-Za-z_]\w*)∪ 空串(<>ptr 裸地址档),尾部可挂数组字形:
43
- // '*' = 零或多(<N*>ptr 入参连续数组位,元素形 = 单对象位 codec)。其余非标识符
44
- // 字符('+'/'-'/'1' 开头等)不进词法 —— 与 <1abc>ptr/<X-y>ptr 同策略:正则不匹配、
45
- // 绑定时落通用 Unknown token,类型层不设专属禁分支(运行时兜底,无静默通过)。旧版
46
- // ([^<>\s]*) 通配曾使 <FOO+>ptr 被静默当品牌 'FOO+' 接受——语义字形必须结构可见。
47
- const PTR_TOKEN_RE = /^<([A-Za-z_]\w*|)>ptr(!|@[A-Za-z_]\w*)?$/
48
-
49
- export function isCPtrToken(t: string): t is `<${string}>ptr` | `${string}ptr!` | `${string}ptr@${string}` { return PTR_TOKEN_RE.test(t) }
50
-
51
- // '<N>' 裸品牌形 = 按值传参位(<N>ptr 传地址 / <N> 传值)。名字形同指针形(标识符,
52
- // 空名 <> 仅 ptr 档有),不带任何修饰 —— 按值位无 '!'(值不为 NULL)、无 '@'(值域由
53
- // codec 推导、不标枚举)、无 '*'(数组走 structArray encoder 的值域):含修饰的形
54
- // 正则不匹配,落绑定时通用 Unknown token(与 '<X+>ptr' 同策略,运行时兜底)。
55
- const VAL_TOKEN_RE = /^<([A-Za-z_]\w*)>$/
56
-
57
- export function isCValToken(t: string): t is `<${string}>` { return VAL_TOKEN_RE.test(t) }
58
- export function valName<const N extends string>(t: `<${N}>`): N {
59
- const m = VAL_TOKEN_RE.exec(t)
60
- return (m?.[1] || "") as N
61
- }
62
- export function ptrName<const N extends string>(t: `<${N}>ptr` | `<${N}>ptr!`): N {
63
- const m = PTR_TOKEN_RE.exec(t)
64
- return (m?.[1] || "") as N
65
- }
66
- /**
67
- * @description `<${string}>ptr` / `<${string}>ptr!` -> 'ptr'。按值形 `<${string}>` 无
68
- * 标量槽等价物 —— 运行时 throw(返回位由 parseSig 拒、closure 入参位由 closure() 拒,
69
- * 正常路径不可达),返回类型同时 Exclude 掉按值形:消费方(readRet / dispatchClosure
70
- * 的 IA32_ARG_SIZE 索引)拿不到会误导编译期的标量误判。
71
- */
72
- export const cTokenToType = <const T extends string>(
73
- t: T,
74
- ): Exclude<T, `<${string}>ptr` | `<${string}>ptr!` | `<${string}>`> | 'ptr' => {
75
- if (isCPtrToken(t)) return 'ptr'
76
- if (isCValToken(t))
77
- throw new Error(`ffi: cTokenToType: by-value token "${t}" has no scalar slot type`)
78
- return t as Exclude<T, `<${string}>ptr` | `<${string}>ptr!` | `<${string}>`>
79
- }
80
-
81
- // C 的数字类型档:可作结构体字段 / bind 签名 token。排除项理由见 §1。
82
- export type C_Number = Exclude<C_BasicType, 'void' | 'ptr'>
83
-
84
- // 整数档:位域存储单元的合法类型(C 位域只能用整型)。
85
- export type C_Integer = Exclude<C_Number, 'f32' | 'f64'>
86
-
87
- export type Encoding = 'utf-8' | 'utf-16le'
88
-
89
- type First =
90
- | '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm'
91
- | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
92
- | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M'
93
- | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
94
-
95
- // ============================================================
96
- // §4 值词汇(SimpleValue)—— 字段值/数组元素的全部合法形态:
97
- // token 'u32'(规范 token 词汇;'void'/裸 'ptr'/拼错 token 运行时拒绝 —— typedef 别名已移除)
98
- // 数组糖 'u32[4]'(仅 token 元素 —— 更复杂的元素写 '#' array 声明)
99
- // 位域糖 'u32:3'(unit 位归一后须为整数档)
100
- // 字符串糖 'u16[128]@utf-16le'(布局 unit[length] × 解释 @encoding 正交:
101
- // size = typesize × length 由 unit/length 决定,encoding 只管怎么读写
102
- // 这些字节 —— 错配如 'u8[128]@utf-16le' 也语义自洽。与键侧 alignas 同
103
- // 用 '@' 但位置不同(键名尾 vs 值串尾),解析互不干扰。string 是唯一
104
- // 没有 '#' 声明形式的值 —— 糖与 C_String 三元组双射,一种概念一种写法)
105
- // '#' 声明 struct/union(平铺字段 + '#pack')、array(element+length)——
106
- // 对象值的唯一判别键是 '#'(多字段/聚合元素无法用糖表达,故保留)
107
- // '#' 必填(无「裸嵌套 map 默认 struct」):漏写 '#' 时 union 不会静默翻转成 struct,
108
- // 类型层直接报错、运行时 throw。顶层 struct()/union() 例外 —— kind 由函数名表明,
109
- // 参数是平铺字段表(本身不含 '#';DECL 常量直传时 '#' 须与函数名 kind 一致 —— 参数
110
- // 类型交叉 `{ '#'?: 'struct' }` / `{ '#'?: 'union' }` 编译期锁),'#'/`#pack` 由构造器
111
- // 写入声明(buildDecl)。
112
- // ============================================================
113
-
114
- // token 值面:规范 token(C_Number 档)∪ 指针形(含 '!' 非空尾缀)∪ '@枚举标注形'
115
- // (枚举名限 keyof EnumMap —— 未知枚举名在定义点就 ∉ SimpleValue 被拒,与拼错 token
116
- // 同一道闸)。'void' 除外 —— 无大小,不能作字段值。
117
- export type SimpleToken =
118
- | C_Number
119
- | `${C_Number}@${keyof EnumMap}`
120
- | `<${string}>ptr`
121
- | `${string}ptr!`
122
- | `<${string}>ptr@${keyof EnumMap}`
123
-
124
- // 平铺字段表:struct()/union() 参数与 '#' 声明的字段部分(声明类型见下方 C_Struct/C_Union)。
125
- // 键侧词汇:'k@N' = alignas N(键尾 @+数字,字段名不含 '@');'$x' = 匿名槽(只收聚合)。
126
- // '#' 前缀键是指令位,与字段名(First 不含 '#')天然无撞名。
127
- export type SimpleMember = {
128
- [K: `${First}${string}`]: SimpleValue
129
- [K: `$${string}`]: C_Struct | C_Union
130
- }
131
-
132
- // 用 interface(而非 `{'#': ...} & SimpleMember` 交叉别名):交叉 + 循环别名(SimpleMember
133
- // ↔ SimpleValue ↔ 本类型)在展开时有解析顺序陷阱 —— 实测 C_Union 拿到的 SimpleMember
134
- // 丢失索引签名(`'a' extends keyof C_Union` = false,字段字面量被 excess check 拒绝),
135
- // 而 interface 成员惰性求值无此问题。索引签名与 SimpleMember 逐字同源,改一处须同步另一处。
136
- export interface C_Struct {
137
- '#': 'struct'
138
- '#pack'?: number
139
- [K: `${First}${string}`]: SimpleValue
140
- [K: `$${string}`]: C_Struct | C_Union
141
- }
142
- export interface C_Union {
143
- '#': 'union'
144
- '#pack'?: number
145
- [K: `${First}${string}`]: SimpleValue
146
- [K: `$${string}`]: C_Struct | C_Union
147
- }
148
- export type C_Array = { '#': 'array', element: SimpleValue, length: number }
149
-
150
- export type SimpleValue =
151
- | SimpleToken
152
- | `${SimpleToken}[${number}]`
153
- | `${C_Number}:${number}` // 位域糖:仅裸数字档('@'/'!'/'<T>ptr' 尾缀在位域位词汇拒)
154
- | `${'u8' | 'u16'}[${number}]@${Encoding}` // 字符串糖(unit/length 布局 + encoding 解释)
155
- | C_Struct | C_Union | C_Array
156
-
157
-
158
- export const PTR_SIZE = os.arch === 'x64' ? 8 : 4
159
-
160
- export const SizeAlign: Record<C_Number, number> = {
161
- u8: 1, i8: 1,
162
- u16: 2, i16: 2,
163
- u32: 4, i32: 4,
164
- u64: 8, i64: 8,
165
- f32: 4, f64: 8,
166
- }
167
-
168
- // brand 属性用普通字符串键(phantom——运行时就是裸 number,属性不存在):结构等价使
169
- // quickwin.d.ts 的 gui.HWND 能直接书写 `number & { readonly ptrBrand: "HWND" }`,
170
- // 与 Ptr<"HWND"> 双向可赋值、d.ts 零依赖 ctype;unique symbol 按声明位置定身份,
171
- // 反而使跨包的重复副本互不兼容。同构碰撞的防线由 `number &` 交叉保证(裸 number
172
- // 缺属性、纯对象缺 number,构造源只有 Ptr 本身或故意手写)。
173
- // `''` 判在左侧(右侧实例化,不作 naked 分布):T=never 不再塌缩成 never(否则
174
- // `Ptr<never>` 不可构造,decode(… | Ptr<N>) 在 N=never 时直接堵死),含 '' 的并集
175
- // 不再拆分,宽 string 归一裸 number。字面品牌照旧走交叉 brand 分支。
176
- // 空品牌塌缩成 number 是有意设计:FFI 的 `<>ptr` 是 uintptr 双态位(WPARAM/LPARAM/
177
- // void*/LONG_PTR 在 C ABI 里既收地址又收整数),品牌化会把 sel、max、算术值这类
178
- // 合法实参拦成伪错误——裸档误用靠 NULL 迁移后的调用点纪律兜底,不做 tsc 强制。
179
- export type Ptr<T extends string> =
180
- '' extends T ? number : number & { readonly ptrBrand: T }
181
-
182
- /** NULL 品牌零:0 的品牌形态 —— 全 FFI 层唯一的空指针字面量(对应 C 的 NULL 宏,
183
- * 运行时就是 0)。JS 的 null 不在指针值域:类型层禁收,运行时不做 null→0 转换
184
- * (动态 null 在参数槽 / 写槽处 fail-loud 报错)。 */
185
- export type NULL = 0 & { readonly ptrBrand: 'NULL' }
186
- export const NULL = 0 as NULL
187
-
188
- /** 唯一指针类型:参数位 / 返回位 / struct 字段 / closure 双侧通用。
189
- * C→JS 0 保真(readScalar 不做 0→null);JS→C 空位写 NULL(写槽即 0)。
190
- * 传参前由 tsc 收窄掉空位(truthy / === NULL / === 0)。 */
191
- export type MaybePtr<T extends string> =
192
- NULL | Ptr<T>
193
-
194
- // 用户 token 词表 → JS 类型。刻意不含 'ptr':用户面禁写裸 ptr,Arg/Ret 的
195
- // `K & keyof` 索引到 never 自塌拒绝;IR 层 kind 含 'ptr' 的消费者(Entry)
196
- // 自行 `& { ptr: number }` 增量。
197
- export type C_TypeJsTypeMap = {
198
- u8: number; i8: number; u16: number; i16: number
199
- u32: number; i32: number; i64: bigint, u64: bigint
200
- f32: number; f64: number
201
- }
202
-
203
- export type TokenArgJsTypeMap = C_TypeJsTypeMap
204
- export type TokenReturnJsTypeMap = C_TypeJsTypeMap & { void: void }
205
-
206
- /** token 枚举标注('u32@Name' / '<>ptr@Name')的值域表 —— 全局 interface 声明合并:
207
- * 预填由 tools/gen_enum_map.sh 从 quickwin_const.d.ts 提取(quickwin_enum_map.d.ts),
208
- * 用户在自己的 .d.ts 里直接扩展(interface EnumMap { MyEnum: import('...').MyEnum })——
209
- * 勿用 declare module:用户 import specifier 形态五花八门,模块匹配不上;全局合并对
210
- * 「按枚举名索引」的 token 语义才成立。消费点(bind Arg/Ret、struct 字段)统一以
211
- * `infer E extends keyof EnumMap` 收紧后直接索引本表 —— 值域类型不分参数/返回语境
212
- * (拦异种枚举、域外字面量靠枚举类型自身的 nominal);未知枚举名由词汇/分支约束
213
- * 挡在外面:struct 定义点 ∉ SimpleValue,bind 签名落链末 map[never] 塌 never
214
- * (参数位)/ unknown(返回位——never 是 bottom 会被任意使用放行,反而危险)。 */
215
- declare global {
216
- // 预填见 quickwin_enum_map.d.ts;此处空声明兜底(预填文件缺省时引用处仍可解析)。
217
- interface EnumMap { }
218
- }
219
-
220
- // token → JS 类型(实参语境)。L = 布局名→JS 形;M/D 已固化(TokenArgJsTypeMap /
221
- // never —— 'void'/裸 'ptr'/拼错 token 经 map[K & keyof] 塌 never,参数位调用点全红
222
- // fail-loud)。分支链:'!' 在链首(非空担保 → Ptr<N> 排 NULL,带布局形照收);
223
- // '@E' 枚举值域(模式用 `infer E extends keyof EnumMap` 收紧:未知枚举名分支失配、
224
- // 落链末 map[never] —— 与 struct 侧词汇定义点拒绝构成双层防线;nominal:拦异种枚举、
225
- // 拦裸 0/NULL;单值位标注,flags 组合位不标;不并 layout 形 —— codec 入参编码成
226
- // 地址必然落在枚举域外,留着就是绕过值域承诺的无检查后门);裸 ptr 形收
227
- // MaybePtr | L[N]。'u32!'/'DWORD' 等不匹配任何已知形 → map[never] 塌 never
228
- // (非法形态宁可全红也不放行)。泛型未解析位(K = string —— closure/bindLib
229
- // 泛型体内)由 `string & keyof map` = 全键联合兜底成非 never —— 否则 BindFn 塌
230
- // (never)=>never 使内层强转失去可比性。
231
- export type ArgJsTypeOfToken<K extends string, L> =
232
- // 非标识符名字形('<X+>ptr'/'<X*>ptr'/'<1abc>ptr')不设专属分支:落 '<N>ptr'
233
- // 通配、运行时 Unknown token 兜底('*' 已非 token 字形 —— 数组物化走
234
- // structArray(def) encoder 的值域推导,token/引擎/类型层零数组概念)。
235
- K extends `<${infer N}>ptr!` ? Ptr<N> | L[N & keyof L] :
236
- K extends `<${string}>ptr@${infer E extends keyof EnumMap}` ? EnumMap[E] :
237
- K extends `<${infer N}>ptr` ? MaybePtr<N> | L[N & keyof L] :
238
- // '<N>' 按值位:值域 = 注册布局的 encode 入参形(对象直传),无 MaybePtr —— 按值
239
- // 位不收 NULL / 地址(引擎按值语义编码,地址进位是必然错位)。未注册布局 →
240
- // L[never] → 整位塌 never(与拼错 token 同策略)。
241
- K extends `<${infer N}>` ? L[N & keyof L] :
242
- K extends `${C_Number}@${infer E extends keyof EnumMap}` ? EnumMap[E] :
243
- TokenArgJsTypeMap[K & keyof TokenArgJsTypeMap] extends never ? never
244
- : TokenArgJsTypeMap[K & keyof TokenArgJsTypeMap]
245
-
246
- // token → JS 类型(返回语境)。D = 返回位布局表 decode 值域:该键有 decode →
247
- // D[N] | NULL(解码结果替换地址,空指针 0 保真为 NULL);否则 MaybePtr<N>,
248
- // 与实参位同型(空品牌 <''> 归一裸 number,联合坍缩)。'!' 分支 = 「C 保证非零」
249
- // 的作者担保:去掉 NULL 分支(有 decode → D[N],无 decode → Ptr<N>),运行时返回
250
- // 0 当场 throw 兜底标错;'@E' 分支 = 担保返回值在枚举值域(标错同担,值域校验按需
251
- // Phase 2)。非法 token('i3z'/裸 'ptr')经 map[never] 塌 unknown —— 返回位刻意不是
252
- // never:never 是 bottom 会被任意使用全放行,unknown 逼调用方显式收窄(与参数位
253
- // never 拦调用的不对称是设计)。
254
- export type RetJsTypeOfToken<K extends string, D> =
255
- K extends `<${infer N}>ptr!`
256
- ? (D[N & keyof D] extends never ? Ptr<N> : D[N & keyof D])
257
- : K extends `<${string}>ptr@${infer E extends keyof EnumMap}`
258
- ? EnumMap[E]
259
- : K extends `<${infer N}>ptr`
260
- ? (D[N & keyof D] extends never ? MaybePtr<N> : D[N & keyof D] | NULL)
261
- : K extends `${C_Number}@${infer E extends keyof EnumMap}`
262
- ? EnumMap[E]
263
- : TokenReturnJsTypeMap[K & keyof TokenReturnJsTypeMap] extends never ? unknown
264
- : TokenReturnJsTypeMap[K & keyof TokenReturnJsTypeMap]
265
-
266
- // token 归一:只收规范 token(C_BASIC_TYPE 去 'ptr' = C_Number ∪ 'void',由 §1 唯一手写
267
- // 清单派生)与指针形;拼错 token、已移除的 typedef 别名('DWORD'/'HANDLE')一律 fail-loud。
268
- export function normToken(t: string): C_BasicType_Token {
269
- if (isCPtrToken(t)) {
270
- // 只剥 '@Name'(枚举标注是纯类型层语义,运行时不校验、不理解);'!' 保留在
271
- // token 上——运行时要执法的语义(0 检查)跟着 token 走到 callPacked,
272
- // 无独立 flag 可被解构丢失。槽宽/ABI 判型走 isCPtrToken,带修饰不受影响。
273
- const m = PTR_TOKEN_RE.exec(t)
274
- const name = m?.[1] || ''
275
- const mod = m?.[2]
276
- // 剥 '@'(纯类型层语义);'!' 形随 token 走。('*' 等词法外字符不设专属分支:
277
- // 不匹配正则,落末尾 Unknown token —— 与 '<X+>ptr' 同待遇。)
278
- return (mod?.startsWith('@') ? `<${name}>ptr` : t) as C_BasicType_Token
279
- }
280
- // 按值形 '<N>' 无修饰可剥(见 VAL_TOKEN_RE 注释),原样归一。
281
- if (isCValToken(t)) return t
282
- // 整数档尾缀 '@Name'(枚举值域标注,与 ptr 位的 '@' 同源):剥掉归一到原 token,
283
- // 槽宽/ABI 只看归一形式。@ 后缀须为纯枚举名形 —— 'u32@WmMsg:3' 这类混进位域/数组
284
- // 串的直接 throw,不静默吞成纯标量(布局会错);名 ∈ EnumMap 的语义校验留给类型层
285
- // (运行时不理解枚举名)。白名单 = C_BASIC_TYPE(§1 唯一手写清单);'u32!' 等非
286
- // ptr 位 '!' 尾缀、别名、拼错 token 不命中,落 throw(类型层先塌 never,这里
287
- // 兜底动态传入)。
288
- const at = t.indexOf('@')
289
- const base = at >= 0 ? t.slice(0, at) : t
290
- const suffixOk = at < 0 || /^[A-Za-z_]\w*$/.test(t.slice(at + 1))
291
- if (suffixOk && base !== 'ptr' && (C_BASIC_TYPE as readonly string[]).includes(base)) return base as C_BasicType_Token
292
- throw new Error("Unknown token: " + t)
293
- }
294
-
295
- export function readScalar(dv: DataView, off: number, k: C_BasicType_No_Void): number | bigint | null {
296
- switch (k) {
297
- case 'u8': return dv.getUint8(off)
298
- case 'i8': return dv.getInt8(off)
299
- case 'u16': return dv.getUint16(off, true)
300
- case 'i16': return dv.getInt16(off, true)
301
- case 'u32': return dv.getUint32(off, true)
302
- case 'i32': return dv.getInt32(off, true)
303
- case 'u64': return dv.getBigUint64(off, true)
304
- case 'i64': return dv.getBigInt64(off, true)
305
- case 'f32': return dv.getFloat32(off, true)
306
- case 'f64': return dv.getFloat64(off, true)
307
- case 'ptr': {
308
- // 有符号读(对齐 C 版 JS_NewInt64):-1 哨兵等负值保真;用户态指针高位
309
- // 为 0,有符号读与无符号同值。0 保真返回(即 NULL 品牌零,类型层
310
- // MaybePtr = NULL | Ptr<N>,传参前收窄掉空位)。写回位模式见 writeScalar。
311
- return PTR_SIZE === 8 ? Number(dv.getBigInt64(off, true)) : dv.getInt32(off, true)
312
- }
313
- }
314
- }
315
-
316
- // IR kind 词汇(C_BasicType_No_Void 含 'ptr')——用户词表无 ptr 档,这里自行增量。
317
- type Entry =
318
- { [K in C_BasicType_No_Void]: { k: K; v: (C_TypeJsTypeMap & { ptr: number })[K] } }[C_BasicType_No_Void];
319
-
320
- /** 内存写:按 sizeof 精确写,供 struct 字段编码用。小整数只占自己的字节,
321
- * 否则 `{a:u8,b:u8}` 这类紧凑布局会被 setUint32 越界覆盖相邻字段。 */
322
- export function writeScalar(dv: DataView, off: number, { k, v }: Entry): void {
323
- switch (k) {
324
- case 'u8': dv.setUint8(off, Number(v)); break
325
- case 'i8': dv.setInt8(off, Number(v)); break
326
- case 'u16': dv.setUint16(off, Number(v), true); break
327
- case 'i16': dv.setInt16(off, Number(v), true); break
328
- case 'u32': dv.setUint32(off, (v) >>> 0, true); break
329
- case 'i32': dv.setUint32(off, (v) >>> 0, true); break
330
- case 'u64': dv.setBigUint64(off, v, true); break
331
- case 'i64': dv.setBigInt64(off, v, true); break
332
- case 'f32': dv.setFloat32(off, (v), true); break
333
- case 'f64': dv.setFloat64(off, (v), true); break
334
- case 'ptr': {
335
- // JS null/undefined 不是指针词汇(空位写 NULL)——fail-loud,不做 null→0 转换。
336
- if ((v as unknown) == null) {
337
- throw new Error('ffi: got null/undefined for a ptr slot; pass the imported NULL constant for empty')
338
- }
339
- // 读回的负值(LRESULT/句柄)再作参数回传时按二补位位模式写:asUintN /
340
- // >>> 0 取模保真,否则 x64 传负 setBigUint64 直接 RangeError。
341
- if (PTR_SIZE === 8) dv.setBigUint64(off, BigInt.asUintN(64, BigInt(v)), true)
342
- else dv.setUint32(off, v >>> 0, true)
343
- break
344
- }
345
- }
346
- }
347
-
348
- /** 槽写:供 bind 的参数槽/返回槽用。小整数扩展到 4 字节 —— 可变参数按 int 提升读,
349
- * `i8 = -1` 必须给 `0xFFFFFFFF` 而非 `0x000000FF`。u32/i32/u64/i64/f32/f64/ptr
350
- * 槽宽 == sizeof,直接委托 writeScalar。 */
351
- export function writeSlot(dv: DataView, off: number, e: Entry): void {
352
- const { k, v } = e
353
- if (k === 'u8' || k === 'i8' || k === 'u16' || k === 'i16') {
354
- dv.setUint32(off, Number(v) >>> 0, true)
355
- return
356
- }
357
- writeScalar(dv, off, e)
358
- }
359
-
360
- /** buffer + 品牌指针合一:一个引用既是 ArrayBuffer(喂 decode / encode(v, buf) 复用)
361
- * 又带 `.ptr` 直接喂 <N>ptr 形参 —— 替代旧 { buf, ptr } 结构包装。
362
- * `ptr` 是构造时快照(与旧 StructAlloc 同性质:底层数据不可 detach/transfer)。
363
- * 品牌 N 由创建方声明:struct def 的 alloc()/encode() 返回值在类型层带 def 的 N(不可伪造);
364
- * 直接 new 属自报品牌,仅限内部/原型场景 —— 生产路径一律走 def.alloc()。 */
365
- export class PtrArrayBuffer<N extends string> extends ArrayBuffer {
366
- readonly ptr: Ptr<N>
367
- constructor(byteLength: number) {
368
- super(byteLength)
369
- this.ptr = bufferPtr(this) as Ptr<N>
370
- }
371
- }
package/lib/ffi/index.ts DELETED
@@ -1,6 +0,0 @@
1
- // FFI 公共入口:bind()/bindLib()/closure()(bind.ts)+ struct()/union()(struct.ts)。
2
- // 共享的 CType IR / 标量 kind / C 别名表在 ctype.ts(bind.ts 再透传其类型与函数)。
3
- // 仓库内调用点按需深引用(./bind.js / ./struct.js / ./ctype.js)以保留 tree-shaking;
4
- // 此 barrel 主要供外部/package 使用。
5
- export * from './bind.js'
6
- export * from './struct.js'