Skip to content

Commit

Permalink
parse the outArgs in one go
Browse files Browse the repository at this point in the history
ensures that the return argument's length can be inferred
  • Loading branch information
vixalien committed Jan 15, 2024
1 parent aefedbb commit 46d6bae
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 56 deletions.
52 changes: 35 additions & 17 deletions src/types/callable.js
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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];
Expand Down
20 changes: 1 addition & 19 deletions src/types/callable/function.js
Original file line number Diff line number Diff line change
@@ -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) => {
Expand Down Expand Up @@ -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);
};
}
11 changes: 1 addition & 10 deletions src/types/callable/method.js
Original file line number Diff line number Diff line change
@@ -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) => {
Expand Down Expand Up @@ -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);
};
}
11 changes: 1 addition & 10 deletions src/types/callable/vfunc.js
Original file line number Diff line number Diff line change
@@ -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) => {
Expand Down Expand Up @@ -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);
};
}

0 comments on commit 46d6bae

Please sign in to comment.