@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.
Files changed (129) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +163 -2
  3. package/README.zh-CN.md +140 -0
  4. package/dist/cjs/components/NativeLibrary.d.ts +229 -0
  5. package/dist/cjs/components/NativeLibrary.js +346 -0
  6. package/dist/cjs/decorators/Library.d.ts +61 -0
  7. package/dist/cjs/decorators/Library.js +44 -0
  8. package/dist/cjs/decorators/Native.d.ts +69 -0
  9. package/dist/cjs/decorators/Native.js +90 -0
  10. package/dist/cjs/exceptions/NativeDeclarationException.d.ts +12 -0
  11. package/dist/cjs/exceptions/NativeDeclarationException.js +19 -0
  12. package/dist/cjs/exceptions/NativeLibraryClosedException.d.ts +12 -0
  13. package/dist/cjs/exceptions/NativeLibraryClosedException.js +19 -0
  14. package/dist/cjs/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
  15. package/dist/cjs/exceptions/NativeLibraryNotFoundException.js +18 -0
  16. package/dist/cjs/exceptions/NativeMemoryException.d.ts +11 -0
  17. package/dist/cjs/exceptions/NativeMemoryException.js +18 -0
  18. package/dist/cjs/exports/FFI.d.ts +12 -0
  19. package/dist/cjs/exports/FFI.js +40 -0
  20. package/dist/cjs/exports/Generator.d.ts +2 -0
  21. package/dist/cjs/exports/Generator.js +10 -0
  22. package/dist/cjs/lib/Memory.d.ts +188 -0
  23. package/dist/cjs/lib/Memory.js +227 -0
  24. package/dist/cjs/lib/Runtime.d.ts +98 -0
  25. package/dist/cjs/lib/Runtime.js +209 -0
  26. package/dist/cjs/lib/backend/Functions.d.ts +65 -0
  27. package/dist/cjs/lib/backend/Functions.js +214 -0
  28. package/dist/cjs/lib/backend/KoffiTypes.d.ts +53 -0
  29. package/dist/cjs/lib/backend/KoffiTypes.js +426 -0
  30. package/dist/cjs/lib/declarations/Builtins.d.ts +33 -0
  31. package/dist/cjs/lib/declarations/Builtins.js +179 -0
  32. package/dist/cjs/lib/declarations/Layout.d.ts +41 -0
  33. package/dist/cjs/lib/declarations/Layout.js +180 -0
  34. package/dist/cjs/lib/declarations/Lexer.d.ts +40 -0
  35. package/dist/cjs/lib/declarations/Lexer.js +325 -0
  36. package/dist/cjs/lib/declarations/Parser.d.ts +90 -0
  37. package/dist/cjs/lib/declarations/Parser.js +1425 -0
  38. package/dist/cjs/lib/declarations/Platform.d.ts +50 -0
  39. package/dist/cjs/lib/declarations/Platform.js +27 -0
  40. package/dist/cjs/lib/declarations/Types.d.ts +173 -0
  41. package/dist/cjs/lib/declarations/Types.js +179 -0
  42. package/dist/cjs/lib/generator/CText.d.ts +14 -0
  43. package/dist/cjs/lib/generator/CText.js +133 -0
  44. package/dist/cjs/lib/generator/Generator.d.ts +136 -0
  45. package/dist/cjs/lib/generator/Generator.js +395 -0
  46. package/dist/cjs/lib/generator/Preprocessor.d.ts +60 -0
  47. package/dist/cjs/lib/generator/Preprocessor.js +94 -0
  48. package/dist/cjs/lib/generator/TypeScriptTypes.d.ts +35 -0
  49. package/dist/cjs/lib/generator/TypeScriptTypes.js +153 -0
  50. package/dist/cjs/lib/library/NativeCallback.d.ts +44 -0
  51. package/dist/cjs/lib/library/NativeCallback.js +66 -0
  52. package/dist/cjs/lib/library/NativeLibraryHandle.d.ts +268 -0
  53. package/dist/cjs/lib/library/NativeLibraryHandle.js +540 -0
  54. package/dist/cjs/lib/library/Resolve.d.ts +49 -0
  55. package/dist/cjs/lib/library/Resolve.js +130 -0
  56. package/dist/cjs/lib/thread/NativeThreads.d.ts +80 -0
  57. package/dist/cjs/lib/thread/NativeThreads.js +384 -0
  58. package/dist/cjs/lib/thread/NativeWorker.d.ts +6 -0
  59. package/dist/cjs/lib/thread/NativeWorker.js +96 -0
  60. package/dist/cjs/lib/thread/NativeWorkerCode.d.ts +5 -0
  61. package/dist/cjs/lib/thread/NativeWorkerCode.js +4 -0
  62. package/dist/cjs/lib/thread/PackageRequire.d.ts +6 -0
  63. package/dist/cjs/lib/thread/PackageRequire.js +4 -0
  64. package/dist/cjs/lib/thread/ThreadProtocol.d.ts +77 -0
  65. package/dist/cjs/lib/thread/ThreadProtocol.js +2 -0
  66. package/dist/cjs/package.json +1 -0
  67. package/dist/esm/components/NativeLibrary.js +338 -0
  68. package/dist/esm/decorators/Library.js +40 -0
  69. package/dist/esm/decorators/Native.js +85 -0
  70. package/dist/esm/exceptions/NativeDeclarationException.js +15 -0
  71. package/dist/esm/exceptions/NativeLibraryClosedException.js +15 -0
  72. package/dist/esm/exceptions/NativeLibraryNotFoundException.js +14 -0
  73. package/dist/esm/exceptions/NativeMemoryException.js +14 -0
  74. package/dist/esm/exports/FFI.js +10 -0
  75. package/dist/esm/exports/Generator.js +2 -0
  76. package/dist/esm/lib/Memory.js +210 -0
  77. package/dist/esm/lib/Runtime.js +192 -0
  78. package/dist/esm/lib/backend/Functions.js +206 -0
  79. package/dist/esm/lib/backend/KoffiTypes.js +418 -0
  80. package/dist/esm/lib/declarations/Builtins.js +174 -0
  81. package/dist/esm/lib/declarations/Layout.js +175 -0
  82. package/dist/esm/lib/declarations/Lexer.js +321 -0
  83. package/dist/esm/lib/declarations/Parser.js +1421 -0
  84. package/dist/esm/lib/declarations/Platform.js +23 -0
  85. package/dist/esm/lib/declarations/Types.js +170 -0
  86. package/dist/esm/lib/generator/CText.js +129 -0
  87. package/dist/esm/lib/generator/Generator.js +388 -0
  88. package/dist/esm/lib/generator/Preprocessor.js +87 -0
  89. package/dist/esm/lib/generator/TypeScriptTypes.js +149 -0
  90. package/dist/esm/lib/library/NativeCallback.js +59 -0
  91. package/dist/esm/lib/library/NativeLibraryHandle.js +532 -0
  92. package/dist/esm/lib/library/Resolve.js +122 -0
  93. package/dist/esm/lib/thread/NativeThreads.js +377 -0
  94. package/dist/esm/lib/thread/NativeWorker.js +93 -0
  95. package/dist/esm/lib/thread/NativeWorkerCode.js +1 -0
  96. package/dist/esm/lib/thread/PackageRequire.js +2 -0
  97. package/dist/esm/lib/thread/ThreadProtocol.js +1 -0
  98. package/dist/types/components/NativeLibrary.d.ts +229 -0
  99. package/dist/types/decorators/Library.d.ts +61 -0
  100. package/dist/types/decorators/Native.d.ts +69 -0
  101. package/dist/types/exceptions/NativeDeclarationException.d.ts +12 -0
  102. package/dist/types/exceptions/NativeLibraryClosedException.d.ts +12 -0
  103. package/dist/types/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
  104. package/dist/types/exceptions/NativeMemoryException.d.ts +11 -0
  105. package/dist/types/exports/FFI.d.ts +12 -0
  106. package/dist/types/exports/Generator.d.ts +2 -0
  107. package/dist/types/lib/Memory.d.ts +188 -0
  108. package/dist/types/lib/Runtime.d.ts +98 -0
  109. package/dist/types/lib/backend/Functions.d.ts +65 -0
  110. package/dist/types/lib/backend/KoffiTypes.d.ts +53 -0
  111. package/dist/types/lib/declarations/Builtins.d.ts +33 -0
  112. package/dist/types/lib/declarations/Layout.d.ts +41 -0
  113. package/dist/types/lib/declarations/Lexer.d.ts +40 -0
  114. package/dist/types/lib/declarations/Parser.d.ts +90 -0
  115. package/dist/types/lib/declarations/Platform.d.ts +50 -0
  116. package/dist/types/lib/declarations/Types.d.ts +173 -0
  117. package/dist/types/lib/generator/CText.d.ts +14 -0
  118. package/dist/types/lib/generator/Generator.d.ts +136 -0
  119. package/dist/types/lib/generator/Preprocessor.d.ts +60 -0
  120. package/dist/types/lib/generator/TypeScriptTypes.d.ts +35 -0
  121. package/dist/types/lib/library/NativeCallback.d.ts +44 -0
  122. package/dist/types/lib/library/NativeLibraryHandle.d.ts +268 -0
  123. package/dist/types/lib/library/Resolve.d.ts +49 -0
  124. package/dist/types/lib/thread/NativeThreads.d.ts +80 -0
  125. package/dist/types/lib/thread/NativeWorker.d.ts +6 -0
  126. package/dist/types/lib/thread/NativeWorkerCode.d.ts +5 -0
  127. package/dist/types/lib/thread/PackageRequire.d.ts +6 -0
  128. package/dist/types/lib/thread/ThreadProtocol.d.ts +77 -0
  129. package/package.json +85 -4
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The platform of a system and an architecture
3
+ * @param os
4
+ * @param arch
5
+ */
6
+ export function platformOf(os, arch) {
7
+ const bits64 = !['ia32', 'arm', 'x32'].includes(arch);
8
+ const windows = os === 'win32';
9
+ return {
10
+ os: os,
11
+ arch: arch,
12
+ pointerSize: bits64 ? 8 : 4,
13
+ longSize: bits64 && !windows ? 8 : 4,
14
+ wcharSize: windows ? 2 : 4,
15
+ int64Alignment: !bits64 && !windows && arch === 'ia32' ? 4 : 8,
16
+ bitfields: windows ? 'msvc' : (arch === 'arm' || arch === 'arm64') && os !== 'darwin' ? 'aapcs' : 'sysv',
17
+ underscoredSymbols: os === 'darwin'
18
+ };
19
+ }
20
+ /**
21
+ * The platform the process runs on
22
+ */
23
+ export const CURRENT_PLATFORM = platformOf(process.platform, process.arch);
@@ -0,0 +1,170 @@
1
+ /**
2
+ * An empty set of declarations
3
+ */
4
+ export function emptyDeclarations() {
5
+ return { types: new Map(), tags: new Map(), functions: new Map(), variables: new Map(), constants: new Map(), macros: new Map() };
6
+ }
7
+ export const VOID = { kind: 'primitive', name: 'void' };
8
+ /**
9
+ * The size of an arithmetic type, in bytes
10
+ * @param name
11
+ * @param platform
12
+ */
13
+ export function primitiveSize(name, platform) {
14
+ switch (name) {
15
+ case 'void':
16
+ return 0;
17
+ case 'bool':
18
+ case 'char':
19
+ case 'schar':
20
+ case 'uchar':
21
+ case 'int8':
22
+ case 'uint8':
23
+ return 1;
24
+ case 'short':
25
+ case 'ushort':
26
+ case 'int16':
27
+ case 'uint16':
28
+ case 'char16':
29
+ return 2;
30
+ case 'int':
31
+ case 'uint':
32
+ case 'int32':
33
+ case 'uint32':
34
+ case 'char32':
35
+ case 'float':
36
+ return 4;
37
+ case 'long':
38
+ case 'ulong':
39
+ return platform.longSize;
40
+ case 'longlong':
41
+ case 'ulonglong':
42
+ case 'int64':
43
+ case 'uint64':
44
+ case 'double':
45
+ return 8;
46
+ case 'size':
47
+ case 'ssize':
48
+ case 'intptr':
49
+ case 'uintptr':
50
+ case 'ptrdiff':
51
+ return platform.pointerSize;
52
+ case 'wchar':
53
+ return platform.wcharSize;
54
+ }
55
+ }
56
+ /**
57
+ * Whether an arithmetic type is signed
58
+ * @param name
59
+ * @param platform
60
+ */
61
+ export function primitiveSigned(name, platform) {
62
+ switch (name) {
63
+ case 'char':
64
+ //char is signed but on the ARM systems other than Apple's and Microsoft's (koffi reads it as signed everywhere)
65
+ return true;
66
+ case 'schar':
67
+ case 'short':
68
+ case 'int':
69
+ case 'long':
70
+ case 'longlong':
71
+ case 'int8':
72
+ case 'int16':
73
+ case 'int32':
74
+ case 'int64':
75
+ case 'ssize':
76
+ case 'intptr':
77
+ case 'ptrdiff':
78
+ case 'float':
79
+ case 'double':
80
+ return true;
81
+ case 'wchar':
82
+ return platform.os !== 'win32';
83
+ default:
84
+ return false;
85
+ }
86
+ }
87
+ /**
88
+ * Whether an arithmetic type is an integer
89
+ * @param name
90
+ */
91
+ export function primitiveInteger(name) {
92
+ return name !== 'void' && name !== 'float' && name !== 'double';
93
+ }
94
+ /**
95
+ * Whether an integer type is 64-bit on one of the platforms at least: its values are bigints (long is 64-bit but on
96
+ * Windows, size_t but on 32-bit systems)
97
+ * @param name
98
+ */
99
+ export function primitiveBig(name) {
100
+ switch (name) {
101
+ case 'long':
102
+ case 'ulong':
103
+ case 'longlong':
104
+ case 'ulonglong':
105
+ case 'int64':
106
+ case 'uint64':
107
+ case 'size':
108
+ case 'ssize':
109
+ case 'intptr':
110
+ case 'uintptr':
111
+ case 'ptrdiff':
112
+ return true;
113
+ default:
114
+ return false;
115
+ }
116
+ }
117
+ /**
118
+ * A type, as C writes it (for the messages)
119
+ * @param type
120
+ */
121
+ export function typeText(type) {
122
+ switch (type.kind) {
123
+ case 'primitive':
124
+ return PRIMITIVE_TEXT[type.name];
125
+ case 'pointer':
126
+ return `${type.constTarget ? 'const ' : ''}${typeText(type.to)} *`;
127
+ case 'array':
128
+ return `${typeText(type.of)}[${type.length}]`;
129
+ case 'struct':
130
+ case 'union':
131
+ return `${type.kind} ${type.tag ?? '(anonymous)'}`;
132
+ case 'enum':
133
+ return `enum ${type.tag ?? '(anonymous)'}`;
134
+ case 'function':
135
+ return `${typeText(type.result)} (${type.parameters.map((parameter) => typeText(parameter.type)).concat(type.variadic ? ['...'] : []).join(', ')})`;
136
+ }
137
+ }
138
+ const PRIMITIVE_TEXT = {
139
+ void: 'void',
140
+ bool: 'bool',
141
+ char: 'char',
142
+ schar: 'signed char',
143
+ uchar: 'unsigned char',
144
+ short: 'short',
145
+ ushort: 'unsigned short',
146
+ int: 'int',
147
+ uint: 'unsigned int',
148
+ long: 'long',
149
+ ulong: 'unsigned long',
150
+ longlong: 'long long',
151
+ ulonglong: 'unsigned long long',
152
+ int8: 'int8_t',
153
+ uint8: 'uint8_t',
154
+ int16: 'int16_t',
155
+ uint16: 'uint16_t',
156
+ int32: 'int32_t',
157
+ uint32: 'uint32_t',
158
+ int64: 'int64_t',
159
+ uint64: 'uint64_t',
160
+ size: 'size_t',
161
+ ssize: 'ssize_t',
162
+ intptr: 'intptr_t',
163
+ uintptr: 'uintptr_t',
164
+ ptrdiff: 'ptrdiff_t',
165
+ char16: 'char16_t',
166
+ char32: 'char32_t',
167
+ wchar: 'wchar_t',
168
+ float: 'float',
169
+ double: 'double'
170
+ };
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The words that change nothing of what a declaration declares, removed from the declarations written
3
+ */
4
+ const NOISE = new Set([
5
+ '__extension__', '__restrict', '__restrict__', 'restrict', '_Nullable', '_Nonnull', '_Null_unspecified', '__nullable', '__nonnull',
6
+ '__null_unspecified', '_Nullable_result', '__ptr32', '__ptr64', '__unaligned', '__w64'
7
+ ]);
8
+ /**
9
+ * The words that can follow the parenthesis of a declarator of a pointer to a function: void (*f)(void), void (__stdcall *f)(void)
10
+ */
11
+ const DECLARATOR_STARTS = new Set(['*', '__stdcall', '_stdcall', '__cdecl', '_cdecl', '__fastcall', '_fastcall', '__thiscall', '__vectorcall', '__clrcall']);
12
+ /**
13
+ * The end of the balanced brackets opened at an index: the index of the closing one
14
+ * @param tokens
15
+ * @param open
16
+ */
17
+ function closing(tokens, open) {
18
+ let depth = 0;
19
+ for (let index = open; index < tokens.length; index++) {
20
+ const token = tokens[index];
21
+ if (token.kind !== 'punctuator')
22
+ continue;
23
+ if (token.text === '(' || token.text === '[' || token.text === '{')
24
+ depth++;
25
+ else if ((token.text === ')' || token.text === ']' || token.text === '}') && --depth === 0)
26
+ return index;
27
+ }
28
+ return tokens.length - 1;
29
+ }
30
+ /**
31
+ * The tokens of a declaration without what changes nothing of what it declares: the attributes but packed and aligned,
32
+ * the __declspec but align, the qualifiers the parser ignores
33
+ * @param tokens
34
+ */
35
+ export function prunedTokens(tokens) {
36
+ const kept = [];
37
+ for (let index = 0; index < tokens.length; index++) {
38
+ const token = tokens[index];
39
+ if (token.kind === 'identifier' && NOISE.has(token.text))
40
+ continue;
41
+ const attribute = token.kind === 'identifier' && (token.text === '__attribute__' || token.text === '__attribute' || token.text === '__declspec');
42
+ if (attribute && tokens[index + 1]?.text === '(') {
43
+ const end = closing(tokens, index + 1);
44
+ const inner = tokens.slice(index + 2, end).map((part) => part.text.replace(/^__|__$/g, ''));
45
+ const meaningful = token.text === '__declspec' ? inner.includes('align') : inner.includes('packed') || inner.includes('aligned');
46
+ if (meaningful)
47
+ kept.push(...tokens.slice(index, end + 1));
48
+ index = end;
49
+ continue;
50
+ }
51
+ kept.push(token);
52
+ }
53
+ return kept;
54
+ }
55
+ /**
56
+ * The text of a token as C writes it
57
+ * @param token
58
+ */
59
+ function textOf(token) {
60
+ if (token.kind === 'string')
61
+ return token.source ?? JSON.stringify(token.text);
62
+ if (token.kind === 'pragma')
63
+ return `#pragma ${token.text}`;
64
+ return token.text;
65
+ }
66
+ /**
67
+ * A declaration written as C, one member of a struct or a value of an enum by line
68
+ * @param tokens Its tokens.
69
+ * @param indent The indentation of a level.
70
+ * @returns Its lines.
71
+ */
72
+ export function declarationText(tokens, indent = ' ') {
73
+ const lines = [];
74
+ let line = '';
75
+ //The braces open: whether each one is the body of an enum
76
+ const braces = [];
77
+ let parens = 0;
78
+ const breakLine = () => {
79
+ if (line.trim())
80
+ lines.push(line.replace(/\s+$/, ''));
81
+ line = indent.repeat(braces.length);
82
+ };
83
+ let previous;
84
+ for (let index = 0; index < tokens.length; index++) {
85
+ const token = tokens[index];
86
+ const text = textOf(token);
87
+ if (token.kind === 'pragma') {
88
+ breakLine();
89
+ line += text;
90
+ breakLine();
91
+ previous = undefined;
92
+ continue;
93
+ }
94
+ const punctuator = token.kind === 'punctuator' ? token.text : undefined;
95
+ if (punctuator === '{') {
96
+ const enumBody = tokens.slice(Math.max(0, index - 2), index).some((part) => part.kind === 'identifier' && part.text === 'enum');
97
+ line += `${line.trim() ? ' ' : ''}{`;
98
+ braces.push(enumBody);
99
+ breakLine();
100
+ previous = token;
101
+ continue;
102
+ }
103
+ if (punctuator === '}') {
104
+ braces.pop();
105
+ breakLine();
106
+ line += '}';
107
+ previous = token;
108
+ continue;
109
+ }
110
+ if (punctuator === '(' || punctuator === '[')
111
+ parens++;
112
+ if (punctuator === ')' || punctuator === ']')
113
+ parens--;
114
+ const glued = !previous
115
+ || [',', ';', ')', ']', '['].includes(punctuator ?? '')
116
+ || (previous.kind === 'punctuator' && ['(', '[', '*', '~', '!'].includes(previous.text))
117
+ || (punctuator === '(' && (previous.kind === 'identifier' || previous.text === ')') && !DECLARATOR_STARTS.has(tokens[index + 1]?.text ?? ''))
118
+ || !line.trim();
119
+ line += `${glued ? '' : ' '}${text}`;
120
+ previous = token;
121
+ //A member of a struct, a value of an enum: one by line
122
+ if (braces.length && !parens && (punctuator === ';' || (punctuator === ',' && braces[braces.length - 1]))) {
123
+ breakLine();
124
+ previous = undefined;
125
+ }
126
+ }
127
+ breakLine();
128
+ return lines;
129
+ }