Browse Source

n-api: Sync with back-compat changes

Background: To enable N-API support for node versions back to v4, the
N-API code can also be built as an external addon. To make maintenance
easier, a single codebase needs to support both built-in and external
scenarios, along with Node versions >= 4 (and corresponding V8
versions).

This change includes several minor fixes to avoid using node
internal APIs and support older V8 versions:
  - Expand node::arraysize
  - In the CHECK_ENV() macro, return an error code instead of calling
    node::FatalError(). This is more consistent with how other invalid
    arguments to N-API functions are handled.
  - In v8impl::SetterCallbackWrapper::SetReturnValue(), do nothing
    instead of calling node::FatalError(). This is more consistent
    with JavaScript setter callbacks, where any returned value is
    silently ignored.
  - When queueing async work items, get the uv default loop instead of
    getting the loop from node::Environment::GetCurrent(). Currently
    that returns the same loop anyway. If/when node supports multiple
    environments, it should have a public API for getting the
    environment & event loop, and we can update this implementation
    then.
  - Use v8::Maybe::FromJust() instead of the newer alias ToChecked()

PR-URL: https://github.com/nodejs/node/pull/12674
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
v6
Jason Ginchereau 8 years ago
committed by Michael Dawson
parent
commit
972bfe1514
  1. 25
      src/node_api.cc

25
src/node_api.cc

@ -12,10 +12,11 @@
#include <node_object_wrap.h> #include <node_object_wrap.h>
#include <string.h> #include <string.h>
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include "uv.h"
#include "node_api.h" #include "node_api.h"
#include "env-inl.h"
static static
napi_status napi_set_last_error(napi_env env, napi_status error_code, napi_status napi_set_last_error(napi_env env, napi_status error_code,
@ -47,7 +48,7 @@ struct napi_env__ {
#define CHECK_ENV(env) \ #define CHECK_ENV(env) \
if ((env) == nullptr) { \ if ((env) == nullptr) { \
node::FatalError(__func__, "environment(env) must not be null"); \ return napi_invalid_arg; \
} }
#define CHECK_ARG(env, arg) \ #define CHECK_ARG(env, arg) \
@ -578,8 +579,7 @@ class SetterCallbackWrapper
/*virtual*/ /*virtual*/
void SetReturnValue(napi_value value) override { void SetReturnValue(napi_value value) override {
node::FatalError("napi_set_return_value", // Ignore any value returned from a setter callback.
"Cannot return a value from a setter callback.");
} }
private: private:
@ -744,7 +744,8 @@ napi_status napi_get_last_error_info(napi_env env,
CHECK_ENV(env); CHECK_ENV(env);
CHECK_ARG(env, result); CHECK_ARG(env, result);
static_assert(node::arraysize(error_messages) == napi_status_last, static_assert(
(sizeof (error_messages) / sizeof (*error_messages)) == napi_status_last,
"Count of error messages must match count of error values"); "Count of error messages must match count of error values");
assert(env->last_error.error_code < napi_status_last); assert(env->last_error.error_code < napi_status_last);
@ -1696,7 +1697,7 @@ napi_status napi_get_value_int32(napi_env env,
v8::Isolate* isolate = env->isolate; v8::Isolate* isolate = env->isolate;
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
*result = val->Int32Value(context).ToChecked(); *result = val->Int32Value(context).FromJust();
return napi_clear_last_error(env); return napi_clear_last_error(env);
} }
@ -1715,7 +1716,7 @@ napi_status napi_get_value_uint32(napi_env env,
v8::Isolate* isolate = env->isolate; v8::Isolate* isolate = env->isolate;
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
*result = val->Uint32Value(context).ToChecked(); *result = val->Uint32Value(context).FromJust();
return napi_clear_last_error(env); return napi_clear_last_error(env);
} }
@ -1740,7 +1741,7 @@ napi_status napi_get_value_int64(napi_env env,
} else { } else {
v8::Isolate* isolate = env->isolate; v8::Isolate* isolate = env->isolate;
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
*result = val->IntegerValue(context).ToChecked(); *result = val->IntegerValue(context).FromJust();
} }
return napi_clear_last_error(env); return napi_clear_last_error(env);
@ -2821,9 +2822,11 @@ napi_status napi_queue_async_work(napi_env env, napi_async_work work) {
CHECK_ENV(env); CHECK_ENV(env);
CHECK_ARG(env, work); CHECK_ARG(env, work);
// Consider: Encapsulate the uv_loop_t into an opaque pointer parameter // Consider: Encapsulate the uv_loop_t into an opaque pointer parameter.
uv_loop_t* event_loop = // Currently the environment event loop is the same as the UV default loop.
node::Environment::GetCurrent(env->isolate)->event_loop(); // Someday (if node ever supports multiple isolates), it may be better to get
// the loop from node::Environment::GetCurrent(env->isolate)->event_loop();
uv_loop_t* event_loop = uv_default_loop();
uvimpl::Work* w = reinterpret_cast<uvimpl::Work*>(work); uvimpl::Work* w = reinterpret_cast<uvimpl::Work*>(work);

Loading…
Cancel
Save