From 46d6bae3fa56c19f4d8624c70f2e3cbefb995671 Mon Sep 17 00:00:00 2001 From: Angelo Verlain Date: Mon, 15 Jan 2024 22:03:48 +0200 Subject: [PATCH] parse the outArgs in one go ensures that the return argument's length can be inferred --- src/types/callable.js | 52 +++++++++++++++++++++++----------- src/types/callable/function.js | 20 +------------ src/types/callable/method.js | 11 +------ src/types/callable/vfunc.js | 11 +------ 4 files changed, 38 insertions(+), 56 deletions(-) diff --git a/src/types/callable.js b/src/types/callable.js index e6a9d10..1a2c5c4 100644 --- a/src/types/callable.js +++ b/src/types/callable.js @@ -1,8 +1,8 @@ -import { cast_u64_ptr, deref_buf } from "../base_utils/convert.ts"; import { GIDirection, GIFunctionInfoFlags, GIInfoType, + GITypeTag, } from "../bindings/enums.js"; import g from "../bindings/mod.js"; import { ExtendedDataView } from "../utils/dataview.js"; @@ -34,12 +34,12 @@ export function createArg(info) { export function parseCallableArgs(info) { const nArgs = g.callable_info.get_n_args(info); - //const returnType = g.callable_info.get_return_type(info); + const returnType = g.callable_info.get_return_type(info); const argDetails = []; for (let i = 0; i < nArgs; i++) { const argInfo = g.callable_info.get_arg(info, i); - const arg = createArg(argInfo); + const arg = { ...createArg(argInfo), index: i }; argDetails.push(arg); g.base_info.unref(argInfo); } @@ -73,29 +73,47 @@ export function parseCallableArgs(info) { return new BigUint64Array(outArgsDetail.map((d) => initArgument(d.type))); }; - const parseOutArgs = (outArgs) => { + const parseOutArgs = (returnArg, outArgs) => { const values = []; - for (const [index, arg] of outArgsDetail.entries()) { - if (outArgsDetail.some((d) => d.arrLength === index)) continue; + const args = Array.from(outArgsDetail.entries()); - // extract the length of this argument (if it's an array) - const lengthArg = outArgsDetail.findIndex(({ index }) => - arg.arrLength === index - ); + const lengthArgs = outArgsDetail.map((arg) => arg.arrLength); - let length = -1; + // don't include VOID return types + if (g.type_info.get_tag(returnType) !== GITypeTag.VOID) { + args.unshift([-1, { + type: returnType, + arrLength: g.type_info.get_array_length(returnType), + }]); - if (lengthArg !== -1) { - const lengthPointer = cast_u64_ptr(outArgs[lengthArg]); - length = new ExtendedDataView(deref_buf(lengthPointer, 8)) - .getBigUint64(); + lengthArgs.push(g.type_info.get_array_length(returnType)); + } + + // parsing outArgs + for (const [index, arg] of args) { + // skip length parameters + if (index !== -1 && args.some(([_, arg]) => arg.arrLength === index)) { + continue; } - values.push(unboxArgument(arg.type, outArgs[index], length)); + // extract the length of this argument (if it's an array) + const lengthArg = outArgsDetail.findIndex((outArg) => + outArg.index === arg.arrLength + ); + const length = lengthArg !== -1 ? outArgs[lengthArg] : -1; + + const value = index === -1 ? returnArg : outArgs[index]; + values.push(unboxArgument(arg.type, value, length)); } - return values; + if (values.length === 1) { + return values[0]; + } else if (values.length === 0) { + return; + } else { + return values; + } }; return [parseInArgs, initOutArgs, parseOutArgs]; diff --git a/src/types/callable/function.js b/src/types/callable/function.js index ef7806e..86de46a 100644 --- a/src/types/callable/function.js +++ b/src/types/callable/function.js @@ -1,11 +1,8 @@ -import { GITypeTag } from "../../bindings/enums.js"; import g from "../../bindings/mod.js"; import { createGError } from "../../utils/error.ts"; -import { unboxArgument } from "../argument.js"; import { parseCallableArgs } from "../callable.js"; export function createFunction(info) { - const returnType = g.callable_info.get_return_type(info); const [parseInArgs, initOutArgs, parseOutArgs] = parseCallableArgs(info); return (...args) => { @@ -33,21 +30,6 @@ export function createFunction(info) { throw createGError(error[0]); } - const retVal = unboxArgument(returnType, returnValue[0]); - - if (outArgs.length > 0) { - const parsedOutArgs = parseOutArgs(outArgs); - - // don't include a return value if it's void - if (g.type_info.get_tag(returnType) !== GITypeTag.VOID) { - return [retVal, ...parsedOutArgs]; - } else if (parsedOutArgs.length === 1) { - return parsedOutArgs[0]; - } else { - return parsedOutArgs; - } - } - - return retVal; + return parseOutArgs(returnValue[0], outArgs); }; } diff --git a/src/types/callable/method.js b/src/types/callable/method.js index b95d755..0992aaa 100644 --- a/src/types/callable/method.js +++ b/src/types/callable/method.js @@ -1,12 +1,9 @@ import g from "../../bindings/mod.js"; import { cast_ptr_u64 } from "../../base_utils/convert.ts"; import { createGError } from "../../utils/error.ts"; -import { unboxArgument } from "../argument.js"; import { parseCallableArgs } from "../callable.js"; export function createMethod(info) { - const returnType = g.callable_info.get_return_type(info); - const [parseInArgs, initOutArgs, parseOutArgs] = parseCallableArgs(info); return (caller, ...args) => { @@ -36,12 +33,6 @@ export function createMethod(info) { throw createGError(error[0]); } - const retVal = unboxArgument(returnType, returnValue[0]); - - if (outArgs.length > 0) { - return [retVal, ...parseOutArgs(outArgs)]; - } - - return retVal; + return parseOutArgs(returnValue[0], outArgs); }; } diff --git a/src/types/callable/vfunc.js b/src/types/callable/vfunc.js index ca5dd67..a8fe7e1 100644 --- a/src/types/callable/vfunc.js +++ b/src/types/callable/vfunc.js @@ -1,12 +1,9 @@ import g from "../../bindings/mod.js"; import { cast_ptr_u64 } from "../../base_utils/convert.ts"; import { createGError } from "../../utils/error.ts"; -import { unboxArgument } from "../argument.js"; import { parseCallableArgs } from "../callable.js"; export function createVFunc(info) { - const returnType = g.callable_info.get_return_type(info); - const [parseInArgs, initOutArgs, parseOutArgs] = parseCallableArgs(info); return (caller, implimentor, ...args) => { @@ -37,12 +34,6 @@ export function createVFunc(info) { throw createGError(error[0]); } - const retVal = unboxArgument(returnType, returnValue[0]); - - if (outArgs.length > 0) { - return [retVal, ...parseOutArgs(outArgs)]; - } - - return retVal; + return parseOutArgs(returnValue[0], outArgs); }; }