35 lines
1.2 KiB
JavaScript
Raw Permalink Normal View History

n-api: add support for abi stable module API Add support for abi stable module API (N-API) as "Experimental feature". The goal of this API is to provide a stable Node API for native module developers. N-API aims to provide ABI compatibility guarantees across different Node versions and also across different Node VMs - allowing N-API enabled native modules to just work across different versions and flavors of Node.js without recompilation. A more detailed introduction is provided in: https://github.com/nodejs/node-eps/blob/master/005-ABI-Stable-Module-API.md and https://github.com/nodejs/abi-stable-node/blob/doc/VM%20Summit.pdf. The feature, during its experimental state, will be guarded by a runtime flag "--napi-modules". Only when this flag is added to the command line will N-API modules along with regular non N-API modules be supported. The API is defined by the methods in "src/node_api.h" and "src/node_api_types.h". This is the best starting point to review the API surface. More documentation will follow. In addition to the implementation of the API using V8, which is included in this PR, the API has also been validated against chakracore and that port is available in https://github.com/nodejs/abi-stable-node/tree/api-prototype-chakracore-8.x. The current plan is to provide N-API support in versions 8.X and 6.X directly. For older versions, such as 4.X or pre N-API versions of 6.X, we plan to create an external npm module to provide a migration path that will allow modules targeting older Node.js versions to use the API, albeit without getting the advantage of not having to recompile. In addition, we also plan an external npm package with C++ sugar to simplify the use of the API. The sugar will be in-line only and will only use the exported N-API methods but is not part of the N-API itself. The current version is in: https://github.com/nodejs/node-api. This PR is a result of work in the abi-stable-node repo: https://github.com/nodejs/abi-stable-node/tree/doc, with this PR being the cumulative work on the api-prototype-8.x branch with the following contributors in alphabetical order: Author: Arunesh Chandra <arunesh.chandra@microsoft.com> Author: Gabriel Schulhof <gabriel.schulhof@intel.com> Author: Hitesh Kanwathirtha <hiteshk@microsoft.com> Author: Ian Halliday <ianhall@microsoft.com> Author: Jason Ginchereau <jasongin@microsoft.com> Author: Michael Dawson <michael_dawson@ca.ibm.com> Author: Sampson Gao <sampsong@ca.ibm.com> Author: Taylor Woll <taylor.woll@microsoft.com> PR-URL: https://github.com/nodejs/node/pull/11975 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
2017-03-20 14:55:26 -07:00
'use strict';
// Flags: --expose-gc --no-concurrent-array-buffer-sweeping
n-api: add support for abi stable module API Add support for abi stable module API (N-API) as "Experimental feature". The goal of this API is to provide a stable Node API for native module developers. N-API aims to provide ABI compatibility guarantees across different Node versions and also across different Node VMs - allowing N-API enabled native modules to just work across different versions and flavors of Node.js without recompilation. A more detailed introduction is provided in: https://github.com/nodejs/node-eps/blob/master/005-ABI-Stable-Module-API.md and https://github.com/nodejs/abi-stable-node/blob/doc/VM%20Summit.pdf. The feature, during its experimental state, will be guarded by a runtime flag "--napi-modules". Only when this flag is added to the command line will N-API modules along with regular non N-API modules be supported. The API is defined by the methods in "src/node_api.h" and "src/node_api_types.h". This is the best starting point to review the API surface. More documentation will follow. In addition to the implementation of the API using V8, which is included in this PR, the API has also been validated against chakracore and that port is available in https://github.com/nodejs/abi-stable-node/tree/api-prototype-chakracore-8.x. The current plan is to provide N-API support in versions 8.X and 6.X directly. For older versions, such as 4.X or pre N-API versions of 6.X, we plan to create an external npm module to provide a migration path that will allow modules targeting older Node.js versions to use the API, albeit without getting the advantage of not having to recompile. In addition, we also plan an external npm package with C++ sugar to simplify the use of the API. The sugar will be in-line only and will only use the exported N-API methods but is not part of the N-API itself. The current version is in: https://github.com/nodejs/node-api. This PR is a result of work in the abi-stable-node repo: https://github.com/nodejs/abi-stable-node/tree/doc, with this PR being the cumulative work on the api-prototype-8.x branch with the following contributors in alphabetical order: Author: Arunesh Chandra <arunesh.chandra@microsoft.com> Author: Gabriel Schulhof <gabriel.schulhof@intel.com> Author: Hitesh Kanwathirtha <hiteshk@microsoft.com> Author: Ian Halliday <ianhall@microsoft.com> Author: Jason Ginchereau <jasongin@microsoft.com> Author: Michael Dawson <michael_dawson@ca.ibm.com> Author: Sampson Gao <sampsong@ca.ibm.com> Author: Taylor Woll <taylor.woll@microsoft.com> PR-URL: https://github.com/nodejs/node/pull/11975 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
2017-03-20 14:55:26 -07:00
const common = require('../../common');
const binding = require(`./build/${common.buildType}/test_buffer`);
n-api: add support for abi stable module API Add support for abi stable module API (N-API) as "Experimental feature". The goal of this API is to provide a stable Node API for native module developers. N-API aims to provide ABI compatibility guarantees across different Node versions and also across different Node VMs - allowing N-API enabled native modules to just work across different versions and flavors of Node.js without recompilation. A more detailed introduction is provided in: https://github.com/nodejs/node-eps/blob/master/005-ABI-Stable-Module-API.md and https://github.com/nodejs/abi-stable-node/blob/doc/VM%20Summit.pdf. The feature, during its experimental state, will be guarded by a runtime flag "--napi-modules". Only when this flag is added to the command line will N-API modules along with regular non N-API modules be supported. The API is defined by the methods in "src/node_api.h" and "src/node_api_types.h". This is the best starting point to review the API surface. More documentation will follow. In addition to the implementation of the API using V8, which is included in this PR, the API has also been validated against chakracore and that port is available in https://github.com/nodejs/abi-stable-node/tree/api-prototype-chakracore-8.x. The current plan is to provide N-API support in versions 8.X and 6.X directly. For older versions, such as 4.X or pre N-API versions of 6.X, we plan to create an external npm module to provide a migration path that will allow modules targeting older Node.js versions to use the API, albeit without getting the advantage of not having to recompile. In addition, we also plan an external npm package with C++ sugar to simplify the use of the API. The sugar will be in-line only and will only use the exported N-API methods but is not part of the N-API itself. The current version is in: https://github.com/nodejs/node-api. This PR is a result of work in the abi-stable-node repo: https://github.com/nodejs/abi-stable-node/tree/doc, with this PR being the cumulative work on the api-prototype-8.x branch with the following contributors in alphabetical order: Author: Arunesh Chandra <arunesh.chandra@microsoft.com> Author: Gabriel Schulhof <gabriel.schulhof@intel.com> Author: Hitesh Kanwathirtha <hiteshk@microsoft.com> Author: Ian Halliday <ianhall@microsoft.com> Author: Jason Ginchereau <jasongin@microsoft.com> Author: Michael Dawson <michael_dawson@ca.ibm.com> Author: Sampson Gao <sampsong@ca.ibm.com> Author: Taylor Woll <taylor.woll@microsoft.com> PR-URL: https://github.com/nodejs/node/pull/11975 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
2017-03-20 14:55:26 -07:00
const assert = require('assert');
const tick = require('util').promisify(require('../../common/tick'));
n-api: add support for abi stable module API Add support for abi stable module API (N-API) as "Experimental feature". The goal of this API is to provide a stable Node API for native module developers. N-API aims to provide ABI compatibility guarantees across different Node versions and also across different Node VMs - allowing N-API enabled native modules to just work across different versions and flavors of Node.js without recompilation. A more detailed introduction is provided in: https://github.com/nodejs/node-eps/blob/master/005-ABI-Stable-Module-API.md and https://github.com/nodejs/abi-stable-node/blob/doc/VM%20Summit.pdf. The feature, during its experimental state, will be guarded by a runtime flag "--napi-modules". Only when this flag is added to the command line will N-API modules along with regular non N-API modules be supported. The API is defined by the methods in "src/node_api.h" and "src/node_api_types.h". This is the best starting point to review the API surface. More documentation will follow. In addition to the implementation of the API using V8, which is included in this PR, the API has also been validated against chakracore and that port is available in https://github.com/nodejs/abi-stable-node/tree/api-prototype-chakracore-8.x. The current plan is to provide N-API support in versions 8.X and 6.X directly. For older versions, such as 4.X or pre N-API versions of 6.X, we plan to create an external npm module to provide a migration path that will allow modules targeting older Node.js versions to use the API, albeit without getting the advantage of not having to recompile. In addition, we also plan an external npm package with C++ sugar to simplify the use of the API. The sugar will be in-line only and will only use the exported N-API methods but is not part of the N-API itself. The current version is in: https://github.com/nodejs/node-api. This PR is a result of work in the abi-stable-node repo: https://github.com/nodejs/abi-stable-node/tree/doc, with this PR being the cumulative work on the api-prototype-8.x branch with the following contributors in alphabetical order: Author: Arunesh Chandra <arunesh.chandra@microsoft.com> Author: Gabriel Schulhof <gabriel.schulhof@intel.com> Author: Hitesh Kanwathirtha <hiteshk@microsoft.com> Author: Ian Halliday <ianhall@microsoft.com> Author: Jason Ginchereau <jasongin@microsoft.com> Author: Michael Dawson <michael_dawson@ca.ibm.com> Author: Sampson Gao <sampsong@ca.ibm.com> Author: Taylor Woll <taylor.woll@microsoft.com> PR-URL: https://github.com/nodejs/node/pull/11975 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
2017-03-20 14:55:26 -07:00
n-api: defer Buffer finalizer with SetImmediate We have a test that verifies that JS execution from the Buffer finalizer is accepted, and that errors thrown are passed down synchronously. However, since the finalizer executes during GC, this is behaviour is fundamentally invalid and, for good reasons, disallowed by the JS engine. This leaves us with the options of either finding a way to allow JS execution from the callback, or explicitly forbidding it on the N-API side as well. This commit implements the former option, since it is the more backwards-compatible one, in the sense that the current situation sometimes appears to work as well and we should not break that behaviour if we don’t have to, but rather try to actually make it work reliably. Since GC timing is largely unobservable anyway, this commit moves the callback into a `SetImmediate()`, as we do elsewhere in the code, and a second pass callback is not an easily implemented option, as the API is supposed to wrap around Node’s `Buffer` API. In this case, exceptions are handled like other uncaught exceptions. Two tests have to be adjusted to account for the timing difference. This is unfortunate, but unavoidable if we want to conform to the JS engine API contract and keep all tests. Fixes: https://github.com/nodejs/node/issues/26754 PR-URL: https://github.com/nodejs/node/pull/28082 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: James M Snell <jasnell@gmail.com>
2019-06-05 23:29:18 +02:00
(async function() {
assert.strictEqual(binding.newBuffer().toString(), binding.theText);
assert.strictEqual(binding.newExternalBuffer().toString(), binding.theText);
console.log('gc1');
global.gc();
assert.strictEqual(binding.getDeleterCallCount(), 0);
await tick(10);
n-api: defer Buffer finalizer with SetImmediate We have a test that verifies that JS execution from the Buffer finalizer is accepted, and that errors thrown are passed down synchronously. However, since the finalizer executes during GC, this is behaviour is fundamentally invalid and, for good reasons, disallowed by the JS engine. This leaves us with the options of either finding a way to allow JS execution from the callback, or explicitly forbidding it on the N-API side as well. This commit implements the former option, since it is the more backwards-compatible one, in the sense that the current situation sometimes appears to work as well and we should not break that behaviour if we don’t have to, but rather try to actually make it work reliably. Since GC timing is largely unobservable anyway, this commit moves the callback into a `SetImmediate()`, as we do elsewhere in the code, and a second pass callback is not an easily implemented option, as the API is supposed to wrap around Node’s `Buffer` API. In this case, exceptions are handled like other uncaught exceptions. Two tests have to be adjusted to account for the timing difference. This is unfortunate, but unavoidable if we want to conform to the JS engine API contract and keep all tests. Fixes: https://github.com/nodejs/node/issues/26754 PR-URL: https://github.com/nodejs/node/pull/28082 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: James M Snell <jasnell@gmail.com>
2019-06-05 23:29:18 +02:00
assert.strictEqual(binding.getDeleterCallCount(), 1);
assert.strictEqual(binding.copyBuffer().toString(), binding.theText);
n-api: add support for abi stable module API Add support for abi stable module API (N-API) as "Experimental feature". The goal of this API is to provide a stable Node API for native module developers. N-API aims to provide ABI compatibility guarantees across different Node versions and also across different Node VMs - allowing N-API enabled native modules to just work across different versions and flavors of Node.js without recompilation. A more detailed introduction is provided in: https://github.com/nodejs/node-eps/blob/master/005-ABI-Stable-Module-API.md and https://github.com/nodejs/abi-stable-node/blob/doc/VM%20Summit.pdf. The feature, during its experimental state, will be guarded by a runtime flag "--napi-modules". Only when this flag is added to the command line will N-API modules along with regular non N-API modules be supported. The API is defined by the methods in "src/node_api.h" and "src/node_api_types.h". This is the best starting point to review the API surface. More documentation will follow. In addition to the implementation of the API using V8, which is included in this PR, the API has also been validated against chakracore and that port is available in https://github.com/nodejs/abi-stable-node/tree/api-prototype-chakracore-8.x. The current plan is to provide N-API support in versions 8.X and 6.X directly. For older versions, such as 4.X or pre N-API versions of 6.X, we plan to create an external npm module to provide a migration path that will allow modules targeting older Node.js versions to use the API, albeit without getting the advantage of not having to recompile. In addition, we also plan an external npm package with C++ sugar to simplify the use of the API. The sugar will be in-line only and will only use the exported N-API methods but is not part of the N-API itself. The current version is in: https://github.com/nodejs/node-api. This PR is a result of work in the abi-stable-node repo: https://github.com/nodejs/abi-stable-node/tree/doc, with this PR being the cumulative work on the api-prototype-8.x branch with the following contributors in alphabetical order: Author: Arunesh Chandra <arunesh.chandra@microsoft.com> Author: Gabriel Schulhof <gabriel.schulhof@intel.com> Author: Hitesh Kanwathirtha <hiteshk@microsoft.com> Author: Ian Halliday <ianhall@microsoft.com> Author: Jason Ginchereau <jasongin@microsoft.com> Author: Michael Dawson <michael_dawson@ca.ibm.com> Author: Sampson Gao <sampsong@ca.ibm.com> Author: Taylor Woll <taylor.woll@microsoft.com> PR-URL: https://github.com/nodejs/node/pull/11975 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
2017-03-20 14:55:26 -07:00
n-api: defer Buffer finalizer with SetImmediate We have a test that verifies that JS execution from the Buffer finalizer is accepted, and that errors thrown are passed down synchronously. However, since the finalizer executes during GC, this is behaviour is fundamentally invalid and, for good reasons, disallowed by the JS engine. This leaves us with the options of either finding a way to allow JS execution from the callback, or explicitly forbidding it on the N-API side as well. This commit implements the former option, since it is the more backwards-compatible one, in the sense that the current situation sometimes appears to work as well and we should not break that behaviour if we don’t have to, but rather try to actually make it work reliably. Since GC timing is largely unobservable anyway, this commit moves the callback into a `SetImmediate()`, as we do elsewhere in the code, and a second pass callback is not an easily implemented option, as the API is supposed to wrap around Node’s `Buffer` API. In this case, exceptions are handled like other uncaught exceptions. Two tests have to be adjusted to account for the timing difference. This is unfortunate, but unavoidable if we want to conform to the JS engine API contract and keep all tests. Fixes: https://github.com/nodejs/node/issues/26754 PR-URL: https://github.com/nodejs/node/pull/28082 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: James M Snell <jasnell@gmail.com>
2019-06-05 23:29:18 +02:00
let buffer = binding.staticBuffer();
assert.strictEqual(binding.bufferHasInstance(buffer), true);
assert.strictEqual(binding.bufferInfo(buffer), true);
buffer = null;
global.gc();
assert.strictEqual(binding.getDeleterCallCount(), 1);
await tick(10);
n-api: defer Buffer finalizer with SetImmediate We have a test that verifies that JS execution from the Buffer finalizer is accepted, and that errors thrown are passed down synchronously. However, since the finalizer executes during GC, this is behaviour is fundamentally invalid and, for good reasons, disallowed by the JS engine. This leaves us with the options of either finding a way to allow JS execution from the callback, or explicitly forbidding it on the N-API side as well. This commit implements the former option, since it is the more backwards-compatible one, in the sense that the current situation sometimes appears to work as well and we should not break that behaviour if we don’t have to, but rather try to actually make it work reliably. Since GC timing is largely unobservable anyway, this commit moves the callback into a `SetImmediate()`, as we do elsewhere in the code, and a second pass callback is not an easily implemented option, as the API is supposed to wrap around Node’s `Buffer` API. In this case, exceptions are handled like other uncaught exceptions. Two tests have to be adjusted to account for the timing difference. This is unfortunate, but unavoidable if we want to conform to the JS engine API contract and keep all tests. Fixes: https://github.com/nodejs/node/issues/26754 PR-URL: https://github.com/nodejs/node/pull/28082 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: James M Snell <jasnell@gmail.com>
2019-06-05 23:29:18 +02:00
console.log('gc2');
assert.strictEqual(binding.getDeleterCallCount(), 2);
// To test this doesn't crash
binding.invalidObjectAsBuffer({});
const testBuffer = binding.bufferFromArrayBuffer();
assert(testBuffer instanceof Buffer, 'Expected a Buffer');
n-api: defer Buffer finalizer with SetImmediate We have a test that verifies that JS execution from the Buffer finalizer is accepted, and that errors thrown are passed down synchronously. However, since the finalizer executes during GC, this is behaviour is fundamentally invalid and, for good reasons, disallowed by the JS engine. This leaves us with the options of either finding a way to allow JS execution from the callback, or explicitly forbidding it on the N-API side as well. This commit implements the former option, since it is the more backwards-compatible one, in the sense that the current situation sometimes appears to work as well and we should not break that behaviour if we don’t have to, but rather try to actually make it work reliably. Since GC timing is largely unobservable anyway, this commit moves the callback into a `SetImmediate()`, as we do elsewhere in the code, and a second pass callback is not an easily implemented option, as the API is supposed to wrap around Node’s `Buffer` API. In this case, exceptions are handled like other uncaught exceptions. Two tests have to be adjusted to account for the timing difference. This is unfortunate, but unavoidable if we want to conform to the JS engine API contract and keep all tests. Fixes: https://github.com/nodejs/node/issues/26754 PR-URL: https://github.com/nodejs/node/pull/28082 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: James M Snell <jasnell@gmail.com>
2019-06-05 23:29:18 +02:00
})().then(common.mustCall());