@gtkx/runtime 1.6.0 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.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 +22 -51
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +53 -27
- package/dist/descriptors.js.map +1 -1
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +23 -9
- 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 +2 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -24
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +18 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +14 -2
- package/dist/internal.js.map +1 -1
- package/dist/listeners.d.ts +3 -13
- package/dist/listeners.d.ts.map +1 -1
- package/dist/listeners.js +12 -12
- package/dist/listeners.js.map +1 -1
- package/dist/mixin.d.ts +5 -3
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +36 -9
- package/dist/mixin.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 +20 -3
- package/dist/native-value.js.map +1 -1
- package/dist/object.d.ts +11 -0
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +18 -25
- package/dist/object.js.map +1 -1
- package/dist/properties.d.ts +5 -3
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +67 -23
- package/dist/properties.js.map +1 -1
- package/dist/property-brand.d.ts +5 -0
- package/dist/property-brand.d.ts.map +1 -0
- package/dist/property-brand.js +5 -0
- package/dist/property-brand.js.map +1 -0
- package/dist/register-class.d.ts +142 -264
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +19 -37
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -4
- package/dist/registry.js.map +1 -1
- package/dist/signal-brand.d.ts +12 -0
- package/dist/signal-brand.d.ts.map +1 -0
- package/dist/signal-brand.js +6 -0
- package/dist/signal-brand.js.map +1 -0
- package/dist/signal.d.ts +39 -2
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +84 -27
- 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.map +1 -1
- package/dist/type.js +8 -2
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +7 -1
- 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 +9 -5
- 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 +95 -59
- package/src/fn.ts +31 -10
- package/src/folded-lengths.ts +23 -10
- package/src/index.ts +2 -24
- package/src/internal.ts +43 -2
- package/src/listeners.ts +21 -26
- package/src/mixin.ts +55 -9
- package/src/native-value.ts +24 -3
- package/src/object.ts +55 -5
- package/src/properties.ts +90 -26
- package/src/property-brand.ts +5 -0
- package/src/register-class.ts +338 -341
- package/src/registry.ts +4 -4
- package/src/signal-brand.ts +29 -0
- package/src/signal.ts +185 -39
- package/src/t.ts +5 -21
- package/src/type.ts +10 -2
- package/src/value.ts +9 -1
- package/src/variant.ts +2 -6
- package/src/vfunc-call.ts +3 -16
package/dist/vfunc-call.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vfunc-call.d.ts","sourceRoot":"","sources":["../src/vfunc-call.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vfunc-call.d.ts","sourceRoot":"","sources":["../src/vfunc-call.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAyJ5C;;;;;;;;;;;;;GAaG;AACH,iBAAS,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAIxG;AAkCD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAQ7F;AAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/vfunc-call.js
CHANGED
|
@@ -63,17 +63,8 @@ function buildInvoker(slot, instanceType, caller) {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
function cachedInvoker(cache, owner, key, build) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
byKey = new Map();
|
|
69
|
-
cache.set(owner, byKey);
|
|
70
|
-
}
|
|
71
|
-
let invoker = byKey.get(key);
|
|
72
|
-
if (invoker === undefined) {
|
|
73
|
-
invoker = build();
|
|
74
|
-
byKey.set(key, invoker);
|
|
75
|
-
}
|
|
76
|
-
return invoker;
|
|
66
|
+
const byKey = cache.getOrInsertComputed(owner, () => new Map());
|
|
67
|
+
return byKey.getOrInsertComputed(key, build);
|
|
77
68
|
}
|
|
78
69
|
function resolveParentSlot(klass, parentType, methodName) {
|
|
79
70
|
const classDescriptor = findClassVfuncDescriptor(klass, methodName);
|
package/dist/vfunc-call.js.map
CHANGED
|
@@ -1 +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"]}
|
|
1
|
+
{"version":3,"file":"vfunc-call.js","sourceRoot":"","sources":["../src/vfunc-call.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnyClass } from \"@gtkx/utils\";\nimport { bindVfunc, type BindVfuncOptions } 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 const byKey = cache.getOrInsertComputed(owner, () => new Map<string, Invoker>());\n\n return byKey.getOrInsertComputed(key, build);\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "FFI runtime for the generated GTK bindings: types, GValues, signals.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -34,10 +34,14 @@
|
|
|
34
34
|
"./package.json": "./package.json",
|
|
35
35
|
".": {
|
|
36
36
|
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"require": null,
|
|
37
39
|
"default": "./dist/index.js"
|
|
38
40
|
},
|
|
39
41
|
"./internal": {
|
|
40
42
|
"types": "./dist/internal.d.ts",
|
|
43
|
+
"import": "./dist/internal.js",
|
|
44
|
+
"require": null,
|
|
41
45
|
"default": "./dist/internal.js"
|
|
42
46
|
}
|
|
43
47
|
},
|
|
@@ -57,14 +61,14 @@
|
|
|
57
61
|
}
|
|
58
62
|
},
|
|
59
63
|
"engines": {
|
|
60
|
-
"node": ">=
|
|
64
|
+
"node": ">=26.7.0"
|
|
61
65
|
},
|
|
62
66
|
"dependencies": {
|
|
63
|
-
"@gtkx/
|
|
64
|
-
"@gtkx/
|
|
67
|
+
"@gtkx/native": "2.0.0-beta.2",
|
|
68
|
+
"@gtkx/utils": "2.0.0-beta.2"
|
|
65
69
|
},
|
|
66
70
|
"devDependencies": {
|
|
67
|
-
"@gtkx/vitest": "
|
|
71
|
+
"@gtkx/vitest": "2.0.0-beta.2"
|
|
68
72
|
},
|
|
69
73
|
"scripts": {
|
|
70
74
|
"release": "tsx ../../scripts/release-package.ts"
|
package/src/application-class.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AnyClass } from "@gtkx/utils";
|
|
2
2
|
import { releaseDefaultApplication } from "./default-application.js";
|
|
3
3
|
import { registerClass } from "./register-class.js";
|
|
4
4
|
import { getClassType } from "./registry.js";
|
|
@@ -93,7 +93,7 @@ const shutDownThroughRun = (application: ShutdownApplication): void => {
|
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
const deriveApplicationClass = <T extends CommandLineApplication>(base: AnyClass<T>): AnyClass<T> =>
|
|
96
|
-
|
|
96
|
+
derivedClasses.getOrInsertComputed(base, () => buildApplicationClass(base)) as AnyClass<T>;
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Constructs an application GTKX can shut down. GLib parses an application's command line at most
|
package/src/arg.ts
CHANGED
|
@@ -12,7 +12,10 @@ type Arg = {
|
|
|
12
12
|
isConsumed?: boolean;
|
|
13
13
|
/** When true, the argument is a `GValue` the callee fills in, packed into the result as what it holds. */
|
|
14
14
|
isUnpacked?: boolean;
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* When true, the caller must provide the argument: `undefined` is rejected instead of reaching
|
|
17
|
+
* C as `NULL`, and so is `null` for a type that reaches C as a pointer.
|
|
18
|
+
*/
|
|
16
19
|
isRequired?: boolean;
|
|
17
20
|
};
|
|
18
21
|
|
package/src/bind.ts
CHANGED
|
@@ -25,18 +25,7 @@ function bind(
|
|
|
25
25
|
function createBindCache(): (key: string, ...args: Parameters<typeof bind>) => ReturnType<typeof bind> {
|
|
26
26
|
const cache: Map<string, ReturnType<typeof bind>> = new Map();
|
|
27
27
|
|
|
28
|
-
return (key, ...args) =>
|
|
29
|
-
const existing = cache.get(key);
|
|
30
|
-
|
|
31
|
-
if (existing !== undefined) {
|
|
32
|
-
return existing;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const bound = bind(...args);
|
|
36
|
-
cache.set(key, bound);
|
|
37
|
-
|
|
38
|
-
return bound;
|
|
39
|
-
};
|
|
28
|
+
return (key, ...args) => cache.getOrInsertComputed(key, () => bind(...args));
|
|
40
29
|
}
|
|
41
30
|
|
|
42
31
|
export { bind, createBindCache };
|
package/src/callback.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import { copy, type Descriptor } from "@gtkx/native";
|
|
2
2
|
import type { CallbackDescriptor, RefDescriptor } from "./descriptors.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
foldedLengthArgIndices,
|
|
5
|
+
foldedLengthSources,
|
|
6
|
+
type LengthSource,
|
|
7
|
+
type LengthSources,
|
|
8
|
+
} from "./folded-lengths.js";
|
|
4
9
|
import { fromNative, toNative } from "./native-value.js";
|
|
5
|
-
import { getHandle } from "./registry.js";
|
|
10
|
+
import { describeValueKind, getHandle } from "./registry.js";
|
|
6
11
|
import { splitTupleResult } from "./tuple.js";
|
|
7
12
|
import { copyValue } from "./value.js";
|
|
8
13
|
import { popSeedFrame, pushSeedFrame, type RefSeeds } from "./vfunc-seeds.js";
|
|
9
14
|
|
|
10
15
|
type Callback = (...args: unknown[]) => unknown;
|
|
11
16
|
type CallbackKind = "vfunc" | "signal" | "callback";
|
|
12
|
-
type CallbackTraits = {
|
|
17
|
+
type CallbackTraits = {
|
|
18
|
+
isInstanceBound: boolean;
|
|
19
|
+
hasInstanceArg: boolean;
|
|
20
|
+
hasFoldedLengths: boolean;
|
|
21
|
+
hasFoldedInputs: boolean;
|
|
22
|
+
};
|
|
13
23
|
type OutParam = { value: unknown; descriptor: Descriptor; argIndex: number };
|
|
24
|
+
type CollectedArgs = { params: OutParam[]; argIndex: number; isFolded: boolean };
|
|
25
|
+
type PartitionedArgs = { inputs: unknown[]; outParams: OutParam[] };
|
|
14
26
|
type LengthLink = { target: OutParam; sources: LengthSource[] };
|
|
15
27
|
type OutParamGroups = { lengthLinks: LengthLink[]; valueParams: OutParam[] };
|
|
16
28
|
type OutValues = Map<number, unknown>;
|
|
@@ -31,12 +43,13 @@ type CallbackPlan = {
|
|
|
31
43
|
lengthSources: LengthSources;
|
|
32
44
|
hasOutParams: boolean;
|
|
33
45
|
hasRefOutParams: boolean;
|
|
46
|
+
foldedInputIndices: ReadonlySet<number>;
|
|
34
47
|
};
|
|
35
48
|
|
|
36
49
|
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 },
|
|
50
|
+
callback: { isInstanceBound: false, hasInstanceArg: false, hasFoldedLengths: true, hasFoldedInputs: true },
|
|
51
|
+
signal: { isInstanceBound: false, hasInstanceArg: true, hasFoldedLengths: false, hasFoldedInputs: false },
|
|
52
|
+
vfunc: { isInstanceBound: true, hasInstanceArg: true, hasFoldedLengths: true, hasFoldedInputs: false },
|
|
40
53
|
};
|
|
41
54
|
|
|
42
55
|
const fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {
|
|
@@ -62,9 +75,9 @@ const collectRefArg = (
|
|
|
62
75
|
descriptor: RefDescriptor,
|
|
63
76
|
wrappedValue: unknown,
|
|
64
77
|
inputs: unknown[],
|
|
65
|
-
out:
|
|
78
|
+
out: CollectedArgs,
|
|
66
79
|
): void => {
|
|
67
|
-
if (descriptor.inout === true) {
|
|
80
|
+
if (descriptor.inout === true && !out.isFolded) {
|
|
68
81
|
inputs.push((wrappedValue as { value: unknown }).value);
|
|
69
82
|
}
|
|
70
83
|
|
|
@@ -75,7 +88,7 @@ const collectCallbackArg = (
|
|
|
75
88
|
descriptor: Descriptor | undefined,
|
|
76
89
|
wrappedValue: unknown,
|
|
77
90
|
inputs: unknown[],
|
|
78
|
-
out:
|
|
91
|
+
out: CollectedArgs,
|
|
79
92
|
): void => {
|
|
80
93
|
if (descriptor?.kind === "ref") {
|
|
81
94
|
collectRefArg(descriptor, wrappedValue, inputs, out);
|
|
@@ -83,25 +96,24 @@ const collectCallbackArg = (
|
|
|
83
96
|
return;
|
|
84
97
|
}
|
|
85
98
|
|
|
86
|
-
|
|
99
|
+
if (!out.isFolded) {
|
|
100
|
+
inputs.push(wrappedValue);
|
|
101
|
+
}
|
|
87
102
|
|
|
88
103
|
if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {
|
|
89
104
|
out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });
|
|
90
105
|
}
|
|
91
106
|
};
|
|
92
107
|
|
|
93
|
-
const partitionCallbackArgs = (
|
|
94
|
-
effectiveTypes: Descriptor[],
|
|
95
|
-
wrapped: unknown[],
|
|
96
|
-
start: number,
|
|
97
|
-
): { inputs: unknown[]; outParams: OutParam[] } => {
|
|
108
|
+
const partitionCallbackArgs = (plan: CallbackPlan, wrapped: unknown[]): PartitionedArgs => {
|
|
98
109
|
const inputs: unknown[] = [];
|
|
99
110
|
const params: OutParam[] = [];
|
|
100
|
-
const collected = { params, argIndex: start };
|
|
111
|
+
const collected: CollectedArgs = { params, argIndex: plan.start, isFolded: false };
|
|
101
112
|
|
|
102
|
-
for (let i = start; i < effectiveTypes.length; i++) {
|
|
113
|
+
for (let i = plan.start; i < plan.effectiveTypes.length; i++) {
|
|
103
114
|
collected.argIndex = i;
|
|
104
|
-
|
|
115
|
+
collected.isFolded = plan.foldedInputIndices.has(i);
|
|
116
|
+
collectCallbackArg(plan.effectiveTypes[i], wrapped[i], inputs, collected);
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
return { inputs, outParams: params };
|
|
@@ -215,17 +227,15 @@ const wrapCallbackArgs = (effectiveTypes: Descriptor[], rawArgs: unknown[]): voi
|
|
|
215
227
|
};
|
|
216
228
|
|
|
217
229
|
const trimCallbackInputs = (plan: CallbackPlan, wrapped: unknown[]): unknown[] => {
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
if (wrapped.length > count) {
|
|
221
|
-
wrapped.length = count;
|
|
222
|
-
}
|
|
230
|
+
const inputs: unknown[] = [];
|
|
223
231
|
|
|
224
|
-
for (let index =
|
|
225
|
-
|
|
232
|
+
for (let index = plan.start; index < plan.effectiveTypes.length; index++) {
|
|
233
|
+
if (!plan.foldedInputIndices.has(index)) {
|
|
234
|
+
inputs.push(wrapped[index]);
|
|
235
|
+
}
|
|
226
236
|
}
|
|
227
237
|
|
|
228
|
-
return
|
|
238
|
+
return inputs;
|
|
229
239
|
};
|
|
230
240
|
|
|
231
241
|
const nativeReturn = (plan: CallbackPlan, primary: unknown): unknown =>
|
|
@@ -240,7 +250,7 @@ const runCallback = (plan: CallbackPlan, rawArgs: unknown[]): unknown => {
|
|
|
240
250
|
return nativeReturn(plan, plan.fn.apply(thisArg, trimCallbackInputs(plan, rawArgs)));
|
|
241
251
|
}
|
|
242
252
|
|
|
243
|
-
const { inputs, outParams } = partitionCallbackArgs(
|
|
253
|
+
const { inputs, outParams } = partitionCallbackArgs(plan, rawArgs);
|
|
244
254
|
const result = applyCallback(plan, thisArg, inputs, outParams);
|
|
245
255
|
|
|
246
256
|
if (outParams.length === 0) {
|
|
@@ -270,9 +280,22 @@ const getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {
|
|
|
270
280
|
const wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>
|
|
271
281
|
callback == null ? callback : wrapCallback(callback as Callback, spec, "callback");
|
|
272
282
|
|
|
283
|
+
const planFoldedInputIndices = (spec: CallbackSpec, hasFoldedInputs: boolean): ReadonlySet<number> =>
|
|
284
|
+
hasFoldedInputs ? foldedLengthArgIndices(spec) : new Set<number>();
|
|
285
|
+
|
|
286
|
+
/** Thrown when a value passed where a callback, signal handler or vfunc is expected cannot be called. */
|
|
287
|
+
class CallbackMarshalError extends TypeError {
|
|
288
|
+
/** Name callers match on when the error is caught as a plain `TypeError`. */
|
|
289
|
+
public override name = "CallbackMarshalError";
|
|
290
|
+
}
|
|
291
|
+
|
|
273
292
|
function wrapCallback(fn: Callback, spec: CallbackSpec, kind: CallbackKind): Callback {
|
|
293
|
+
if (typeof fn !== "function") {
|
|
294
|
+
throw new CallbackMarshalError(`Cannot marshal ${describeValueKind(fn)} into a ${kind}`);
|
|
295
|
+
}
|
|
296
|
+
|
|
274
297
|
const effectiveTypes = getEffectiveTypes(spec);
|
|
275
|
-
const { isInstanceBound, hasInstanceArg, hasFoldedLengths } = CALLBACK_TRAITS[kind];
|
|
298
|
+
const { isInstanceBound, hasInstanceArg, hasFoldedLengths, hasFoldedInputs } = CALLBACK_TRAITS[kind];
|
|
276
299
|
const start = hasInstanceArg ? 1 : 0;
|
|
277
300
|
|
|
278
301
|
const plan: CallbackPlan = {
|
|
@@ -285,9 +308,10 @@ function wrapCallback(fn: Callback, spec: CallbackSpec, kind: CallbackKind): Cal
|
|
|
285
308
|
lengthSources: planLengthSources(spec, hasFoldedLengths),
|
|
286
309
|
hasOutParams: haveOutParamArgs(effectiveTypes, start),
|
|
287
310
|
hasRefOutParams: haveRefOutParamArgs(effectiveTypes, start),
|
|
311
|
+
foldedInputIndices: planFoldedInputIndices(spec, hasFoldedInputs),
|
|
288
312
|
};
|
|
289
313
|
|
|
290
314
|
return (...rawArgs: unknown[]): unknown => runCallback(plan, rawArgs);
|
|
291
315
|
}
|
|
292
316
|
|
|
293
|
-
export { isCallerAllocatedOut, wrapCallbackValue, wrapCallback };
|
|
317
|
+
export { CallbackMarshalError, isCallerAllocatedOut, wrapCallbackValue, wrapCallback };
|
package/src/closure.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import { type ExternalObject, type Handle, read } from "@gtkx/native";
|
|
1
|
+
import { type ExternalObject, type Handle, read, symbolAddress } from "@gtkx/native";
|
|
2
2
|
import { type AnyClass } from "@gtkx/utils";
|
|
3
|
-
import { bind } from "./bind.js";
|
|
4
|
-
import {
|
|
3
|
+
import { bind, createBindCache } from "./bind.js";
|
|
4
|
+
import {
|
|
5
|
+
biguint64T,
|
|
6
|
+
boxedT,
|
|
7
|
+
type CallbackDescriptor,
|
|
8
|
+
callbackT,
|
|
9
|
+
sizedArrayT,
|
|
10
|
+
structT,
|
|
11
|
+
uint32T,
|
|
12
|
+
uint64T,
|
|
13
|
+
voidT,
|
|
14
|
+
} from "./descriptors.js";
|
|
5
15
|
import { CLOSURE_SIZE, LIB, VALUE_SIZE, VALUE_T } from "./library.js";
|
|
6
16
|
import { describeValueKind, getClassType, getHandle, getWrapperClass, wrapHandle } from "./registry.js";
|
|
7
17
|
import { resolveBoxedType, typeIsA } from "./type.js";
|
|
@@ -59,7 +69,12 @@ const gCclosureNew = bind(LIB, "g_cclosure_new", [MARSHAL_T], OWNED_CLOSURE_T);
|
|
|
59
69
|
const gValueGetBoxed = bind(LIB, "g_value_get_boxed", [VALUE_T], NESTED_VALUE_T);
|
|
60
70
|
const gClosureRef = bind(LIB, "g_closure_ref", [CLOSURE_T], uint64T);
|
|
61
71
|
const gClosureSink = bind(LIB, "g_closure_sink", [CLOSURE_T], voidT);
|
|
62
|
-
const gClosureSetMarshal = bind(LIB, "g_closure_set_marshal", [CLOSURE_T,
|
|
72
|
+
const gClosureSetMarshal = bind(LIB, "g_closure_set_marshal", [CLOSURE_T, biguint64T], voidT);
|
|
73
|
+
const cclosureNewCache = createBindCache();
|
|
74
|
+
const genericMarshal: { address?: bigint } = {};
|
|
75
|
+
|
|
76
|
+
const genericClosureMarshal = (): bigint =>
|
|
77
|
+
(genericMarshal.address ??= symbolAddress(LIB, "g_cclosure_marshal_generic"));
|
|
63
78
|
|
|
64
79
|
const isClosureInstance = (value: object): boolean =>
|
|
65
80
|
typeIsA(getClassType(value.constructor as AnyClass), resolveBoxedType(CLOSURE_T));
|
|
@@ -84,7 +99,7 @@ function marshalFor(callback: ClosureCallback): (...args: unknown[]) => void {
|
|
|
84
99
|
|
|
85
100
|
function newClosure(callback: ClosureCallback): ExternalObject<Handle> {
|
|
86
101
|
const handle = gCclosureNew(marshalFor(callback)) as ExternalObject<Handle>;
|
|
87
|
-
const marshal = read(handle,
|
|
102
|
+
const marshal = read(handle, biguint64T, CCLOSURE_CALLBACK_OFFSET);
|
|
88
103
|
gClosureRef(handle);
|
|
89
104
|
gClosureSink(handle);
|
|
90
105
|
gClosureSetMarshal(handle, marshal);
|
|
@@ -92,6 +107,16 @@ function newClosure(callback: ClosureCallback): ExternalObject<Handle> {
|
|
|
92
107
|
return handle;
|
|
93
108
|
}
|
|
94
109
|
|
|
110
|
+
function newCCallbackClosure(key: string, callback: CallbackDescriptor, fn: unknown): ExternalObject<Handle> {
|
|
111
|
+
const create = cclosureNewCache(key, LIB, "g_cclosure_new", [callback], OWNED_CLOSURE_T);
|
|
112
|
+
const handle = create(fn) as ExternalObject<Handle>;
|
|
113
|
+
gClosureRef(handle);
|
|
114
|
+
gClosureSink(handle);
|
|
115
|
+
gClosureSetMarshal(handle, genericClosureMarshal());
|
|
116
|
+
|
|
117
|
+
return handle;
|
|
118
|
+
}
|
|
119
|
+
|
|
95
120
|
/**
|
|
96
121
|
* Marshals a value passed where a `GObject.Closure` is expected into a closure handle: a function
|
|
97
122
|
* becomes a new `GClosure` dispatching into it, and an existing closure yields its own handle.
|
|
@@ -121,4 +146,4 @@ class ClosureMarshalError extends TypeError {
|
|
|
121
146
|
public override name = "ClosureMarshalError";
|
|
122
147
|
}
|
|
123
148
|
|
|
124
|
-
export { type ClosureCallback, ClosureMarshalError, toClosure, tryToClosure };
|
|
149
|
+
export { type ClosureCallback, ClosureMarshalError, newCCallbackClosure, toClosure, tryToClosure };
|