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.
- package/README.en.md +3 -0
- package/README.md +2 -0
- package/lib/abort.d.ts +21 -0
- package/lib/assert.d.ts +2 -0
- package/lib/bitmap.d.ts +7 -0
- package/lib/cache-utils.d.ts +6 -0
- package/lib/certs.d.ts +1 -0
- package/lib/dpi.d.ts +9 -0
- package/lib/dumpRects.d.ts +2 -0
- package/lib/exec-log.d.ts +23 -0
- package/lib/fetch.d.ts +4 -0
- package/lib/ffi/bind.d.ts +70 -0
- package/lib/ffi/ctype.d.ts +117 -0
- package/lib/ffi/index.d.ts +2 -0
- package/lib/ffi/struct.d.ts +174 -0
- package/lib/http-common.d.ts +143 -0
- package/lib/http-server.d.ts +59 -0
- package/lib/polyfill.d.ts +22 -0
- package/lib/react-qw/components/Button.d.ts +9 -0
- package/lib/react-qw/components/CheckBox.d.ts +11 -0
- package/lib/react-qw/components/ComboBox.d.ts +11 -0
- package/lib/react-qw/components/DateTimePicker.d.ts +15 -0
- package/lib/react-qw/components/Input.d.ts +15 -0
- package/lib/react-qw/components/Link.d.ts +12 -0
- package/lib/react-qw/components/ListBox.d.ts +13 -0
- package/lib/react-qw/components/ListView.d.ts +37 -0
- package/lib/react-qw/components/PathPicker.d.ts +23 -0
- package/lib/react-qw/components/ProgressBar.d.ts +9 -0
- package/lib/react-qw/components/RadioButton.d.ts +11 -0
- package/lib/react-qw/components/ScrollView.d.ts +9 -0
- package/lib/react-qw/components/Slider.d.ts +12 -0
- package/lib/react-qw/components/Tab.d.ts +14 -0
- package/lib/react-qw/components/Tooltip.d.ts +7 -0
- package/lib/react-qw/components/TreeView.d.ts +18 -0
- package/lib/react-qw/components/index.d.ts +16 -0
- package/lib/react-qw/index.d.ts +24 -0
- package/lib/react-qw/layout.d.ts +29 -0
- package/lib/react-qw/nmhdr.d.ts +1 -0
- package/lib/react-qw/props.d.ts +2 -0
- package/lib/react-qw/reconciler.d.ts +21 -0
- package/lib/stream.d.ts +20 -0
- package/lib/text-codec.d.ts +39 -0
- package/lib/text-measure.d.ts +14 -0
- package/lib/url.d.ts +54 -0
- package/lib/websocket.d.ts +73 -0
- package/lib/windows/{advapi32.ts → advapi32.d.ts} +6 -21
- package/lib/windows/comctl32.d.ts +14 -0
- package/lib/windows/comdlg32.d.ts +4 -0
- package/lib/windows/{gdi32.ts → gdi32.d.ts} +161 -98
- package/lib/windows/{kernel32.ts → kernel32.d.ts} +138 -115
- package/lib/windows/{msimg32.ts → msimg32.d.ts} +11 -14
- package/lib/windows/ntdll.d.ts +5 -0
- package/lib/windows/ole32.d.ts +3 -0
- package/lib/windows/{psapi.ts → psapi.d.ts} +9 -18
- package/lib/windows/{shell32.ts → shell32.d.ts} +25 -24
- package/lib/windows/structs.d.ts +3141 -0
- package/lib/windows/{user32.ts → user32.d.ts} +196 -193
- package/lib/windows/version.d.ts +27 -0
- package/lib/windows/{winspool.ts → winspool.d.ts} +18 -32
- package/package.json +15 -8
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/examples/PdfCanvas.js +0 -38
- package/examples/PdfCanvas.tsx +0 -54
- package/examples/execd/main.js +0 -23379
- package/examples/execd/tray.js +0 -192
- package/examples/execd/worker.js +0 -122
- package/examples/pdf_preview2.js +0 -398
- package/examples/pdf_preview2.ts +0 -353
- package/examples/pdf_viewer.js +0 -22515
- package/examples/pdf_viewer.tsx +0 -228
- package/examples/test_gallery.js +0 -18692
- package/examples/test_gallery.tsx +0 -291
- package/examples/test_react_lazy.js +0 -18560
- package/examples/test_react_lazy.tsx +0 -65
- package/examples/test_react_listbox.js +0 -18562
- package/examples/test_react_listbox.tsx +0 -73
- package/examples/test_root_window.js +0 -18532
- package/examples/test_root_window.tsx +0 -41
- package/examples/test_tab.js +0 -18563
- package/examples/test_tab.tsx +0 -77
- package/examples/tray_demo.js +0 -86
- package/examples/tray_demo.tsx +0 -89
- package/lib/abort.ts +0 -69
- package/lib/assert.ts +0 -7
- package/lib/bitmap.ts +0 -39
- package/lib/cache-utils.ts +0 -40
- package/lib/certs.ts +0 -258
- package/lib/dpi.ts +0 -31
- package/lib/dumpRects.ts +0 -34
- package/lib/exec-log.ts +0 -30
- package/lib/fetch.ts +0 -589
- package/lib/ffi/bind.ts +0 -540
- package/lib/ffi/ctype.ts +0 -371
- package/lib/ffi/index.ts +0 -6
- package/lib/ffi/struct.ts +0 -780
- package/lib/http-common.ts +0 -441
- package/lib/http-server.ts +0 -604
- package/lib/polyfill.ts +0 -171
- package/lib/react-qw/components/index.ts +0 -17
- package/lib/react-qw/index.ts +0 -96
- package/lib/react-qw/layout.ts +0 -111
- package/lib/react-qw/nmhdr.ts +0 -7
- package/lib/react-qw/props.ts +0 -41
- package/lib/react-qw/reconciler.ts +0 -379
- package/lib/stream.ts +0 -22
- package/lib/text-codec.ts +0 -171
- package/lib/text-measure.ts +0 -44
- package/lib/url.ts +0 -201
- package/lib/websocket.ts +0 -600
- package/lib/windows/comctl32.ts +0 -20
- package/lib/windows/comdlg32.ts +0 -10
- package/lib/windows/ntdll.ts +0 -11
- package/lib/windows/ole32.ts +0 -9
- package/lib/windows/structs.ts +0 -807
- package/lib/windows/version.ts +0 -35
- package/test/add.wasm +0 -0
- package/test/bench_ffi_callraw.js +0 -235
- package/test/bench_ffi_callraw.ts +0 -235
- package/test/bench_ffi_overhead.js +0 -139
- package/test/bench_ffi_overhead.ts +0 -141
- package/test/bench_sendmessage.js +0 -104
- package/test/bench_sendmessage.ts +0 -100
- package/test/bench_sendmessage_nonnull.js +0 -187
- package/test/bench_sendmessage_nonnull.ts +0 -188
- package/test/complex.wasm +0 -0
- package/test/complex_imports.wasm +0 -0
- package/test/debug/http_server_e2e.js +0 -31
- package/test/debug/minwasm.js +0 -52
- package/test/debug/mupdf_debug.js +0 -86
- package/test/debug/wasm.js +0 -122
- package/test/debug/wasm_export_debug.js +0 -54
- package/test/debug/wasm_names.js +0 -36
- package/test/example.pdf +0 -0
- package/test/global_imports.wasm +0 -0
- package/test/import_func.wasm +0 -0
- package/test/imports.wasm +0 -0
- package/test/mupdf-cdn.js +0 -40
- package/test/mupdf-cdn.ts +0 -43
- package/test/run.js +0 -111
- package/test/run.ts +0 -116
- package/test/sjlj.wasm +0 -0
- package/test/test_basic.js +0 -7
- package/test/test_basic.ts +0 -9
- package/test/test_basic_fetch.js +0 -63
- package/test/test_basic_fetch.ts +0 -59
- package/test/test_brotli.js +0 -48
- package/test/test_brotli.ts +0 -52
- package/test/test_fetch_cache.js +0 -169
- package/test/test_fetch_cache.ts +0 -187
- package/test/test_ffi.js +0 -157
- package/test/test_ffi.ts +0 -170
- package/test/test_ffi_abi.js +0 -290
- package/test/test_ffi_abi.ts +0 -274
- package/test/test_ffi_array.js +0 -116
- package/test/test_ffi_array.ts +0 -141
- package/test/test_ffi_bind.js +0 -656
- package/test/test_ffi_bind.ts +0 -670
- package/test/test_ffi_struct.js +0 -779
- package/test/test_ffi_struct.ts +0 -828
- package/test/test_ffi_struct_layout.js +0 -495
- package/test/test_ffi_struct_layout.ts +0 -543
- package/test/test_ffi_user32.js +0 -103
- package/test/test_ffi_user32.ts +0 -113
- package/test/test_ffi_windows.js +0 -172
- package/test/test_ffi_windows.ts +0 -187
- package/test/test_files.js +0 -102
- package/test/test_files.ts +0 -121
- package/test/test_frame_encoding.js +0 -128
- package/test/test_frame_encoding.ts +0 -132
- package/test/test_gdi_draw.js +0 -681
- package/test/test_gdi_draw.ts +0 -725
- package/test/test_helper.js +0 -91
- package/test/test_helper.ts +0 -88
- package/test/test_http_import.js +0 -96
- package/test/test_http_import.ts +0 -93
- package/test/test_http_server.js +0 -214
- package/test/test_http_server.ts +0 -211
- package/test/test_import_dir.js +0 -4
- package/test/test_import_dir.ts +0 -5
- package/test/test_ipv6.js +0 -134
- package/test/test_ipv6.ts +0 -130
- package/test/test_jsx.js +0 -1314
- package/test/test_meta_url.js +0 -3
- package/test/test_meta_url.ts +0 -4
- package/test/test_mupdf_render.js +0 -51
- package/test/test_mupdf_render.ts +0 -55
- package/test/test_mupdf_twice.js +0 -62
- package/test/test_mupdf_twice.ts +0 -65
- package/test/test_mupdf_wasm.js +0 -39
- package/test/test_mupdf_wasm.ts +0 -32
- package/test/test_net_event.js +0 -57
- package/test/test_net_event.ts +0 -56
- package/test/test_net_fetch.js +0 -384
- package/test/test_net_fetch.ts +0 -373
- package/test/test_net_websocket.js +0 -180
- package/test/test_net_websocket.ts +0 -164
- package/test/test_polyfill.js +0 -144
- package/test/test_polyfill.ts +0 -159
- package/test/test_printer.js +0 -137
- package/test/test_printer.ts +0 -148
- package/test/test_proc.js +0 -141
- package/test/test_proc.ts +0 -163
- package/test/test_react_complex.js +0 -18678
- package/test/test_react_counter.js +0 -18555
- package/test/test_react_flex.js +0 -18871
- package/test/test_react_hidden.js +0 -18560
- package/test/test_react_listview_link.js +0 -18590
- package/test/test_react_notify.js +0 -18797
- package/test/test_react_render.js +0 -18550
- package/test/test_registry.js +0 -74
- package/test/test_registry.ts +0 -95
- package/test/test_sysinfo.js +0 -122
- package/test/test_sysinfo.ts +0 -141
- package/test/test_url.js +0 -173
- package/test/test_url.ts +0 -183
- package/test/test_wasm_basic.js +0 -85
- package/test/test_wasm_basic.ts +0 -73
- package/test/test_wasm_import_global.js +0 -41
- package/test/test_wasm_import_global.ts +0 -45
- package/test/test_wasm_sjlj.js +0 -145
- package/test/test_wasm_sjlj.ts +0 -125
- package/test/test_wasm_types.js +0 -97
- package/test/test_wasm_types.ts +0 -124
- package/test/test_wolfssl_read.js +0 -203
- package/test/test_wolfssl_read.ts +0 -184
- package/test/test_worker.js +0 -21
- package/test/test_worker.ts +0 -24
- package/test/test_worker_concurrent.js +0 -45
- package/test/test_worker_concurrent.ts +0 -56
- package/test/test_worker_data_url.js +0 -46
- package/test/test_worker_data_url.ts +0 -51
- package/test/test_worker_fetch.js +0 -26
- package/test/test_worker_fetch.ts +0 -27
- package/test/test_worker_net.js +0 -69
- package/test/test_worker_net.ts +0 -66
- package/test/test_worker_wasm_concurrent.js +0 -44
- package/test/test_worker_wasm_concurrent.ts +0 -45
- package/test/types.wasm +0 -0
- package/test/worker_fetch.js +0 -13
- package/test/worker_fetch.ts +0 -13
- package/test/worker_helper.js +0 -1
- package/test/worker_helper.ts +0 -1
- package/test/worker_http.js +0 -18
- package/test/worker_http.ts +0 -20
- package/test/worker_import_lib.js +0 -12
- package/test/worker_import_lib.ts +0 -13
- package/test/worker_module.js +0 -16
- package/test/worker_module.ts +0 -17
- package/test/worker_wasm_concurrent.js +0 -22
- 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'
|