@lakutata/ffi 0.0.0-stage → 3.1.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/LICENSE +23 -0
- package/README.md +163 -2
- package/README.zh-CN.md +140 -0
- package/dist/cjs/components/NativeLibrary.d.ts +229 -0
- package/dist/cjs/components/NativeLibrary.js +346 -0
- package/dist/cjs/decorators/Library.d.ts +61 -0
- package/dist/cjs/decorators/Library.js +44 -0
- package/dist/cjs/decorators/Native.d.ts +69 -0
- package/dist/cjs/decorators/Native.js +90 -0
- package/dist/cjs/exceptions/NativeDeclarationException.d.ts +12 -0
- package/dist/cjs/exceptions/NativeDeclarationException.js +19 -0
- package/dist/cjs/exceptions/NativeLibraryClosedException.d.ts +12 -0
- package/dist/cjs/exceptions/NativeLibraryClosedException.js +19 -0
- package/dist/cjs/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
- package/dist/cjs/exceptions/NativeLibraryNotFoundException.js +18 -0
- package/dist/cjs/exceptions/NativeMemoryException.d.ts +11 -0
- package/dist/cjs/exceptions/NativeMemoryException.js +18 -0
- package/dist/cjs/exports/FFI.d.ts +12 -0
- package/dist/cjs/exports/FFI.js +40 -0
- package/dist/cjs/exports/Generator.d.ts +2 -0
- package/dist/cjs/exports/Generator.js +10 -0
- package/dist/cjs/lib/Memory.d.ts +188 -0
- package/dist/cjs/lib/Memory.js +227 -0
- package/dist/cjs/lib/Runtime.d.ts +98 -0
- package/dist/cjs/lib/Runtime.js +209 -0
- package/dist/cjs/lib/backend/Functions.d.ts +65 -0
- package/dist/cjs/lib/backend/Functions.js +214 -0
- package/dist/cjs/lib/backend/KoffiTypes.d.ts +53 -0
- package/dist/cjs/lib/backend/KoffiTypes.js +426 -0
- package/dist/cjs/lib/declarations/Builtins.d.ts +33 -0
- package/dist/cjs/lib/declarations/Builtins.js +179 -0
- package/dist/cjs/lib/declarations/Layout.d.ts +41 -0
- package/dist/cjs/lib/declarations/Layout.js +180 -0
- package/dist/cjs/lib/declarations/Lexer.d.ts +40 -0
- package/dist/cjs/lib/declarations/Lexer.js +325 -0
- package/dist/cjs/lib/declarations/Parser.d.ts +90 -0
- package/dist/cjs/lib/declarations/Parser.js +1425 -0
- package/dist/cjs/lib/declarations/Platform.d.ts +50 -0
- package/dist/cjs/lib/declarations/Platform.js +27 -0
- package/dist/cjs/lib/declarations/Types.d.ts +173 -0
- package/dist/cjs/lib/declarations/Types.js +179 -0
- package/dist/cjs/lib/generator/CText.d.ts +14 -0
- package/dist/cjs/lib/generator/CText.js +133 -0
- package/dist/cjs/lib/generator/Generator.d.ts +136 -0
- package/dist/cjs/lib/generator/Generator.js +395 -0
- package/dist/cjs/lib/generator/Preprocessor.d.ts +60 -0
- package/dist/cjs/lib/generator/Preprocessor.js +94 -0
- package/dist/cjs/lib/generator/TypeScriptTypes.d.ts +35 -0
- package/dist/cjs/lib/generator/TypeScriptTypes.js +153 -0
- package/dist/cjs/lib/library/NativeCallback.d.ts +44 -0
- package/dist/cjs/lib/library/NativeCallback.js +66 -0
- package/dist/cjs/lib/library/NativeLibraryHandle.d.ts +268 -0
- package/dist/cjs/lib/library/NativeLibraryHandle.js +540 -0
- package/dist/cjs/lib/library/Resolve.d.ts +49 -0
- package/dist/cjs/lib/library/Resolve.js +130 -0
- package/dist/cjs/lib/thread/NativeThreads.d.ts +80 -0
- package/dist/cjs/lib/thread/NativeThreads.js +384 -0
- package/dist/cjs/lib/thread/NativeWorker.d.ts +6 -0
- package/dist/cjs/lib/thread/NativeWorker.js +96 -0
- package/dist/cjs/lib/thread/NativeWorkerCode.d.ts +5 -0
- package/dist/cjs/lib/thread/NativeWorkerCode.js +4 -0
- package/dist/cjs/lib/thread/PackageRequire.d.ts +6 -0
- package/dist/cjs/lib/thread/PackageRequire.js +4 -0
- package/dist/cjs/lib/thread/ThreadProtocol.d.ts +77 -0
- package/dist/cjs/lib/thread/ThreadProtocol.js +2 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/components/NativeLibrary.js +338 -0
- package/dist/esm/decorators/Library.js +40 -0
- package/dist/esm/decorators/Native.js +85 -0
- package/dist/esm/exceptions/NativeDeclarationException.js +15 -0
- package/dist/esm/exceptions/NativeLibraryClosedException.js +15 -0
- package/dist/esm/exceptions/NativeLibraryNotFoundException.js +14 -0
- package/dist/esm/exceptions/NativeMemoryException.js +14 -0
- package/dist/esm/exports/FFI.js +10 -0
- package/dist/esm/exports/Generator.js +2 -0
- package/dist/esm/lib/Memory.js +210 -0
- package/dist/esm/lib/Runtime.js +192 -0
- package/dist/esm/lib/backend/Functions.js +206 -0
- package/dist/esm/lib/backend/KoffiTypes.js +418 -0
- package/dist/esm/lib/declarations/Builtins.js +174 -0
- package/dist/esm/lib/declarations/Layout.js +175 -0
- package/dist/esm/lib/declarations/Lexer.js +321 -0
- package/dist/esm/lib/declarations/Parser.js +1421 -0
- package/dist/esm/lib/declarations/Platform.js +23 -0
- package/dist/esm/lib/declarations/Types.js +170 -0
- package/dist/esm/lib/generator/CText.js +129 -0
- package/dist/esm/lib/generator/Generator.js +388 -0
- package/dist/esm/lib/generator/Preprocessor.js +87 -0
- package/dist/esm/lib/generator/TypeScriptTypes.js +149 -0
- package/dist/esm/lib/library/NativeCallback.js +59 -0
- package/dist/esm/lib/library/NativeLibraryHandle.js +532 -0
- package/dist/esm/lib/library/Resolve.js +122 -0
- package/dist/esm/lib/thread/NativeThreads.js +377 -0
- package/dist/esm/lib/thread/NativeWorker.js +93 -0
- package/dist/esm/lib/thread/NativeWorkerCode.js +1 -0
- package/dist/esm/lib/thread/PackageRequire.js +2 -0
- package/dist/esm/lib/thread/ThreadProtocol.js +1 -0
- package/dist/types/components/NativeLibrary.d.ts +229 -0
- package/dist/types/decorators/Library.d.ts +61 -0
- package/dist/types/decorators/Native.d.ts +69 -0
- package/dist/types/exceptions/NativeDeclarationException.d.ts +12 -0
- package/dist/types/exceptions/NativeLibraryClosedException.d.ts +12 -0
- package/dist/types/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
- package/dist/types/exceptions/NativeMemoryException.d.ts +11 -0
- package/dist/types/exports/FFI.d.ts +12 -0
- package/dist/types/exports/Generator.d.ts +2 -0
- package/dist/types/lib/Memory.d.ts +188 -0
- package/dist/types/lib/Runtime.d.ts +98 -0
- package/dist/types/lib/backend/Functions.d.ts +65 -0
- package/dist/types/lib/backend/KoffiTypes.d.ts +53 -0
- package/dist/types/lib/declarations/Builtins.d.ts +33 -0
- package/dist/types/lib/declarations/Layout.d.ts +41 -0
- package/dist/types/lib/declarations/Lexer.d.ts +40 -0
- package/dist/types/lib/declarations/Parser.d.ts +90 -0
- package/dist/types/lib/declarations/Platform.d.ts +50 -0
- package/dist/types/lib/declarations/Types.d.ts +173 -0
- package/dist/types/lib/generator/CText.d.ts +14 -0
- package/dist/types/lib/generator/Generator.d.ts +136 -0
- package/dist/types/lib/generator/Preprocessor.d.ts +60 -0
- package/dist/types/lib/generator/TypeScriptTypes.d.ts +35 -0
- package/dist/types/lib/library/NativeCallback.d.ts +44 -0
- package/dist/types/lib/library/NativeLibraryHandle.d.ts +268 -0
- package/dist/types/lib/library/Resolve.d.ts +49 -0
- package/dist/types/lib/thread/NativeThreads.d.ts +80 -0
- package/dist/types/lib/thread/NativeWorker.d.ts +6 -0
- package/dist/types/lib/thread/NativeWorkerCode.d.ts +5 -0
- package/dist/types/lib/thread/PackageRequire.d.ts +6 -0
- package/dist/types/lib/thread/ThreadProtocol.d.ts +77 -0
- package/package.json +85 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the sizes of the C types and the layout of the structs depend on
|
|
3
|
+
*/
|
|
4
|
+
export interface Platform {
|
|
5
|
+
/**
|
|
6
|
+
* The operating system, as process.platform names it
|
|
7
|
+
*/
|
|
8
|
+
readonly os: string;
|
|
9
|
+
/**
|
|
10
|
+
* The architecture, as process.arch names it
|
|
11
|
+
*/
|
|
12
|
+
readonly arch: string;
|
|
13
|
+
/**
|
|
14
|
+
* The size of a pointer (and of size_t), in bytes
|
|
15
|
+
*/
|
|
16
|
+
readonly pointerSize: 4 | 8;
|
|
17
|
+
/**
|
|
18
|
+
* The size of long: 8 on 64-bit Unix systems (LP64), 4 on Windows (LLP64) and on 32-bit systems
|
|
19
|
+
*/
|
|
20
|
+
readonly longSize: 4 | 8;
|
|
21
|
+
/**
|
|
22
|
+
* The size of wchar_t: 2 on Windows, 4 elsewhere
|
|
23
|
+
*/
|
|
24
|
+
readonly wcharSize: 2 | 4;
|
|
25
|
+
/**
|
|
26
|
+
* The alignment of the 8-byte types (long long, double) as members: 4 on 32-bit Linux (i386), 8 elsewhere
|
|
27
|
+
*/
|
|
28
|
+
readonly int64Alignment: 4 | 8;
|
|
29
|
+
/**
|
|
30
|
+
* How bitfields are laid out: by the rules of GCC and Clang (sysv), of the ARM procedure call standard where the
|
|
31
|
+
* type of every bitfield aligns the struct, the unnamed and the empty ones too (aapcs: ARM but on Apple systems), or
|
|
32
|
+
* of the compiler of Microsoft (msvc)
|
|
33
|
+
*/
|
|
34
|
+
readonly bitfields: 'sysv' | 'aapcs' | 'msvc';
|
|
35
|
+
/**
|
|
36
|
+
* Whether the symbols of the C functions start with an underscore in the binaries (macOS): the labels of __asm
|
|
37
|
+
* name them so
|
|
38
|
+
*/
|
|
39
|
+
readonly underscoredSymbols: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The platform of a system and an architecture
|
|
43
|
+
* @param os
|
|
44
|
+
* @param arch
|
|
45
|
+
*/
|
|
46
|
+
export declare function platformOf(os: string, arch: string): Platform;
|
|
47
|
+
/**
|
|
48
|
+
* The platform the process runs on
|
|
49
|
+
*/
|
|
50
|
+
export declare const CURRENT_PLATFORM: Platform;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CURRENT_PLATFORM = void 0;
|
|
4
|
+
exports.platformOf = platformOf;
|
|
5
|
+
/**
|
|
6
|
+
* The platform of a system and an architecture
|
|
7
|
+
* @param os
|
|
8
|
+
* @param arch
|
|
9
|
+
*/
|
|
10
|
+
function platformOf(os, arch) {
|
|
11
|
+
const bits64 = !['ia32', 'arm', 'x32'].includes(arch);
|
|
12
|
+
const windows = os === 'win32';
|
|
13
|
+
return {
|
|
14
|
+
os: os,
|
|
15
|
+
arch: arch,
|
|
16
|
+
pointerSize: bits64 ? 8 : 4,
|
|
17
|
+
longSize: bits64 && !windows ? 8 : 4,
|
|
18
|
+
wcharSize: windows ? 2 : 4,
|
|
19
|
+
int64Alignment: !bits64 && !windows && arch === 'ia32' ? 4 : 8,
|
|
20
|
+
bitfields: windows ? 'msvc' : (arch === 'arm' || arch === 'arm64') && os !== 'darwin' ? 'aapcs' : 'sysv',
|
|
21
|
+
underscoredSymbols: os === 'darwin'
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The platform the process runs on
|
|
26
|
+
*/
|
|
27
|
+
exports.CURRENT_PLATFORM = platformOf(process.platform, process.arch);
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type { Platform } from './Platform.js';
|
|
2
|
+
/**
|
|
3
|
+
* The arithmetic types of C, by their meaning (long is not int64: their sizes differ between the platforms)
|
|
4
|
+
*/
|
|
5
|
+
export type PrimitiveName = 'void' | 'bool' | 'char' | 'schar' | 'uchar' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'longlong' | 'ulonglong' | 'int8' | 'uint8' | 'int16' | 'uint16' | 'int32' | 'uint32' | 'int64' | 'uint64' | 'size' | 'ssize' | 'intptr' | 'uintptr' | 'ptrdiff' | 'char16' | 'char32' | 'wchar' | 'float' | 'double';
|
|
6
|
+
/**
|
|
7
|
+
* How the arguments of a function are passed: different on 32-bit Windows only
|
|
8
|
+
*/
|
|
9
|
+
export type CallingConvention = 'cdecl' | 'stdcall' | 'fastcall' | 'thiscall';
|
|
10
|
+
/**
|
|
11
|
+
* Which way a pointer argument carries its value: into the function, out of it (the object or the array given is
|
|
12
|
+
* filled once it returns), or both
|
|
13
|
+
*/
|
|
14
|
+
export type Direction = 'in' | 'out' | 'inout';
|
|
15
|
+
export interface PrimitiveType {
|
|
16
|
+
readonly kind: 'primitive';
|
|
17
|
+
readonly name: PrimitiveName;
|
|
18
|
+
}
|
|
19
|
+
export interface PointerType {
|
|
20
|
+
readonly kind: 'pointer';
|
|
21
|
+
readonly to: CType;
|
|
22
|
+
/**
|
|
23
|
+
* Whether what it points to is const (const char * is a string given to the function)
|
|
24
|
+
*/
|
|
25
|
+
readonly constTarget: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface ArrayType {
|
|
28
|
+
readonly kind: 'array';
|
|
29
|
+
readonly of: CType;
|
|
30
|
+
readonly length: number;
|
|
31
|
+
}
|
|
32
|
+
export interface Member {
|
|
33
|
+
/**
|
|
34
|
+
* Its name; the anonymous structs and unions inside a struct are named _0, _1… in the order of the struct
|
|
35
|
+
*/
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly type: CType;
|
|
38
|
+
/**
|
|
39
|
+
* The width of a bitfield
|
|
40
|
+
*/
|
|
41
|
+
readonly bits?: number;
|
|
42
|
+
/**
|
|
43
|
+
* The alignment its aligned attribute asks for, in bytes
|
|
44
|
+
*/
|
|
45
|
+
readonly align?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A struct or a union. One without members is opaque (declared, not defined); it is completed in place when defined
|
|
49
|
+
*/
|
|
50
|
+
export interface RecordType {
|
|
51
|
+
readonly kind: 'struct' | 'union';
|
|
52
|
+
readonly tag?: string;
|
|
53
|
+
members?: Member[];
|
|
54
|
+
/**
|
|
55
|
+
* The alignment its members are capped at (#pragma pack, the packed attribute)
|
|
56
|
+
*/
|
|
57
|
+
pack?: number;
|
|
58
|
+
/**
|
|
59
|
+
* The alignment its aligned attribute asks for, in bytes
|
|
60
|
+
*/
|
|
61
|
+
align?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface EnumType {
|
|
64
|
+
readonly kind: 'enum';
|
|
65
|
+
readonly tag?: string;
|
|
66
|
+
/**
|
|
67
|
+
* The integer type holding its values
|
|
68
|
+
*/
|
|
69
|
+
readonly base: PrimitiveName;
|
|
70
|
+
readonly values: ReadonlyMap<string, bigint>;
|
|
71
|
+
}
|
|
72
|
+
export interface Parameter {
|
|
73
|
+
readonly name?: string;
|
|
74
|
+
readonly type: CType;
|
|
75
|
+
readonly direction: Direction;
|
|
76
|
+
}
|
|
77
|
+
export interface FunctionType {
|
|
78
|
+
readonly kind: 'function';
|
|
79
|
+
readonly result: CType;
|
|
80
|
+
readonly parameters: readonly Parameter[];
|
|
81
|
+
readonly variadic: boolean;
|
|
82
|
+
readonly convention: CallingConvention;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A C type, as the declarations describe it
|
|
86
|
+
*/
|
|
87
|
+
export type CType = PrimitiveType | PointerType | ArrayType | RecordType | EnumType | FunctionType;
|
|
88
|
+
/**
|
|
89
|
+
* A function the library exports
|
|
90
|
+
*/
|
|
91
|
+
export interface FunctionDeclaration {
|
|
92
|
+
readonly name: string;
|
|
93
|
+
/**
|
|
94
|
+
* The name of its symbol in the library: its name, or the one of its __asm label
|
|
95
|
+
*/
|
|
96
|
+
readonly symbol: string;
|
|
97
|
+
readonly type: FunctionType;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A variable the library exports
|
|
101
|
+
*/
|
|
102
|
+
export interface VariableDeclaration {
|
|
103
|
+
readonly name: string;
|
|
104
|
+
readonly symbol: string;
|
|
105
|
+
readonly type: CType;
|
|
106
|
+
readonly constant: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* What a text of declarations declares
|
|
110
|
+
*/
|
|
111
|
+
export interface Declarations {
|
|
112
|
+
/**
|
|
113
|
+
* The typedefs
|
|
114
|
+
*/
|
|
115
|
+
readonly types: Map<string, CType>;
|
|
116
|
+
/**
|
|
117
|
+
* The tags of the structs, unions and enums ("struct timeval")
|
|
118
|
+
*/
|
|
119
|
+
readonly tags: Map<string, RecordType | EnumType>;
|
|
120
|
+
readonly functions: Map<string, FunctionDeclaration>;
|
|
121
|
+
readonly variables: Map<string, VariableDeclaration>;
|
|
122
|
+
/**
|
|
123
|
+
* The values of the enumerations, of the static constants and of the macros whose value is an integer
|
|
124
|
+
*/
|
|
125
|
+
readonly constants: Map<string, bigint>;
|
|
126
|
+
/**
|
|
127
|
+
* The macros without arguments (#define): their tokens, empty for the ones that are removed where used (the
|
|
128
|
+
* markers of exported functions); null for the macros with arguments, which cannot be used
|
|
129
|
+
*/
|
|
130
|
+
readonly macros: Map<string, MacroToken[] | null>;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A token of a macro: its kind and its text (and its value, for a number or a character)
|
|
134
|
+
*/
|
|
135
|
+
export interface MacroToken {
|
|
136
|
+
readonly kind: 'identifier' | 'number' | 'char' | 'string' | 'punctuator';
|
|
137
|
+
readonly text: string;
|
|
138
|
+
readonly value?: bigint;
|
|
139
|
+
readonly float?: boolean;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* An empty set of declarations
|
|
143
|
+
*/
|
|
144
|
+
export declare function emptyDeclarations(): Declarations;
|
|
145
|
+
export declare const VOID: PrimitiveType;
|
|
146
|
+
/**
|
|
147
|
+
* The size of an arithmetic type, in bytes
|
|
148
|
+
* @param name
|
|
149
|
+
* @param platform
|
|
150
|
+
*/
|
|
151
|
+
export declare function primitiveSize(name: PrimitiveName, platform: Platform): number;
|
|
152
|
+
/**
|
|
153
|
+
* Whether an arithmetic type is signed
|
|
154
|
+
* @param name
|
|
155
|
+
* @param platform
|
|
156
|
+
*/
|
|
157
|
+
export declare function primitiveSigned(name: PrimitiveName, platform: Platform): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Whether an arithmetic type is an integer
|
|
160
|
+
* @param name
|
|
161
|
+
*/
|
|
162
|
+
export declare function primitiveInteger(name: PrimitiveName): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Whether an integer type is 64-bit on one of the platforms at least: its values are bigints (long is 64-bit but on
|
|
165
|
+
* Windows, size_t but on 32-bit systems)
|
|
166
|
+
* @param name
|
|
167
|
+
*/
|
|
168
|
+
export declare function primitiveBig(name: PrimitiveName): boolean;
|
|
169
|
+
/**
|
|
170
|
+
* A type, as C writes it (for the messages)
|
|
171
|
+
* @param type
|
|
172
|
+
*/
|
|
173
|
+
export declare function typeText(type: CType): string;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VOID = void 0;
|
|
4
|
+
exports.emptyDeclarations = emptyDeclarations;
|
|
5
|
+
exports.primitiveSize = primitiveSize;
|
|
6
|
+
exports.primitiveSigned = primitiveSigned;
|
|
7
|
+
exports.primitiveInteger = primitiveInteger;
|
|
8
|
+
exports.primitiveBig = primitiveBig;
|
|
9
|
+
exports.typeText = typeText;
|
|
10
|
+
/**
|
|
11
|
+
* An empty set of declarations
|
|
12
|
+
*/
|
|
13
|
+
function emptyDeclarations() {
|
|
14
|
+
return { types: new Map(), tags: new Map(), functions: new Map(), variables: new Map(), constants: new Map(), macros: new Map() };
|
|
15
|
+
}
|
|
16
|
+
exports.VOID = { kind: 'primitive', name: 'void' };
|
|
17
|
+
/**
|
|
18
|
+
* The size of an arithmetic type, in bytes
|
|
19
|
+
* @param name
|
|
20
|
+
* @param platform
|
|
21
|
+
*/
|
|
22
|
+
function primitiveSize(name, platform) {
|
|
23
|
+
switch (name) {
|
|
24
|
+
case 'void':
|
|
25
|
+
return 0;
|
|
26
|
+
case 'bool':
|
|
27
|
+
case 'char':
|
|
28
|
+
case 'schar':
|
|
29
|
+
case 'uchar':
|
|
30
|
+
case 'int8':
|
|
31
|
+
case 'uint8':
|
|
32
|
+
return 1;
|
|
33
|
+
case 'short':
|
|
34
|
+
case 'ushort':
|
|
35
|
+
case 'int16':
|
|
36
|
+
case 'uint16':
|
|
37
|
+
case 'char16':
|
|
38
|
+
return 2;
|
|
39
|
+
case 'int':
|
|
40
|
+
case 'uint':
|
|
41
|
+
case 'int32':
|
|
42
|
+
case 'uint32':
|
|
43
|
+
case 'char32':
|
|
44
|
+
case 'float':
|
|
45
|
+
return 4;
|
|
46
|
+
case 'long':
|
|
47
|
+
case 'ulong':
|
|
48
|
+
return platform.longSize;
|
|
49
|
+
case 'longlong':
|
|
50
|
+
case 'ulonglong':
|
|
51
|
+
case 'int64':
|
|
52
|
+
case 'uint64':
|
|
53
|
+
case 'double':
|
|
54
|
+
return 8;
|
|
55
|
+
case 'size':
|
|
56
|
+
case 'ssize':
|
|
57
|
+
case 'intptr':
|
|
58
|
+
case 'uintptr':
|
|
59
|
+
case 'ptrdiff':
|
|
60
|
+
return platform.pointerSize;
|
|
61
|
+
case 'wchar':
|
|
62
|
+
return platform.wcharSize;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether an arithmetic type is signed
|
|
67
|
+
* @param name
|
|
68
|
+
* @param platform
|
|
69
|
+
*/
|
|
70
|
+
function primitiveSigned(name, platform) {
|
|
71
|
+
switch (name) {
|
|
72
|
+
case 'char':
|
|
73
|
+
//char is signed but on the ARM systems other than Apple's and Microsoft's (koffi reads it as signed everywhere)
|
|
74
|
+
return true;
|
|
75
|
+
case 'schar':
|
|
76
|
+
case 'short':
|
|
77
|
+
case 'int':
|
|
78
|
+
case 'long':
|
|
79
|
+
case 'longlong':
|
|
80
|
+
case 'int8':
|
|
81
|
+
case 'int16':
|
|
82
|
+
case 'int32':
|
|
83
|
+
case 'int64':
|
|
84
|
+
case 'ssize':
|
|
85
|
+
case 'intptr':
|
|
86
|
+
case 'ptrdiff':
|
|
87
|
+
case 'float':
|
|
88
|
+
case 'double':
|
|
89
|
+
return true;
|
|
90
|
+
case 'wchar':
|
|
91
|
+
return platform.os !== 'win32';
|
|
92
|
+
default:
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Whether an arithmetic type is an integer
|
|
98
|
+
* @param name
|
|
99
|
+
*/
|
|
100
|
+
function primitiveInteger(name) {
|
|
101
|
+
return name !== 'void' && name !== 'float' && name !== 'double';
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Whether an integer type is 64-bit on one of the platforms at least: its values are bigints (long is 64-bit but on
|
|
105
|
+
* Windows, size_t but on 32-bit systems)
|
|
106
|
+
* @param name
|
|
107
|
+
*/
|
|
108
|
+
function primitiveBig(name) {
|
|
109
|
+
switch (name) {
|
|
110
|
+
case 'long':
|
|
111
|
+
case 'ulong':
|
|
112
|
+
case 'longlong':
|
|
113
|
+
case 'ulonglong':
|
|
114
|
+
case 'int64':
|
|
115
|
+
case 'uint64':
|
|
116
|
+
case 'size':
|
|
117
|
+
case 'ssize':
|
|
118
|
+
case 'intptr':
|
|
119
|
+
case 'uintptr':
|
|
120
|
+
case 'ptrdiff':
|
|
121
|
+
return true;
|
|
122
|
+
default:
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A type, as C writes it (for the messages)
|
|
128
|
+
* @param type
|
|
129
|
+
*/
|
|
130
|
+
function typeText(type) {
|
|
131
|
+
switch (type.kind) {
|
|
132
|
+
case 'primitive':
|
|
133
|
+
return PRIMITIVE_TEXT[type.name];
|
|
134
|
+
case 'pointer':
|
|
135
|
+
return `${type.constTarget ? 'const ' : ''}${typeText(type.to)} *`;
|
|
136
|
+
case 'array':
|
|
137
|
+
return `${typeText(type.of)}[${type.length}]`;
|
|
138
|
+
case 'struct':
|
|
139
|
+
case 'union':
|
|
140
|
+
return `${type.kind} ${type.tag ?? '(anonymous)'}`;
|
|
141
|
+
case 'enum':
|
|
142
|
+
return `enum ${type.tag ?? '(anonymous)'}`;
|
|
143
|
+
case 'function':
|
|
144
|
+
return `${typeText(type.result)} (${type.parameters.map((parameter) => typeText(parameter.type)).concat(type.variadic ? ['...'] : []).join(', ')})`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const PRIMITIVE_TEXT = {
|
|
148
|
+
void: 'void',
|
|
149
|
+
bool: 'bool',
|
|
150
|
+
char: 'char',
|
|
151
|
+
schar: 'signed char',
|
|
152
|
+
uchar: 'unsigned char',
|
|
153
|
+
short: 'short',
|
|
154
|
+
ushort: 'unsigned short',
|
|
155
|
+
int: 'int',
|
|
156
|
+
uint: 'unsigned int',
|
|
157
|
+
long: 'long',
|
|
158
|
+
ulong: 'unsigned long',
|
|
159
|
+
longlong: 'long long',
|
|
160
|
+
ulonglong: 'unsigned long long',
|
|
161
|
+
int8: 'int8_t',
|
|
162
|
+
uint8: 'uint8_t',
|
|
163
|
+
int16: 'int16_t',
|
|
164
|
+
uint16: 'uint16_t',
|
|
165
|
+
int32: 'int32_t',
|
|
166
|
+
uint32: 'uint32_t',
|
|
167
|
+
int64: 'int64_t',
|
|
168
|
+
uint64: 'uint64_t',
|
|
169
|
+
size: 'size_t',
|
|
170
|
+
ssize: 'ssize_t',
|
|
171
|
+
intptr: 'intptr_t',
|
|
172
|
+
uintptr: 'uintptr_t',
|
|
173
|
+
ptrdiff: 'ptrdiff_t',
|
|
174
|
+
char16: 'char16_t',
|
|
175
|
+
char32: 'char32_t',
|
|
176
|
+
wchar: 'wchar_t',
|
|
177
|
+
float: 'float',
|
|
178
|
+
double: 'double'
|
|
179
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Token } from '../declarations/Lexer.js';
|
|
2
|
+
/**
|
|
3
|
+
* The tokens of a declaration without what changes nothing of what it declares: the attributes but packed and aligned,
|
|
4
|
+
* the __declspec but align, the qualifiers the parser ignores
|
|
5
|
+
* @param tokens
|
|
6
|
+
*/
|
|
7
|
+
export declare function prunedTokens(tokens: readonly Token[]): Token[];
|
|
8
|
+
/**
|
|
9
|
+
* A declaration written as C, one member of a struct or a value of an enum by line
|
|
10
|
+
* @param tokens Its tokens.
|
|
11
|
+
* @param indent The indentation of a level.
|
|
12
|
+
* @returns Its lines.
|
|
13
|
+
*/
|
|
14
|
+
export declare function declarationText(tokens: readonly Token[], indent?: string): string[];
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prunedTokens = prunedTokens;
|
|
4
|
+
exports.declarationText = declarationText;
|
|
5
|
+
/**
|
|
6
|
+
* The words that change nothing of what a declaration declares, removed from the declarations written
|
|
7
|
+
*/
|
|
8
|
+
const NOISE = new Set([
|
|
9
|
+
'__extension__', '__restrict', '__restrict__', 'restrict', '_Nullable', '_Nonnull', '_Null_unspecified', '__nullable', '__nonnull',
|
|
10
|
+
'__null_unspecified', '_Nullable_result', '__ptr32', '__ptr64', '__unaligned', '__w64'
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* The words that can follow the parenthesis of a declarator of a pointer to a function: void (*f)(void), void (__stdcall *f)(void)
|
|
14
|
+
*/
|
|
15
|
+
const DECLARATOR_STARTS = new Set(['*', '__stdcall', '_stdcall', '__cdecl', '_cdecl', '__fastcall', '_fastcall', '__thiscall', '__vectorcall', '__clrcall']);
|
|
16
|
+
/**
|
|
17
|
+
* The end of the balanced brackets opened at an index: the index of the closing one
|
|
18
|
+
* @param tokens
|
|
19
|
+
* @param open
|
|
20
|
+
*/
|
|
21
|
+
function closing(tokens, open) {
|
|
22
|
+
let depth = 0;
|
|
23
|
+
for (let index = open; index < tokens.length; index++) {
|
|
24
|
+
const token = tokens[index];
|
|
25
|
+
if (token.kind !== 'punctuator')
|
|
26
|
+
continue;
|
|
27
|
+
if (token.text === '(' || token.text === '[' || token.text === '{')
|
|
28
|
+
depth++;
|
|
29
|
+
else if ((token.text === ')' || token.text === ']' || token.text === '}') && --depth === 0)
|
|
30
|
+
return index;
|
|
31
|
+
}
|
|
32
|
+
return tokens.length - 1;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The tokens of a declaration without what changes nothing of what it declares: the attributes but packed and aligned,
|
|
36
|
+
* the __declspec but align, the qualifiers the parser ignores
|
|
37
|
+
* @param tokens
|
|
38
|
+
*/
|
|
39
|
+
function prunedTokens(tokens) {
|
|
40
|
+
const kept = [];
|
|
41
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
42
|
+
const token = tokens[index];
|
|
43
|
+
if (token.kind === 'identifier' && NOISE.has(token.text))
|
|
44
|
+
continue;
|
|
45
|
+
const attribute = token.kind === 'identifier' && (token.text === '__attribute__' || token.text === '__attribute' || token.text === '__declspec');
|
|
46
|
+
if (attribute && tokens[index + 1]?.text === '(') {
|
|
47
|
+
const end = closing(tokens, index + 1);
|
|
48
|
+
const inner = tokens.slice(index + 2, end).map((part) => part.text.replace(/^__|__$/g, ''));
|
|
49
|
+
const meaningful = token.text === '__declspec' ? inner.includes('align') : inner.includes('packed') || inner.includes('aligned');
|
|
50
|
+
if (meaningful)
|
|
51
|
+
kept.push(...tokens.slice(index, end + 1));
|
|
52
|
+
index = end;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
kept.push(token);
|
|
56
|
+
}
|
|
57
|
+
return kept;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The text of a token as C writes it
|
|
61
|
+
* @param token
|
|
62
|
+
*/
|
|
63
|
+
function textOf(token) {
|
|
64
|
+
if (token.kind === 'string')
|
|
65
|
+
return token.source ?? JSON.stringify(token.text);
|
|
66
|
+
if (token.kind === 'pragma')
|
|
67
|
+
return `#pragma ${token.text}`;
|
|
68
|
+
return token.text;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A declaration written as C, one member of a struct or a value of an enum by line
|
|
72
|
+
* @param tokens Its tokens.
|
|
73
|
+
* @param indent The indentation of a level.
|
|
74
|
+
* @returns Its lines.
|
|
75
|
+
*/
|
|
76
|
+
function declarationText(tokens, indent = ' ') {
|
|
77
|
+
const lines = [];
|
|
78
|
+
let line = '';
|
|
79
|
+
//The braces open: whether each one is the body of an enum
|
|
80
|
+
const braces = [];
|
|
81
|
+
let parens = 0;
|
|
82
|
+
const breakLine = () => {
|
|
83
|
+
if (line.trim())
|
|
84
|
+
lines.push(line.replace(/\s+$/, ''));
|
|
85
|
+
line = indent.repeat(braces.length);
|
|
86
|
+
};
|
|
87
|
+
let previous;
|
|
88
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
89
|
+
const token = tokens[index];
|
|
90
|
+
const text = textOf(token);
|
|
91
|
+
if (token.kind === 'pragma') {
|
|
92
|
+
breakLine();
|
|
93
|
+
line += text;
|
|
94
|
+
breakLine();
|
|
95
|
+
previous = undefined;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const punctuator = token.kind === 'punctuator' ? token.text : undefined;
|
|
99
|
+
if (punctuator === '{') {
|
|
100
|
+
const enumBody = tokens.slice(Math.max(0, index - 2), index).some((part) => part.kind === 'identifier' && part.text === 'enum');
|
|
101
|
+
line += `${line.trim() ? ' ' : ''}{`;
|
|
102
|
+
braces.push(enumBody);
|
|
103
|
+
breakLine();
|
|
104
|
+
previous = token;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (punctuator === '}') {
|
|
108
|
+
braces.pop();
|
|
109
|
+
breakLine();
|
|
110
|
+
line += '}';
|
|
111
|
+
previous = token;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (punctuator === '(' || punctuator === '[')
|
|
115
|
+
parens++;
|
|
116
|
+
if (punctuator === ')' || punctuator === ']')
|
|
117
|
+
parens--;
|
|
118
|
+
const glued = !previous
|
|
119
|
+
|| [',', ';', ')', ']', '['].includes(punctuator ?? '')
|
|
120
|
+
|| (previous.kind === 'punctuator' && ['(', '[', '*', '~', '!'].includes(previous.text))
|
|
121
|
+
|| (punctuator === '(' && (previous.kind === 'identifier' || previous.text === ')') && !DECLARATOR_STARTS.has(tokens[index + 1]?.text ?? ''))
|
|
122
|
+
|| !line.trim();
|
|
123
|
+
line += `${glued ? '' : ' '}${text}`;
|
|
124
|
+
previous = token;
|
|
125
|
+
//A member of a struct, a value of an enum: one by line
|
|
126
|
+
if (braces.length && !parens && (punctuator === ';' || (punctuator === ',' && braces[braces.length - 1]))) {
|
|
127
|
+
breakLine();
|
|
128
|
+
previous = undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
breakLine();
|
|
132
|
+
return lines;
|
|
133
|
+
}
|