Make `Environment::GetCurrent()` return `nullptr` if the current
`Context` is not a Node.js context, and for the relevant usage of
this function, either:
- Switch to the better `GetCurrent(args)` variant
- Turn functions in to no-ops where it makes sense
- Make it a `CHECK`, i.e. an API requirement, where it make sense
- Leave a `TODO` comment for verifying what, if anything, is to be done
PR-URL: https://github.com/nodejs/node/pull/22819
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Add `napi_add_finalizer()`, which provides the ability to attach data
to an arbitrary object and be notified when that object is garbage-
collected so as to have an opportunity to delete the data previously
attached.
This differs from `napi_wrap()` in that it does not use up the private
slot on the object, and is therefore neither removable, nor retrievable
after the call to `napi_add_finalizer()`. It is assumed that the data
is accessible by other means, yet it must be tied to the lifetime of
the object. This is the case for data passed to a dynamically created
function which is itself heap-allocated and must therefore be freed
along with the function.
Fixes: https://github.com/nodejs/abi-stable-node/issues/313
PR-URL: https://github.com/nodejs/node/pull/22244
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Bundle a `uv_async_t`, a `uv_idle_t`, a `uv_mutex_t`, a `uv_cond_t`,
and a `v8::Persistent<v8::Function>` to make it possible to call into JS
from another thread. The API accepts a void data pointer and a callback
which will be invoked on the loop thread and which will receive the
`napi_value` representing the JavaScript function to call so as to
perform the call into JS. The callback is run inside a
`node::CallbackScope`.
A `std::queue<void*>` is used to store calls from the secondary
threads, and an idle loop is started by the `uv_async_t` callback on the
loop thread to drain the queue, calling into JS with each item.
Items can be added to the queue blockingly or non-blockingly.
The thread-safe function can be referenced or unreferenced, with the
same semantics as libuv handles.
Re: https://github.com/nodejs/help/issues/1035
Re: https://github.com/nodejs/node/issues/20964
Fixes: https://github.com/nodejs/node/issues/13512
PR-URL: https://github.com/nodejs/node/pull/17887
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Added a new struct CallbackBundle to eliminate all
GetInternalField() calls.
The principle is to store all required data inside a C++ struct,
and then store the pointer in the JavaScript object. Before this
change, the required data are stored in the JavaScript object in
3 or 4 seperate pointers. For every napi fun call, 3 of them
have to be fetched out, which are 3 GetInternalField() calls;
after this change, the C++ struct will be directly fetched out
by using v8::External::Value(), which is faster.
Profiling data show that GetInternalField() is slow.
On an i7-4770K (3.50GHz) box, a C++ V8-binding fun call is 8 ns,
before this change, napi fun call is 36 ns; after this change,
napi fun call is 20 ns.
The above data are measured using a modified benchmark in
'benchmark/misc/function_call'. The modification adds an indicator
of the average time of a "chatty" napi fun call (max 50M runs).
This change will speed up chatty case 1.8x (overall), and will cut
down the delay of napi mechanism to approx. 0.5x.
Background: a simple C++ binding function (e.g. receiving little
from JS, doing little and returning little to JS) is called
'chatty' case for JS<-->C++ fun call routine.
This improvement also applies to getter/setter fun calls.
PR-URL: https://github.com/nodejs/node/pull/21072
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
Currently the following warnings are displayed when compiling:
../src/node_api.cc:3380:8:
warning: 'AfterThreadPoolWork' overrides a member function but is not
marked 'override' [-Winconsistent-missing-override]
void AfterThreadPoolWork(int status) {
^
../src/node_internals.h:513:16: note: overridden virtual function is
here
virtual void AfterThreadPoolWork(int status) = 0;
^
1 warning generated.
../src/node_zlib.cc:220:8:
warning: 'DoThreadPoolWork' overrides a member function but is not
marked 'override' [-Winconsistent-missing-override]
void DoThreadPoolWork() {
^
../src/node_internals.h:512:16: note: overridden virtual function is
here
virtual void DoThreadPoolWork() = 0;
^
../src/node_zlib.cc:224:8:
warning: 'AfterThreadPoolWork' overrides a member function but is
not marked 'override' [-Winconsistent-missing-override]
void AfterThreadPoolWork(int status) {
^
../src/node_internals.h:513:16: note: overridden virtual function is
here
virtual void AfterThreadPoolWork(int status) = 0;
^
2 warnings generated.
This commit adds override to the functions.
PR-URL: https://github.com/nodejs/node/pull/20663
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Instead of using the libuv mechanism directly, provide an internal
`ThreadPoolWork` wrapper that takes care of increasing/decreasing
the waiting request counter.
PR-URL: https://github.com/nodejs/node/pull/19377
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
This adds pairs of methods to the `Environment` class and to public APIs
which can add and remove cleanup handlers.
Unlike `AtExit`, this API targets addon developers rather than
embedders, giving them (and Node’s internals) the ability to register
per-`Environment` cleanup work.
We may want to replace `AtExit` with this API at some point.
Many thanks for Stephen Belanger for reviewing the original version of
this commit in the Ayo.js project.
Refs: https://github.com/ayojs/ayo/pull/82
PR-URL: https://github.com/nodejs/node/pull/19377
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Whenever we call into an addon, whether it is for a callback, for
module init, or for async work-related reasons, we should make sure
that
* the last error is cleared,
* the scopes before the call are the same as after, and
* if an exception was thrown and captured inside the module, then it is
re-thrown after the call.
Therefore we should call into the module in a unified fashion. This
change introduces the macro NAPI_CALL_INTO_MODULE() which should be
used whenever invoking a callback provided by the module.
Fixes: https://github.com/nodejs/node/issues/19437
PR-URL: https://github.com/nodejs/node/pull/19537
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Replace v8::Persistent with node::Persistent, a specialization that
resets the persistent handle on destruction. Prevents accidental
resource leaks when forgetting to call .Reset() manually.
I'm fairly confident this commit fixes a number of resource leaks that
have gone undiagnosed so far.
PR-URL: https://github.com/nodejs/node/pull/18656
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
According to the ECMA spec, we should throw a RangeError in the
following cases:
- `(length * elementSize) + offset` > the size of the array passed in
- `offset % elementSize` != `0`
In the current implementation, this check was omitted. So, the following
code will cause a crash.
```
napi_create_typedarray(env, napi_uint16_array, 2 /* length */,
buffer, 1 /* byte_offset */, &output_array);
```
This change fixes the problem and write some related tests.
Refs:
https://tc39.github.io/ecma262/#sec-typedarray-buffer-byteoffset-length
PR-URL: https://github.com/nodejs/node/pull/18037
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Add a utility functions for addons to use when they need
a reference to the current event loop.
While the libuv API is not directly part of N-API, it
provides a quite stable C API as well, and is tightly
integrated with Node itself.
As a particular use case, without access to the event loop
it is hard to do something interesting from inside a N-API
finalizer function, since calls into JS and therefore virtually
all other N-API functions are not allowed.
PR-URL: https://github.com/nodejs/node/pull/17109
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
* namespaced functions such as v8impl::JsHandleScopeFromV8HandleScope
become part of Node's public symbols unless they are declared static.
* the class uvimpl::Work needs to be enclosed in an anonymous namespace
else it, too becomes part of Node's public symbols.
* remove references to EXTERNAL_NAPI.
PR-URL: https://github.com/nodejs/node/pull/16234
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
These changes are necessary in order to retain source compatibility
with older versions of node.
The removal of `module_version` from `napi_module_register()` is
reverted from the flag removal PR, because it should not have been a
part of it.
`CallbackWrapper::NewTarget()` is renamed to
`CallbackWrapper::GetNewTarget()` to distinguish it from V8's native
method, thus allowing for a macro which reduces `NewTarget()` to
`This()` on V8 versions where it was not yet available.
`AsyncResource` is constructed with a C string rather than a V8 string
because the former is available on all versions of node.
PR-URL: https://github.com/nodejs/node/pull/16102
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jason Ginchereau <jasongin@microsoft.com>
n-api uses size_t for the size of strings when specifying
string lengths. V8 only supports a size of int. Add
a check so that an error will be returned if the user
passes in a string with a size larger than will fit into
an int.
PR-URL: https://github.com/nodejs/node/pull/15611
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>