@gtkx/runtime 1.0.0-rc.4 → 1.1.0
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 +37 -0
- package/dist/application-class.d.ts.map +1 -0
- package/dist/application-class.js +78 -0
- package/dist/application-class.js.map +1 -0
- package/dist/arg.d.ts +2 -1
- package/dist/arg.d.ts.map +1 -1
- package/dist/arg.js +2 -1
- package/dist/arg.js.map +1 -1
- package/dist/bind.d.ts +11 -0
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +11 -0
- package/dist/bind.js.map +1 -1
- package/dist/callback.d.ts +4 -3
- package/dist/callback.d.ts.map +1 -1
- package/dist/callback.js +124 -29
- package/dist/callback.js.map +1 -1
- package/dist/closure.d.ts +26 -0
- package/dist/closure.d.ts.map +1 -0
- package/dist/closure.js +99 -0
- package/dist/closure.js.map +1 -0
- package/dist/default-application.d.ts +4 -0
- package/dist/default-application.d.ts.map +1 -0
- package/dist/default-application.js +17 -0
- package/dist/default-application.js.map +1 -0
- package/dist/descriptors.d.ts +98 -4
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +72 -6
- package/dist/descriptors.js.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/exit-hook.js +13 -0
- package/dist/exit-hook.js.map +1 -1
- package/dist/fn.d.ts +24 -2
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +67 -32
- package/dist/fn.js.map +1 -1
- package/dist/folded-lengths.d.ts +16 -0
- package/dist/folded-lengths.d.ts.map +1 -0
- package/dist/folded-lengths.js +38 -0
- package/dist/folded-lengths.js.map +1 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -1
- package/dist/library.d.ts +3 -1
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +3 -1
- package/dist/library.js.map +1 -1
- package/dist/lifecycle.d.ts +58 -11
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +95 -22
- package/dist/lifecycle.js.map +1 -1
- package/dist/listeners.d.ts.map +1 -1
- package/dist/listeners.js +19 -5
- package/dist/listeners.js.map +1 -1
- package/dist/mixin.d.ts +3 -2
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +13 -1
- package/dist/mixin.js.map +1 -1
- package/dist/native-value.d.ts.map +1 -1
- package/dist/native-value.js +4 -3
- package/dist/native-value.js.map +1 -1
- package/dist/object.d.ts +40 -7
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +95 -26
- package/dist/object.js.map +1 -1
- package/dist/param-spec.d.ts +11 -0
- package/dist/param-spec.d.ts.map +1 -0
- package/dist/param-spec.js +147 -0
- package/dist/param-spec.js.map +1 -0
- package/dist/promisify.d.ts.map +1 -1
- package/dist/promisify.js +3 -2
- package/dist/promisify.js.map +1 -1
- package/dist/properties.d.ts +39 -7
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +310 -43
- package/dist/properties.js.map +1 -1
- package/dist/register-class.d.ts +147 -12
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +129 -83
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +80 -21
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +86 -33
- package/dist/registry.js.map +1 -1
- package/dist/signal.d.ts +11 -4
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +85 -25
- package/dist/signal.js.map +1 -1
- package/dist/t.d.ts +2 -0
- package/dist/t.d.ts.map +1 -1
- package/dist/t.js +1 -0
- package/dist/t.js.map +1 -1
- package/dist/tuple.d.ts +6 -3
- package/dist/tuple.d.ts.map +1 -1
- package/dist/tuple.js +9 -7
- package/dist/tuple.js.map +1 -1
- package/dist/type.d.ts +2 -1
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +2 -0
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts +10 -1
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +99 -24
- package/dist/value.js.map +1 -1
- package/dist/vfunc-call.d.ts +37 -0
- package/dist/vfunc-call.d.ts.map +1 -0
- package/dist/vfunc-call.js +172 -0
- package/dist/vfunc-call.js.map +1 -0
- package/dist/vfunc-seeds.d.ts +12 -0
- package/dist/vfunc-seeds.d.ts.map +1 -0
- package/dist/vfunc-seeds.js +19 -0
- package/dist/vfunc-seeds.js.map +1 -0
- package/dist/vfunc.d.ts +8 -0
- package/dist/vfunc.d.ts.map +1 -0
- package/dist/vfunc.js +29 -0
- package/dist/vfunc.js.map +1 -0
- package/package.json +14 -4
- package/src/application-class.ts +126 -0
- package/src/arg.ts +2 -1
- package/src/bind.ts +11 -0
- package/src/callback.ts +178 -34
- package/src/closure.ts +136 -0
- package/src/default-application.ts +21 -0
- package/src/descriptors.ts +150 -34
- package/src/error.ts +1 -0
- package/src/exit-hook.ts +18 -0
- package/src/fn.ts +107 -36
- package/src/folded-lengths.ts +64 -0
- package/src/index.ts +21 -6
- package/src/internal.ts +2 -0
- package/src/library.ts +3 -1
- package/src/lifecycle.ts +138 -25
- package/src/listeners.ts +25 -6
- package/src/mixin.ts +15 -2
- package/src/native-value.ts +5 -3
- package/src/object.ts +134 -35
- package/src/param-spec.ts +234 -0
- package/src/promisify.ts +4 -2
- package/src/properties.ts +473 -46
- package/src/register-class.ts +386 -114
- package/src/registry.ts +169 -49
- package/src/signal.ts +116 -42
- package/src/t.ts +3 -0
- package/src/tuple.ts +18 -12
- package/src/type.ts +3 -1
- package/src/value.ts +143 -23
- package/src/vfunc-call.ts +247 -0
- package/src/vfunc-seeds.ts +36 -0
- package/src/vfunc.ts +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vfunc-call.js","sourceRoot":"","sources":["../src/vfunc-call.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BindVfuncOptions } from \"@gtkx/native\";\nimport type { AnyClass } from \"@gtkx/utils\";\nimport { bindVfunc } from \"@gtkx/native\";\nimport { type Arg, isCallerAllocatedArg, requiresInputArg } from \"./arg.js\";\nimport { buildNativeArgTypes, fromNativeCallable } from \"./fn.js\";\nimport { toNative } from \"./native-value.js\";\nimport {\n getClassType,\n getHandle,\n getInterfaceVfuncRegistry,\n getVfuncRegistry,\n instanceClassName,\n resolveWrapperType,\n type VfuncDescriptor,\n} from \"./registry.js\";\nimport { TYPE_INVALID, typeInterfaces, typeIsA, typeParent } from \"./type.js\";\nimport { type RefSeeds, seedsFor } from \"./vfunc-seeds.js\";\nimport { findClassVfuncDescriptor, findInterfaceVfuncDescriptor, vfuncArgs } from \"./vfunc.js\";\n\ntype Invoker = (instance: object, inputs: unknown[]) => unknown;\ntype InvokerCache = WeakMap<AnyClass, Map<string, Invoker>>;\ntype ResolvedSlot = { descriptor: VfuncDescriptor; interfaceType?: bigint };\n\nconst NO_BASELINE = -1;\n\nconst SEEDED_SLOTS: Record<string, RefSeeds> = {\n \"LayoutManagerClass.measure\": new Map([[6, NO_BASELINE], [7, NO_BASELINE]]),\n \"WidgetClass.measure\": new Map([[5, NO_BASELINE], [6, NO_BASELINE]]),\n};\n\nconst parentInvokers: InvokerCache = new WeakMap();\nconst vfuncInvokers: InvokerCache = new WeakMap();\n\nfunction toNativeInput(arg: Arg, input: unknown): unknown {\n return isCallerAllocatedArg(arg) ? input : toNative(arg.type, input);\n}\n\nfunction bindOptionsFor(\n slot: ResolvedSlot,\n instanceType: bigint | undefined,\n args: Arg[],\n label: string,\n): BindVfuncOptions {\n const { descriptor, interfaceType } = slot;\n\n const options: BindVfuncOptions = {\n byteOffset: descriptor.byteOffset,\n label,\n argDescriptors: buildNativeArgTypes(args, descriptor.canThrow === true),\n returnDescriptor: descriptor.returnDescriptor,\n };\n\n if (descriptor.vtableSize !== undefined) {\n options.vtableSize = descriptor.vtableSize;\n }\n\n if (instanceType !== undefined) {\n options.instanceType = instanceType;\n }\n\n if (interfaceType !== undefined) {\n options.interfaceType = interfaceType;\n }\n\n return options;\n}\n\nfunction buildInvoker(slot: ResolvedSlot, instanceType: bigint | undefined, caller: string): Invoker {\n const { descriptor } = slot;\n const args = vfuncArgs(descriptor);\n const canThrow = descriptor.canThrow === true;\n const label = `${descriptor.className}.${descriptor.vfuncName}`;\n const [, ...inputArgs] = args.filter(requiresInputArg);\n let pendingSeeds: RefSeeds | undefined;\n\n const takeRefSeeds = (): RefSeeds | undefined => {\n const seeds = pendingSeeds;\n pendingSeeds = undefined;\n\n return seeds;\n };\n\n const shaped = fromNativeCallable(\n bindVfunc(bindOptionsFor(slot, instanceType, args, label)),\n {\n args,\n returns: descriptor.returnDescriptor,\n canThrow,\n },\n takeRefSeeds,\n );\n\n return (instance, inputs) => {\n if (inputs.length !== inputArgs.length) {\n throw new Error(\n `${caller}: ${label} expects ${String(inputArgs.length)} arguments, ` +\n `received ${String(inputs.length)}`,\n );\n }\n\n const nativeInputs = inputArgs.map((arg, index) => toNativeInput(arg, inputs[index]));\n pendingSeeds = SEEDED_SLOTS[label] ?? seedsFor(descriptor.argDescriptors, instance);\n\n return shaped(getHandle(instance), ...nativeInputs);\n };\n}\n\nfunction cachedInvoker(cache: InvokerCache, owner: AnyClass, key: string, build: () => Invoker): Invoker {\n let byKey = cache.get(owner);\n\n if (byKey === undefined) {\n byKey = new Map();\n cache.set(owner, byKey);\n }\n\n let invoker = byKey.get(key);\n\n if (invoker === undefined) {\n invoker = build();\n byKey.set(key, invoker);\n }\n\n return invoker;\n}\n\nfunction resolveParentSlot(klass: AnyClass, parentType: bigint, methodName: string): ResolvedSlot | undefined {\n const classDescriptor = findClassVfuncDescriptor(klass, methodName);\n\n if (classDescriptor) {\n return { descriptor: classDescriptor };\n }\n\n for (const interfaceType of typeInterfaces(parentType)) {\n const descriptor = findInterfaceVfuncDescriptor(interfaceType, methodName);\n\n if (descriptor) {\n return { descriptor, interfaceType };\n }\n }\n\n return undefined;\n}\n\nfunction resolveParentType(klass: AnyClass, methodName: string): bigint {\n const gtype = getClassType(klass);\n\n if (gtype === TYPE_INVALID) {\n throw new Error(\n `callParent: cannot call '${methodName}' because ${klass.name} was never passed to registerClass`,\n );\n }\n\n return typeParent(gtype);\n}\n\nfunction buildParentInvoker(klass: AnyClass, methodName: string): Invoker {\n const parentType = resolveParentType(klass, methodName);\n const slot = resolveParentSlot(klass, parentType, methodName);\n\n if (!slot) {\n throw new Error(`callParent: ${klass.name} inherits no '${methodName}' vtable slot`);\n }\n\n return buildInvoker(slot, parentType, \"callParent\");\n}\n\n/**\n * Calls the implementation of a virtual function that the parent type of `klass` provides, so an\n * override can chain up to the behavior it replaces. `klass` is the class whose override is\n * running, named lexically rather than taken from `instance`, so each level of a hierarchy reaches\n * exactly one level up. Arguments and the return value follow the same convention the override\n * itself uses: pure out parameters are left out and returned instead, and a slot with several\n * outputs returns them as a tuple. Throws if `klass` was never registered, inherits no such slot,\n * or the parent type leaves the slot empty.\n *\n * @param klass The registered class whose override is chaining up.\n * @param methodName Name of the overridden method, such as `vfuncMeasure`.\n * @param instance The instance the override was invoked on.\n * @param inputs The arguments the override received.\n */\nfunction callParent(klass: AnyClass, methodName: string, instance: object, ...inputs: unknown[]): unknown {\n const invoker = cachedInvoker(parentInvokers, klass, methodName, () => buildParentInvoker(klass, methodName));\n\n return invoker(instance, inputs);\n}\n\nfunction resolveOwnerSlot(owner: AnyClass, key: string): ResolvedSlot {\n const classDescriptor = getVfuncRegistry(owner)?.[key];\n\n if (classDescriptor !== undefined) {\n return { descriptor: classDescriptor };\n }\n\n const interfaceType = getClassType(owner);\n const descriptor = getInterfaceVfuncRegistry(interfaceType)?.[key];\n\n if (descriptor === undefined) {\n throw new Error(`callVfunc: ${owner.name} declares no '${key}' vtable slot`);\n }\n\n return { descriptor, interfaceType };\n}\n\nfunction requiresDefaultVtable(slot: ResolvedSlot, instanceType: bigint): boolean {\n return slot.interfaceType !== undefined && !typeIsA(instanceType, slot.interfaceType);\n}\n\nfunction resolveInstanceType(key: string, instance: object, slot: ResolvedSlot): bigint | undefined {\n const instanceType = resolveWrapperType(instance);\n\n if (instanceType === TYPE_INVALID) {\n const name = instanceClassName(instance);\n throw new Error(`callVfunc: cannot call '${key}' because ${name} descends from no registered wrapper class`);\n }\n\n return requiresDefaultVtable(slot, instanceType) ? undefined : instanceType;\n}\n\n/**\n * Calls the implementation of a virtual function a wrapper class or interface declares, backing the\n * `vfunc`-prefixed members the generated bindings emit. The slot is read from the nearest generated\n * wrapper class in the instance's class chain rather than from the instance's own type, so an\n * override reaching it through `super` runs the implementation it replaced instead of re-entering\n * itself. When that wrapper class does not carry the interface the slot belongs to, because a class\n * registered below it adopted the interface, the slot comes from the interface's own default vtable\n * instead, which holds exactly what the adopting class replaced. Arguments and the return value\n * follow the same convention an override uses: pure out parameters are left out and returned\n * instead, and a slot with several outputs returns them as a tuple. Throws if the owner declares no\n * such slot, the instance descends from no wrapper class, or the resolved vtable leaves the slot\n * empty.\n *\n * @param owner The wrapper class or interface declaring the slot.\n * @param key Name of the generated member, such as `vfuncMeasure`.\n * @param instance The instance to invoke the slot on.\n * @param inputs The arguments the slot receives.\n */\nfunction callVfunc(owner: AnyClass, key: string, instance: object, inputs: unknown[]): unknown {\n const slot = resolveOwnerSlot(owner, key);\n const instanceType = resolveInstanceType(key, instance, slot);\n\n const invoker = cachedInvoker(vfuncInvokers, owner, `${key}:${String(instanceType)}`, () =>\n buildInvoker(slot, instanceType, \"callVfunc\"));\n\n return invoker(instance, inputs);\n}\n\nexport { callParent, callVfunc };\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Descriptor } from "@gtkx/native";
|
|
2
|
+
type RefSeeds = Map<number, unknown>;
|
|
3
|
+
type SeedFrame = {
|
|
4
|
+
argDescriptors: Descriptor[];
|
|
5
|
+
instance: unknown;
|
|
6
|
+
seeds: RefSeeds;
|
|
7
|
+
};
|
|
8
|
+
declare const pushSeedFrame: (frame: SeedFrame) => void;
|
|
9
|
+
declare const popSeedFrame: () => void;
|
|
10
|
+
declare const seedsFor: (argDescriptors: Descriptor[], instance: unknown) => RefSeeds | undefined;
|
|
11
|
+
export { popSeedFrame, pushSeedFrame, type RefSeeds, seedsFor };
|
|
12
|
+
//# sourceMappingURL=vfunc-seeds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vfunc-seeds.d.ts","sourceRoot":"","sources":["../src/vfunc-seeds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,KAAK,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErC,KAAK,SAAS,GAAG;IACb,cAAc,EAAE,UAAU,EAAE,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;CACnB,CAAC;AAIF,QAAA,MAAM,aAAa,GAAI,OAAO,SAAS,KAAG,IAEzC,CAAC;AAEF,QAAA,MAAM,YAAY,QAAO,IAExB,CAAC;AAKF,QAAA,MAAM,QAAQ,GAAI,gBAAgB,UAAU,EAAE,EAAE,UAAU,OAAO,KAAG,QAAQ,GAAG,SAU9E,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const frames = [];
|
|
2
|
+
const pushSeedFrame = (frame) => {
|
|
3
|
+
frames.push(frame);
|
|
4
|
+
};
|
|
5
|
+
const popSeedFrame = () => {
|
|
6
|
+
frames.pop();
|
|
7
|
+
};
|
|
8
|
+
const isMatchingFrame = (frame, argDescriptors, instance) => frame.argDescriptors === argDescriptors && frame.instance === instance;
|
|
9
|
+
const seedsFor = (argDescriptors, instance) => {
|
|
10
|
+
for (let index = frames.length - 1; index >= 0; index--) {
|
|
11
|
+
const frame = frames[index];
|
|
12
|
+
if (frame !== undefined && isMatchingFrame(frame, argDescriptors, instance)) {
|
|
13
|
+
return frame.seeds;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
};
|
|
18
|
+
export { popSeedFrame, pushSeedFrame, seedsFor };
|
|
19
|
+
//# sourceMappingURL=vfunc-seeds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vfunc-seeds.js","sourceRoot":"","sources":["../src/vfunc-seeds.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,GAAgB,EAAE,CAAC;AAE/B,MAAM,aAAa,GAAG,CAAC,KAAgB,EAAQ,EAAE;IAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,GAAS,EAAE;IAC5B,MAAM,CAAC,GAAG,EAAE,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,KAAgB,EAAE,cAA4B,EAAE,QAAiB,EAAW,EAAE,CACnG,KAAK,CAAC,cAAc,KAAK,cAAc,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAE3E,MAAM,QAAQ,GAAG,CAAC,cAA4B,EAAE,QAAiB,EAAwB,EAAE;IACvF,KAAK,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAE5B,IAAI,KAAK,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC1E,OAAO,KAAK,CAAC,KAAK,CAAC;QACvB,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAiB,QAAQ,EAAE,CAAC","sourcesContent":["import type { Descriptor } from \"@gtkx/native\";\n\ntype RefSeeds = Map<number, unknown>;\n\ntype SeedFrame = {\n argDescriptors: Descriptor[];\n instance: unknown;\n seeds: RefSeeds;\n};\n\nconst frames: SeedFrame[] = [];\n\nconst pushSeedFrame = (frame: SeedFrame): void => {\n frames.push(frame);\n};\n\nconst popSeedFrame = (): void => {\n frames.pop();\n};\n\nconst isMatchingFrame = (frame: SeedFrame, argDescriptors: Descriptor[], instance: unknown): boolean =>\n frame.argDescriptors === argDescriptors && frame.instance === instance;\n\nconst seedsFor = (argDescriptors: Descriptor[], instance: unknown): RefSeeds | undefined => {\n for (let index = frames.length - 1; index >= 0; index--) {\n const frame = frames[index];\n\n if (frame !== undefined && isMatchingFrame(frame, argDescriptors, instance)) {\n return frame.seeds;\n }\n }\n\n return undefined;\n};\n\nexport { popSeedFrame, pushSeedFrame, type RefSeeds, seedsFor };\n"]}
|
package/dist/vfunc.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type AnyClass } from "@gtkx/utils";
|
|
2
|
+
import type { Arg } from "./arg.js";
|
|
3
|
+
import { type VfuncDescriptor } from "./registry.js";
|
|
4
|
+
declare function findClassVfuncDescriptor(klass: AnyClass, methodName: string): VfuncDescriptor | null;
|
|
5
|
+
declare function findInterfaceVfuncDescriptor(interfaceGtype: bigint, methodName: string): VfuncDescriptor | undefined;
|
|
6
|
+
declare function vfuncArgs(descriptor: VfuncDescriptor): Arg[];
|
|
7
|
+
export { findClassVfuncDescriptor, findInterfaceVfuncDescriptor, vfuncArgs };
|
|
8
|
+
//# sourceMappingURL=vfunc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vfunc.d.ts","sourceRoot":"","sources":["../src/vfunc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAkC,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAA+C,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAElG,iBAAS,wBAAwB,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAE7F;AAED,iBAAS,4BAA4B,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAE7G;AAkBD,iBAAS,SAAS,CAAC,UAAU,EAAE,eAAe,GAAG,GAAG,EAAE,CAIrD;AAED,OAAO,EAAE,wBAAwB,EAAE,4BAA4B,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/vfunc.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getParentClass, walkClassChain } from "@gtkx/utils";
|
|
2
|
+
import { isCallerAllocatedOut } from "./callback.js";
|
|
3
|
+
import { foldedLengthSources } from "./folded-lengths.js";
|
|
4
|
+
import { getInterfaceVfuncRegistry, getVfuncRegistry } from "./registry.js";
|
|
5
|
+
function findClassVfuncDescriptor(klass, methodName) {
|
|
6
|
+
return walkClassChain(getParentClass(klass), (cls) => getVfuncRegistry(cls)?.[methodName]) ?? null;
|
|
7
|
+
}
|
|
8
|
+
function findInterfaceVfuncDescriptor(interfaceGtype, methodName) {
|
|
9
|
+
return getInterfaceVfuncRegistry(interfaceGtype)?.[methodName];
|
|
10
|
+
}
|
|
11
|
+
function vfuncArg(descriptor, isFoldedLength) {
|
|
12
|
+
if (descriptor.kind === "ref") {
|
|
13
|
+
return {
|
|
14
|
+
type: descriptor.innerDescriptor,
|
|
15
|
+
direction: descriptor.inout === true ? "inout" : "out",
|
|
16
|
+
isConsumed: isFoldedLength,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (isCallerAllocatedOut(descriptor)) {
|
|
20
|
+
return { type: descriptor, direction: "out", isCallerAllocated: true };
|
|
21
|
+
}
|
|
22
|
+
return { type: descriptor };
|
|
23
|
+
}
|
|
24
|
+
function vfuncArgs(descriptor) {
|
|
25
|
+
const lengths = foldedLengthSources(descriptor);
|
|
26
|
+
return descriptor.argDescriptors.map((argDescriptor, index) => vfuncArg(argDescriptor, lengths.has(index)));
|
|
27
|
+
}
|
|
28
|
+
export { findClassVfuncDescriptor, findInterfaceVfuncDescriptor, vfuncArgs };
|
|
29
|
+
//# sourceMappingURL=vfunc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vfunc.js","sourceRoot":"","sources":["../src/vfunc.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAwB,MAAM,eAAe,CAAC;AAElG,SAAS,wBAAwB,CAAC,KAAe,EAAE,UAAkB;IACjE,OAAO,cAAc,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC;AACvG,CAAC;AAED,SAAS,4BAA4B,CAAC,cAAsB,EAAE,UAAkB;IAC5E,OAAO,yBAAyB,CAAC,cAAc,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,QAAQ,CAAC,UAAsB,EAAE,cAAuB;IAC7D,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO;YACH,IAAI,EAAE,UAAU,CAAC,eAAe;YAChC,SAAS,EAAE,UAAU,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;YACtD,UAAU,EAAE,cAAc;SAC7B,CAAC;IACN,CAAC;IAED,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAC3E,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,SAAS,CAAC,UAA2B;IAC1C,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAEhD,OAAO,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChH,CAAC;AAED,OAAO,EAAE,wBAAwB,EAAE,4BAA4B,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import type { Descriptor } from \"@gtkx/native\";\nimport { type AnyClass, getParentClass, walkClassChain } from \"@gtkx/utils\";\nimport type { Arg } from \"./arg.js\";\nimport { isCallerAllocatedOut } from \"./callback.js\";\nimport { foldedLengthSources } from \"./folded-lengths.js\";\nimport { getInterfaceVfuncRegistry, getVfuncRegistry, type VfuncDescriptor } from \"./registry.js\";\n\nfunction findClassVfuncDescriptor(klass: AnyClass, methodName: string): VfuncDescriptor | null {\n return walkClassChain(getParentClass(klass), (cls) => getVfuncRegistry(cls)?.[methodName]) ?? null;\n}\n\nfunction findInterfaceVfuncDescriptor(interfaceGtype: bigint, methodName: string): VfuncDescriptor | undefined {\n return getInterfaceVfuncRegistry(interfaceGtype)?.[methodName];\n}\n\nfunction vfuncArg(descriptor: Descriptor, isFoldedLength: boolean): Arg {\n if (descriptor.kind === \"ref\") {\n return {\n type: descriptor.innerDescriptor,\n direction: descriptor.inout === true ? \"inout\" : \"out\",\n isConsumed: isFoldedLength,\n };\n }\n\n if (isCallerAllocatedOut(descriptor)) {\n return { type: descriptor, direction: \"out\", isCallerAllocated: true };\n }\n\n return { type: descriptor };\n}\n\nfunction vfuncArgs(descriptor: VfuncDescriptor): Arg[] {\n const lengths = foldedLengthSources(descriptor);\n\n return descriptor.argDescriptors.map((argDescriptor, index) => vfuncArg(argDescriptor, lengths.has(index)));\n}\n\nexport { findClassVfuncDescriptor, findInterfaceVfuncDescriptor, vfuncArgs };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/runtime",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "FFI runtime the generated GTKX bindings call into: type descriptors, GValue marshalling, signals, GObject lifecycle",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -41,15 +41,25 @@
|
|
|
41
41
|
"src",
|
|
42
42
|
"!**/*.tsbuildinfo"
|
|
43
43
|
],
|
|
44
|
+
"nx": {
|
|
45
|
+
"targets": {
|
|
46
|
+
"lint": {
|
|
47
|
+
"options": {
|
|
48
|
+
"cwd": ".",
|
|
49
|
+
"command": "eslint {projectRoot}"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
44
54
|
"engines": {
|
|
45
55
|
"node": ">=24"
|
|
46
56
|
},
|
|
47
57
|
"dependencies": {
|
|
48
|
-
"@gtkx/native": "1.
|
|
49
|
-
"@gtkx/utils": "1.
|
|
58
|
+
"@gtkx/native": "1.1.0",
|
|
59
|
+
"@gtkx/utils": "1.1.0"
|
|
50
60
|
},
|
|
51
61
|
"devDependencies": {
|
|
52
|
-
"@gtkx/vitest": "1.
|
|
62
|
+
"@gtkx/vitest": "1.1.0"
|
|
53
63
|
},
|
|
54
64
|
"scripts": {
|
|
55
65
|
"release": "tsx ../../scripts/release-package.ts"
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { type AnyClass, getOrInsert } from "@gtkx/utils";
|
|
2
|
+
import { releaseDefaultApplication } from "./default-application.js";
|
|
3
|
+
import { registerClass } from "./register-class.js";
|
|
4
|
+
import { getClassType } from "./registry.js";
|
|
5
|
+
import { typeName } from "./type.js";
|
|
6
|
+
import { callParent } from "./vfunc-call.js";
|
|
7
|
+
|
|
8
|
+
type CommandLineResult = [boolean, string[], number];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The GIO application surface {@link createApplication} builds on, which `Gio.Application` and
|
|
12
|
+
* every subclass of it satisfies structurally.
|
|
13
|
+
*/
|
|
14
|
+
type CommandLineApplication = {
|
|
15
|
+
/** Marks the application as quitting, so GLib's own `run` returns without driving a main loop. */
|
|
16
|
+
quit(): void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type LocalCommandLineApplication = {
|
|
20
|
+
runLocalCommandLine(argv: string[]): CommandLineResult;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type ShutdownApplication = {
|
|
24
|
+
run(argv: string[]): number;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** An application class together with the construct properties it accepts. */
|
|
28
|
+
type ApplicationClass<T extends CommandLineApplication, P> = AnyClass<T> & (new (props: P) => T);
|
|
29
|
+
|
|
30
|
+
const derivedClasses: WeakMap<AnyClass, AnyClass> = new WeakMap();
|
|
31
|
+
const derivedApplicationClasses: Set<AnyClass> = new Set();
|
|
32
|
+
const quitApplications: WeakSet<object> = new WeakSet();
|
|
33
|
+
const shuttingDownApplications: WeakSet<object> = new WeakSet();
|
|
34
|
+
|
|
35
|
+
const derivedTypeName = (base: AnyClass): string => `Gtkx${typeName(getClassType(base)) ?? base.name}`;
|
|
36
|
+
|
|
37
|
+
const buildApplicationClass = (base: AnyClass<CommandLineApplication>): AnyClass<CommandLineApplication> => {
|
|
38
|
+
class DerivedApplication extends base {
|
|
39
|
+
runLocalCommandLine(argv: string[]): CommandLineResult {
|
|
40
|
+
return this.vfuncLocalCommandLine(argv);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
protected vfuncLocalCommandLine(argv: string[]): CommandLineResult {
|
|
44
|
+
if (shuttingDownApplications.has(this)) {
|
|
45
|
+
this.quit();
|
|
46
|
+
|
|
47
|
+
return [true, argv, 0];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return callParent(DerivedApplication, "vfuncLocalCommandLine", this, argv) as CommandLineResult;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
protected vfuncNameLost(): boolean {
|
|
54
|
+
quitApplications.add(this);
|
|
55
|
+
|
|
56
|
+
return callParent(DerivedApplication, "vfuncNameLost", this) as boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
override quit(): void {
|
|
60
|
+
quitApplications.add(this);
|
|
61
|
+
super.quit();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const derived = registerClass(DerivedApplication, { typeName: derivedTypeName(base) });
|
|
66
|
+
derivedApplicationClasses.add(derived);
|
|
67
|
+
|
|
68
|
+
return derived;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const isDerivedApplication = (application: object): application is LocalCommandLineApplication => {
|
|
72
|
+
for (const derived of derivedApplicationClasses) {
|
|
73
|
+
if (application instanceof derived) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return false;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const shutDownThroughRun = (application: ShutdownApplication): void => {
|
|
82
|
+
if (!isDerivedApplication(application) || quitApplications.has(application)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
shuttingDownApplications.add(application);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
application.run([]);
|
|
90
|
+
} finally {
|
|
91
|
+
shuttingDownApplications.delete(application);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const deriveApplicationClass = <T extends CommandLineApplication>(base: AnyClass<T>): AnyClass<T> =>
|
|
96
|
+
getOrInsert(derivedClasses, base, () => buildApplicationClass(base)) as AnyClass<T>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Constructs an application GTKX can shut down. GLib parses an application's command line at most
|
|
100
|
+
* once per instance and crashes on a second parse, so {@link runApplication} and
|
|
101
|
+
* {@link quitApplication} only accept an application built here.
|
|
102
|
+
*
|
|
103
|
+
* Whatever `g_application_constructed` assigned to the process-wide default is handed straight back,
|
|
104
|
+
* so merely building an application never makes it what `Gio.Application.getDefault()` returns.
|
|
105
|
+
* {@link runApplication} is the only place that claims that default, which keeps it pointing at an
|
|
106
|
+
* application GTKX has actually started rather than at one that is still unregistered.
|
|
107
|
+
*
|
|
108
|
+
* @param base The application class to construct, such as `Gtk.Application`.
|
|
109
|
+
* @param props Construct properties, passed through unchanged.
|
|
110
|
+
* @returns An instance of a class derived from `base`, registered once per base class as its own GType.
|
|
111
|
+
*/
|
|
112
|
+
const createApplication = <T extends CommandLineApplication, P>(base: ApplicationClass<T, P>, props: P): T => {
|
|
113
|
+
const application = new (deriveApplicationClass(base) as new (props: P) => T)(props);
|
|
114
|
+
releaseDefaultApplication(application);
|
|
115
|
+
|
|
116
|
+
return application;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export {
|
|
120
|
+
createApplication,
|
|
121
|
+
isDerivedApplication,
|
|
122
|
+
shutDownThroughRun,
|
|
123
|
+
type ApplicationClass,
|
|
124
|
+
type CommandLineApplication,
|
|
125
|
+
type LocalCommandLineApplication,
|
|
126
|
+
};
|
package/src/arg.ts
CHANGED
|
@@ -16,5 +16,6 @@ const isOutputArg = (arg: Arg): boolean => arg.direction !== undefined;
|
|
|
16
16
|
const isInoutArg = (arg: Arg): boolean => arg.direction === "inout";
|
|
17
17
|
const isCallerAllocatedArg = (arg: Arg): boolean => arg.isCallerAllocated === true;
|
|
18
18
|
const isRefArg = (arg: Arg): boolean => arg.direction !== undefined && arg.isCallerAllocated !== true;
|
|
19
|
+
const requiresInputArg = (arg: Arg): boolean => !isRefArg(arg) || isInoutArg(arg);
|
|
19
20
|
|
|
20
|
-
export { isOutputArg, isInoutArg, isCallerAllocatedArg, isRefArg, type Arg };
|
|
21
|
+
export { isOutputArg, isInoutArg, isCallerAllocatedArg, isRefArg, requiresInputArg, type Arg };
|
package/src/bind.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { call, type Descriptor, bind as nativeBind } from "@gtkx/native";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Precompiles a call to a C function, marshalling the values it is given through the argument
|
|
5
|
+
* descriptors and the result through the return one. The symbol is resolved in the shared library
|
|
6
|
+
* on the first call.
|
|
7
|
+
*
|
|
8
|
+
* @param sharedLibrary The shared library to resolve the symbol in.
|
|
9
|
+
* @param symbol The name of the C function to bind.
|
|
10
|
+
* @param argDescriptors Describe the C arguments, in declaration order.
|
|
11
|
+
* @param returnDescriptor Describes the C return value.
|
|
12
|
+
* @returns A function calling the bound symbol.
|
|
13
|
+
*/
|
|
3
14
|
function bind(
|
|
4
15
|
sharedLibrary: string,
|
|
5
16
|
symbol: string,
|
package/src/callback.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { copy, type Descriptor } from "@gtkx/native";
|
|
2
2
|
import type { CallbackDescriptor, RefDescriptor } from "./descriptors.js";
|
|
3
|
+
import { foldedLengthSources, type LengthSource, type LengthSources } from "./folded-lengths.js";
|
|
3
4
|
import { fromNative, toNative } from "./native-value.js";
|
|
4
5
|
import { getHandle } from "./registry.js";
|
|
5
6
|
import { splitTupleResult } from "./tuple.js";
|
|
6
7
|
import { copyValue } from "./value.js";
|
|
8
|
+
import { popSeedFrame, pushSeedFrame, type RefSeeds } from "./vfunc-seeds.js";
|
|
7
9
|
|
|
8
10
|
type Callback = (...args: unknown[]) => unknown;
|
|
9
|
-
type
|
|
10
|
-
type
|
|
11
|
+
type CallbackKind = "vfunc" | "signal" | "callback";
|
|
12
|
+
type CallbackTraits = { isInstanceBound: boolean; hasInstanceArg: boolean; hasFoldedLengths: boolean };
|
|
13
|
+
type OutParam = { value: unknown; descriptor: Descriptor; argIndex: number };
|
|
14
|
+
type LengthLink = { target: OutParam; sources: LengthSource[] };
|
|
15
|
+
type OutParamGroups = { lengthLinks: LengthLink[]; valueParams: OutParam[] };
|
|
16
|
+
type OutValues = Map<number, unknown>;
|
|
11
17
|
|
|
12
18
|
type CallbackSpec = {
|
|
13
19
|
argDescriptors: Descriptor[];
|
|
@@ -19,8 +25,18 @@ type CallbackPlan = {
|
|
|
19
25
|
fn: Callback;
|
|
20
26
|
effectiveTypes: Descriptor[];
|
|
21
27
|
returnDescriptor: Descriptor;
|
|
28
|
+
hasPrimary: boolean;
|
|
22
29
|
start: number;
|
|
23
|
-
|
|
30
|
+
isInstanceBound: boolean;
|
|
31
|
+
lengthSources: LengthSources;
|
|
32
|
+
hasOutParams: boolean;
|
|
33
|
+
hasRefOutParams: boolean;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const CALLBACK_TRAITS: Record<CallbackKind, CallbackTraits> = {
|
|
37
|
+
callback: { isInstanceBound: false, hasInstanceArg: false, hasFoldedLengths: true },
|
|
38
|
+
signal: { isInstanceBound: false, hasInstanceArg: true, hasFoldedLengths: false },
|
|
39
|
+
vfunc: { isInstanceBound: true, hasInstanceArg: true, hasFoldedLengths: true },
|
|
24
40
|
};
|
|
25
41
|
|
|
26
42
|
const fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {
|
|
@@ -46,23 +62,23 @@ const collectRefArg = (
|
|
|
46
62
|
descriptor: RefDescriptor,
|
|
47
63
|
wrappedValue: unknown,
|
|
48
64
|
inputs: unknown[],
|
|
49
|
-
|
|
65
|
+
out: { params: OutParam[]; argIndex: number },
|
|
50
66
|
): void => {
|
|
51
67
|
if (descriptor.inout === true) {
|
|
52
68
|
inputs.push((wrappedValue as { value: unknown }).value);
|
|
53
69
|
}
|
|
54
70
|
|
|
55
|
-
|
|
71
|
+
out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });
|
|
56
72
|
};
|
|
57
73
|
|
|
58
74
|
const collectCallbackArg = (
|
|
59
75
|
descriptor: Descriptor | undefined,
|
|
60
76
|
wrappedValue: unknown,
|
|
61
77
|
inputs: unknown[],
|
|
62
|
-
|
|
78
|
+
out: { params: OutParam[]; argIndex: number },
|
|
63
79
|
): void => {
|
|
64
80
|
if (descriptor?.kind === "ref") {
|
|
65
|
-
collectRefArg(descriptor, wrappedValue, inputs,
|
|
81
|
+
collectRefArg(descriptor, wrappedValue, inputs, out);
|
|
66
82
|
|
|
67
83
|
return;
|
|
68
84
|
}
|
|
@@ -70,7 +86,7 @@ const collectCallbackArg = (
|
|
|
70
86
|
inputs.push(wrappedValue);
|
|
71
87
|
|
|
72
88
|
if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {
|
|
73
|
-
|
|
89
|
+
out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });
|
|
74
90
|
}
|
|
75
91
|
};
|
|
76
92
|
|
|
@@ -80,47 +96,167 @@ const partitionCallbackArgs = (
|
|
|
80
96
|
start: number,
|
|
81
97
|
): { inputs: unknown[]; outParams: OutParam[] } => {
|
|
82
98
|
const inputs: unknown[] = [];
|
|
83
|
-
const
|
|
99
|
+
const params: OutParam[] = [];
|
|
100
|
+
const collected = { params, argIndex: start };
|
|
84
101
|
|
|
85
102
|
for (let i = start; i < effectiveTypes.length; i++) {
|
|
86
|
-
|
|
103
|
+
collected.argIndex = i;
|
|
104
|
+
collectCallbackArg(effectiveTypes[i], wrapped[i], inputs, collected);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return { inputs, outParams: params };
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const hasOutParamArg = (descriptor: Descriptor | undefined): boolean =>
|
|
111
|
+
descriptor !== undefined && (descriptor.kind === "ref" || isCallerAllocatedOut(descriptor));
|
|
112
|
+
|
|
113
|
+
const hasRefOutParamArg = (descriptor: Descriptor | undefined): boolean =>
|
|
114
|
+
descriptor?.kind === "ref" && descriptor.inout !== true;
|
|
115
|
+
|
|
116
|
+
const haveOutParamArgs = (effectiveTypes: Descriptor[], start: number): boolean =>
|
|
117
|
+
effectiveTypes.slice(start).some((descriptor) => hasOutParamArg(descriptor));
|
|
118
|
+
|
|
119
|
+
const haveRefOutParamArgs = (effectiveTypes: Descriptor[], start: number): boolean =>
|
|
120
|
+
effectiveTypes.slice(start).some((descriptor) => hasRefOutParamArg(descriptor));
|
|
121
|
+
|
|
122
|
+
const groupOutParams = (outParams: OutParam[], lengthSources: LengthSources): OutParamGroups => {
|
|
123
|
+
const groups: OutParamGroups = { lengthLinks: [], valueParams: [] };
|
|
124
|
+
|
|
125
|
+
for (const outParam of outParams) {
|
|
126
|
+
const sources = lengthSources.get(outParam.argIndex);
|
|
127
|
+
|
|
128
|
+
if (sources === undefined) {
|
|
129
|
+
groups.valueParams.push(outParam);
|
|
130
|
+
} else {
|
|
131
|
+
groups.lengthLinks.push({ target: outParam, sources });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return groups;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const getLength = (value: unknown): number => {
|
|
139
|
+
const length = (value as { length?: unknown } | null | undefined)?.length;
|
|
140
|
+
|
|
141
|
+
return typeof length === "number" ? length : 0;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const lengthSourceValue = (source: LengthSource, outValues: OutValues, primary: unknown): unknown =>
|
|
145
|
+
source.kind === "return" ? primary : outValues.get(source.argIndex);
|
|
146
|
+
|
|
147
|
+
const foldedLength = (sources: LengthSource[], outValues: OutValues, primary: unknown): number =>
|
|
148
|
+
Math.min(...sources.map((source) => getLength(lengthSourceValue(source, outValues, primary))));
|
|
149
|
+
|
|
150
|
+
const resolveOutValues = (groups: OutParamGroups, values: unknown[], primary: unknown): OutValues => {
|
|
151
|
+
const outValues: OutValues = new Map();
|
|
152
|
+
|
|
153
|
+
for (const [position, outParam] of groups.valueParams.entries()) {
|
|
154
|
+
outValues.set(outParam.argIndex, values[position]);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for (const link of groups.lengthLinks) {
|
|
158
|
+
outValues.set(link.target.argIndex, foldedLength(link.sources, outValues, primary));
|
|
87
159
|
}
|
|
88
160
|
|
|
89
|
-
return
|
|
161
|
+
return outValues;
|
|
90
162
|
};
|
|
91
163
|
|
|
92
|
-
const writeOutParams = (outParams: OutParam[], outValues:
|
|
93
|
-
for (const
|
|
94
|
-
const
|
|
164
|
+
const writeOutParams = (outParams: OutParam[], outValues: OutValues): void => {
|
|
165
|
+
for (const outParam of outParams) {
|
|
166
|
+
const { descriptor } = outParam;
|
|
167
|
+
const outValue = outValues.get(outParam.argIndex);
|
|
95
168
|
|
|
96
|
-
if (
|
|
97
|
-
(outParam.value as { value: unknown }).value = outValue;
|
|
169
|
+
if (descriptor.kind === "ref") {
|
|
170
|
+
(outParam.value as { value: unknown }).value = toNative(descriptor.innerDescriptor, outValue);
|
|
98
171
|
} else if (outValue != null && outParam.value != null) {
|
|
99
|
-
fillCallerAllocatedBuffer(
|
|
172
|
+
fillCallerAllocatedBuffer(descriptor, outParam.value, outValue);
|
|
100
173
|
}
|
|
101
174
|
}
|
|
102
175
|
};
|
|
103
176
|
|
|
104
|
-
const
|
|
105
|
-
|
|
177
|
+
const collectRefSeeds = (outParams: OutParam[]): RefSeeds => {
|
|
178
|
+
const seeds: RefSeeds = new Map();
|
|
179
|
+
|
|
180
|
+
for (const outParam of outParams) {
|
|
181
|
+
const seed = (outParam.value as { value?: unknown } | null)?.value;
|
|
182
|
+
|
|
183
|
+
if (seed != null && hasRefOutParamArg(outParam.descriptor)) {
|
|
184
|
+
seeds.set(outParam.argIndex, seed);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return seeds;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const applyCallback = (plan: CallbackPlan, thisArg: unknown, inputs: unknown[], outParams: OutParam[]): unknown => {
|
|
192
|
+
if (!plan.hasRefOutParams) {
|
|
193
|
+
return plan.fn.apply(thisArg, inputs);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
pushSeedFrame({ argDescriptors: plan.effectiveTypes, instance: thisArg, seeds: collectRefSeeds(outParams) });
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
return plan.fn.apply(thisArg, inputs);
|
|
200
|
+
} finally {
|
|
201
|
+
popSeedFrame();
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const getThisArg = (isInstanceBound: boolean, wrapped: unknown[]): unknown =>
|
|
206
|
+
isInstanceBound ? (wrapped[0] ?? null) : null;
|
|
207
|
+
|
|
208
|
+
const wrapCallbackArgs = (effectiveTypes: Descriptor[], rawArgs: unknown[]): void => {
|
|
209
|
+
let index = 0;
|
|
210
|
+
|
|
211
|
+
for (const descriptor of effectiveTypes) {
|
|
212
|
+
rawArgs[index] = fromNative(descriptor, rawArgs[index]);
|
|
213
|
+
index += 1;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const trimCallbackInputs = (plan: CallbackPlan, wrapped: unknown[]): unknown[] => {
|
|
218
|
+
const count = plan.effectiveTypes.length;
|
|
219
|
+
|
|
220
|
+
if (wrapped.length > count) {
|
|
221
|
+
wrapped.length = count;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
for (let index = 0; index < plan.start; index++) {
|
|
225
|
+
wrapped.shift();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return wrapped;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const nativeReturn = (plan: CallbackPlan, primary: unknown): unknown =>
|
|
232
|
+
toNative(plan.returnDescriptor, plan.hasPrimary ? primary : undefined);
|
|
106
233
|
|
|
107
234
|
const runCallback = (plan: CallbackPlan, rawArgs: unknown[]): unknown => {
|
|
108
|
-
const { effectiveTypes
|
|
109
|
-
|
|
110
|
-
const thisArg = getThisArg(plan.
|
|
111
|
-
|
|
112
|
-
|
|
235
|
+
const { effectiveTypes } = plan;
|
|
236
|
+
wrapCallbackArgs(effectiveTypes, rawArgs);
|
|
237
|
+
const thisArg = getThisArg(plan.isInstanceBound, rawArgs);
|
|
238
|
+
|
|
239
|
+
if (!plan.hasOutParams) {
|
|
240
|
+
return nativeReturn(plan, plan.fn.apply(thisArg, trimCallbackInputs(plan, rawArgs)));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, rawArgs, plan.start);
|
|
244
|
+
const result = applyCallback(plan, thisArg, inputs, outParams);
|
|
113
245
|
|
|
114
246
|
if (outParams.length === 0) {
|
|
115
|
-
return
|
|
247
|
+
return nativeReturn(plan, result);
|
|
116
248
|
}
|
|
117
249
|
|
|
118
|
-
const
|
|
119
|
-
|
|
250
|
+
const groups = groupOutParams(outParams, plan.lengthSources);
|
|
251
|
+
const { primary, outValues } = splitTupleResult(result, plan.hasPrimary, groups.valueParams.length);
|
|
252
|
+
writeOutParams(outParams, resolveOutValues(groups, outValues, primary));
|
|
120
253
|
|
|
121
|
-
return
|
|
254
|
+
return nativeReturn(plan, primary);
|
|
122
255
|
};
|
|
123
256
|
|
|
257
|
+
const planLengthSources = (spec: CallbackSpec, hasFoldedLengths: boolean): LengthSources =>
|
|
258
|
+
hasFoldedLengths ? foldedLengthSources(spec) : new Map<number, LengthSource[]>();
|
|
259
|
+
|
|
124
260
|
const getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {
|
|
125
261
|
const { userDataIndex } = spec;
|
|
126
262
|
|
|
@@ -132,18 +268,26 @@ const getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {
|
|
|
132
268
|
};
|
|
133
269
|
|
|
134
270
|
const wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>
|
|
135
|
-
callback == null ? callback : wrapCallback(callback as Callback, spec, "
|
|
271
|
+
callback == null ? callback : wrapCallback(callback as Callback, spec, "callback");
|
|
272
|
+
|
|
273
|
+
function wrapCallback(fn: Callback, spec: CallbackSpec, kind: CallbackKind): Callback {
|
|
274
|
+
const effectiveTypes = getEffectiveTypes(spec);
|
|
275
|
+
const { isInstanceBound, hasInstanceArg, hasFoldedLengths } = CALLBACK_TRAITS[kind];
|
|
276
|
+
const start = hasInstanceArg ? 1 : 0;
|
|
136
277
|
|
|
137
|
-
function wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {
|
|
138
278
|
const plan: CallbackPlan = {
|
|
139
279
|
fn,
|
|
140
|
-
effectiveTypes
|
|
280
|
+
effectiveTypes,
|
|
141
281
|
returnDescriptor: spec.returnDescriptor,
|
|
142
|
-
|
|
143
|
-
|
|
282
|
+
hasPrimary: spec.returnDescriptor.kind !== "void",
|
|
283
|
+
start,
|
|
284
|
+
isInstanceBound,
|
|
285
|
+
lengthSources: planLengthSources(spec, hasFoldedLengths),
|
|
286
|
+
hasOutParams: haveOutParamArgs(effectiveTypes, start),
|
|
287
|
+
hasRefOutParams: haveRefOutParamArgs(effectiveTypes, start),
|
|
144
288
|
};
|
|
145
289
|
|
|
146
290
|
return (...rawArgs: unknown[]): unknown => runCallback(plan, rawArgs);
|
|
147
291
|
}
|
|
148
292
|
|
|
149
|
-
export { wrapCallbackValue, wrapCallback };
|
|
293
|
+
export { isCallerAllocatedOut, wrapCallbackValue, wrapCallback };
|