Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module: add support for abi stable module API #11975

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
43ab5a8
module: add support for abi stable module API
jasongin Mar 20, 2017
a5d43d1
Fix undefined snprintf use for older compiler
jasongin Mar 22, 2017
87c42e7
all: update --napi-modules flag to not have a yes/no
Mar 22, 2017
876e6c8
doc: mention experimental status of --napi-modules flag
Mar 22, 2017
b129624
src: improve message regarding N-API experimental status
Mar 22, 2017
66944b8
test: convert most addons-napi tests to C
Mar 22, 2017
9e3ab83
Use size_t where appropriate (#181)
jasongin Mar 22, 2017
fb8ced4
Convert all locals and parameter names to snake_case (#193)
boingoing Mar 23, 2017
116bd19
Address some minor PR feedback (#187)
jasongin Mar 23, 2017
1b2f2db
Add tests for type casts and coercions (#194)
jasongin Mar 23, 2017
1427b33
napi: change napi_instanceof() to use Symbol.hasInstance
Mar 22, 2017
6b4ce53
Add some type checking (#195)
jasongin Mar 23, 2017
f21ab80
Updates for review feedback (#199)
jasongin Mar 25, 2017
e1ca374
Address PR feedback (#201)
jasongin Mar 27, 2017
9c0b151
Updates for review feedback (#203)
jasongin Mar 28, 2017
375af79
Refcount for v8impl::Reference should be unsigned (#207)
boingoing Mar 28, 2017
20b6cf2
Check value is external in napi_unwrap (#210)
jasongin Mar 29, 2017
7a339c0
Remove the async API sources (#212)
boingoing Mar 29, 2017
232f004
napi: add napi_env to napi_get_last_error_info() (#211)
Mar 29, 2017
aa22a2a
Add the _array suffix to the TypedArray type enum (#213)
boingoing Mar 30, 2017
0e61d00
Fix jslint issue in addons-napi test
jasongin Mar 30, 2017
c87eade
Remove NAPI_EXTERN from napi_addon_register_func
jasongin Mar 31, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 52 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,10 @@ v8:

test: all
$(MAKE) build-addons
$(MAKE) build-addons-napi
$(MAKE) cctest
$(PYTHON) tools/test.py --mode=release -J \
addons doctool inspector known_issues message pseudo-tty parallel sequential
addons addons-napi doctool inspector known_issues message pseudo-tty parallel sequential
$(MAKE) lint

test-parallel: all
Expand Down Expand Up @@ -262,6 +263,41 @@ test/addons/.buildstamp: config.gypi \
# TODO(bnoordhuis) Force rebuild after gyp update.
build-addons: $(NODE_EXE) test/addons/.buildstamp

ADDONS_NAPI_BINDING_GYPS := \
$(filter-out test/addons-napi/??_*/binding.gyp, \
$(wildcard test/addons-napi/*/binding.gyp))

ADDONS_NAPI_BINDING_SOURCES := \
$(filter-out test/addons-napi/??_*/*.cc, $(wildcard test/addons-napi/*/*.cc)) \
$(filter-out test/addons-napi/??_*/*.h, $(wildcard test/addons-napi/*/*.h))

# Implicitly depends on $(NODE_EXE), see the build-addons-napi rule for rationale.
test/addons-napi/.buildstamp: config.gypi \
deps/npm/node_modules/node-gyp/package.json \
$(ADDONS_NAPI_BINDING_GYPS) $(ADDONS_NAPI_BINDING_SOURCES) \
deps/uv/include/*.h deps/v8/include/*.h \
src/node.h src/node_buffer.h src/node_object_wrap.h src/node_version.h \
src/node_api.h src/node_api_types.h
# Cannot use $(wildcard test/addons-napi/*/) here, it's evaluated before
# embedded addons have been generated from the documentation.
@for dirname in test/addons-napi/*/; do \
printf "\nBuilding addon $$PWD/$$dirname\n" ; \
env MAKEFLAGS="-j1" $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp \
--loglevel=$(LOGLEVEL) rebuild \
--python="$(PYTHON)" \
--directory="$$PWD/$$dirname" \
--nodedir="$$PWD" || exit 1 ; \
done
touch $@

# .buildstamp and .docbuildstamp need $(NODE_EXE) but cannot depend on it
# directly because it calls make recursively. The parent make cannot know
# if the subprocess touched anything so it pessimistically assumes that
# .buildstamp and .docbuildstamp are out of date and need a rebuild.
# Just goes to show that recursive make really is harmful...
# TODO(bnoordhuis) Force rebuild after gyp or node-gyp update.
build-addons-napi: $(NODE_EXE) test/addons-napi/.buildstamp

ifeq ($(OSTYPE),$(filter $(OSTYPE),darwin aix))
XARGS = xargs
else
Expand All @@ -274,20 +310,22 @@ clear-stalled:
test-gc: all test/gc/build/Release/binding.node
$(PYTHON) tools/test.py --mode=release gc

test-build: | all build-addons
test-build: | all build-addons build-addons-napi

test-build-addons-napi: all build-addons-napi

test-all: test-build test/gc/build/Release/binding.node
$(PYTHON) tools/test.py --mode=debug,release

test-all-valgrind: test-build
$(PYTHON) tools/test.py --mode=debug,release --valgrind

CI_NATIVE_SUITES := addons
CI_NATIVE_SUITES := addons addons-napi
CI_JS_SUITES := doctool inspector known_issues message parallel pseudo-tty sequential

# Build and test addons without building anything else
test-ci-native: LOGLEVEL := info
test-ci-native: | test/addons/.buildstamp
test-ci-native: | test/addons/.buildstamp test/addons-napi/.buildstamp
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
--mode=release --flaky-tests=$(FLAKY_TESTS) \
$(TEST_CI_ARGS) $(CI_NATIVE_SUITES)
Expand All @@ -304,11 +342,11 @@ test-ci-js: | clear-stalled
fi

test-ci: LOGLEVEL := info
test-ci: | clear-stalled build-addons
test-ci: | clear-stalled build-addons build-addons-napi
out/Release/cctest --gtest_output=tap:cctest.tap
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
--mode=release --flaky-tests=$(FLAKY_TESTS) \
$(TEST_CI_ARGS) $(CI_NATIVE_SUITES) $(CI_JS_SUITES)
$(TEST_CI_ARGS) $(CI_NATIVE_SUITES) addons-napi $(CI_JS_SUITES)
# Clean up any leftover processes
PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \
if [ "$${PS_OUT}" ]; then \
Expand Down Expand Up @@ -355,7 +393,10 @@ test-npm: $(NODE_EXE)
test-npm-publish: $(NODE_EXE)
npm_package_config_publishtest=true $(NODE) deps/npm/test/run.js

test-addons: test-build
test-addons-napi: test-build-addons-napi
$(PYTHON) tools/test.py --mode=release addons-napi

test-addons: test-build test-addons-napi
$(PYTHON) tools/test.py --mode=release addons

test-addons-clean:
Expand Down Expand Up @@ -821,6 +862,7 @@ CPPLINT_EXCLUDE += src/node_root_certs.h
CPPLINT_EXCLUDE += src/queue.h
CPPLINT_EXCLUDE += src/tree.h
CPPLINT_EXCLUDE += $(wildcard test/addons/??_*/*.cc test/addons/??_*/*.h)
CPPLINT_EXCLUDE += $(wildcard test/addons-napi/??_*/*.cc test/addons-napi/??_*/*.h)

CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard \
src/*.c \
Expand All @@ -830,6 +872,8 @@ CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard \
test/addons/*/*.h \
test/cctest/*.cc \
test/cctest/*.h \
test/addons-napi/*/*.cc \
test/addons-napi/*/*.h \
test/gc/binding.cc \
tools/icu/*.cc \
tools/icu/*.h \
Expand Down Expand Up @@ -869,4 +913,4 @@ endif
test-v8-intl test-v8-benchmarks test-v8-all v8 lint-ci bench-ci jslint-ci \
doc-only $(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci \
clear-stalled coverage-clean coverage-build coverage-test coverage \
list-gtests
list-gtests test-addons-napi build-addons-napi
8 changes: 8 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ added: v6.0.0

Silence all process warnings (including deprecations).

### `--napi-modules`
<!-- YAML
added: REPLACEME
-->

Enable loading native modules compiled with the ABI-stable Node.js API (N-API)
(experimental).

### `--trace-warnings`
<!-- YAML
added: v6.0.0
Expand Down
5 changes: 5 additions & 0 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ Throw errors for deprecations.
.BR \-\-no\-warnings
Silence all process warnings (including deprecations).

.TP
.BR \-\-napi\-modules
Enable loading native modules compiled with the ABI-stable Node.js API (N-API)
(experimental).

.TP
.BR \-\-trace\-warnings
Print stack traces for process warnings (including deprecations).
Expand Down
3 changes: 3 additions & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@
'src/handle_wrap.cc',
'src/js_stream.cc',
'src/node.cc',
'src/node_api.cc',
'src/node_api.h',
'src/node_api_types.h',
'src/node_buffer.cc',
'src/node_config.cc',
'src/node_constants.cc',
Expand Down
39 changes: 30 additions & 9 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ static const char* trace_enabled_categories = nullptr;
std::string icu_data_dir; // NOLINT(runtime/string)
#endif

// N-API is in experimental state, disabled by default.
bool load_napi_modules = false;

// used by C++ modules as well
bool no_deprecation = false;

Expand Down Expand Up @@ -2463,15 +2466,25 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
}
if (mp->nm_version != NODE_MODULE_VERSION) {
char errmsg[1024];
snprintf(errmsg,
sizeof(errmsg),
"The module '%s'"
"\nwas compiled against a different Node.js version using"
"\nNODE_MODULE_VERSION %d. This version of Node.js requires"
"\nNODE_MODULE_VERSION %d. Please try re-compiling or "
"re-installing\nthe module (for instance, using `npm rebuild` or "
"`npm install`).",
*filename, mp->nm_version, NODE_MODULE_VERSION);
if (mp->nm_version == -1) {
snprintf(errmsg,
sizeof(errmsg),
"The module '%s'"
"\nwas compiled against the ABI-stable Node.js API (N-API)."
"\nThis feature is experimental and must be enabled on the "
"\ncommand-line by adding --napi-modules.",
*filename);
} else {
snprintf(errmsg,
sizeof(errmsg),
"The module '%s'"
"\nwas compiled against a different Node.js version using"
"\nNODE_MODULE_VERSION %d. This version of Node.js requires"
"\nNODE_MODULE_VERSION %d. Please try re-compiling or "
"re-installing\nthe module (for instance, using `npm rebuild` "
"or `npm install`).",
*filename, mp->nm_version, NODE_MODULE_VERSION);
}

// NOTE: `mp` is allocated inside of the shared library's memory, calling
// `uv_dlclose` will deallocate it
Expand Down Expand Up @@ -3535,6 +3548,7 @@ static void PrintHelp() {
" --trace-deprecation show stack traces on deprecations\n"
" --throw-deprecation throw an exception on deprecations\n"
" --no-warnings silence all process warnings\n"
" --napi-modules load N-API modules\n"
" --trace-warnings show stack traces on process warnings\n"
" --redirect-warnings=path\n"
" write warnings to path instead of\n"
Expand Down Expand Up @@ -3705,6 +3719,8 @@ static void ParseArgs(int* argc,
force_repl = true;
} else if (strcmp(arg, "--no-deprecation") == 0) {
no_deprecation = true;
} else if (strcmp(arg, "--napi-modules") == 0) {
load_napi_modules = true;
} else if (strcmp(arg, "--no-warnings") == 0) {
no_process_warnings = true;
} else if (strcmp(arg, "--trace-warnings") == 0) {
Expand Down Expand Up @@ -4473,6 +4489,11 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
if (debug_enabled)
EnableDebug(&env);

if (load_napi_modules) {
ProcessEmitWarning(&env, "N-API is an experimental feature "
"and could change at any time.");
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not a fan of printing warnings like these… if the user opted into the feature, then they opted in because they know what they were asking for.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CTC has specifically requested command-line enablement along with a warning message for features with experimental status. Tracing does the same thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a link somewhere to that decision?

I don't quite understand the justification for a printed warning for a feature that can't even be used without a flag. If you're using the flag, you wanted the feature and are quite aware that it is experimental. Do any V8 features do this?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VM Summit 3 meeting notes has this
For 8.0, include an opt-in runtime flag, show experimental warning when a NAPI module is loaded.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If consensus is that documentation of experimental status is sufficient and this warning message is not necessary, we can take it out. I don't recall anyone feeling very strongly about this at the VM summit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasongin I’d say take it out, and we can re-visit that in the unlikely case anybody complains.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the main motivation was to ensure that anybody turning it on is fully aware of the status and to be consistent with what we have done for other experimental features.

{
SealHandleScope seal(isolate);
bool more;
Expand Down
Loading