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 1 commit
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 52 additions & 8 deletions Makefile
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_async.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 node.gyp
Expand Up @@ -163,6 +163,14 @@
'src/handle_wrap.cc',
'src/js_stream.cc',
'src/node.cc',
'src/node_api.cc',
'src/node_api.h',
'src/node_api_internal.h',
'src/node_api_types.h',
'src/node_api_async.cc',
'src/node_api_async.h',
'src/node_api_async_internal.h',
'src/node_api_async_types.h',
'src/node_buffer.cc',
'src/node_config.cc',
'src/node_constants.cc',
Expand Down
42 changes: 33 additions & 9 deletions src/node.cc
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,24 @@ 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 Node.js API. This feature is "
Copy link
Member

Choose a reason for hiding this comment

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

This error message could be a bit more specific than the Node.js API, I’d say. Also, maybe display the flag name here directly?

Copy link
Member Author

Choose a reason for hiding this comment

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

Resolved by b129624

"\nexperimental and must be enabled on the command-line.",
*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 +3547,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[=yes|no] load N-API modules (default no)\n"
Copy link
Member

Choose a reason for hiding this comment

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

As the comment at the beginning of this function says:

   // XXX: If you add an option here, please also add it to doc/node.1 and
   // doc/api/cli.md

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 this would be our only option that has a [=yes|no] format (apart from configure flags, I guess). Is there a reason for that?

Copy link
Contributor

Choose a reason for hiding this comment

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

If somebody really wants to avoid loading N-API modules even after we've eventually set the default to "yes", thus rendering the use of the command line option unnecessary, they will be unable to do so unless we give them the option to say "no".

Of course, if the consensus is that we do not need to provide users with a way to explicitly disable the support for N-API modules, then the option can be reducded to --napi-modules.

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 somebody really wants to avoid loading N-API modules even after we've eventually set the default to "yes"

I'm not sure that's something that we'll need to support at that point. If N-API is successful it should become the normal way of writing native modules, so it wouldn't really make sense to disable it.

Copy link
Member

Choose a reason for hiding this comment

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

I agree. Once non-experimental we would would most likely just remove the flag. I think at this point we could just likely make it --napi-modules with no options.

Copy link
Member

Choose a reason for hiding this comment

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

I personally would prefer --napi-modules and then once it goes live we could add an optional =false or something to force-disable?

Copy link
Member Author

Choose a reason for hiding this comment

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

@Fishrock123 can you explain why you (or someone) might want to disable the feature after it is out of experimental status?

Copy link
Member

Choose a reason for hiding this comment

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

No, actually. I really do not know, but I would prefer to not have =yes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Resolved by 87c42e7

" --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 +3718,12 @@ 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, "--napi-modules=yes") == 0) {
load_napi_modules = true;
} else if (strcmp(arg, "--napi-modules=no") == 0) {
load_napi_modules = false;
} else if (strcmp(arg, "--no-warnings") == 0) {
no_process_warnings = true;
} else if (strcmp(arg, "--trace-warnings") == 0) {
Expand Down Expand Up @@ -4473,6 +4492,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