diff --git a/LICENSE b/LICENSE index 4ffd4869b2360a..f87654b61c3dbf 100644 --- a/LICENSE +++ b/LICENSE @@ -1071,23 +1071,6 @@ The externally maintained libraries used by Node.js are: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ -- node-weak, located at test/gc/node_modules/weak, is licensed as follows: - """ - Copyright (c) 2011, Ben Noordhuis - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - """ - - v8_inspector, located at deps/v8_inspector/third_party/v8_inspector, is licensed as follows: """ // Copyright 2015 The Chromium Authors. All rights reserved. diff --git a/Makefile b/Makefile index d0fdfbcef6d91a..d4548ba99d580a 100644 --- a/Makefile +++ b/Makefile @@ -133,10 +133,11 @@ test-parallel: all test-valgrind: all $(PYTHON) tools/test.py --mode=release --valgrind sequential parallel message -test/gc/node_modules/weak/build/Release/weakref.node: $(NODE_EXE) +test/gc/build/Release/binding.node: \ + $(NODE_EXE) test/gc/binding.cc test/gc/binding.gyp $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \ --python="$(PYTHON)" \ - --directory="$(shell pwd)/test/gc/node_modules/weak" \ + --directory="$(shell pwd)/test/gc" \ --nodedir="$(shell pwd)" # Implicitly depends on $(NODE_EXE), see the build-addons rule for rationale. @@ -197,12 +198,12 @@ clear-stalled: ps awwx | grep Release/node | grep -v grep | cat ps awwx | grep Release/node | grep -v grep | awk '{print $$1}' | $(XARGS) kill -test-gc: all test/gc/node_modules/weak/build/Release/weakref.node +test-gc: all test/gc/build/Release/binding.node $(PYTHON) tools/test.py --mode=release gc test-build: | all build-addons -test-all: test-build test/gc/node_modules/weak/build/Release/weakref.node +test-all: test-build test/gc/build/Release/binding.node $(PYTHON) tools/test.py --mode=debug,release test-all-valgrind: test-build @@ -737,6 +738,7 @@ CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard \ test/addons/*/*.h \ test/cctest/*.cc \ test/cctest/*.h \ + test/gc/binding.cc \ tools/icu/*.cc \ tools/icu/*.h \ )) diff --git a/test/gc/.gitignore b/test/gc/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/test/gc/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/test/gc/binding.cc b/test/gc/binding.cc new file mode 100644 index 00000000000000..197bb6a40a2988 --- /dev/null +++ b/test/gc/binding.cc @@ -0,0 +1,80 @@ +#include "node.h" +#include "uv.h" + +#include +#include + +#include + +#ifdef NDEBUG +#define CHECK(x) do { if (!(x)) abort(); } while (false) +#else +#define CHECK assert +#endif + +#define CHECK_EQ(a, b) CHECK((a) == (b)) + +namespace { + +struct Callback { + inline Callback(v8::Isolate* isolate, + v8::Local object, + v8::Local function) + : object(isolate, object), function(isolate, function) {} + + v8::Persistent object; + v8::Persistent function; +}; + +static uv_async_t async_handle; +static std::vector callbacks; + +inline void Prime() { + uv_ref(reinterpret_cast(&async_handle)); + CHECK_EQ(0, uv_async_send(&async_handle)); +} + +inline void AsyncCallback(uv_async_t*) { + auto isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handle_scope(isolate); + auto context = isolate->GetCurrentContext(); + auto global = context->Global(); + while (!callbacks.empty()) { + v8::HandleScope handle_scope(isolate); + auto callback = callbacks.back(); + callbacks.pop_back(); + auto function = v8::Local::New(isolate, callback->function); + delete callback; + if (node::MakeCallback(isolate, global, function, 0, nullptr).IsEmpty()) + return Prime(); // Have exception, flush remainder on next loop tick. + } + uv_unref(reinterpret_cast(&async_handle)); +} + +inline void OnGC(const v8::FunctionCallbackInfo& info) { + CHECK(info[0]->IsObject()); + CHECK(info[1]->IsFunction()); + auto object = info[0].As(); + auto function = info[1].As(); + auto callback = new Callback(info.GetIsolate(), object, function); + auto on_callback = [] (const v8::WeakCallbackInfo& data) { + auto callback = data.GetParameter(); + callbacks.push_back(callback); + callback->object.Reset(); + Prime(); + }; + callback->object.SetWeak(callback, on_callback, + v8::WeakCallbackType::kParameter); +} + +inline void Initialize(v8::Local exports, + v8::Local module, + v8::Local context) { + NODE_SET_METHOD(module->ToObject(context).ToLocalChecked(), "exports", OnGC); + CHECK_EQ(0, uv_async_init(uv_default_loop(), &async_handle, AsyncCallback)); + uv_unref(reinterpret_cast(&async_handle)); +} + +} // anonymous namespace + +NODE_MODULE_CONTEXT_AWARE(binding, Initialize) diff --git a/test/gc/binding.gyp b/test/gc/binding.gyp new file mode 100644 index 00000000000000..dc89633601723f --- /dev/null +++ b/test/gc/binding.gyp @@ -0,0 +1,9 @@ +{ + 'targets': [ + { + 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], + 'sources': [ 'binding.cc' ], + }, + ], +} diff --git a/test/gc/test-http-client-connaborted.js b/test/gc/test-http-client-connaborted.js index 30ec63b8852594..b0c8c1dd2f9fac 100644 --- a/test/gc/test-http-client-connaborted.js +++ b/test/gc/test-http-client-connaborted.js @@ -2,14 +2,14 @@ // just like test/gc/http-client.js, // but aborting every connection that comes in. -require('../common'); +const common = require('../common'); function serverHandler(req, res) { res.connection.destroy(); } const http = require('http'); -const weak = require('weak'); +const weak = require(`./build/${common.buildType}/binding`); const todo = 500; let done = 0; let count = 0; diff --git a/test/gc/test-http-client-onerror.js b/test/gc/test-http-client-onerror.js index aac622b3901b2e..53a98626ed28fa 100644 --- a/test/gc/test-http-client-onerror.js +++ b/test/gc/test-http-client-onerror.js @@ -2,7 +2,7 @@ // just like test/gc/http-client.js, // but with an on('error') handler that does nothing. -require('../common'); +const common = require('../common'); function serverHandler(req, res) { req.resume(); @@ -11,7 +11,7 @@ function serverHandler(req, res) { } const http = require('http'); -const weak = require('weak'); +const weak = require(`./build/${common.buildType}/binding`); const todo = 500; let done = 0; let count = 0; diff --git a/test/gc/test-http-client-timeout.js b/test/gc/test-http-client-timeout.js index 2ef54cad79bdfc..f37daacd214b04 100644 --- a/test/gc/test-http-client-timeout.js +++ b/test/gc/test-http-client-timeout.js @@ -2,7 +2,7 @@ // just like test/gc/http-client.js, // but with a timeout set -require('../common'); +const common = require('../common'); function serverHandler(req, res) { setTimeout(function() { @@ -13,7 +13,7 @@ function serverHandler(req, res) { } const http = require('http'); -const weak = require('weak'); +const weak = require(`./build/${common.buildType}/binding`); const todo = 550; let done = 0; let count = 0; diff --git a/test/gc/test-http-client.js b/test/gc/test-http-client.js index 03c159fa24f76e..5c7cab8c97bdd7 100644 --- a/test/gc/test-http-client.js +++ b/test/gc/test-http-client.js @@ -1,7 +1,7 @@ 'use strict'; // just a simple http server and client. -require('../common'); +const common = require('../common'); function serverHandler(req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); @@ -9,7 +9,7 @@ function serverHandler(req, res) { } const http = require('http'); -const weak = require('weak'); +const weak = require(`./build/${common.buildType}/binding`); const todo = 500; let done = 0; let count = 0; diff --git a/test/gc/test-net-timeout.js b/test/gc/test-net-timeout.js index ce71f4d9e8be82..ad6c29e28bad89 100644 --- a/test/gc/test-net-timeout.js +++ b/test/gc/test-net-timeout.js @@ -2,7 +2,7 @@ // just like test/gc/http-client-timeout.js, // but using a net server/client instead -require('../common'); +const common = require('../common'); function serverHandler(sock) { sock.setTimeout(120000); @@ -19,7 +19,7 @@ function serverHandler(sock) { } const net = require('net'); -const weak = require('weak'); +const weak = require(`./build/${common.buildType}/binding`); const assert = require('assert'); const todo = 500; let done = 0; diff --git a/tools/license-builder.sh b/tools/license-builder.sh index 94da24ebeb3d74..8e20df02174d73 100755 --- a/tools/license-builder.sh +++ b/tools/license-builder.sh @@ -79,8 +79,6 @@ addlicense "cpplint.py" "tools/cpplint.py" \ "$(sed -e '/^$/,$d' -e 's/^#$//' -e 's/^# //' ${rootdir}/tools/cpplint.py | tail -n +3)" addlicense "ESLint" "tools/eslint" "$(cat ${rootdir}/tools/eslint/LICENSE)" addlicense "gtest" "deps/gtest" "$(cat ${rootdir}/deps/gtest/LICENSE)" -addlicense "node-weak" "test/gc/node_modules/weak" \ - "$(cat ${rootdir}/test/gc/node_modules/weak/LICENSE)" # v8_inspector addlicense "v8_inspector" "deps/v8_inspector/third_party/v8_inspector" \ diff --git a/vcbuild.bat b/vcbuild.bat index 3cf7fe910a6f26..06d09fd792b463 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -27,7 +27,7 @@ set msi= set upload= set licensertf= set jslint= -set buildnodeweak= +set build_testgc_addon= set noetw= set noetw_msi_arg= set noperfctr= @@ -61,12 +61,12 @@ if /i "%1"=="test-ci" set test_args=%test_args% %test_ci_args% -p tap --lo if /i "%1"=="test-addons" set test_args=%test_args% addons&set build_addons=1&goto arg-ok if /i "%1"=="test-simple" set test_args=%test_args% sequential parallel -J&goto arg-ok if /i "%1"=="test-message" set test_args=%test_args% message&goto arg-ok -if /i "%1"=="test-gc" set test_args=%test_args% gc&set buildnodeweak=1&goto arg-ok +if /i "%1"=="test-gc" set test_args=%test_args% gc&set build_testgc_addon=1&goto arg-ok if /i "%1"=="test-inspector" set test_args=%test_args% inspector&goto arg-ok if /i "%1"=="test-tick-processor" set test_args=%test_args% tick-processor&goto arg-ok if /i "%1"=="test-internet" set test_args=%test_args% internet&goto arg-ok if /i "%1"=="test-pummel" set test_args=%test_args% pummel&goto arg-ok -if /i "%1"=="test-all" set test_args=%test_args% sequential parallel message gc inspector internet pummel&set buildnodeweak=1&set jslint=1&goto arg-ok +if /i "%1"=="test-all" set test_args=%test_args% sequential parallel message gc inspector internet pummel&set build_testgc_addon=1&set jslint=1&goto arg-ok if /i "%1"=="test-known-issues" set test_args=%test_args% known_issues&goto arg-ok if /i "%1"=="jslint" set jslint=1&goto arg-ok if /i "%1"=="jslint-ci" set jslint_ci=1&goto arg-ok @@ -295,15 +295,14 @@ ssh -F %SSHCONFIG% %STAGINGSERVER% "touch nodejs/%DISTTYPEDIR%/v%FULLVERSION%/no :run @rem Run tests if requested. -:build-node-weak -@rem Build node-weak if required -if "%buildnodeweak%"=="" goto build-addons -"%config%\node" deps\npm\node_modules\node-gyp\bin\node-gyp rebuild --directory="%~dp0test\gc\node_modules\weak" --nodedir="%~dp0." -if errorlevel 1 goto build-node-weak-failed +@rem Build test/gc add-on if required. +if "%build_testgc_addon%"=="" goto build-addons +"%config%\node" deps\npm\node_modules\node-gyp\bin\node-gyp rebuild --directory="%~dp0test\gc" --nodedir="%~dp0." +if errorlevel 1 goto build-testgc-addon-failed goto build-addons -:build-node-weak-failed -echo Failed to build node-weak. +:build-testgc-addon-failed +echo Failed to build test/gc add-on." goto exit :build-addons