Skip to content

Commit

Permalink
src: return Maybe<> on pending exception when cpp exception disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
legendecas committed Apr 15, 2021
1 parent 5e64d1f commit e42a1b9
Show file tree
Hide file tree
Showing 87 changed files with 1,059 additions and 649 deletions.
535 changes: 373 additions & 162 deletions napi-inl.h

Large diffs are not rendered by default.

358 changes: 230 additions & 128 deletions napi.h

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions test/addon.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));
module.exports = require('./common').runTest(test);

function test(binding) {
assert.strictEqual(binding.addon.increment(), 43);
Expand Down
4 changes: 3 additions & 1 deletion test/addon_data.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#if (NAPI_VERSION > 5)
#include <stdio.h>
#include "napi.h"
#include "test_helper.h"

// An overly elaborate way to get/set a boolean stored in the instance data:
// 0. A boolean named "verbose" is stored in the instance data. The constructor
Expand Down Expand Up @@ -42,7 +43,8 @@ class Addon {
};

static Napi::Value Getter(const Napi::CallbackInfo& info) {
return info.Env().GetInstanceData<Addon>()->VerboseIndicator.New({});
return MaybeToChecked(
info.Env().GetInstanceData<Addon>()->VerboseIndicator.New({}));
}

static void Setter(const Napi::CallbackInfo& info) {
Expand Down
9 changes: 2 additions & 7 deletions test/addon_data.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');
const { spawn } = require('child_process');
const readline = require('readline');
const path = require('path');

module.exports =
test(path.resolve(__dirname, `./build/${buildType}/binding.node`))
.then(() =>
test(path.resolve(__dirname,
`./build/${buildType}/binding_noexcept.node`)));
module.exports = require('./common').runTestWithBindingPath(test);

// Make sure the instance data finalizer is called at process exit. If the hint
// is non-zero, it will be printed out by the child process.
Expand Down
5 changes: 2 additions & 3 deletions test/arraybuffer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');
const testUtil = require('./testUtil');

module.exports = test(require(`./build/${buildType}/binding.node`))
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
module.exports = require('./common').runTest(test);

function test(binding) {
return testUtil.runGCTests([
Expand Down
5 changes: 2 additions & 3 deletions test/asynccontext.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');
const common = require('./common');

Expand All @@ -17,8 +17,7 @@ function checkAsyncHooks() {
return false;
}

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));
module.exports = common.runTest(test);

function installAsyncHooksForTest() {
return new Promise((resolve, reject) => {
Expand Down
6 changes: 2 additions & 4 deletions test/asyncprogressqueueworker.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const common = require('./common')
const assert = require('assert');
const os = require('os');

module.exports = test(require(`./build/${buildType}/binding.node`))
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
module.exports = common.runTest(test);

async function test({ asyncprogressqueueworker }) {
await success(asyncprogressqueueworker);
Expand Down
5 changes: 2 additions & 3 deletions test/asyncprogressworker.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const common = require('./common')
const assert = require('assert');

module.exports = test(require(`./build/${buildType}/binding.node`))
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
module.exports = common.runTest(test);

async function test({ asyncprogressworker }) {
await success(asyncprogressworker);
Expand Down
5 changes: 2 additions & 3 deletions test/asyncworker-nocallback.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const common = require('./common');

module.exports = test(require(`./build/${buildType}/binding.node`))
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
module.exports = common.runTest(test);

async function test(binding) {
await binding.asyncworker.doWorkNoCallback(true, {})
Expand Down
13 changes: 5 additions & 8 deletions test/asyncworker-persistent.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');
const common = require('./common');
const binding = require(`./build/${buildType}/binding.node`);
const noexceptBinding = require(`./build/${buildType}/binding_noexcept.node`);

function test(binding, succeed) {
return new Promise((resolve) =>
Expand All @@ -21,7 +18,7 @@ function test(binding, succeed) {
}));
}

module.exports = test(binding.persistentasyncworker, false)
.then(() => test(binding.persistentasyncworker, true))
.then(() => test(noexceptBinding.persistentasyncworker, false))
.then(() => test(noexceptBinding.persistentasyncworker, true));
module.exports = require('./common').runTest(async binding => {
await test(binding.persistentasyncworker, false);
await test(binding.persistentasyncworker, true);
});
4 changes: 1 addition & 3 deletions test/asyncworker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');
const common = require('./common');

Expand All @@ -17,8 +16,7 @@ function checkAsyncHooks() {
return false;
}

module.exports = test(require(`./build/${buildType}/binding.node`))
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
module.exports = common.runTest(test);

function installAsyncHooksForTest() {
return new Promise((resolve, reject) => {
Expand Down
4 changes: 1 addition & 3 deletions test/basic_types/array.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`../build/${buildType}/binding.node`));
test(require(`../build/${buildType}/binding_noexcept.node`));
module.exports = require('../common').runTest(test);

function test(binding) {

Expand Down
5 changes: 2 additions & 3 deletions test/basic_types/boolean.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');

test(require(`../build/${buildType}/binding.node`));
test(require(`../build/${buildType}/binding_noexcept.node`));
module.exports = require('../common').runTest(test);

function test(binding) {
const bool1 = binding.basic_types_boolean.createBoolean(true);
Expand Down
4 changes: 1 addition & 3 deletions test/basic_types/number.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use strict';

const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`../build/${buildType}/binding.node`));
test(require(`../build/${buildType}/binding_noexcept.node`));
module.exports = require('../common').runTest(test);

function test(binding) {
const MIN_INT32 = -2147483648;
Expand Down
9 changes: 5 additions & 4 deletions test/basic_types/value.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "napi.h"
#include "test_helper.h"

using namespace Napi;

Expand Down Expand Up @@ -75,19 +76,19 @@ static Value IsExternal(const CallbackInfo& info) {
}

static Value ToBoolean(const CallbackInfo& info) {
return info[0].ToBoolean();
return FromMaybe(info[0].ToBoolean());
}

static Value ToNumber(const CallbackInfo& info) {
return info[0].ToNumber();
return FromMaybe(info[0].ToNumber());
}

static Value ToString(const CallbackInfo& info) {
return info[0].ToString();
return FromMaybe(info[0].ToString());
}

static Value ToObject(const CallbackInfo& info) {
return info[0].ToObject();
return FromMaybe(info[0].ToObject());
}

Object InitBasicTypesValue(Env env) {
Expand Down
4 changes: 1 addition & 3 deletions test/basic_types/value.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use strict';

const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`../build/${buildType}/binding.node`));
test(require(`../build/${buildType}/binding_noexcept.node`));
module.exports = require('../common').runTest(test);

function test(binding) {
const externalValue = binding.basic_types_value.createExternal();
Expand Down
4 changes: 3 additions & 1 deletion test/bigint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#define NAPI_EXPERIMENTAL
#include "napi.h"

#include "test_helper.h"

using namespace Napi;

namespace {
Expand All @@ -11,7 +13,7 @@ Value IsLossless(const CallbackInfo& info) {
Env env = info.Env();

BigInt big = info[0].As<BigInt>();
bool is_signed = info[1].ToBoolean().Value();
bool is_signed = MaybeToChecked(info[1].ToBoolean()).Value();

bool lossless;
if (is_signed) {
Expand Down
4 changes: 1 addition & 3 deletions test/bigint.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use strict';

const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));
module.exports = require('./common').runTest(test);

function test(binding) {
const {
Expand Down
6 changes: 6 additions & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
'target_defaults': {
'includes': ['../common.gypi'],
'include_dirs': ['./common'],
'sources': [
'addon.cc',
'addon_data.cc',
Expand Down Expand Up @@ -81,5 +82,10 @@
'target_name': 'binding_noexcept',
'includes': ['../noexcept.gypi']
},
{
'target_name': 'binding_noexcept_maybe',
'includes': ['../noexcept.gypi'],
'defines': ['NODE_ADDON_API_ENABLE_MAYBE']
},
],
}
5 changes: 2 additions & 3 deletions test/buffer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;

const assert = require('assert');
const testUtil = require('./testUtil');
const safeBuffer = require('safe-buffer');

module.exports = test(require(`./build/${buildType}/binding.node`))
.then(() => test(require(`./build/${buildType}/binding_noexcept.node`)));
module.exports = require('./common').runTest(test);

function test(binding) {
return testUtil.runGCTests([
Expand Down
5 changes: 1 addition & 4 deletions test/callbackscope.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');
const common = require('./common');

// we only check async hooks on 8.x an higher were
// they are closer to working properly
Expand All @@ -17,8 +15,7 @@ function checkAsyncHooks() {
return false;
}

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));
module.exports = require('./common').runTest(test);

function test(binding) {
if (!checkAsyncHooks())
Expand Down
28 changes: 28 additions & 0 deletions test/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,31 @@ exports.mustNotCall = function(msg) {
assert.fail(msg || 'function should not have been called');
};
};

exports.runTest = async function(test, buildType) {
buildType = buildType ?? process.config.target_defaults.default_configuration;

const bindings = [
`../build/${buildType}/binding.node`,
`../build/${buildType}/binding_noexcept.node`,
`../build/${buildType}/binding_noexcept_maybe.node`,
].map(it => require.resolve(it));

for (const item of bindings) {
await test(require(item));
}
}

exports.runTestWithBindingPath = async function(test, buildType) {
buildType = buildType ?? process.config.target_defaults.default_configuration;

const bindings = [
`../build/${buildType}/binding.node`,
`../build/${buildType}/binding_noexcept.node`,
`../build/${buildType}/binding_noexcept_maybe.node`,
].map(it => require.resolve(it));

for (const item of bindings) {
await test(item);
}
}
44 changes: 44 additions & 0 deletions test/common/test_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once
#include "napi.h"

namespace Napi {

// Use this when a variable or parameter is unused in order to explicitly
// silence a compiler warning about that.
template <typename T>
inline void USE(T&&) {}

/**
* A test helper that converts MaybeOrValue<T> to T by checking that
* MaybeOrValue is NOT an empty Maybe when NODE_ADDON_API_ENABLE_MAYBE is
* defined.
*
* Do nothing when NODE_ADDON_API_ENABLE_MAYBE is not defined.
*/
template <typename T>
inline T MaybeToChecked(MaybeOrValue<T> maybe) {
#if defined(NODE_ADDON_API_ENABLE_MAYBE)
return maybe.ToChecked();
#else
return maybe;
#endif
}

/**
* A test helper that converts MaybeOrValue<T> to T by getting the value that
* wrapped by the Maybe or return the default_value if the Maybe is empty when
* NODE_ADDON_API_ENABLE_MAYBE is defined.
*
* Do nothing when NODE_ADDON_API_ENABLE_MAYBE is not defined.
*/
template <typename T>
inline T FromMaybe(MaybeOrValue<T> maybe, const T& default_value = T()) {
#if defined(NODE_ADDON_API_ENABLE_MAYBE)
return maybe.FromMaybe(default_value);
#else
USE(default_value);
return maybe;
#endif
}

} // namespace Napi
Loading

0 comments on commit e42a1b9

Please sign in to comment.