Skip to content

Commit

Permalink
Add Function::Call Napi::Value vector override
Browse files Browse the repository at this point in the history
  • Loading branch information
rgerd committed Feb 11, 2022
1 parent 744c8d2 commit edd0cb4
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
26 changes: 26 additions & 0 deletions napi-inl.h
Expand Up @@ -2287,6 +2287,11 @@ inline MaybeOrValue<Value> Function::Call(
return Call(Env().Undefined(), args);
}

inline MaybeOrValue<Value> Function::Call(
const std::vector<Value>& args) const {
return Call(Env().Undefined(), args);
}

inline MaybeOrValue<Value> Function::Call(size_t argc,
const napi_value* args) const {
return Call(Env().Undefined(), argc, args);
Expand All @@ -2302,6 +2307,27 @@ inline MaybeOrValue<Value> Function::Call(
return Call(recv, args.size(), args.data());
}

inline MaybeOrValue<Value> Function::Call(
napi_value recv, const std::vector<Value>& args) const {
const size_t argc = args.size();
const size_t stackArgsCount = 6;
napi_value stackArgs[stackArgsCount];
std::vector<napi_value> heapArgs;
napi_value* argv;
if (argc <= stackArgsCount) {
argv = stackArgs;
} else {
heapArgs.resize(argc);
argv = heapArgs.data();
}

for (size_t index = 0; index < argc; index++) {
argv[index] = static_cast<napi_value>(args[index]);
}

return Call(recv, argc, argv);
}

inline MaybeOrValue<Value> Function::Call(napi_value recv,
size_t argc,
const napi_value* args) const {
Expand Down
3 changes: 3 additions & 0 deletions napi.h
Expand Up @@ -1350,11 +1350,14 @@ namespace Napi {
MaybeOrValue<Value> Call(
const std::initializer_list<napi_value>& args) const;
MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const;
MaybeOrValue<Value> Call(const std::vector<Value>& args) const;
MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const;
MaybeOrValue<Value> Call(
napi_value recv, const std::initializer_list<napi_value>& args) const;
MaybeOrValue<Value> Call(napi_value recv,
const std::vector<napi_value>& args) const;
MaybeOrValue<Value> Call(napi_value recv,
const std::vector<Value>& args) const;
MaybeOrValue<Value> Call(napi_value recv,
size_t argc,
const napi_value* args) const;
Expand Down
29 changes: 29 additions & 0 deletions test/function.cc
Expand Up @@ -69,6 +69,16 @@ Value CallWithVector(const CallbackInfo& info) {
return MaybeUnwrap(func.Call(args));
}

Value CallWithVectorUsingCppWrapper(const CallbackInfo& info) {
Function func = info[0].As<Function>();
std::vector<Value> args;
args.reserve(3);
args.push_back(info[1]);
args.push_back(info[2]);
args.push_back(info[3]);
return MaybeUnwrap(func.Call(args));
}

Value CallWithCStyleArray(const CallbackInfo& info) {
Function func = info[0].As<Function>();
std::vector<napi_value> args;
Expand Down Expand Up @@ -108,6 +118,17 @@ Value CallWithReceiverAndVector(const CallbackInfo& info) {
return MaybeUnwrap(func.Call(receiver, args));
}

Value CallWithReceiverAndVectorUsingCppWrapper(const CallbackInfo& info) {
Function func = info[0].As<Function>();
Value receiver = info[1];
std::vector<Value> args;
args.reserve(3);
args.push_back(info[2]);
args.push_back(info[3]);
args.push_back(info[4]);
return MaybeUnwrap(func.Call(receiver, args));
}

Value CallWithInvalidReceiver(const CallbackInfo& info) {
Function func = info[0].As<Function>();
return MaybeUnwrapOr(func.Call(Value(), std::initializer_list<napi_value>{}),
Expand Down Expand Up @@ -213,11 +234,15 @@ Object InitFunction(Env env) {
Function::New(env, ValueCallbackWithData, nullptr, &testData);
exports["callWithArgs"] = Function::New(env, CallWithArgs);
exports["callWithVector"] = Function::New(env, CallWithVector);
exports["callWithVectorUsingCppWrapper"] =
Function::New(env, CallWithVectorUsingCppWrapper);
exports["callWithCStyleArray"] = Function::New(env, CallWithCStyleArray);
exports["callWithReceiverAndCStyleArray"] =
Function::New(env, CallWithReceiverAndCStyleArray);
exports["callWithReceiverAndArgs"] = Function::New(env, CallWithReceiverAndArgs);
exports["callWithReceiverAndVector"] = Function::New(env, CallWithReceiverAndVector);
exports["callWithReceiverAndVectorUsingCppWrapper"] =
Function::New(env, CallWithReceiverAndVectorUsingCppWrapper);
exports["callWithInvalidReceiver"] = Function::New(env, CallWithInvalidReceiver);
exports["callConstructorWithArgs"] = Function::New(env, CallConstructorWithArgs);
exports["callConstructorWithVector"] = Function::New(env, CallConstructorWithVector);
Expand Down Expand Up @@ -246,13 +271,17 @@ Object InitFunction(Env env) {
Function::New<ValueCallbackWithData>(env, nullptr, &testData);
exports["callWithArgs"] = Function::New<CallWithArgs>(env);
exports["callWithVector"] = Function::New<CallWithVector>(env);
exports["callWithVectorUsingCppWrapper"] =
Function::New<CallWithVectorUsingCppWrapper>(env);
exports["callWithCStyleArray"] = Function::New<CallWithCStyleArray>(env);
exports["callWithReceiverAndCStyleArray"] =
Function::New<CallWithReceiverAndCStyleArray>(env);
exports["callWithReceiverAndArgs"] =
Function::New<CallWithReceiverAndArgs>(env);
exports["callWithReceiverAndVector"] =
Function::New<CallWithReceiverAndVector>(env);
exports["callWithReceiverAndVectorUsingCppWrapper"] =
Function::New<CallWithReceiverAndVectorUsingCppWrapper>(env);
exports["callWithInvalidReceiver"] =
Function::New<CallWithInvalidReceiver>(env);
exports["callConstructorWithArgs"] =
Expand Down
10 changes: 10 additions & 0 deletions test/function.js
Expand Up @@ -49,6 +49,11 @@ function test(binding) {
assert.strictEqual(receiver, undefined);
assert.deepStrictEqual(args, [ 2, 3, 4 ]);

ret = 5;
assert.strictEqual(binding.callWithVectorUsingCppWrapper(testFunction, 2, 3, 4), 5);
assert.strictEqual(receiver, undefined);
assert.deepStrictEqual(args, [ 2, 3, 4 ]);

ret = 6;
assert.strictEqual(binding.callWithReceiverAndArgs(testFunction, obj, 3, 4, 5), 6);
assert.deepStrictEqual(receiver, obj);
Expand All @@ -59,6 +64,11 @@ function test(binding) {
assert.deepStrictEqual(receiver, obj);
assert.deepStrictEqual(args, [ 4, 5, 6 ]);

ret = 7;
assert.strictEqual(binding.callWithReceiverAndVectorUsingCppWrapper(testFunction, obj, 4, 5, 6), 7);
assert.deepStrictEqual(receiver, obj);
assert.deepStrictEqual(args, [ 4, 5, 6 ]);

ret = 8;
assert.strictEqual(binding.callWithCStyleArray(testFunction, 5, 6, 7), ret);
assert.deepStrictEqual(receiver, undefined);
Expand Down

0 comments on commit edd0cb4

Please sign in to comment.