Skip to content

Commit c54aeef

Browse files
authored
Add Function::Call Napi::Value override (#1026)
* Add Function::Call Napi::Value vector override * Fix lint issues
1 parent e906b5a commit c54aeef

File tree

4 files changed

+93
-23
lines changed

4 files changed

+93
-23
lines changed

napi-inl.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,6 +2287,11 @@ inline MaybeOrValue<Value> Function::Call(
22872287
return Call(Env().Undefined(), args);
22882288
}
22892289

2290+
inline MaybeOrValue<Value> Function::Call(
2291+
const std::vector<Value>& args) const {
2292+
return Call(Env().Undefined(), args);
2293+
}
2294+
22902295
inline MaybeOrValue<Value> Function::Call(size_t argc,
22912296
const napi_value* args) const {
22922297
return Call(Env().Undefined(), argc, args);
@@ -2302,6 +2307,27 @@ inline MaybeOrValue<Value> Function::Call(
23022307
return Call(recv, args.size(), args.data());
23032308
}
23042309

2310+
inline MaybeOrValue<Value> Function::Call(
2311+
napi_value recv, const std::vector<Value>& args) const {
2312+
const size_t argc = args.size();
2313+
const size_t stackArgsCount = 6;
2314+
napi_value stackArgs[stackArgsCount];
2315+
std::vector<napi_value> heapArgs;
2316+
napi_value* argv;
2317+
if (argc <= stackArgsCount) {
2318+
argv = stackArgs;
2319+
} else {
2320+
heapArgs.resize(argc);
2321+
argv = heapArgs.data();
2322+
}
2323+
2324+
for (size_t index = 0; index < argc; index++) {
2325+
argv[index] = static_cast<napi_value>(args[index]);
2326+
}
2327+
2328+
return Call(recv, argc, argv);
2329+
}
2330+
23052331
inline MaybeOrValue<Value> Function::Call(napi_value recv,
23062332
size_t argc,
23072333
const napi_value* args) const {

napi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,11 +1350,14 @@ namespace Napi {
13501350
MaybeOrValue<Value> Call(
13511351
const std::initializer_list<napi_value>& args) const;
13521352
MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const;
1353+
MaybeOrValue<Value> Call(const std::vector<Value>& args) const;
13531354
MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const;
13541355
MaybeOrValue<Value> Call(
13551356
napi_value recv, const std::initializer_list<napi_value>& args) const;
13561357
MaybeOrValue<Value> Call(napi_value recv,
13571358
const std::vector<napi_value>& args) const;
1359+
MaybeOrValue<Value> Call(napi_value recv,
1360+
const std::vector<Value>& args) const;
13581361
MaybeOrValue<Value> Call(napi_value recv,
13591362
size_t argc,
13601363
const napi_value* args) const;

test/function.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ Value CallWithVector(const CallbackInfo& info) {
6969
return MaybeUnwrap(func.Call(args));
7070
}
7171

72+
Value CallWithVectorUsingCppWrapper(const CallbackInfo& info) {
73+
Function func = info[0].As<Function>();
74+
std::vector<Value> args;
75+
args.reserve(3);
76+
args.push_back(info[1]);
77+
args.push_back(info[2]);
78+
args.push_back(info[3]);
79+
return MaybeUnwrap(func.Call(args));
80+
}
81+
7282
Value CallWithCStyleArray(const CallbackInfo& info) {
7383
Function func = info[0].As<Function>();
7484
std::vector<napi_value> args;
@@ -108,6 +118,17 @@ Value CallWithReceiverAndVector(const CallbackInfo& info) {
108118
return MaybeUnwrap(func.Call(receiver, args));
109119
}
110120

121+
Value CallWithReceiverAndVectorUsingCppWrapper(const CallbackInfo& info) {
122+
Function func = info[0].As<Function>();
123+
Value receiver = info[1];
124+
std::vector<Value> args;
125+
args.reserve(3);
126+
args.push_back(info[2]);
127+
args.push_back(info[3]);
128+
args.push_back(info[4]);
129+
return MaybeUnwrap(func.Call(receiver, args));
130+
}
131+
111132
Value CallWithInvalidReceiver(const CallbackInfo& info) {
112133
Function func = info[0].As<Function>();
113134
return MaybeUnwrapOr(func.Call(Value(), std::initializer_list<napi_value>{}),
@@ -213,11 +234,15 @@ Object InitFunction(Env env) {
213234
Function::New(env, ValueCallbackWithData, nullptr, &testData);
214235
exports["callWithArgs"] = Function::New(env, CallWithArgs);
215236
exports["callWithVector"] = Function::New(env, CallWithVector);
237+
exports["callWithVectorUsingCppWrapper"] =
238+
Function::New(env, CallWithVectorUsingCppWrapper);
216239
exports["callWithCStyleArray"] = Function::New(env, CallWithCStyleArray);
217240
exports["callWithReceiverAndCStyleArray"] =
218241
Function::New(env, CallWithReceiverAndCStyleArray);
219242
exports["callWithReceiverAndArgs"] = Function::New(env, CallWithReceiverAndArgs);
220243
exports["callWithReceiverAndVector"] = Function::New(env, CallWithReceiverAndVector);
244+
exports["callWithReceiverAndVectorUsingCppWrapper"] =
245+
Function::New(env, CallWithReceiverAndVectorUsingCppWrapper);
221246
exports["callWithInvalidReceiver"] = Function::New(env, CallWithInvalidReceiver);
222247
exports["callConstructorWithArgs"] = Function::New(env, CallConstructorWithArgs);
223248
exports["callConstructorWithVector"] = Function::New(env, CallConstructorWithVector);
@@ -246,13 +271,17 @@ Object InitFunction(Env env) {
246271
Function::New<ValueCallbackWithData>(env, nullptr, &testData);
247272
exports["callWithArgs"] = Function::New<CallWithArgs>(env);
248273
exports["callWithVector"] = Function::New<CallWithVector>(env);
274+
exports["callWithVectorUsingCppWrapper"] =
275+
Function::New<CallWithVectorUsingCppWrapper>(env);
249276
exports["callWithCStyleArray"] = Function::New<CallWithCStyleArray>(env);
250277
exports["callWithReceiverAndCStyleArray"] =
251278
Function::New<CallWithReceiverAndCStyleArray>(env);
252279
exports["callWithReceiverAndArgs"] =
253280
Function::New<CallWithReceiverAndArgs>(env);
254281
exports["callWithReceiverAndVector"] =
255282
Function::New<CallWithReceiverAndVector>(env);
283+
exports["callWithReceiverAndVectorUsingCppWrapper"] =
284+
Function::New<CallWithReceiverAndVectorUsingCppWrapper>(env);
256285
exports["callWithInvalidReceiver"] =
257286
Function::New<CallWithInvalidReceiver>(env);
258287
exports["callConstructorWithArgs"] =

test/function.js

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,113 +8,125 @@ module.exports = require('./common').runTest(binding => {
88
testLambda(binding.function.lambda);
99
});
1010

11-
function test(binding) {
11+
function test (binding) {
1212
assert.strictEqual(binding.emptyConstructor(true), true);
1313
assert.strictEqual(binding.emptyConstructor(false), false);
1414

1515
let obj = {};
1616
assert.deepStrictEqual(binding.voidCallback(obj), undefined);
17-
assert.deepStrictEqual(obj, { "foo": "bar" });
17+
assert.deepStrictEqual(obj, { foo: 'bar' });
1818

19-
assert.deepStrictEqual(binding.valueCallback(), { "foo": "bar" });
19+
assert.deepStrictEqual(binding.valueCallback(), { foo: 'bar' });
2020

2121
let args = null;
2222
let ret = null;
2323
let receiver = null;
24-
function testFunction() {
24+
function testFunction () {
2525
receiver = this;
2626
args = [].slice.call(arguments);
2727
return ret;
2828
}
29-
function testConstructor() {
29+
function testConstructor () {
3030
args = [].slice.call(arguments);
3131
}
3232

33-
function makeCallbackTestFunction(receiver, expectedOne, expectedTwo, expectedThree) {
34-
return function callback(one, two, three) {
33+
function makeCallbackTestFunction (receiver, expectedOne, expectedTwo, expectedThree) {
34+
return function callback (one, two, three) {
3535
assert.strictEqual(this, receiver);
3636
assert.strictEqual(one, expectedOne);
3737
assert.strictEqual(two, expectedTwo);
3838
assert.strictEqual(three, expectedThree);
39-
}
39+
};
4040
}
4141

4242
ret = 4;
4343
assert.strictEqual(binding.callWithArgs(testFunction, 1, 2, 3), 4);
4444
assert.strictEqual(receiver, undefined);
45-
assert.deepStrictEqual(args, [ 1, 2, 3 ]);
45+
assert.deepStrictEqual(args, [1, 2, 3]);
4646

4747
ret = 5;
4848
assert.strictEqual(binding.callWithVector(testFunction, 2, 3, 4), 5);
4949
assert.strictEqual(receiver, undefined);
50-
assert.deepStrictEqual(args, [ 2, 3, 4 ]);
50+
assert.deepStrictEqual(args, [2, 3, 4]);
51+
52+
ret = 5;
53+
assert.strictEqual(binding.callWithVectorUsingCppWrapper(testFunction, 2, 3, 4), 5);
54+
assert.strictEqual(receiver, undefined);
55+
assert.deepStrictEqual(args, [2, 3, 4]);
5156

5257
ret = 6;
5358
assert.strictEqual(binding.callWithReceiverAndArgs(testFunction, obj, 3, 4, 5), 6);
5459
assert.deepStrictEqual(receiver, obj);
55-
assert.deepStrictEqual(args, [ 3, 4, 5 ]);
60+
assert.deepStrictEqual(args, [3, 4, 5]);
5661

5762
ret = 7;
5863
assert.strictEqual(binding.callWithReceiverAndVector(testFunction, obj, 4, 5, 6), 7);
5964
assert.deepStrictEqual(receiver, obj);
60-
assert.deepStrictEqual(args, [ 4, 5, 6 ]);
65+
assert.deepStrictEqual(args, [4, 5, 6]);
66+
67+
ret = 7;
68+
assert.strictEqual(binding.callWithReceiverAndVectorUsingCppWrapper(testFunction, obj, 4, 5, 6), 7);
69+
assert.deepStrictEqual(receiver, obj);
70+
assert.deepStrictEqual(args, [4, 5, 6]);
6171

6272
ret = 8;
6373
assert.strictEqual(binding.callWithCStyleArray(testFunction, 5, 6, 7), ret);
6474
assert.deepStrictEqual(receiver, undefined);
65-
assert.deepStrictEqual(args, [ 5, 6, 7 ]);
75+
assert.deepStrictEqual(args, [5, 6, 7]);
6676

6777
ret = 9;
6878
assert.strictEqual(binding.callWithReceiverAndCStyleArray(testFunction, obj, 6, 7, 8), ret);
6979
assert.deepStrictEqual(receiver, obj);
70-
assert.deepStrictEqual(args, [ 6, 7, 8 ]);
80+
assert.deepStrictEqual(args, [6, 7, 8]);
7181

7282
ret = 10;
7383
assert.strictEqual(binding.callWithFunctionOperator(testFunction, 7, 8, 9), ret);
7484
assert.strictEqual(receiver, undefined);
75-
assert.deepStrictEqual(args, [ 7, 8, 9 ]);
85+
assert.deepStrictEqual(args, [7, 8, 9]);
7686

7787
assert.throws(() => {
7888
binding.callWithInvalidReceiver();
7989
}, /Invalid (pointer passed as )?argument/);
8090

8191
obj = binding.callConstructorWithArgs(testConstructor, 5, 6, 7);
8292
assert(obj instanceof testConstructor);
83-
assert.deepStrictEqual(args, [ 5, 6, 7 ]);
93+
assert.deepStrictEqual(args, [5, 6, 7]);
8494

8595
obj = binding.callConstructorWithVector(testConstructor, 6, 7, 8);
8696
assert(obj instanceof testConstructor);
87-
assert.deepStrictEqual(args, [ 6, 7, 8 ]);
97+
assert.deepStrictEqual(args, [6, 7, 8]);
8898

8999
obj = binding.callConstructorWithCStyleArray(testConstructor, 7, 8, 9);
90100
assert(obj instanceof testConstructor);
91-
assert.deepStrictEqual(args, [ 7, 8, 9 ]);
101+
assert.deepStrictEqual(args, [7, 8, 9]);
92102

93103
obj = {};
94104
assert.deepStrictEqual(binding.voidCallbackWithData(obj), undefined);
95-
assert.deepStrictEqual(obj, { "foo": "bar", "data": 1 });
105+
assert.deepStrictEqual(obj, { foo: 'bar', data: 1 });
96106

97-
assert.deepStrictEqual(binding.valueCallbackWithData(), { "foo": "bar", "data": 1 });
107+
assert.deepStrictEqual(binding.valueCallbackWithData(), { foo: 'bar', data: 1 });
98108

99109
assert.strictEqual(binding.voidCallback.name, 'voidCallback');
100110
assert.strictEqual(binding.valueCallback.name, 'valueCallback');
101111

102-
let testConstructCall = undefined;
112+
let testConstructCall;
103113
binding.isConstructCall((result) => { testConstructCall = result; });
104114
assert.ok(!testConstructCall);
115+
/* eslint-disable no-new, new-cap */
105116
new binding.isConstructCall((result) => { testConstructCall = result; });
117+
/* eslint-enable no-new, new-cap */
106118
assert.ok(testConstructCall);
107119

108120
obj = {};
109-
binding.makeCallbackWithArgs(makeCallbackTestFunction(obj, "1", "2", "3"), obj, "1", "2", "3");
121+
binding.makeCallbackWithArgs(makeCallbackTestFunction(obj, '1', '2', '3'), obj, '1', '2', '3');
110122
binding.makeCallbackWithVector(makeCallbackTestFunction(obj, 4, 5, 6), obj, 4, 5, 6);
111123
binding.makeCallbackWithCStyleArray(makeCallbackTestFunction(obj, 7, 8, 9), obj, 7, 8, 9);
112124
assert.throws(() => {
113125
binding.makeCallbackWithInvalidReceiver(() => {});
114126
});
115127
}
116128

117-
function testLambda(binding) {
129+
function testLambda (binding) {
118130
assert.ok(binding.lambdaWithNoCapture());
119131
assert.ok(binding.lambdaWithCapture());
120132
assert.ok(binding.lambdaWithMoveOnlyCapture());

0 commit comments

Comments
 (0)