@gtkx/runtime 1.5.0 → 2.0.0-beta.1
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.md +5 -5
- package/dist/application-class.d.ts +1 -1
- package/dist/application-class.d.ts.map +1 -1
- package/dist/application-class.js +1 -2
- package/dist/application-class.js.map +1 -1
- package/dist/arg.d.ts +4 -1
- package/dist/arg.d.ts.map +1 -1
- package/dist/arg.js.map +1 -1
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +1 -9
- package/dist/bind.js.map +1 -1
- package/dist/callback.d.ts +6 -1
- package/dist/callback.d.ts.map +1 -1
- package/dist/callback.js +33 -21
- package/dist/callback.js.map +1 -1
- package/dist/closure.d.ts +3 -1
- package/dist/closure.d.ts.map +1 -1
- package/dist/closure.js +17 -6
- package/dist/closure.js.map +1 -1
- package/dist/descriptors.d.ts +36 -36
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +65 -26
- package/dist/descriptors.js.map +1 -1
- package/dist/element-metadata.d.ts +9 -0
- package/dist/element-metadata.d.ts.map +1 -0
- package/dist/element-metadata.js +14 -0
- package/dist/element-metadata.js.map +1 -0
- package/dist/fn.d.ts +8 -2
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +43 -13
- package/dist/fn.js.map +1 -1
- package/dist/folded-lengths.d.ts +2 -1
- package/dist/folded-lengths.d.ts.map +1 -1
- package/dist/folded-lengths.js +17 -7
- package/dist/folded-lengths.js.map +1 -1
- package/dist/index.d.ts +4 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -26
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +5 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +5 -2
- package/dist/internal.js.map +1 -1
- package/dist/native-value.d.ts +9 -1
- package/dist/native-value.d.ts.map +1 -1
- package/dist/native-value.js +41 -5
- package/dist/native-value.js.map +1 -1
- package/dist/properties.d.ts +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +2 -11
- package/dist/properties.js.map +1 -1
- package/dist/register-class.d.ts +45 -249
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +38 -1
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +26 -3
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +75 -20
- package/dist/registry.js.map +1 -1
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +9 -22
- package/dist/signal.js.map +1 -1
- package/dist/t.d.ts +5 -21
- package/dist/t.d.ts.map +1 -1
- package/dist/t.js +1 -5
- package/dist/t.js.map +1 -1
- package/dist/type.d.ts +10 -1
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +21 -2
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +26 -4
- package/dist/value.js.map +1 -1
- package/dist/variant.d.ts +2 -6
- package/dist/variant.d.ts.map +1 -1
- package/dist/variant.js.map +1 -1
- package/dist/vfunc-call.d.ts.map +1 -1
- package/dist/vfunc-call.js +2 -11
- package/dist/vfunc-call.js.map +1 -1
- package/package.json +15 -6
- package/src/application-class.ts +2 -2
- package/src/arg.ts +4 -1
- package/src/bind.ts +1 -12
- package/src/callback.ts +53 -29
- package/src/closure.ts +31 -6
- package/src/descriptors.ts +126 -44
- package/src/element-metadata.ts +24 -0
- package/src/fn.ts +64 -15
- package/src/folded-lengths.ts +23 -10
- package/src/index.ts +5 -24
- package/src/internal.ts +9 -2
- package/src/native-value.ts +54 -5
- package/src/properties.ts +3 -16
- package/src/register-class.ts +104 -249
- package/src/registry.ts +110 -19
- package/src/signal.ts +9 -34
- package/src/t.ts +5 -21
- package/src/type.ts +34 -1
- package/src/value.ts +37 -5
- package/src/variant.ts +2 -6
- package/src/vfunc-call.ts +3 -16
package/src/descriptors.ts
CHANGED
|
@@ -33,16 +33,25 @@ type FlagsDescriptor = Extract<Descriptor, { kind: "flags" }>;
|
|
|
33
33
|
type BooleanDescriptor = Extract<Descriptor, { kind: "boolean" }>;
|
|
34
34
|
/** Descriptor variant for a C string. */
|
|
35
35
|
type StringDescriptor = Extract<Descriptor, { kind: "string" }>;
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
|
|
37
|
+
/** Descriptor variant for a `GObject`, extended with the statically declared type of its value. */
|
|
38
|
+
type ObjectDescriptor = Extract<Descriptor, { kind: "object" }> & {
|
|
39
|
+
/** Retains and supplies the declared wrapper when no more-derived wrapper is registered. */
|
|
40
|
+
fallbackClass?: () => AnyClass;
|
|
41
|
+
};
|
|
42
|
+
|
|
38
43
|
/** Descriptor variant for a `gunichar`. */
|
|
39
44
|
type UnicharDescriptor = Extract<Descriptor, { kind: "unichar" }>;
|
|
40
45
|
/** Descriptor variant for the absence of a value. */
|
|
41
46
|
type VoidDescriptor = Extract<Descriptor, { kind: "void" }>;
|
|
42
47
|
/** Descriptor variant for an opaque `gpointer`. */
|
|
43
48
|
type BufferDescriptor = Extract<Descriptor, { kind: "buffer" }>;
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
|
|
50
|
+
/** Descriptor variant for a `GBoxed` value, extended with the statically declared type of its value. */
|
|
51
|
+
type BoxedDescriptor = Extract<Descriptor, { kind: "boxed" }> & {
|
|
52
|
+
/** Retains and supplies the declared wrapper when none is registered. */
|
|
53
|
+
fallbackClass?: () => AnyClass;
|
|
54
|
+
};
|
|
46
55
|
|
|
47
56
|
/** Descriptor variant for a plain C struct, extended with the class its decoded value is wrapped in. */
|
|
48
57
|
type StructDescriptor = Extract<Descriptor, { kind: "struct" }> & {
|
|
@@ -54,6 +63,8 @@ type StructDescriptor = Extract<Descriptor, { kind: "struct" }> & {
|
|
|
54
63
|
type FundamentalDescriptor = Extract<Descriptor, { kind: "fundamental" }> & {
|
|
55
64
|
/** Class a decoded value is wrapped in; without it the wrapper comes from the type named by `typeName`. */
|
|
56
65
|
wrapperClass?: AnyClass;
|
|
66
|
+
/** Retains and supplies the declared wrapper after checking the runtime-type registry. */
|
|
67
|
+
fallbackClass?: () => AnyClass;
|
|
57
68
|
};
|
|
58
69
|
|
|
59
70
|
/** Descriptor variant for an array of items in one of the supported container layouts. */
|
|
@@ -87,12 +98,11 @@ type BoxedOptions = {
|
|
|
87
98
|
freeFnName?: string;
|
|
88
99
|
/** Byte size of the value, needed to copy it into an inline field. */
|
|
89
100
|
size?: number;
|
|
101
|
+
/** Returns the wrapper class of the declared type, used when none is registered for the GType. */
|
|
102
|
+
fallbackClass?: () => AnyClass;
|
|
90
103
|
};
|
|
91
104
|
|
|
92
|
-
/**
|
|
93
|
-
* What the bindings do with a callback's return value, how the callee takes its closure, and how
|
|
94
|
-
* long that closure has to stay alive.
|
|
95
|
-
*/
|
|
105
|
+
/** Callback result, closure ownership, and lifetime options. */
|
|
96
106
|
type CallbackOptions = {
|
|
97
107
|
/** The callee also takes a destroy notify, which frees the closure once it is done with it. */
|
|
98
108
|
hasDestroy?: boolean;
|
|
@@ -102,10 +112,7 @@ type CallbackOptions = {
|
|
|
102
112
|
hasUserData?: boolean;
|
|
103
113
|
/** Position of `user_data` among the callback's own arguments, dropped before the closure is called. */
|
|
104
114
|
userDataIndex?: number;
|
|
105
|
-
/**
|
|
106
|
-
* The callback's C signature ends with a `GError**`, which receives a `GError` built from
|
|
107
|
-
* whatever the JavaScript function throws while the callback returns its failure value.
|
|
108
|
-
*/
|
|
115
|
+
/** Converts a thrown value to the callback's trailing `GError**`. */
|
|
109
116
|
canThrow?: boolean;
|
|
110
117
|
/** Lifetime of the closure; defaults to `notified` when `hasDestroy` is set and `call` otherwise. */
|
|
111
118
|
scope?: CallbackDescriptor["scope"];
|
|
@@ -123,12 +130,10 @@ type ArrayOptions = {
|
|
|
123
130
|
fixedSize?: number | undefined;
|
|
124
131
|
/** Whether the array carries raw bytes, and so decodes to a `Uint8Array` rather than to numbers. */
|
|
125
132
|
isBytes?: boolean | undefined;
|
|
126
|
-
/**
|
|
127
|
-
* Whether the caller supplies the storage for a fixed-length out array: the runtime allocates
|
|
128
|
-
* a buffer of the element stride times the fixed element count, passes its pointer, and
|
|
129
|
-
* decodes the elements the callee wrote into it.
|
|
130
|
-
*/
|
|
133
|
+
/** Allocates and decodes caller-owned storage for a fixed-length out array. */
|
|
131
134
|
isCallerAllocated?: boolean | undefined;
|
|
135
|
+
/** Adds a zero element after the declared length. */
|
|
136
|
+
isZeroTerminated?: boolean | undefined;
|
|
132
137
|
};
|
|
133
138
|
|
|
134
139
|
/** Where a cursor array's base buffer and total length come from. */
|
|
@@ -147,6 +152,8 @@ type FundamentalOptions = {
|
|
|
147
152
|
typeName?: string;
|
|
148
153
|
/** Class a decoded value is wrapped in, instead of the one registered for `typeName`. */
|
|
149
154
|
wrapperClass?: AnyClass;
|
|
155
|
+
/** Returns the wrapper class of the declared type, used when none is registered for the value's type. */
|
|
156
|
+
fallbackClass?: () => AnyClass;
|
|
150
157
|
/** The caller owns the storage the callee fills, so a decoded value is borrowed instead of acquired. */
|
|
151
158
|
isCallerAllocated?: boolean;
|
|
152
159
|
/** The value is embedded in the containing struct rather than reached through a pointer. */
|
|
@@ -169,6 +176,12 @@ type StructOptions = {
|
|
|
169
176
|
size?: number;
|
|
170
177
|
/** Class a decoded value is wrapped in, instead of the one registered for its GType. */
|
|
171
178
|
wrapperClass?: AnyClass;
|
|
179
|
+
/** Library the struct's declared copy and free functions are resolved from; without it neither is used. */
|
|
180
|
+
sharedLibrary?: string;
|
|
181
|
+
/** Function duplicating an instance, used instead of a byte copy when the struct declares one. */
|
|
182
|
+
copyFnName?: string;
|
|
183
|
+
/** Function releasing an instance, used instead of `g_free` when the struct declares one. */
|
|
184
|
+
freeFnName?: string;
|
|
172
185
|
};
|
|
173
186
|
|
|
174
187
|
/** Descriptor for a `gint8`, marshalled as a number. */
|
|
@@ -210,15 +223,43 @@ const fundamentalLifecycles: Map<string, FundamentalLifecycle> = new Map();
|
|
|
210
223
|
const isGtypeDescriptor = (descriptor: Descriptor): descriptor is TypeDescriptor =>
|
|
211
224
|
descriptor.kind === "biguint64" && "type" in descriptor;
|
|
212
225
|
|
|
213
|
-
/**
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
226
|
+
/** Builds a C-string descriptor, including optional buffer length and record-owned storage. */
|
|
227
|
+
const stringT = (
|
|
228
|
+
ownership: Ownership = "borrowed",
|
|
229
|
+
length?: number,
|
|
230
|
+
hasOwnedStorage?: boolean,
|
|
231
|
+
): StringDescriptor => {
|
|
232
|
+
const result: StringDescriptor = { kind: "string", ownership };
|
|
233
|
+
|
|
234
|
+
if (length !== undefined) {
|
|
235
|
+
result.length = length;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (hasOwnedStorage === true) {
|
|
239
|
+
result.hasOwnedStorage = true;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return result;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
/** Builds a runtime-typed `GObject` descriptor with an optional retained fallback class. */
|
|
246
|
+
const objectT = (
|
|
247
|
+
ownership: Ownership = "borrowed",
|
|
248
|
+
fallbackClass?: () => AnyClass,
|
|
249
|
+
typeName?: string,
|
|
250
|
+
): ObjectDescriptor => {
|
|
251
|
+
const result: ObjectDescriptor = { kind: "object", ownership };
|
|
252
|
+
|
|
253
|
+
if (fallbackClass !== undefined) {
|
|
254
|
+
result.fallbackClass = fallbackClass;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (typeName !== undefined) {
|
|
258
|
+
result.typeName = typeName;
|
|
259
|
+
}
|
|
219
260
|
|
|
220
|
-
|
|
221
|
-
|
|
261
|
+
return result;
|
|
262
|
+
};
|
|
222
263
|
|
|
223
264
|
/** Wraps a descriptor in a pointer to it, for an output or inout argument. */
|
|
224
265
|
const refT = (innerDescriptor: Descriptor, isInout = false): RefDescriptor =>
|
|
@@ -236,19 +277,28 @@ const hashTableT = (
|
|
|
236
277
|
ownership,
|
|
237
278
|
});
|
|
238
279
|
|
|
239
|
-
/** Builds
|
|
240
|
-
const enumT = (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
280
|
+
/** Builds an enum descriptor from a GType function or an explicit set of members. */
|
|
281
|
+
const enumT = (
|
|
282
|
+
sharedLibrary: string,
|
|
283
|
+
typeFnName: string,
|
|
284
|
+
isSigned: boolean,
|
|
285
|
+
members?: number[],
|
|
286
|
+
): EnumDescriptor => {
|
|
287
|
+
const result: EnumDescriptor = {
|
|
288
|
+
kind: "enum",
|
|
289
|
+
sharedLibrary,
|
|
290
|
+
getTypeFnName: typeFnName,
|
|
291
|
+
isSigned,
|
|
292
|
+
};
|
|
246
293
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
294
|
+
if (members !== undefined) {
|
|
295
|
+
result.members = members;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return result;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/** Builds a flags descriptor from a GType function or an explicit bit mask. */
|
|
252
302
|
const flagsT = (sharedLibrary: string, typeFnName: string, isSigned: boolean, mask?: number): FlagsDescriptor => {
|
|
253
303
|
const result: FlagsDescriptor = {
|
|
254
304
|
kind: "flags",
|
|
@@ -281,6 +331,10 @@ const applyBoxedNames = (result: BoxedDescriptor, options: BoxedOptions): void =
|
|
|
281
331
|
const applyBoxedOptions = (result: BoxedDescriptor, options: BoxedOptions): void => {
|
|
282
332
|
applyBoxedNames(result, options);
|
|
283
333
|
|
|
334
|
+
if (options.fallbackClass !== undefined) {
|
|
335
|
+
result.fallbackClass = options.fallbackClass;
|
|
336
|
+
}
|
|
337
|
+
|
|
284
338
|
if (options.isCallerAllocated) {
|
|
285
339
|
result.isCallerAllocated = true;
|
|
286
340
|
}
|
|
@@ -307,6 +361,22 @@ const boxedT = (typeName: string, options: BoxedOptions = {}): BoxedDescriptor =
|
|
|
307
361
|
return result;
|
|
308
362
|
};
|
|
309
363
|
|
|
364
|
+
const applyStructLifecycle = (result: StructDescriptor, options: StructOptions): void => {
|
|
365
|
+
if (options.sharedLibrary === undefined) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
result.sharedLibrary = options.sharedLibrary;
|
|
370
|
+
|
|
371
|
+
if (options.copyFnName !== undefined) {
|
|
372
|
+
result.copyFnName = options.copyFnName;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (options.freeFnName !== undefined) {
|
|
376
|
+
result.freeFnName = options.freeFnName;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
310
380
|
/** Builds a descriptor for a plain C struct. */
|
|
311
381
|
const structT = (ownership: Ownership = "borrowed", options: StructOptions = {}): StructDescriptor => {
|
|
312
382
|
const result: StructDescriptor = { kind: "struct", ownership };
|
|
@@ -327,6 +397,8 @@ const structT = (ownership: Ownership = "borrowed", options: StructOptions = {})
|
|
|
327
397
|
result.isInline = true;
|
|
328
398
|
}
|
|
329
399
|
|
|
400
|
+
applyStructLifecycle(result, options);
|
|
401
|
+
|
|
330
402
|
return result;
|
|
331
403
|
};
|
|
332
404
|
|
|
@@ -339,6 +411,16 @@ const recordFundamentalLifecycle = (typeName: string, lifecycle: FundamentalLife
|
|
|
339
411
|
const fundamentalLifecycleFor = (typeName: string): FundamentalLifecycle | undefined =>
|
|
340
412
|
fundamentalLifecycles.get(typeName);
|
|
341
413
|
|
|
414
|
+
const applyFundamentalClasses = (result: FundamentalDescriptor, options: FundamentalOptions): void => {
|
|
415
|
+
if (options.wrapperClass !== undefined) {
|
|
416
|
+
result.wrapperClass = options.wrapperClass;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (options.fallbackClass !== undefined) {
|
|
420
|
+
result.fallbackClass = options.fallbackClass;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
342
424
|
/** Builds a descriptor for a fundamental type whose lifetime is managed by named ref and unref functions. */
|
|
343
425
|
const fundamentalT = (
|
|
344
426
|
sharedLibrary: string,
|
|
@@ -354,9 +436,7 @@ const fundamentalT = (
|
|
|
354
436
|
recordFundamentalLifecycle(options.typeName, { sharedLibrary, refFnName, unrefFnName });
|
|
355
437
|
}
|
|
356
438
|
|
|
357
|
-
|
|
358
|
-
result.wrapperClass = options.wrapperClass;
|
|
359
|
-
}
|
|
439
|
+
applyFundamentalClasses(result, options);
|
|
360
440
|
|
|
361
441
|
if (options.isCallerAllocated) {
|
|
362
442
|
result.isCallerAllocated = true;
|
|
@@ -410,6 +490,10 @@ const arrayT = (
|
|
|
410
490
|
result.isCallerAllocated = true;
|
|
411
491
|
}
|
|
412
492
|
|
|
493
|
+
if (options.isZeroTerminated === true) {
|
|
494
|
+
result.isZeroTerminated = true;
|
|
495
|
+
}
|
|
496
|
+
|
|
413
497
|
return result;
|
|
414
498
|
};
|
|
415
499
|
|
|
@@ -453,10 +537,7 @@ const sizedArrayT = (
|
|
|
453
537
|
options: ArrayOptions = {},
|
|
454
538
|
): ArrayDescriptor => arrayT(itemDescriptor, "sized", ownership, { ...options, sizeParamIndex });
|
|
455
539
|
|
|
456
|
-
/**
|
|
457
|
-
* Builds a descriptor for an out pointer into the buffer another argument supplied, decoded as the
|
|
458
|
-
* elements from where it points to the end of that buffer.
|
|
459
|
-
*/
|
|
540
|
+
/** Builds an out-array cursor into another argument's buffer. */
|
|
460
541
|
const cursorArrayT = (
|
|
461
542
|
itemDescriptor: Descriptor,
|
|
462
543
|
bounds: CursorBounds,
|
|
@@ -559,6 +640,7 @@ export {
|
|
|
559
640
|
cursorArrayT,
|
|
560
641
|
callbackT,
|
|
561
642
|
type BoxedDescriptor,
|
|
643
|
+
type ObjectDescriptor,
|
|
562
644
|
type StructDescriptor,
|
|
563
645
|
type FundamentalDescriptor,
|
|
564
646
|
type ArrayDescriptor,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
type ElementPropertyEntry = [name: string, flags: number, defaultValue?: unknown];
|
|
2
|
+
|
|
3
|
+
const registeredElementSignals: Record<string, Record<string, string>> = {};
|
|
4
|
+
const registeredElementProperties: Record<string, Record<string, ElementPropertyEntry>> = {};
|
|
5
|
+
const state = { version: 0 };
|
|
6
|
+
|
|
7
|
+
const registerElementMetadata = (
|
|
8
|
+
name: string,
|
|
9
|
+
_parent: string | undefined,
|
|
10
|
+
ownSignals: Record<string, string>,
|
|
11
|
+
ownProperties: Record<string, ElementPropertyEntry>,
|
|
12
|
+
): string => {
|
|
13
|
+
registeredElementSignals[name] = ownSignals;
|
|
14
|
+
registeredElementProperties[name] = ownProperties;
|
|
15
|
+
state.version += 1;
|
|
16
|
+
|
|
17
|
+
return name;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const elementMetadataVersion = (): number => state.version;
|
|
21
|
+
|
|
22
|
+
/** @internal */
|
|
23
|
+
export { type ElementPropertyEntry, registerElementMetadata };
|
|
24
|
+
export { elementMetadataVersion, registeredElementProperties, registeredElementSignals };
|
package/src/fn.ts
CHANGED
|
@@ -158,12 +158,33 @@ const isPassThroughPlan = (plan: ArgSpec, index: number): boolean =>
|
|
|
158
158
|
!plan.carriesGtype &&
|
|
159
159
|
plan.arg.type.kind !== "callback";
|
|
160
160
|
|
|
161
|
-
const
|
|
162
|
-
|
|
161
|
+
const KINDS_PASSED_AS_POINTER: ReadonlySet<Descriptor["kind"]> = new Set<Descriptor["kind"]>([
|
|
162
|
+
"array",
|
|
163
|
+
"boxed",
|
|
164
|
+
"buffer",
|
|
165
|
+
"callback",
|
|
166
|
+
"fundamental",
|
|
167
|
+
"hashtable",
|
|
168
|
+
"object",
|
|
169
|
+
"string",
|
|
170
|
+
"struct",
|
|
171
|
+
]);
|
|
172
|
+
|
|
173
|
+
type RequiredInput = {
|
|
174
|
+
index: number;
|
|
175
|
+
rejectsNull: boolean;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const requiredInputs = (plans: ArgSpec[]): RequiredInput[] =>
|
|
179
|
+
plans
|
|
180
|
+
.filter((plan) => plan.requiresInput && plan.arg.isRequired === true)
|
|
181
|
+
.map((plan) => ({ index: plan.inputIndex, rejectsNull: KINDS_PASSED_AS_POINTER.has(plan.arg.type.kind) }));
|
|
163
182
|
|
|
164
|
-
const assertRequiredInputs = (
|
|
165
|
-
for (const index of
|
|
166
|
-
|
|
183
|
+
const assertRequiredInputs = (required: RequiredInput[], inputs: unknown[]): void => {
|
|
184
|
+
for (const { index, rejectsNull } of required) {
|
|
185
|
+
const input = inputs[index];
|
|
186
|
+
|
|
187
|
+
if (input === undefined || (rejectsNull && input === null)) {
|
|
167
188
|
throw new TypeError(`Missing required argument at position ${String(index + 1)}`);
|
|
168
189
|
}
|
|
169
190
|
}
|
|
@@ -193,10 +214,10 @@ const directCallable = (
|
|
|
193
214
|
plans: ArgSpec[],
|
|
194
215
|
): ((...inputs: unknown[]) => unknown) => {
|
|
195
216
|
const argCount = plans.length;
|
|
196
|
-
const
|
|
217
|
+
const required = requiredInputs(plans);
|
|
197
218
|
|
|
198
219
|
const marshal = (inputs: unknown[]): unknown => {
|
|
199
|
-
assertRequiredInputs(
|
|
220
|
+
assertRequiredInputs(required, inputs);
|
|
200
221
|
|
|
201
222
|
return readReturn(call(descriptor, resizeInputs(inputs, argCount)));
|
|
202
223
|
};
|
|
@@ -226,14 +247,14 @@ function fromNativeCallable(
|
|
|
226
247
|
return directCallable(descriptor, readReturn, hasPrimary, plans);
|
|
227
248
|
}
|
|
228
249
|
|
|
229
|
-
const
|
|
250
|
+
const required = requiredInputs(plans);
|
|
230
251
|
|
|
231
252
|
const shape = (inputs: unknown[], nativeValues: unknown[], nativeResult: unknown): unknown =>
|
|
232
253
|
packTupleResult(readOutParams(outPlans, inputs, nativeValues), readReturn(nativeResult), hasPrimary);
|
|
233
254
|
|
|
234
255
|
if (canThrow) {
|
|
235
256
|
return (...inputs) => {
|
|
236
|
-
assertRequiredInputs(
|
|
257
|
+
assertRequiredInputs(required, inputs);
|
|
237
258
|
const nativeValues = buildNativeValues(plans, inputs, getRefSeeds?.());
|
|
238
259
|
const errorRef: Ref = { value: null };
|
|
239
260
|
nativeValues.push(errorRef);
|
|
@@ -245,26 +266,54 @@ function fromNativeCallable(
|
|
|
245
266
|
}
|
|
246
267
|
|
|
247
268
|
return (...inputs) => {
|
|
248
|
-
assertRequiredInputs(
|
|
269
|
+
assertRequiredInputs(required, inputs);
|
|
249
270
|
const nativeValues = buildNativeValues(plans, inputs, getRefSeeds?.());
|
|
250
271
|
|
|
251
272
|
return shape(inputs, nativeValues, call(descriptor, nativeValues));
|
|
252
273
|
};
|
|
253
274
|
}
|
|
254
275
|
|
|
276
|
+
const bindNativeCallable = (
|
|
277
|
+
sharedLibrary: string,
|
|
278
|
+
symbol: string,
|
|
279
|
+
spec: FnSpec,
|
|
280
|
+
): ((...inputs: unknown[]) => unknown) => {
|
|
281
|
+
const nativeArgTypes = buildNativeArgTypes(spec.args, spec.canThrow ?? false);
|
|
282
|
+
const descriptor = nativeBind(sharedLibrary, symbol, nativeArgTypes, spec.returns, spec.fixedArgCount);
|
|
283
|
+
|
|
284
|
+
return fromNativeCallable(descriptor, spec);
|
|
285
|
+
};
|
|
286
|
+
|
|
255
287
|
/**
|
|
256
288
|
* Binds a symbol in a shared library to a callable that marshals its inputs and packs output
|
|
257
289
|
* arguments into the result. When the spec sets `canThrow`, the reported `GError` is thrown.
|
|
258
290
|
*
|
|
291
|
+
* A plain spec is bound when `fn` is called, so a malformed descriptor throws at binding time.
|
|
292
|
+
* Passing a function returning the spec instead defers building the descriptors and the binding
|
|
293
|
+
* to the first call, so describing such a binding costs nothing until something calls it and a
|
|
294
|
+
* module full of them loads without touching the shared library.
|
|
295
|
+
*
|
|
259
296
|
* @param sharedLibrary Shared library the symbol is looked up in.
|
|
260
297
|
* @param symbol Name of the C symbol to bind.
|
|
261
|
-
* @param spec Argument and return descriptors the call is marshalled through
|
|
298
|
+
* @param spec Argument and return descriptors the call is marshalled through, or a function
|
|
299
|
+
* returning them, which defers building the descriptors and the binding to the first call.
|
|
262
300
|
*/
|
|
263
|
-
function fn(
|
|
264
|
-
|
|
265
|
-
|
|
301
|
+
function fn(
|
|
302
|
+
sharedLibrary: string,
|
|
303
|
+
symbol: string,
|
|
304
|
+
spec: FnSpec | (() => FnSpec),
|
|
305
|
+
): (...inputs: unknown[]) => unknown {
|
|
306
|
+
if (typeof spec !== "function") {
|
|
307
|
+
return bindNativeCallable(sharedLibrary, symbol, spec);
|
|
308
|
+
}
|
|
266
309
|
|
|
267
|
-
|
|
310
|
+
let bound: ((...inputs: unknown[]) => unknown) | undefined;
|
|
311
|
+
|
|
312
|
+
return (...inputs) => {
|
|
313
|
+
bound ??= bindNativeCallable(sharedLibrary, symbol, spec());
|
|
314
|
+
|
|
315
|
+
return bound(...inputs);
|
|
316
|
+
};
|
|
268
317
|
}
|
|
269
318
|
|
|
270
319
|
export { buildNativeArgTypes, fn, fromNativeCallable };
|
package/src/folded-lengths.ts
CHANGED
|
@@ -28,15 +28,7 @@ const addLengthSource = (sources: LengthSources, index: number | undefined, sour
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (existing === undefined) {
|
|
34
|
-
sources.set(index, [source]);
|
|
35
|
-
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
existing.push(source);
|
|
31
|
+
sources.getOrInsertComputed(index, () => []).push(source);
|
|
40
32
|
};
|
|
41
33
|
|
|
42
34
|
const addOutArgLengthSources = (sources: LengthSources, spec: FoldedLengthSpec): void => {
|
|
@@ -52,6 +44,27 @@ const addOutArgLengthSources = (sources: LengthSources, spec: FoldedLengthSpec):
|
|
|
52
44
|
}
|
|
53
45
|
};
|
|
54
46
|
|
|
47
|
+
const foldedLengthArgIndices = (spec: FoldedLengthSpec): ReadonlySet<number> => {
|
|
48
|
+
const indices: Set<number> = new Set();
|
|
49
|
+
|
|
50
|
+
const add = (declaredIndex: number | undefined): void => {
|
|
51
|
+
const argIndex = effectiveArgIndex(declaredIndex, spec.userDataIndex);
|
|
52
|
+
|
|
53
|
+
if (argIndex !== undefined) {
|
|
54
|
+
indices.add(argIndex);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
add(sizedArrayLengthIndex(spec.returnDescriptor));
|
|
59
|
+
|
|
60
|
+
for (const descriptor of spec.argDescriptors) {
|
|
61
|
+
add(sizedArrayLengthIndex(descriptor));
|
|
62
|
+
add(outArgLengthIndex(descriptor));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return indices;
|
|
66
|
+
};
|
|
67
|
+
|
|
55
68
|
const foldedLengthSources = (spec: FoldedLengthSpec): LengthSources => {
|
|
56
69
|
const sources: LengthSources = new Map();
|
|
57
70
|
const returnLengthIndex = effectiveArgIndex(sizedArrayLengthIndex(spec.returnDescriptor), spec.userDataIndex);
|
|
@@ -61,4 +74,4 @@ const foldedLengthSources = (spec: FoldedLengthSpec): LengthSources => {
|
|
|
61
74
|
return sources;
|
|
62
75
|
};
|
|
63
76
|
|
|
64
|
-
export { foldedLengthSources, type LengthSource, type LengthSources };
|
|
77
|
+
export { foldedLengthArgIndices, foldedLengthSources, type LengthSource, type LengthSources };
|
package/src/index.ts
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import "./exit-hook.js";
|
|
2
2
|
|
|
3
|
-
/** @public */
|
|
4
3
|
export { type ApplicationClass, type CommandLineApplication, createApplication } from "./application-class.js";
|
|
5
|
-
|
|
4
|
+
export { CallbackMarshalError } from "./callback.js";
|
|
6
5
|
export { type ClosureCallback, ClosureMarshalError, toClosure, tryToClosure } from "./closure.js";
|
|
7
|
-
/** @public */
|
|
8
6
|
export { createErrorDomain, type ErrorDomain } from "./error.js";
|
|
9
|
-
/** @public */
|
|
10
7
|
export { type Field, type StridedField } from "./field.js";
|
|
11
|
-
/** @public */
|
|
12
8
|
export { onExit, quit, quitApplication, runApplication, type RunApplicationResult } from "./lifecycle.js";
|
|
13
|
-
/** @public */
|
|
14
9
|
export { offSignal, onceSignal, onSignal } from "./listeners.js";
|
|
15
|
-
/** @public */
|
|
16
10
|
export { installMixins, type Mixin } from "./mixin.js";
|
|
17
|
-
|
|
18
|
-
export { fromNative, toNative } from "./native-value.js";
|
|
19
|
-
/** @public */
|
|
11
|
+
export { fromNative, toHashTableEntries, toNative } from "./native-value.js";
|
|
20
12
|
export {
|
|
21
13
|
type ConstructBinding,
|
|
22
14
|
type ConstructBindings,
|
|
@@ -25,27 +17,22 @@ export {
|
|
|
25
17
|
registerConstructProperties,
|
|
26
18
|
setObjectProperty,
|
|
27
19
|
} from "./object.js";
|
|
28
|
-
/** @public */
|
|
29
20
|
export { getParamSpecFlags, getParamSpecOwnerType, getParamSpecValueType } from "./param-spec.js";
|
|
30
|
-
/** @public */
|
|
31
21
|
export { promisify, trimFinish } from "./promisify.js";
|
|
32
|
-
/** @public */
|
|
33
22
|
export {
|
|
34
23
|
coerceObjectProperty,
|
|
35
24
|
getDeclaredPropertyName,
|
|
36
25
|
isReadableProperty,
|
|
37
26
|
newParamSpecOverride,
|
|
38
27
|
} from "./properties.js";
|
|
39
|
-
/** @public */
|
|
40
28
|
export { matchAllRegex, matchRegex } from "./regex.js";
|
|
41
|
-
/** @public */
|
|
42
29
|
export { type Interface, registerClass, type SignalGType, type SignalSpec } from "./register-class.js";
|
|
43
|
-
/** @public */
|
|
44
30
|
export {
|
|
45
31
|
getClassType,
|
|
46
32
|
getHandle,
|
|
47
33
|
getInstanceType,
|
|
48
34
|
getWrapperClass,
|
|
35
|
+
installInterfaces,
|
|
49
36
|
peekTypeClass,
|
|
50
37
|
registerClassStruct,
|
|
51
38
|
registerInterface,
|
|
@@ -54,9 +41,9 @@ export {
|
|
|
54
41
|
type StaticBase,
|
|
55
42
|
setHandle,
|
|
56
43
|
wrapHandle,
|
|
44
|
+
type WrapperClass,
|
|
57
45
|
type WrapperClassResolver,
|
|
58
46
|
} from "./registry.js";
|
|
59
|
-
/** @public */
|
|
60
47
|
export {
|
|
61
48
|
connectSignal,
|
|
62
49
|
disconnectSignal,
|
|
@@ -65,9 +52,7 @@ export {
|
|
|
65
52
|
type SignalHandler,
|
|
66
53
|
signalForHandlerName,
|
|
67
54
|
} from "./signal.js";
|
|
68
|
-
/** @public */
|
|
69
55
|
export { t } from "./t.js";
|
|
70
|
-
/** @public */
|
|
71
56
|
export {
|
|
72
57
|
resolveType,
|
|
73
58
|
TYPE_BOOLEAN,
|
|
@@ -95,6 +80,7 @@ export {
|
|
|
95
80
|
TYPE_UNICHAR,
|
|
96
81
|
TYPE_VARIANT,
|
|
97
82
|
type TypedClass,
|
|
83
|
+
retainWrapperClasses,
|
|
98
84
|
typeFromName,
|
|
99
85
|
typeInterfaces,
|
|
100
86
|
typeIsA,
|
|
@@ -102,7 +88,6 @@ export {
|
|
|
102
88
|
typeParent,
|
|
103
89
|
valueIsA,
|
|
104
90
|
} from "./type.js";
|
|
105
|
-
/** @public */
|
|
106
91
|
export {
|
|
107
92
|
fromValue,
|
|
108
93
|
getBoxedValue,
|
|
@@ -112,7 +97,6 @@ export {
|
|
|
112
97
|
tryToValueHandle,
|
|
113
98
|
ValueMarshalError,
|
|
114
99
|
} from "./value.js";
|
|
115
|
-
/** @public */
|
|
116
100
|
export {
|
|
117
101
|
type ByteArray,
|
|
118
102
|
type FromVariantOptions,
|
|
@@ -123,9 +107,6 @@ export {
|
|
|
123
107
|
type VariantInput,
|
|
124
108
|
type VariantValue,
|
|
125
109
|
} from "./variant.js";
|
|
126
|
-
/** @public */
|
|
127
110
|
export { callParent, callVfunc } from "./vfunc-call.js";
|
|
128
|
-
/** @public */
|
|
129
111
|
export { alloc, type ExternalObject, type Handle, read, write } from "@gtkx/native";
|
|
130
|
-
/** @public */
|
|
131
112
|
export { type AnyClass } from "@gtkx/utils";
|
package/src/internal.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/** @internal */
|
|
2
|
+
export { registerElementMetadata } from "./element-metadata.js";
|
|
3
|
+
export {
|
|
4
|
+
elementMetadataVersion,
|
|
5
|
+
registeredElementProperties,
|
|
6
|
+
registeredElementSignals,
|
|
7
|
+
} from "./element-metadata.js";
|
|
8
|
+
export { createErrorDomain } from "./error.js";
|
|
2
9
|
export { type ApplicationInstance, getApplicationInstance } from "./lifecycle.js";
|
|
3
|
-
export {
|
|
10
|
+
export { getExactWrapperClass, resolveWrapperClass } from "./registry.js";
|
|
4
11
|
export { hasSignalListener } from "./signal.js";
|
|
5
12
|
export { resolveType } from "./type.js";
|
|
6
13
|
export {
|