From cb68dc4a3a8a267564ada0486ebf4454d4910d62 Mon Sep 17 00:00:00 2001 From: Roger Date: Wed, 18 Mar 2015 08:57:44 +0800 Subject: [PATCH 01/34] chromium-integration run nw as node decouple node dll add g_dom_context --- config.gypi | 38 +++ deps/cares/cares.gyp | 4 + deps/cares/src/ares_create_query.c | 9 + deps/cares/src/ares_process.c | 2 +- deps/http_parser/http_parser.c | 2 +- deps/http_parser/http_parser.gyp | 13 +- deps/openssl/openssl.gyp | 12 +- deps/openssl/openssl/ssl/d1_srvr.c | 1 + deps/openssl/openssl/ssl/s3_srvr.c | 1 + deps/uv/include/uv.h | 9 + deps/uv/src/unix/fs.c | 4 + deps/uv/src/unix/getaddrinfo.c | 2 +- deps/uv/src/win/async.c | 18 ++ deps/uv/src/win/core.c | 5 +- deps/uv/uv.gyp | 12 +- lib/internal/bootstrap_node.js | 11 + lib/module.js | 5 + node.gyp | 104 +++++-- src/node.cc | 445 ++++++++++++++++++++++++++++- src/node.h | 16 +- src/node_buffer.cc | 13 +- src/node_crypto.cc | 12 +- src/node_internals.h | 1 + src/node_webkit.h | 95 ++++++ 24 files changed, 765 insertions(+), 69 deletions(-) create mode 100644 config.gypi create mode 100644 src/node_webkit.h diff --git a/config.gypi b/config.gypi new file mode 100644 index 00000000000..64063131cc7 --- /dev/null +++ b/config.gypi @@ -0,0 +1,38 @@ +# Do not edit. Generated by the configure script. +{ 'target_defaults': { 'cflags': [], + 'default_configuration': 'Release', + 'defines': ['OPENSSL_NO_SSL2=1'], + 'include_dirs': [], + 'libraries': []}, + 'variables': { 'clang': 1, + 'gcc_version': 49, + 'host_arch': 'x64', + 'icu_small': 'false', + 'node_install_npm': 'true', + 'node_prefix': '', + 'node_shared_http_parser': 'false', + 'node_shared_libuv': 'false', + 'node_shared_openssl': 'false', + 'node_shared_v8': 'false', + 'node_shared_zlib': 'false', + 'node_tag': '', + 'node_release_urlbase': '', + 'node_byteorder': 'little', + 'node_use_dtrace': 'false', + 'node_use_etw': 'false', + 'node_use_mdb': 'false', + 'node_use_openssl': 'true', + 'node_use_perfctr': 'false', + 'openssl_no_asm': 0, + 'python': '/usr/bin/python', + 'target_arch': 'x64', + 'uv_library': 'static_library', + 'uv_parent_path': '/deps/uv/', + 'uv_use_dtrace': 'false', + 'v8_enable_gdbjit': 0, + 'v8_enable_i18n_support': 0, + 'v8_no_strict_aliasing': 1, + 'v8_optimized_debug': 0, + 'v8_random_seed': 0, + 'v8_use_snapshot': 'true', + 'want_separate_host_toolset': 0}} diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp index 158cef39b51..3f37437e037 100644 --- a/deps/cares/cares.gyp +++ b/deps/cares/cares.gyp @@ -1,4 +1,7 @@ { + 'variables': { + 'library%': 'static_library', + }, 'target_defaults': { 'conditions': [ ['OS!="win"', { @@ -112,6 +115,7 @@ }], [ 'OS=="win"', { 'include_dirs': [ 'config/win32' ], + 'msvs_disabled_warnings': [4133], 'sources': [ 'src/config-win32.h', 'src/windows_port.c', diff --git a/deps/cares/src/ares_create_query.c b/deps/cares/src/ares_create_query.c index a34dda7de6d..a186194521f 100644 --- a/deps/cares/src/ares_create_query.c +++ b/deps/cares/src/ares_create_query.c @@ -16,6 +16,11 @@ #include "ares_setup.h" +#ifndef _WIN32 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warray-bounds" +#endif + #ifdef HAVE_NETINET_IN_H # include #endif @@ -206,3 +211,7 @@ int ares_create_query(const char *name, int dnsclass, int type, return ARES_SUCCESS; } + +#ifndef _WIN32 +#pragma clang diagnostic pop +#endif diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c index 0325f5191d8..8cab077556a 100644 --- a/deps/cares/src/ares_process.c +++ b/deps/cares/src/ares_process.c @@ -460,7 +460,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, else fromlen = sizeof(from.sa6); count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, - sizeof(buf), 0, &from.sa, &fromlen); + sizeof(buf), 0, &from.sa, (socklen_t *)&fromlen); #else count = sread(server->udp_socket, buf, sizeof(buf)); #endif diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c index 719617549d0..7562a0217b9 100644 --- a/deps/http_parser/http_parser.c +++ b/deps/http_parser/http_parser.c @@ -2391,7 +2391,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, break; default: - assert(!"Unexpected state"); + assert(!(int)"Unexpected state"); return 1; } diff --git a/deps/http_parser/http_parser.gyp b/deps/http_parser/http_parser.gyp index ef34ecaeaea..93d3259e38f 100644 --- a/deps/http_parser/http_parser.gyp +++ b/deps/http_parser/http_parser.gyp @@ -13,20 +13,10 @@ 'Debug': { 'defines': [ 'DEBUG', '_DEBUG' ], 'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'RuntimeLibrary': 1, # static debug - }, - }, }, 'Release': { 'defines': [ 'NDEBUG' ], 'cflags': [ '-Wall', '-Wextra', '-O3' ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'RuntimeLibrary': 0, # static release - }, - }, } }, 'msvs_settings': { @@ -39,6 +29,9 @@ }, }, 'conditions': [ + ['clang==1', { + 'cflags': ['-Wno-error=string-conversion'], + }], ['OS == "win"', { 'defines': [ 'WIN32' diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index ae5c980e06a..d3db5bc6697 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -4,18 +4,22 @@ { 'variables': { - 'is_clang': 0, + 'is_clang': 1, 'gcc_version': 0, 'openssl_no_asm%': 0, 'llvm_version%': 0, 'xcode_version%': 0, 'gas_version%': 0, - 'openssl_fips%': 'false', + 'openssl_fips%': '', + 'node_byteorder%': 'little', + 'conditions': [ + ['OS=="mac"', { 'openssl_no_asm%': 1 } ], + ], }, 'targets': [ { 'target_name': 'openssl', - 'type': '<(library)', + 'type': 'static_library', 'includes': ['openssl.gypi'], 'sources': ['<@(openssl_sources)'], 'sources/': [ @@ -167,7 +171,7 @@ ] }], ['is_clang==1 or gcc_version>=43', { - 'cflags': ['-Wno-old-style-declaration'], + 'cflags': ['-Wno-error=unused-command-line-argument', '-Wno-error=parentheses-equality'], }], ['OS=="solaris"', { 'defines': ['__EXTENSIONS__'], diff --git a/deps/openssl/openssl/ssl/d1_srvr.c b/deps/openssl/openssl/ssl/d1_srvr.c index e677d880f0a..325dd7fe8cd 100644 --- a/deps/openssl/openssl/ssl/d1_srvr.c +++ b/deps/openssl/openssl/ssl/d1_srvr.c @@ -126,6 +126,7 @@ # include #endif + static const SSL_METHOD *dtls1_get_server_method(int ver); static int dtls1_send_hello_verify_request(SSL *s); diff --git a/deps/openssl/openssl/ssl/s3_srvr.c b/deps/openssl/openssl/ssl/s3_srvr.c index ab28702ee97..ab28936a641 100644 --- a/deps/openssl/openssl/ssl/s3_srvr.c +++ b/deps/openssl/openssl/ssl/s3_srvr.c @@ -170,6 +170,7 @@ #endif #include + #ifndef OPENSSL_NO_SSL3_METHOD static const SSL_METHOD *ssl3_get_server_method(int ver); diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index baa0b28124b..2bb9a87619f 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -28,6 +28,8 @@ extern "C" { #endif #ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable: 4201) /* Windows - set up dll import/export decorators. */ # if defined(BUILDING_UV_SHARED) /* Building shared library. */ @@ -766,6 +768,9 @@ UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async, uv_async_cb async_cb); UV_EXTERN int uv_async_send(uv_async_t* async); +#ifdef _WIN32 +UV_EXTERN int uv_async_send_nw(uv_async_t* async); +#endif /* @@ -1489,6 +1494,10 @@ struct uv_loop_s { #undef UV_LOOP_PRIVATE_FIELDS #undef UV_LOOP_PRIVATE_PLATFORM_FIELDS +#ifdef _WIN32 +#pragma warning(pop) +#endif + #ifdef __cplusplus } #endif diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 085970a06d9..f5a02d03c30 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -46,6 +46,9 @@ #include #include +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warray-bounds" + #if defined(__DragonFly__) || \ defined(__FreeBSD__) || \ defined(__OpenBSD__) || \ @@ -1322,3 +1325,4 @@ void uv_fs_req_cleanup(uv_fs_t* req) { uv__free(req->ptr); req->ptr = NULL; } +#pragma clang diagnostic pop diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c index 2049aea2f38..66be10b5b59 100644 --- a/deps/uv/src/unix/getaddrinfo.c +++ b/deps/uv/src/unix/getaddrinfo.c @@ -88,7 +88,7 @@ int uv__getaddrinfo_translate_error(int sys_err) { case EAI_SYSTEM: return -errno; #endif } - assert(!"unknown EAI_* error code"); + assert(!(int)("unknown EAI_* error code")); abort(); return 0; /* Pacify compiler. */ } diff --git a/deps/uv/src/win/async.c b/deps/uv/src/win/async.c index ad240ab8972..11cce85512f 100644 --- a/deps/uv/src/win/async.c +++ b/deps/uv/src/win/async.c @@ -84,6 +84,24 @@ int uv_async_send(uv_async_t* handle) { } +int uv_async_send_nw(uv_async_t* handle) { + uv_loop_t* loop = handle->loop; + + if (handle->type != UV_ASYNC) { + /* Can't set errno because that's not thread-safe. */ + return -1; + } + + /* The user should make sure never to call uv_async_send to a closing */ + /* or closed handle. */ + assert(!(handle->flags & UV__HANDLE_CLOSING)); + + POST_COMPLETION_FOR_REQ(loop, &handle->async_req); + + return 0; +} + + void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, uv_req_t* req) { assert(handle->type == UV_ASYNC); diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index ba306ebc083..def23a2a544 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -98,7 +98,7 @@ static void uv_init(void) { * FDs even though they return the proper error code in the release build. */ #if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) - _CrtSetReportHook(uv__crt_dbg_report_handler); + //_CrtSetReportHook(uv__crt_dbg_report_handler); #endif /* Fetch winapi function pointers. This must be done first because other @@ -374,10 +374,11 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { int r; int ran_pending; void (*poll)(uv_loop_t* loop, DWORD timeout); - +#if 1 if (pGetQueuedCompletionStatusEx) poll = &uv_poll_ex; else +#endif poll = &uv_poll; r = uv__loop_alive(loop); diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 2fdd59ac784..38152218098 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -1,4 +1,7 @@ { + 'variables': { + 'uv_library%': 'static_library', + }, 'target_defaults': { 'conditions': [ ['OS != "win"', { @@ -18,9 +21,10 @@ ], 'xcode_settings': { 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden - 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' ], + 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' , '-Wno-error=gnu-folding-constant'], 'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ], - } + }, + 'msvs_disabled_warnings': [4267], }, 'targets': [ @@ -31,6 +35,7 @@ 'include', 'src/', ], + 'defines': [ 'BUILDING_UV_SHARED=1' ], 'direct_dependent_settings': { 'include_dirs': [ 'include' ], 'conditions': [ @@ -126,6 +131,7 @@ '-Wall', '-Wextra', '-Wno-unused-parameter', + '-Wno-varargs', ], 'sources': [ 'include/uv-unix.h', @@ -271,7 +277,7 @@ [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', { 'sources': [ 'src/unix/kqueue.c' ], }], - ['uv_library=="shared_library"', { + ['component=="shared_library"', { 'defines': [ 'BUILDING_UV_SHARED=1' ] }], ] diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 140816aac08..c42d4737db6 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -41,7 +41,10 @@ setupGlobalVariables(); if (!process._noBrowserGlobals) { setupGlobalTimeouts(); + if (process.__nwjs) { + }else{ setupGlobalConsole(); + } } const _process = NativeModule.require('internal/process'); @@ -69,6 +72,14 @@ }); process.argv[0] = process.execPath; + if (process.__nwjs) { + var Module = NativeModule.require('module'); + var module = new Module('.', null); + global.process.mainModule = module; + module._compile('global.module = module;\n' + + 'global.require = global.__nw_require = require;\n', 'nw-emulate-node'); + return; + } // There are various modes that Node can run in. The most common two // are running from a script and running the REPL - but there are a few // others like the debugger or running --eval arguments. Here we decide diff --git a/lib/module.js b/lib/module.js index fe9700f7a67..ef17aa5a21f 100644 --- a/lib/module.js +++ b/lib/module.js @@ -417,6 +417,11 @@ Module._load = function(request, parent, isMain) { if (isMain) { process.mainModule = module; module.id = '.'; + if (process.__nwjs) { + // require() in DOM needs this module as parent + module._compile('global.module = module;\n' + + 'global.require = require;\n', 'nw-emulate-node'); + } } Module._cache[filename] = module; diff --git a/node.gyp b/node.gyp index 634ba972b57..360766ed52a 100644 --- a/node.gyp +++ b/node.gyp @@ -16,9 +16,18 @@ 'node_shared_libuv%': 'false', 'node_use_openssl%': 'true', 'node_shared_openssl%': 'false', + 'openssl_fips%': '', 'node_v8_options%': '', 'node_enable_v8_vtunejit%': 'false', 'node_core_target_name%': 'node', + 'node_target_type%': 'shared_library', + 'node_tag%': '', + 'node_release_urlbase%': '', + 'node_byteorder%': 'little', + 'python%': 'python', + 'icu_small%': 'false', + 'v8_postmortem_support%' : 'false', + 'V8_BASE%': '<(PRODUCT_DIR)/obj/v8/tools/gyp/libv8_base.a', 'library_files': [ 'lib/internal/bootstrap_node.js', 'lib/_debug_agent.js', @@ -119,22 +128,51 @@ ], }, + 'includes': [ + '../../build/util/version.gypi', + ], + 'targets': [ { 'target_name': '<(node_core_target_name)', 'type': '<(node_target_type)', - 'dependencies': [ 'node_js2c#host', + #'../../v8/tools/gyp/v8.gyp:v8', + '../../v8/src/v8.gyp:v8_libplatform', + '../../chrome/chrome.gyp:chrome_dll', ], + 'msvs_disabled_warnings': [4146, 4267], + + 'xcode_settings': { + 'WARNING_CFLAGS': [ '-Wno-error=deprecated-declarations' ], + 'LD_RUNPATH_SEARCH_PATHS': [ '@loader_path/../../../../../../..', ], + }, + 'include_dirs': [ 'src', + 'deps/openssl/openssl/include', + #'../boringssl/src/include', 'tools/msvs/genfiles', 'deps/uv/src/ares', '<(SHARED_INTERMEDIATE_DIR)', # for node_natives.h + '../../v8', # include/v8_platform.h + '../../v8/include' ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../../v8/include', + 'deps/uv/include', + 'deps/cares/include', + ], + 'defines': [ + 'BUILDING_NW_NODE=1', + ], + + }, + 'sources': [ 'src/debug-agent.cc', 'src/async-wrap.cc', @@ -216,8 +254,8 @@ 'src/util.cc', 'src/string_search.cc', 'deps/http_parser/http_parser.h', - 'deps/v8/include/v8.h', - 'deps/v8/include/v8-debug.h', + #'deps/v8/include/v8.h', + #'deps/v8/include/v8-debug.h', '<(SHARED_INTERMEDIATE_DIR)/node_natives.h', # javascript files to make for an even more pleasant IDE experience '<@(library_files)', @@ -231,6 +269,9 @@ 'NODE_WANT_INTERNALS=1', # Warn when using deprecated V8 APIs. 'V8_DEPRECATION_WARNINGS=1', + 'BUILDING_NW_NODE=1', + 'V8_SHARED', + 'USING_V8_SHARED', ], @@ -291,6 +332,17 @@ 'NODE_RELEASE_URLBASE="<(node_release_urlbase)"', ] }], + ['node_target_type=="shared_library"', { + 'direct_dependent_settings': { + 'defines': [ + 'USING_UV_SHARED=1', + 'BUILDING_NODE_EXTENSION=1', + ], + }, + }], + ['clang==1', { + 'cflags': ['-Wno-error=missing-declarations', '-Wno-error=array-bounds'], + }], [ 'v8_enable_i18n_support==1', { 'defines': [ 'NODE_HAVE_I18N_SUPPORT=1' ], 'dependencies': [ @@ -352,9 +404,9 @@ [ 'node_shared_openssl=="false"', { 'dependencies': [ './deps/openssl/openssl.gyp:openssl', - + #'../boringssl/boringssl.gyp:boringssl', # For tests - './deps/openssl/openssl.gyp:openssl-cli', + #'./deps/openssl/openssl.gyp:openssl-cli', ], # Do not let unused OpenSSL symbols to slip away 'conditions': [ @@ -363,16 +415,16 @@ [ 'node_target_type!="static_library"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ - '-Wl,-force_load,<(PRODUCT_DIR)/<(OPENSSL_PRODUCT)', + #'-Wl,-force_load,<(PRODUCT_DIR)/<(OPENSSL_PRODUCT)', ], }, 'conditions': [ ['OS in "linux freebsd" and node_shared=="false"', { 'ldflags': [ - '-Wl,--whole-archive,' - '<(PRODUCT_DIR)/obj.target/deps/openssl/' - '<(OPENSSL_PRODUCT)', - '-Wl,--no-whole-archive', + #'-Wl,--whole-archive,' + # '<(PRODUCT_DIR)/obj.target/deps/openssl/' + # '<(OPENSSL_PRODUCT)', + #'-Wl,--no-whole-archive', ], }], # openssl.def is based on zlib.def, zlib symbols @@ -465,7 +517,7 @@ 'defines': [ 'NODE_NO_BROWSER_GLOBALS' ], } ], [ 'node_use_bundled_v8=="true" and v8_postmortem_support=="true"', { - 'dependencies': [ 'deps/v8/tools/gyp/v8.gyp:postmortem-metadata' ], + 'dependencies': [ '../../v8/src/v8.gyp:postmortem-metadata' ], 'conditions': [ # -force_load is not applicable for the static library [ 'node_target_type!="static_library"', { @@ -478,7 +530,7 @@ ], }], [ 'node_shared_zlib=="false"', { - 'dependencies': [ 'deps/zlib/zlib.gyp:zlib' ], + 'dependencies': [ '../zlib/zlib.gyp:zlib' ], }], [ 'node_shared_http_parser=="false"', { @@ -496,7 +548,7 @@ [ 'OS=="win"', { 'sources': [ 'src/backtrace_win32.cc', - 'src/res/node.rc', + #'src/res/node.rc', ], 'defines!': [ 'NODE_PLATFORM="win"', @@ -523,6 +575,18 @@ # we need to use node's preferred "darwin" rather than gyp's preferred "mac" 'NODE_PLATFORM="darwin"', ], + 'postbuilds': [ + { + 'postbuild_name': 'Fix Framework Link', + 'action': [ + 'install_name_tool', + '-change', + '@executable_path/../Versions/<(version_full)/<(mac_product_name) Framework.framework/<(mac_product_name) Framework', + '@executable_path/../../../<(mac_product_name) Framework.framework/<(mac_product_name) Framework', + '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' + ], + }, + ], }], [ 'OS=="freebsd"', { 'libraries': [ @@ -550,9 +614,9 @@ ], }], [ '(OS=="freebsd" or OS=="linux") and node_shared=="false"', { - 'ldflags': [ '-Wl,-z,noexecstack', - '-Wl,--whole-archive <(V8_BASE)', - '-Wl,--no-whole-archive' ] + #'ldflags': [ '-Wl,-z,noexecstack', + # '-Wl,--whole-archive <(V8_BASE)', + # '-Wl,--no-whole-archive' ] }], [ 'OS=="sunos"', { 'ldflags': [ '-Wl,-M,/usr/lib/ld/map.noexstk' ], @@ -827,10 +891,14 @@ { 'target_name': 'cctest', 'type': 'executable', - 'dependencies': [ 'deps/gtest/gtest.gyp:gtest' ], + 'dependencies': [ + '../../testing/gtest.gyp:gtest', + '../../v8/src/v8.gyp:v8', + '../../v8/src/v8.gyp:v8_libplatform' + ], 'include_dirs': [ 'src', - 'deps/v8/include' + '../../v8/include' ], 'defines': [ # gtest's ASSERT macros conflict with our own. diff --git a/src/node.cc b/src/node.cc index af35308047b..8a09a4cf17b 100644 --- a/src/node.cc +++ b/src/node.cc @@ -8,6 +8,9 @@ #include "node_internals.h" #include "node_revert.h" +#include +#include "node_webkit.h" + #if defined HAVE_PERFCTR #include "node_counters.h" #endif @@ -94,6 +97,27 @@ typedef int mode_t; extern char **environ; #endif +NODE_MODULE_REF(cares_wrap) +NODE_MODULE_REF(fs_event_wrap) +NODE_MODULE_REF(buffer) +NODE_MODULE_REF(contextify) +NODE_MODULE_REF(crypto) +NODE_MODULE_REF(fs) +NODE_MODULE_REF(http_parser) +NODE_MODULE_REF(os) +NODE_MODULE_REF(v8) +NODE_MODULE_REF(zlib) +NODE_MODULE_REF(pipe_wrap) +NODE_MODULE_REF(process_wrap) +NODE_MODULE_REF(signal_wrap) +NODE_MODULE_REF(spawn_sync) +NODE_MODULE_REF(tcp_wrap) +NODE_MODULE_REF(timer_wrap) +NODE_MODULE_REF(tls_wrap) +NODE_MODULE_REF(tty_wrap) +NODE_MODULE_REF(udp_wrap) +NODE_MODULE_REF(uv) + namespace node { using v8::Array; @@ -156,11 +180,20 @@ static int v8_thread_pool_size = v8_default_thread_pool_size; static bool prof_process = false; static bool v8_is_profiling = false; static bool node_is_initialized = false; +static bool node_is_nwjs = false; static node_module* modpending; static node_module* modlist_builtin; static node_module* modlist_linked; static node_module* modlist_addon; + +NODE_EXTERN Environment* g_env = nullptr; +NODE_EXTERN v8::Persistent g_context; +NODE_EXTERN v8::Persistent g_dom_context; +static UVRunFn g_nw_uv_run = nullptr; +static NWTickCallback g_nw_tick_callback = nullptr; +static const char* g_native_blob_path = nullptr; + #if defined(NODE_HAVE_I18N_SUPPORT) // Path to ICU data (for i18n / Intl) static const char* icu_data_dir = nullptr; @@ -1022,6 +1055,7 @@ void* ArrayBufferAllocator::Allocate(size_t size) { return malloc(size); } +#if 0 static bool DomainHasErrorHandler(const Environment* env, const Local& domain) { HandleScope scope(env->isolate()); @@ -1067,8 +1101,10 @@ static bool DomainsStackHasErrorHandler(const Environment* env) { return false; } +#endif +#if 0 static bool ShouldAbortOnUncaughtException(Isolate* isolate) { HandleScope scope(isolate); @@ -1081,7 +1117,7 @@ static bool ShouldAbortOnUncaughtException(Isolate* isolate) { return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env); } - +#endif void SetupDomainUse(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -2524,6 +2560,7 @@ void FatalException(Isolate* isolate, // failed before the process._fatalException function was added! // this is probably pretty bad. Nothing to do but report and exit. ReportException(env, error, message); + if (!node_is_nwjs) exit(6); } @@ -2539,11 +2576,13 @@ void FatalException(Isolate* isolate, if (fatal_try_catch.HasCaught()) { // the fatal exception function threw, so we must exit ReportException(env, fatal_try_catch); + if (!node_is_nwjs) exit(7); } if (false == caught->BooleanValue()) { ReportException(env, error, message); + if (!node_is_nwjs) exit(1); } } @@ -2557,7 +2596,7 @@ void FatalException(Isolate* isolate, const TryCatch& try_catch) { } -void OnMessage(Local message, Local error) { +NODE_EXTERN void OnMessage(Local message, Local error) { // The current version of V8 sends messages for errors only // (thus `error` is always set). FatalException(Isolate::GetCurrent(), error, message); @@ -3038,6 +3077,9 @@ void SetupProcessObject(Environment* env, env->as_external()); CHECK(maybe.FromJust()); + if (node_is_nwjs) + READONLY_PROPERTY(process, "__nwjs", Integer::New(env->isolate(), 1)); + // process.version READONLY_PROPERTY(process, "version", @@ -3424,7 +3466,8 @@ void LoadEnvironment(Environment* env) { HandleScope handle_scope(env->isolate()); env->isolate()->SetFatalErrorHandler(node::OnFatalError); - env->isolate()->AddMessageListener(OnMessage); + //if (!node_is_nwjs) + env->isolate()->AddMessageListener(OnMessage); // The node.js file returns a function 'f' atexit(AtExit); @@ -4237,6 +4280,7 @@ void Init(int* argc, // Initialize prog_start_time to get relative uptime. prog_start_time = static_cast(uv_now(uv_default_loop())); + if (!node_is_nwjs) { // Make inherited handles noninheritable. uv_disable_stdio_inheritance(); @@ -4247,6 +4291,8 @@ void Init(int* argc, DispatchDebugMessagesAsyncCallback)); uv_unref(reinterpret_cast(&dispatch_debug_messages_async)); + } //node_is_nwjs + #if defined(NODE_V8_OPTIONS) // Should come before the call to V8::SetFlagsFromCommandLine() // so the user can disable a flag --foo at run-time by passing @@ -4313,9 +4359,11 @@ void Init(int* argc, const char no_typed_array_heap[] = "--typed_array_max_size_in_heap=0"; V8::SetFlagsFromString(no_typed_array_heap, sizeof(no_typed_array_heap) - 1); + if (!node_is_nwjs) { if (!use_debug_agent) { RegisterDebugSignalHandler(); } + } //node_is_nwjs // We should set node_is_initialized here instead of in node::Start, // otherwise embedders using node::Init to initialize everything will not be @@ -4516,8 +4564,10 @@ Environment* CreateEnvironment(Isolate* isolate, static void StartNodeInstance(void* arg) { NodeInstanceData* instance_data = static_cast(arg); Isolate::CreateParams params; - ArrayBufferAllocator* array_buffer_allocator = new ArrayBufferAllocator(); - params.array_buffer_allocator = array_buffer_allocator; + if (!node_is_nwjs) { + ArrayBufferAllocator* array_buffer_allocator = new ArrayBufferAllocator(); + params.array_buffer_allocator = array_buffer_allocator; + } #ifdef NODE_ENABLE_VTUNE_PROFILING params.code_event_handler = vTune::GetVtuneCodeEventHandler(); #endif @@ -4541,12 +4591,12 @@ static void StartNodeInstance(void* arg) { HandleScope handle_scope(isolate); Local context = Context::New(isolate); Environment* env = CreateEnvironment(isolate, context, instance_data); - array_buffer_allocator->set_env(env); + //array_buffer_allocator->set_env(env); Context::Scope context_scope(context); - +#if 0 isolate->SetAbortOnUncaughtExceptionCallback( ShouldAbortOnUncaughtException); - +#endif // Start debug agent when argv has --debug if (instance_data->use_debug_agent()) { StartDebug(env, debug_wait_connect); @@ -4598,7 +4648,7 @@ static void StartNodeInstance(void* arg) { __lsan_do_leak_check(); #endif - array_buffer_allocator->set_env(nullptr); + //array_buffer_allocator->set_env(nullptr); env->Dispose(); env = nullptr; } @@ -4612,9 +4662,118 @@ static void StartNodeInstance(void* arg) { CHECK_NE(isolate, nullptr); isolate->Dispose(); isolate = nullptr; - delete array_buffer_allocator; + //delete array_buffer_allocator; +} + +#ifdef V8_USE_EXTERNAL_STARTUP_DATA +// Helper class to load the startup data files from disk. +// +// This is meant as a convenience for stand-alone binaries like d8, cctest, +// unittest. A V8 embedder would likely either handle startup data on their +// own or just disable the feature if they don't want to handle it at all, +// while tools like cctest need to work in either configuration. Hence this is +// not meant for inclusion in the general v8 library. +class StartupDataHandler { + public: + // Load startup data, and call the v8::V8::Set*DataBlob API functions. + // + // natives_blob and snapshot_blob will be loaded realitive to exec_path, + // which would usually be the equivalent of argv[0]. + StartupDataHandler(const char* exec_path, const char* natives_blob, + const char* snapshot_blob); + ~StartupDataHandler(); + + private: + static char* RelativePath(char** buffer, const char* exec_path, + const char* name); + + void LoadFromFiles(const char* natives_blob, const char* snapshot_blob); + + void Load(const char* blob_file, v8::StartupData* startup_data, + void (*setter_fn)(v8::StartupData*)); + + v8::StartupData natives_; + v8::StartupData snapshot_; + + // Disallow copy & assign. + StartupDataHandler(const StartupDataHandler& other); + void operator=(const StartupDataHandler& other); +}; + +StartupDataHandler::StartupDataHandler(const char* exec_path, + const char* natives_blob, + const char* snapshot_blob) { + // If we have (at least one) explicitly given blob, use those. + // If not, use the default blob locations next to the d8 binary. + if (natives_blob || snapshot_blob) { + LoadFromFiles(natives_blob, snapshot_blob); + } else { + char* natives; + char* snapshot; + LoadFromFiles(RelativePath(&natives, exec_path, "natives_blob.bin"), + RelativePath(&snapshot, exec_path, "snapshot_blob.bin")); + + free(natives); + free(snapshot); + } +} + + +StartupDataHandler::~StartupDataHandler() { + delete[] natives_.data; + delete[] snapshot_.data; +} + + +char* StartupDataHandler::RelativePath(char** buffer, const char* exec_path, + const char* name) { + const char* last_slash = strrchr(exec_path, '/'); + if (last_slash) { + int after_slash = last_slash - exec_path + 1; + int name_length = static_cast(strlen(name)); + *buffer = reinterpret_cast(calloc(after_slash + name_length + 1, 1)); + strncpy(*buffer, exec_path, after_slash); + strncat(*buffer, name, name_length); + } else { + *buffer = strdup(name); + } + return *buffer; +} + + +void StartupDataHandler::LoadFromFiles(const char* natives_blob, + const char* snapshot_blob) { + Load(natives_blob, &natives_, v8::V8::SetNativesDataBlob); + Load(snapshot_blob, &snapshot_, v8::V8::SetSnapshotDataBlob); +} + + +void StartupDataHandler::Load(const char* blob_file, + v8::StartupData* startup_data, + void (*setter_fn)(v8::StartupData*)) { + startup_data->data = NULL; + startup_data->raw_size = 0; + + if (!blob_file) return; + + FILE* file = fopen(blob_file, "rb"); + if (!file) return; + + fseek(file, 0, SEEK_END); + startup_data->raw_size = ftell(file); + rewind(file); + + startup_data->data = new char[startup_data->raw_size]; + int read_size = static_cast(fread(const_cast(startup_data->data), + 1, startup_data->raw_size, file)); + fclose(file); + + if (startup_data->raw_size == read_size) (*setter_fn)(startup_data); } +#endif // V8_USE_EXTERNAL_STARTUP_DATA + + int Start(int argc, char** argv) { PlatformInit(); @@ -4640,7 +4799,17 @@ int Start(int argc, char** argv) { V8::SetEntropySource(crypto::EntropySource); #endif +#ifdef V8_USE_EXTERNAL_STARTUP_DATA + //StartupDataHandler startup_data(argv[0], nullptr, nullptr); +#if defined(__APPLE__) + V8::InitializeExternalStartupData(g_native_blob_path); +#else + V8::InitializeExternalStartupData(argv[0]); +#endif +#endif + v8_platform.Initialize(v8_thread_pool_size); + V8::Initialize(); int exit_code = 1; @@ -4665,5 +4834,261 @@ int Start(int argc, char** argv) { return exit_code; } +void ref_node_modules() { +NODE_MODULE_REF2(cares_wrap) +NODE_MODULE_REF2(fs_event_wrap) +NODE_MODULE_REF2(buffer) +NODE_MODULE_REF2(contextify) +NODE_MODULE_REF2(crypto) +NODE_MODULE_REF2(fs) +NODE_MODULE_REF2(http_parser) +NODE_MODULE_REF2(os) +NODE_MODULE_REF2(v8) +NODE_MODULE_REF2(zlib) +NODE_MODULE_REF2(pipe_wrap) +NODE_MODULE_REF2(process_wrap) +NODE_MODULE_REF2(signal_wrap) +NODE_MODULE_REF2(spawn_sync) +NODE_MODULE_REF2(tcp_wrap) +NODE_MODULE_REF2(timer_wrap) +NODE_MODULE_REF2(tls_wrap) +NODE_MODULE_REF2(tty_wrap) +NODE_MODULE_REF2(udp_wrap) +NODE_MODULE_REF2(uv) +} + +NODE_EXTERN v8::Handle CallNWTickCallback(Environment* env, const v8::Handle ret) { + return (*g_nw_tick_callback)(env, ret); +} + } // namespace node + +extern "C" { +void wakeup_callback(uv_async_t* handle) { + // do nothing, just make libuv exit loop. +} + +void idle_callback(uv_idle_t* handle) { + // do nothing, just make libuv exit loop. +} + +void timer_callback(uv_timer_t* timer) { + // libuv would block unexpectedly with zero-timeout timer + // this is a workaround of libuv bug #574: + // https://github.com/joyent/libuv/issues/574 + uv_idle_start(static_cast(timer->data), idle_callback); +} + + +NODE_EXTERN int g_uv_run(void* loop, int mode) { + return uv_run((uv_loop_t*)loop, (uv_run_mode)mode); +} + +NODE_EXTERN void g_set_uv_run(UVRunFn uv_run_fn) { + node::g_nw_uv_run = uv_run_fn; +} + +NODE_EXTERN int g_node_start(int argc, char** argv) { + return node::Start(argc, argv); +} + +NODE_EXTERN void g_set_blob_path(const char* path) { + node::g_native_blob_path = path; +} + +NODE_EXTERN void g_msg_pump_nest_enter(msg_pump_context_t* ctx) { + ctx->loop = uv_loop_new(); + + ctx->wakeup_events->push_back((uv_async_t*)ctx->wakeup_event); + ctx->wakeup_event = new uv_async_t; + uv_async_init((uv_loop_t*)ctx->loop, (uv_async_t*)ctx->wakeup_event, wakeup_callback); +} + +NODE_EXTERN void g_msg_pump_pre_loop(msg_pump_context_t* ctx) { + ctx->idle_handle = new uv_idle_t; + uv_idle_init((uv_loop_t*)ctx->loop, (uv_idle_t*)ctx->idle_handle); + + ctx->delay_timer = new uv_timer_t; + ((uv_timer_t*)ctx->delay_timer)->data = ctx->idle_handle; + uv_timer_init((uv_loop_t*)ctx->loop, (uv_timer_t*)ctx->delay_timer); +} + +NODE_EXTERN void g_msg_pump_did_work(msg_pump_context_t* ctx) { + if (node::g_env) { + v8::Isolate* isolate = node::g_env->isolate(); + v8::HandleScope handleScope(isolate); + (*node::g_nw_uv_run)((uv_loop_t*)ctx->loop, UV_RUN_NOWAIT); + node::CallNWTickCallback(node::g_env, v8::Undefined(isolate)); + } +} + +NODE_EXTERN void g_msg_pump_need_work(msg_pump_context_t* ctx) { + (*node::g_nw_uv_run)((uv_loop_t*)ctx->loop, UV_RUN_ONCE); +} + +NODE_EXTERN void g_msg_pump_delay_work(msg_pump_context_t* ctx, int sec) { + uv_timer_start((uv_timer_t*)ctx->delay_timer, timer_callback, sec, 0); + (*node::g_nw_uv_run)((uv_loop_t*)ctx->loop, UV_RUN_ONCE); + uv_idle_stop((uv_idle_t*)ctx->idle_handle); + uv_timer_stop((uv_timer_t*)ctx->delay_timer); +} + +NODE_EXTERN void g_msg_pump_nest_leave(msg_pump_context_t* ctx) { + uv_close((uv_handle_t*)(ctx->wakeup_event), NULL); + // Delete external loop. + uv_loop_close((uv_loop_t*)ctx->loop); + free((uv_loop_t*)ctx->loop); + ctx->loop = nullptr; + // // Restore previous async handle. + delete (uv_async_t*)ctx->wakeup_event; + ctx->wakeup_event = ctx->wakeup_events->back(); + ctx->wakeup_events->pop_back(); +} + +NODE_EXTERN uv_loop_t* g_uv_default_loop() { + return uv_default_loop(); +} + +NODE_EXTERN void g_msg_pump_clean_ctx(msg_pump_context_t* ctx) { + delete (uv_idle_t*)ctx->idle_handle; + ctx->idle_handle = nullptr; + + delete (uv_timer_t*)ctx->delay_timer; + ctx->delay_timer = nullptr; +} + +NODE_EXTERN void g_msg_pump_sched_work(uv_async_t* wakeup_event) { +#ifdef _WIN32 + uv_async_send_nw(wakeup_event); +#else + uv_async_send(wakeup_event); +#endif +} + +NODE_EXTERN void g_msg_pump_ctor(uv_async_t** wakeup_event) { + *wakeup_event = new uv_async_t; + uv_async_init(uv_default_loop(), *wakeup_event, wakeup_callback); + node::g_nw_uv_run = (UVRunFn)uv_run; +} + +NODE_EXTERN void g_msg_pump_dtor(uv_async_t** wakeup_event) { + delete *wakeup_event; + *wakeup_event = nullptr; +} + +NODE_EXTERN bool g_is_node_initialized() { + return node::node_is_initialized; +} + +NODE_EXTERN void g_call_tick_callback(node::Environment* env) { + v8::HandleScope scope(env->isolate()); + v8::Context::Scope context_scope(env->context()); + node::Environment::AsyncCallbackScope callback_scope(env); + + env->KickNextTick(&callback_scope); +} + +// copied beginning of Start() until v8::Initialize() +NODE_EXTERN void g_setup_nwnode(int argc, char** argv) { + node::node_is_initialized = true; + node::node_is_nwjs = true; + node::ref_node_modules(); + CHECK_EQ(0, uv_mutex_init(&node::node_isolate_mutex)); + node::node_isolate = v8::Isolate::GetCurrent(); +} + +NODE_EXTERN void g_start_nw_instance(int argc, char *argv[], v8::Handle context) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handle_scope(isolate); + v8::Context::Scope context_scope(context); + + node::g_env = node::CreateEnvironment(isolate, uv_default_loop(), + context, argc, argv, 0, NULL); + node::LoadEnvironment(node::g_env); +} + +NODE_EXTERN void g_set_nw_tick_callback(NWTickCallback tick_callback) { + node::g_nw_tick_callback = tick_callback; +} + +NODE_EXTERN void* g_get_node_env() { + return node::g_env; +} + +NODE_EXTERN void g_get_node_context(v8::Local* ret) { + *ret = v8::Local::New(v8::Isolate::GetCurrent(), node::g_context); +} + +NODE_EXTERN void g_set_node_context(v8::Isolate* isolate, v8::Local* context) { + node::g_context.Reset(isolate, *context); +} + +NODE_EXTERN void* g_get_current_env(v8::Handle context) { + return node::Environment::GetCurrent(context); +} + +NODE_EXTERN void g_emit_exit(node::Environment* env) { + node::EmitExit(env); +} + +NODE_EXTERN void g_run_at_exit(node::Environment* env) { + node::RunAtExit(env); +} + +#ifdef __APPLE__ + +void UvNoOp(uv_async_t* handle) { +} + +NODE_EXTERN void g_msg_pump_ctor_osx(msg_pump_context_t* ctx, void* EmbedThreadRunner, void* data) { + // Add dummy handle for libuv, otherwise libuv would quit when there is + // nothing to do. + ctx->dummy_uv_handle = new uv_async_t; + uv_async_init(uv_default_loop(), (uv_async_t*)ctx->dummy_uv_handle, UvNoOp); + + // Start worker that will interrupt main loop when having uv events. + ctx->embed_sem = new uv_sem_t; + uv_sem_init((uv_sem_t*)ctx->embed_sem, 0); + ctx->embed_thread = new uv_thread_t; + uv_thread_create((uv_thread_t*)ctx->embed_thread, (uv_thread_cb)EmbedThreadRunner, data); + + // Execute loop for once. + uv_run(uv_default_loop(), UV_RUN_NOWAIT); + node::g_nw_uv_run = (UVRunFn)uv_run; +} + +NODE_EXTERN void g_msg_pump_dtor_osx(msg_pump_context_t* ctx) { + uv_thread_join((uv_thread_t*)ctx->embed_thread); + + delete (uv_async_t*)ctx->dummy_uv_handle; + ctx->dummy_uv_handle = nullptr; + + delete (uv_sem_t*)ctx->embed_sem; + ctx->embed_sem = nullptr; + + delete (uv_thread_t*)ctx->embed_thread; + ctx->embed_thread = nullptr; +} + +NODE_EXTERN int g_nw_uvrun_nowait() { + return (*node::g_nw_uv_run)(uv_default_loop(), UV_RUN_NOWAIT); +} + +NODE_EXTERN int g_uv_backend_timeout() { + return uv_backend_timeout(uv_default_loop()); +} + +NODE_EXTERN void g_uv_sem_post(msg_pump_context_t* ctx) { + uv_sem_post((uv_sem_t*)ctx->embed_sem); +} + +NODE_EXTERN int g_uv_backend_fd() { + return uv_backend_fd(uv_default_loop()); +} + +NODE_EXTERN void g_uv_sem_wait(msg_pump_context_t* ctx) { + uv_sem_wait((uv_sem_t*)ctx->embed_sem); +} +#endif +} diff --git a/src/node.h b/src/node.h index c744c3e1d29..4a35f169ca6 100644 --- a/src/node.h +++ b/src/node.h @@ -8,7 +8,7 @@ # define NODE_EXTERN __declspec(dllimport) # endif #else -# define NODE_EXTERN /* nothing */ +# define NODE_EXTERN __attribute__((visibility("default"))) #endif #ifdef BUILDING_NODE_EXTENSION @@ -301,10 +301,6 @@ NODE_DEPRECATED("Use ParseEncoding(isolate, ...)", NODE_EXTERN void FatalException(v8::Isolate* isolate, const v8::TryCatch& try_catch); -NODE_DEPRECATED("Use FatalException(isolate, ...)", - inline void FatalException(const v8::TryCatch& try_catch) { - return FatalException(v8::Isolate::GetCurrent(), try_catch); -}) // Don't call with encoding=UCS2. NODE_EXTERN v8::Local Encode(v8::Isolate* isolate, @@ -455,6 +451,13 @@ extern "C" NODE_EXTERN void node_module_register(void* mod); } \ } +#define NODE_MODULE_REF(modname) \ + extern int _node_ref_ ## modname; + +#define NODE_MODULE_REF2(modname) \ + _node_ref_ ## modname = 1; + + #define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags) \ extern "C" { \ static node::node_module _module = \ @@ -472,7 +475,8 @@ extern "C" NODE_EXTERN void node_module_register(void* mod); NODE_C_CTOR(_register_ ## modname) { \ node_module_register(&_module); \ } \ - } + } \ + int _node_ref_ ## modname; #define NODE_MODULE(modname, regfunc) \ NODE_MODULE_X(modname, regfunc, NULL, 0) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index e685e4d1195..3a7181f4a26 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -270,7 +270,7 @@ MaybeLocal New(Isolate* isolate, // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. if (length > 0) { - data = static_cast(BUFFER_MALLOC(length)); + data = static_cast(isolate->array_buffer_allocator()->Allocate(length)); if (data == nullptr) return Local(); @@ -292,7 +292,7 @@ MaybeLocal New(Isolate* isolate, return scope.Escape(buf); // Object failed to be created. Clean up resources. - free(data); + isolate->array_buffer_allocator()->Free(data, length); return Local(); } @@ -316,7 +316,7 @@ MaybeLocal New(Environment* env, size_t length) { void* data; if (length > 0) { - data = BUFFER_MALLOC(length); + data = env->isolate()->array_buffer_allocator()->Allocate(length); if (data == nullptr) return Local(); } else { @@ -335,7 +335,7 @@ MaybeLocal New(Environment* env, size_t length) { return scope.Escape(ui); // Object failed to be created. Clean up resources. - free(data); + env->isolate()->array_buffer_allocator()->Free(data, length); return Local(); } @@ -361,7 +361,7 @@ MaybeLocal Copy(Environment* env, const char* data, size_t length) { void* new_data; if (length > 0) { CHECK_NE(data, nullptr); - new_data = malloc(length); + new_data = env->isolate()->array_buffer_allocator()->Allocate(length); if (new_data == nullptr) return Local(); memcpy(new_data, data, length); @@ -381,7 +381,7 @@ MaybeLocal Copy(Environment* env, const char* data, size_t length) { return scope.Escape(ui); // Object failed to be created. Clean up resources. - free(new_data); + env->isolate()->array_buffer_allocator()->Free(new_data, length); return Local(); } @@ -460,7 +460,6 @@ MaybeLocal New(Environment* env, char* data, size_t length) { return Local(); } - void CreateFromString(const FunctionCallbackInfo& args) { CHECK(args[0]->IsString()); CHECK(args[1]->IsString()); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 9cf216f2d60..69b8facd244 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3330,7 +3330,7 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const { if (initialised_ || kind_ != kCipher || !auth_tag_) return false; *out_len = auth_tag_len_; - *out = static_cast(malloc(auth_tag_len_)); + *out = static_cast(env()->isolate()->array_buffer_allocator()->Allocate(auth_tag_len_)); CHECK_NE(*out, nullptr); memcpy(*out, auth_tag_, auth_tag_len_); return true; @@ -4906,7 +4906,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { // NOTE: field_size is in bits int field_size = EC_GROUP_get_degree(ecdh->group_); size_t out_len = (field_size + 7) / 8; - char* out = static_cast(malloc(out_len)); + char* out = static_cast(env->isolate()->array_buffer_allocator()->Allocate(out_len)); CHECK_NE(out, nullptr); int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr); @@ -4942,7 +4942,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { if (size == 0) return env->ThrowError("Failed to get public key length"); - unsigned char* out = static_cast(malloc(size)); + unsigned char* out = static_cast(env->isolate()->array_buffer_allocator()->Allocate(size)); CHECK_NE(out, nullptr); int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr); @@ -4968,7 +4968,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { return env->ThrowError("Failed to get ECDH private key"); int size = BN_num_bytes(b); - unsigned char* out = static_cast(malloc(size)); + unsigned char* out = static_cast(env->isolate()->array_buffer_allocator()->Allocate(size)); CHECK_NE(out, nullptr); if (size != BN_bn2bin(b, out)) { @@ -5367,7 +5367,7 @@ class RandomBytesRequest : public AsyncWrap { : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO), error_(0), size_(size), - data_(static_cast(malloc(size))) { + data_(static_cast(env->isolate()->array_buffer_allocator()->Allocate(size))) { if (data() == nullptr) FatalError("node::RandomBytesRequest()", "Out of Memory"); Wrap(object, this); @@ -5391,7 +5391,7 @@ class RandomBytesRequest : public AsyncWrap { } inline void release() { - free(data_); + env()->isolate()->array_buffer_allocator()->Free(data_, size_); size_ = 0; } diff --git a/src/node_internals.h b/src/node_internals.h index 24ea9534bf1..b561781be6c 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -48,6 +48,7 @@ inline v8::Local PersistentToLocal( v8::Isolate* isolate, const v8::Persistent& persistent); +NODE_EXTERN v8::Handle CallTickCallback(Environment* env, const v8::Handle ret); // Call with valid HandleScope and while inside Context scope. v8::Local MakeCallback(Environment* env, v8::Local recv, diff --git a/src/node_webkit.h b/src/node_webkit.h new file mode 100644 index 00000000000..36e2ebc2863 --- /dev/null +++ b/src/node_webkit.h @@ -0,0 +1,95 @@ +#ifndef _NW_NODE_INTERFACE_H +#define _NW_NODE_INTERFACE_H + +#if 0 + +#include "v8.h" +#include "uv.h" + +#ifdef _WIN32 +# ifndef BUILDING_NODE_EXTENSION +# define NODE_EXTERN __declspec(dllexport) +# else +# define NODE_EXTERN __declspec(dllimport) +# endif +#else +# define NODE_EXTERN __attribute__((visibility("default"))) +#endif + +#ifdef BUILDING_NODE_EXTENSION +# undef BUILDING_V8_SHARED +# undef BUILDING_UV_SHARED +# define USING_V8_SHARED 1 +# define USING_UV_SHARED 1 +#endif +#ifdef _WIN32 +# ifdef BUILDING_NW_NODE +# define NW_EXTERN __declspec(dllexport) +# else +# define NW_EXTERN __declspec(dllimport) +# endif +#else +# define NW_EXTERN __attribute__((visibility("default"))) +#endif + +namespace node { +extern NODE_EXTERN v8::Persistent g_context; +extern NODE_EXTERN v8::Persistent g_dom_context; + +// Forward declaration +class Environment; +extern NODE_EXTERN Environment* g_env; + +extern NW_EXTERN void OnMessage(v8::Handle message, v8::Handle error); +extern NW_EXTERN v8::Handle CallNWTickCallback(Environment* env, const v8::Handle ret); + +extern NW_EXTERN void Shutdown(); + +extern NODE_EXTERN int (*g_nw_uv_run)(uv_loop_t* loop, uv_run_mode mode); + +} + +#endif + +#include + +typedef struct _msg_pump_context_t { +#if defined(__APPLE__) + void* embed_thread; + + // Semaphore to wait for main loop in the polling thread. + void* embed_sem; + + // Dummy handle to make uv's loop not quit. + void* dummy_uv_handle; +#endif + void* loop; + std::vector* wakeup_events; + void* wakeup_event; + void* idle_handle; + void* delay_timer; +} msg_pump_context_t; + +typedef bool (*IsNodeInitializedFn)(); +typedef void (*CallTickCallbackFn)(void* env); +typedef v8::Handle (*NWTickCallback)(void* env, const v8::Handle ret); +typedef void (*SetupNWNodeFn)(int argc, char **argv); +typedef void (*GetNodeContextFn)(void*); +typedef void (*SetNodeContextFn)(v8::Isolate* isolate, void* ctx); +typedef void (*SetNWTickCallbackFn)(NWTickCallback tick_callback); +typedef void (*StartNWInstanceFn)(int argc, char *argv[], v8::Handle ctx); +typedef void* (*GetNodeEnvFn)(); +typedef void* (*GetCurrentEnvironmentFn)(v8::Handle context); +typedef int (*EmitExitFn)(void* env); +typedef void (*RunAtExitFn)(void* env); +typedef void (*VoidHookFn)(void*); +typedef void (*VoidIntHookFn)(void*, int); +typedef int (*UVRunFn)(void*, int); +typedef void (*SetUVRunFn)(UVRunFn); +typedef int (*NodeStartFn)(int argc, char *argv[]); +typedef void (*SetBlobPathFn)(const char *path); +typedef void* (*GetPointerFn)(); +typedef void (*VoidPtr3Fn)(void*, void*, void*); +typedef void (*VoidVoidFn)(); +typedef int (*IntVoidFn)(); +#endif From 3e32792fde47c76e056a32079372d3f1aa773260 Mon Sep 17 00:00:00 2001 From: Roger Date: Thu, 23 Apr 2015 22:47:24 +0800 Subject: [PATCH 02/34] export openssl symbols --- deps/openssl/openssl.gyp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index d3db5bc6697..47a2cfd9b21 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -153,6 +153,8 @@ 'includes': ['openssl.gypi'], 'include_dirs': ['<@(openssl_default_include_dirs)'], 'defines': ['<@(openssl_default_defines_all)'], + 'cflags!': ['-fvisibility=hidden'], + 'cflags_cc!': ['-fvisibility-inlines-hidden'], 'conditions': [ ['OS=="win"', { 'defines': ['<@(openssl_default_defines_win)'], From 02a3e5e139f8ca55e4c50e457c56d869b35c0b31 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 22 Jul 2015 09:50:45 +0800 Subject: [PATCH 03/34] fix linux build warning --- src/node_buffer.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/node_buffer.h b/src/node_buffer.h index 686450d984e..400fb0276d7 100644 --- a/src/node_buffer.h +++ b/src/node_buffer.h @@ -13,7 +13,10 @@ namespace Buffer { static const unsigned int kMaxLength = sizeof(int32_t) == sizeof(intptr_t) ? 0x3fffffff : 0x7fffffff; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-attributes" NODE_EXTERN typedef void (*FreeCallback)(char* data, void* hint); +#pragma clang diagnostic pop NODE_EXTERN bool HasInstance(v8::Local val); NODE_EXTERN bool HasInstance(v8::Local val); From d99c265d2718446af4829205695e8e4e729a2e11 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 12 Aug 2015 15:16:46 +0800 Subject: [PATCH 04/34] disable warnings for windows platform --- node.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index 360766ed52a..79915967daa 100644 --- a/node.gyp +++ b/node.gyp @@ -143,7 +143,7 @@ '../../chrome/chrome.gyp:chrome_dll', ], - 'msvs_disabled_warnings': [4146, 4267], + 'msvs_disabled_warnings': [4146, 4267, 4003], 'xcode_settings': { 'WARNING_CFLAGS': [ '-Wno-error=deprecated-declarations' ], From 44924a50b26498ea157da0468161ac02ffdb6c73 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Thu, 20 Aug 2015 10:42:39 +0800 Subject: [PATCH 05/34] dummystream on win32 --- lib/dummystream.js | 17 +++++++++++++++++ lib/internal/process/stdio.js | 22 ++++++++++++++++++++-- node.gyp | 1 + 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 lib/dummystream.js diff --git a/lib/dummystream.js b/lib/dummystream.js new file mode 100644 index 00000000000..e7a6efbe528 --- /dev/null +++ b/lib/dummystream.js @@ -0,0 +1,17 @@ +module.exports = DummyStream; + +var W = require('_stream_writable'); +var util = require('util'); +util.inherits(DummyStream, W); + +function DummyStream() { + W.apply(this, arguments); + this.buffer = []; + this.written = 0; +} + +DummyStream.prototype._write = function(chunk, encoding, cb) { + this.buffer.push(chunk.toString()); + this.written += chunk.length; + cb(); +}; diff --git a/lib/internal/process/stdio.js b/lib/internal/process/stdio.js index cab1f10cd87..ec63561d159 100644 --- a/lib/internal/process/stdio.js +++ b/lib/internal/process/stdio.js @@ -7,7 +7,10 @@ function setupStdio() { function getStdout() { if (stdout) return stdout; - stdout = createWritableStdioStream(1); + if (process.platform === 'win32') + stdout = createWritableDummyStream(1); + else + stdout = createWritableStdioStream(1); stdout.destroy = stdout.destroySoon = function(er) { er = er || new Error('process.stdout cannot be closed.'); stdout.emit('error', er); @@ -20,7 +23,10 @@ function setupStdio() { function getStderr() { if (stderr) return stderr; - stderr = createWritableStdioStream(2); + if (process.platform === 'win32') + stderr = createWritableDummyStream(2); + else + stderr = createWritableStdioStream(2); stderr.destroy = stderr.destroySoon = function(er) { er = er || new Error('process.stderr cannot be closed.'); stderr.emit('error', er); @@ -131,6 +137,18 @@ function setupStdio() { }; } +function createWritableDummyStream(fd) { + var DummyStream = require('dummystream'); + var stream = new DummyStream(); + stream.fd = fd; + + stream._isStdio = true; + stream.isTTY = false; + + return stream; + +} + function createWritableStdioStream(fd) { var stream; const tty_wrap = process.binding('tty_wrap'); diff --git a/node.gyp b/node.gyp index 79915967daa..e0a463103eb 100644 --- a/node.gyp +++ b/node.gyp @@ -42,6 +42,7 @@ 'lib/dgram.js', 'lib/dns.js', 'lib/domain.js', + 'lib/dummystream.js', 'lib/events.js', 'lib/fs.js', 'lib/http.js', From 213c64d3f2ee5f2aa6f2c8eeb7067e178d80f797 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Thu, 22 Oct 2015 20:04:47 +0800 Subject: [PATCH 06/34] new mac loop fixup! chromium-integration fixup! new mac loop --- deps/uv/include/uv.h | 1 + deps/uv/src/unix/kqueue.c | 23 ++++++++++++++--------- deps/uv/src/unix/loop.c | 2 ++ src/node.cc | 17 ++++++++++++++++- src/node_webkit.h | 1 + 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 2bb9a87619f..aa6bb9b0c35 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -1470,6 +1470,7 @@ struct uv_loop_s { void* active_reqs[2]; /* Internal flag to signal loop stop. */ unsigned int stop_flag; + void* keventfunc; UV_LOOP_PRIVATE_FIELDS }; diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index fffd4626f17..a310dee0ff7 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -36,6 +36,8 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags); +typedef int (*keventfunc_t)(int kq, const struct kevent *changelist, int nchanges, + struct kevent *eventlist, int nevents, const struct timespec *timeout); int uv__kqueue_init(uv_loop_t* loop) { loop->backend_fd = kqueue(); @@ -87,6 +89,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { int op; int i; + keventfunc_t keventfunc = loop->keventfunc ? (keventfunc_t)loop->keventfunc : &kevent; + if (loop->nfds == 0) { assert(QUEUE_EMPTY(&loop->watcher_queue)); return; @@ -119,7 +123,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0); if (++nevents == ARRAY_SIZE(events)) { - if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) + if (keventfunc(loop->backend_fd, events, nevents, NULL, 0, NULL)) abort(); nevents = 0; } @@ -129,7 +133,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); if (++nevents == ARRAY_SIZE(events)) { - if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) + if (keventfunc(loop->backend_fd, events, nevents, NULL, 0, NULL)) abort(); nevents = 0; } @@ -158,7 +162,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (pset != NULL) pthread_sigmask(SIG_BLOCK, pset, NULL); - nfds = kevent(loop->backend_fd, + nfds = keventfunc(loop->backend_fd, events, nevents, events, @@ -175,7 +179,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { SAVE_ERRNO(uv__update_time(loop)); if (nfds == 0) { - assert(timeout != -1); + //assert(timeout != -1); return; } @@ -213,7 +217,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { struct kevent events[1]; EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (keventfunc(loop->backend_fd, events, 1, NULL, 0, NULL)) if (errno != EBADF && errno != ENOENT) abort(); @@ -238,7 +242,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { /* TODO batch up */ struct kevent events[1]; EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (keventfunc(loop->backend_fd, events, 1, NULL, 0, NULL)) if (errno != ENOENT) abort(); } @@ -252,7 +256,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { /* TODO batch up */ struct kevent events[1]; EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (keventfunc(loop->backend_fd, events, 1, NULL, 0, NULL)) if (errno != ENOENT) abort(); } @@ -342,7 +346,8 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) { /* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */ char pathbuf[MAXPATHLEN]; #endif - + keventfunc_t keventfunc = loop->keventfunc ? (keventfunc_t)loop->keventfunc : &kevent; + handle = container_of(w, uv_fs_event_t, event_watcher); if (fflags & (NOTE_ATTRIB | NOTE_EXTEND)) @@ -370,7 +375,7 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) { EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0); - if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL)) + if (keventfunc(loop->backend_fd, &ev, 1, NULL, 0, NULL)) abort(); } diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index 92e96f09ed0..df1fc7f2d7f 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -56,6 +56,8 @@ int uv_loop_init(uv_loop_t* loop) { loop->backend_fd = -1; loop->emfile_fd = -1; + loop->keventfunc = NULL; + loop->timer_counter = 0; loop->stop_flag = 0; diff --git a/src/node.cc b/src/node.cc index 8a09a4cf17b..ad1206edb37 100644 --- a/src/node.cc +++ b/src/node.cc @@ -5041,7 +5041,7 @@ NODE_EXTERN void g_run_at_exit(node::Environment* env) { void UvNoOp(uv_async_t* handle) { } -NODE_EXTERN void g_msg_pump_ctor_osx(msg_pump_context_t* ctx, void* EmbedThreadRunner, void* data) { +NODE_EXTERN void g_msg_pump_ctor_osx(msg_pump_context_t* ctx, void* EmbedThreadRunner, void* kevent_hook, void* data) { // Add dummy handle for libuv, otherwise libuv would quit when there is // nothing to do. ctx->dummy_uv_handle = new uv_async_t; @@ -5053,6 +5053,11 @@ NODE_EXTERN void g_msg_pump_ctor_osx(msg_pump_context_t* ctx, void* EmbedThreadR ctx->embed_thread = new uv_thread_t; uv_thread_create((uv_thread_t*)ctx->embed_thread, (uv_thread_cb)EmbedThreadRunner, data); + uv_loop_t* uvloop = uv_default_loop(); + uvloop->keventfunc = kevent_hook; + + ctx->loop = uvloop; + // Execute loop for once. uv_run(uv_default_loop(), UV_RUN_NOWAIT); node::g_nw_uv_run = (UVRunFn)uv_run; @@ -5075,6 +5080,16 @@ NODE_EXTERN int g_nw_uvrun_nowait() { return (*node::g_nw_uv_run)(uv_default_loop(), UV_RUN_NOWAIT); } +NODE_EXTERN int g_uv_runloop_once() { + if (node::g_env) { + v8::Isolate* isolate = node::g_env->isolate(); + v8::HandleScope handleScope(isolate); + v8::Context::Scope cscope(node::g_env->context()); + return (*node::g_nw_uv_run)(uv_default_loop(), UV_RUN_ONCE); + } + return (*node::g_nw_uv_run)(uv_default_loop(), UV_RUN_ONCE); +} + NODE_EXTERN int g_uv_backend_timeout() { return uv_backend_timeout(uv_default_loop()); } diff --git a/src/node_webkit.h b/src/node_webkit.h index 36e2ebc2863..5f70ceec182 100644 --- a/src/node_webkit.h +++ b/src/node_webkit.h @@ -90,6 +90,7 @@ typedef int (*NodeStartFn)(int argc, char *argv[]); typedef void (*SetBlobPathFn)(const char *path); typedef void* (*GetPointerFn)(); typedef void (*VoidPtr3Fn)(void*, void*, void*); +typedef void (*VoidPtr4Fn)(void*, void*, void*, void*); typedef void (*VoidVoidFn)(); typedef int (*IntVoidFn)(); #endif From 8b9cb1a88d78523de5aaee08869b42afacaac2ef Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 9 Dec 2015 14:15:19 +0800 Subject: [PATCH 07/34] content verification in node --- lib/module.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/lib/module.js b/lib/module.js index ef17aa5a21f..3b53b846d61 100644 --- a/lib/module.js +++ b/lib/module.js @@ -12,6 +12,19 @@ const internalModuleReadFile = process.binding('fs').internalModuleReadFile; const internalModuleStat = process.binding('fs').internalModuleStat; const preserveSymlinks = !!process.binding('config').preserveSymlinks; +function extensionUrl(str) { + if (typeof str !== 'string') { + throw new Error('Expected a string'); + } + + var pathName = path.resolve(str).replace(/\\/g, '/'); + + var relative = path.relative(global.__dirname, pathName); + + var ret = encodeURI('chrome-extension://' + global.__nwjs_ext_id + '/' + relative); + return ret; +}; + // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. // See: https://github.com/joyent/node/issues/1707 @@ -566,6 +579,12 @@ Module.prototype._compile = function(content, filename) { // Native extension for .js Module._extensions['.js'] = function(module, filename) { + if (global.__nwjs_cv) { + var url = extensionUrl(filename); + var request = new global.XMLHttpRequest(); + request.open('GET', url, false); + request.send(null); + } var content = fs.readFileSync(filename, 'utf8'); module._compile(internalModule.stripBOM(content), filename); }; @@ -573,6 +592,12 @@ Module._extensions['.js'] = function(module, filename) { // Native extension for .json Module._extensions['.json'] = function(module, filename) { + if (global.__nwjs_cv) { + var url = extensionUrl(filename); + var request = new global.XMLHttpRequest(); + request.open('GET', url, false); + request.send(null); + } var content = fs.readFileSync(filename, 'utf8'); try { module.exports = JSON.parse(internalModule.stripBOM(content)); @@ -585,6 +610,12 @@ Module._extensions['.json'] = function(module, filename) { //Native extension for .node Module._extensions['.node'] = function(module, filename) { + if (global.__nwjs_cv) { + var url = extensionUrl(filename); + var request = new global.XMLHttpRequest(); + request.open('GET', url, false); + request.send(null); + } return process.dlopen(module, path._makeLong(filename)); }; From 7a7b835c2bf09b459933dd48c9ec0d7a90086ab6 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Sun, 20 Dec 2015 19:29:30 +0800 Subject: [PATCH 08/34] don't create console window in spawn --- deps/uv/src/win/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 855c3740816..792ab0ffe63 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -1075,6 +1075,8 @@ int uv_spawn(uv_loop_t* loop, process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; } + process_flags |= CREATE_NO_WINDOW; + if (!CreateProcessW(application_path, arguments, NULL, From 803b2313d5c68962f49b6cec778f42a04e0da628 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Sun, 27 Dec 2015 17:28:39 +0800 Subject: [PATCH 09/34] fix allocator --- src/stream_wrap.cc | 14 ++++++++++---- src/tls_wrap.cc | 5 ++++- src/udp_wrap.cc | 15 +++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 17278ff83aa..54c41dc4061 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -148,7 +148,9 @@ void StreamWrap::OnAlloc(uv_handle_t* handle, void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) { - buf->base = static_cast(malloc(size)); + StreamWrap* wrap = static_cast(ctx); + Environment* env = wrap->env(); + buf->base = static_cast(env->isolate()->array_buffer_allocator()->Allocate(size)); buf->len = size; if (buf->base == nullptr && size > 0) { @@ -193,18 +195,22 @@ void StreamWrap::OnReadImpl(ssize_t nread, if (nread < 0) { if (buf->base != nullptr) - free(buf->base); + env->isolate()->array_buffer_allocator()->Free(buf->base, buf->len); wrap->EmitData(nread, Local(), pending_obj); return; } if (nread == 0) { if (buf->base != nullptr) - free(buf->base); + env->isolate()->array_buffer_allocator()->Free(buf->base, buf->len); return; } - char* base = static_cast(realloc(buf->base, nread)); + char* base = static_cast(buf->base); //NOTE: realloc is + //removed here because + //nread is always less + //than buf->len, see the + //check in the next line CHECK_LE(static_cast(nread), buf->len); if (pending == UV_TCP) { diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 7c5df1105a6..4bd743452c9 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -661,7 +661,10 @@ void TLSWrap::OnReadImpl(ssize_t nread, void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) { - buf->base = static_cast(malloc(suggested_size)); + TLSWrap* wrap = static_cast(ctx); + Environment* env = wrap->env(); + + buf->base = static_cast(env->isolate()->array_buffer_allocator()->Allocate(suggested_size)); CHECK_NE(buf->base, nullptr); buf->len = suggested_size; } diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 1cf9678cb18..c7e9f8fe1b2 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -384,7 +384,10 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) { void UDPWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { - buf->base = static_cast(malloc(suggested_size)); + UDPWrap* wrap = static_cast(((uv_udp_t*)handle)->data); + Environment* env = wrap->env(); + + buf->base = static_cast(env->isolate()->array_buffer_allocator()->Allocate(suggested_size)); buf->len = suggested_size; if (buf->base == nullptr && suggested_size > 0) { @@ -399,14 +402,14 @@ void UDPWrap::OnRecv(uv_udp_t* handle, const uv_buf_t* buf, const struct sockaddr* addr, unsigned int flags) { + UDPWrap* wrap = static_cast(handle->data); + Environment* env = wrap->env(); if (nread == 0 && addr == nullptr) { if (buf->base != nullptr) - free(buf->base); + env->isolate()->array_buffer_allocator()->Free(buf->base, buf->len); return; } - UDPWrap* wrap = static_cast(handle->data); - Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -421,12 +424,12 @@ void UDPWrap::OnRecv(uv_udp_t* handle, if (nread < 0) { if (buf->base != nullptr) - free(buf->base); + env->isolate()->array_buffer_allocator()->Free(buf->base, buf->len); wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv); return; } - char* base = static_cast(realloc(buf->base, nread)); + char* base = static_cast(buf->base); //NOTE: we don't realloc here argv[2] = Buffer::New(env, base, nread).ToLocalChecked(); argv[3] = AddressToJS(env, addr); wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv); From 79613a0885d5c3f621d8393bd132013f5d0314db Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Mon, 28 Dec 2015 12:28:55 +0800 Subject: [PATCH 10/34] fix process.title --- deps/uv/src/unix/proctitle.c | 9 +++++++++ src/node.cc | 2 ++ 2 files changed, 11 insertions(+) diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 19214e5ec97..ed6f9d906b1 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -35,6 +35,14 @@ static struct { char** uv_setup_args(int argc, char** argv) { + if (argc > 0) { + process_title.len = strlen(argv[0]); + process_title.str = uv__malloc(process_title.len + 1); + memcpy(process_title.str, argv[0], process_title.len + 1); + } + return argv; +#if 0 + char** new_argv; size_t size; char* s; @@ -71,6 +79,7 @@ char** uv_setup_args(int argc, char** argv) { new_argv[i] = NULL; return new_argv; +#endif } diff --git a/src/node.cc b/src/node.cc index ad1206edb37..161938a1bef 100644 --- a/src/node.cc +++ b/src/node.cc @@ -5003,6 +5003,8 @@ NODE_EXTERN void g_start_nw_instance(int argc, char *argv[], v8::Handle Date: Mon, 28 Dec 2015 12:37:26 +0800 Subject: [PATCH 11/34] don't insert same req into pending list again Or we'll have loop in the list when the async req is inserted again by uv_async_send_nw Fix nwjs/nw.js#2332 --- deps/uv/src/win/req-inl.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h index b5e502eef55..17425870148 100644 --- a/deps/uv/src/win/req-inl.h +++ b/deps/uv/src/win/req-inl.h @@ -81,6 +81,7 @@ INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { req->type = UV_UNKNOWN_REQ; + req->next_req = NULL; SET_REQ_SUCCESS(req); } @@ -91,7 +92,8 @@ INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) { - req->next_req = NULL; + if (req->next_req) + return; if (loop->pending_reqs_tail) { #ifdef _DEBUG /* Ensure the request is not already in the queue, or the queue @@ -156,6 +158,7 @@ INLINE static int uv_process_reqs(uv_loop_t* loop) { while (next != NULL) { req = next; next = req->next_req != first ? req->next_req : NULL; + req->next_req = NULL; switch (req->type) { case UV_READ: From 3aec44c51946d3e8a945d5490ddd05349604f1ef Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Fri, 8 Jan 2016 13:49:26 +0800 Subject: [PATCH 12/34] enter node's context before callback --- src/node.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/node.cc b/src/node.cc index 161938a1bef..cea27a4f5b7 100644 --- a/src/node.cc +++ b/src/node.cc @@ -4918,20 +4918,33 @@ NODE_EXTERN void g_msg_pump_did_work(msg_pump_context_t* ctx) { if (node::g_env) { v8::Isolate* isolate = node::g_env->isolate(); v8::HandleScope handleScope(isolate); + v8::Context::Scope cscope(node::g_env->context()); (*node::g_nw_uv_run)((uv_loop_t*)ctx->loop, UV_RUN_NOWAIT); node::CallNWTickCallback(node::g_env, v8::Undefined(isolate)); } } NODE_EXTERN void g_msg_pump_need_work(msg_pump_context_t* ctx) { + if (node::g_env) { + node::g_env->context()->Enter(); + } (*node::g_nw_uv_run)((uv_loop_t*)ctx->loop, UV_RUN_ONCE); + if (node::g_env) { + node::g_env->context()->Exit(); + } } NODE_EXTERN void g_msg_pump_delay_work(msg_pump_context_t* ctx, int sec) { + if (node::g_env) { + node::g_env->context()->Enter(); + } uv_timer_start((uv_timer_t*)ctx->delay_timer, timer_callback, sec, 0); (*node::g_nw_uv_run)((uv_loop_t*)ctx->loop, UV_RUN_ONCE); uv_idle_stop((uv_idle_t*)ctx->idle_handle); uv_timer_stop((uv_timer_t*)ctx->delay_timer); + if (node::g_env) { + node::g_env->context()->Exit(); + } } NODE_EXTERN void g_msg_pump_nest_leave(msg_pump_context_t* ctx) { From f74208a7c22680c9d6e201b53aa0b81e6cc441c9 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Tue, 26 Jan 2016 13:50:57 +0800 Subject: [PATCH 13/34] chain PromiseRejectCallback --- src/node.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/node.cc b/src/node.cc index cea27a4f5b7..6d2a18b186f 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1227,7 +1227,7 @@ void SetupPromises(const FunctionCallbackInfo& args) { CHECK(args[0]->IsFunction()); - isolate->SetPromiseRejectCallback(PromiseRejectCallback); + //isolate->SetPromiseRejectCallback(PromiseRejectCallback); env->set_promise_reject_function(args[0].As()); env->process_object()->Delete( @@ -5051,6 +5051,10 @@ NODE_EXTERN void g_run_at_exit(node::Environment* env) { node::RunAtExit(env); } +NODE_EXTERN void g_promise_reject_callback(v8::PromiseRejectMessage* data) { + node::PromiseRejectCallback(*data); +} + #ifdef __APPLE__ void UvNoOp(uv_async_t* handle) { From 310eedd0852d30010b52b71a6cdd70816e0b37a4 Mon Sep 17 00:00:00 2001 From: Kevin Fan Date: Thu, 11 Feb 2016 16:12:34 +0800 Subject: [PATCH 14/34] disable warning C4065 src\third_party\node\src\node_revert.cc(15) : warning C4065: switch statement contains 'default' but no 'case' labels --- node.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index e0a463103eb..7365977adae 100644 --- a/node.gyp +++ b/node.gyp @@ -144,7 +144,7 @@ '../../chrome/chrome.gyp:chrome_dll', ], - 'msvs_disabled_warnings': [4146, 4267, 4003], + 'msvs_disabled_warnings': [4146, 4267, 4003, 4065], 'xcode_settings': { 'WARNING_CFLAGS': [ '-Wno-error=deprecated-declarations' ], From a3b9a670520bac734969dc3c4dac939563a64f4b Mon Sep 17 00:00:00 2001 From: Kevin Fan Date: Sat, 5 Mar 2016 23:59:29 +0800 Subject: [PATCH 15/34] support node-main --- lib/internal/bootstrap_node.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index c42d4737db6..92b3e67af0c 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -78,6 +78,12 @@ global.process.mainModule = module; module._compile('global.module = module;\n' + 'global.require = global.__nw_require = require;\n', 'nw-emulate-node'); + if (process.argv[1]) { + var path = NativeModule.require('path'); + process.argv[1] = path.resolve(process.argv[1]); + preloadModules(); + Module.runMain(); + } return; } // There are various modes that Node can run in. The most common two From abb48f6d1a948277fe1bc5e967aac1304592bd85 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Thu, 17 Mar 2016 14:14:37 +0800 Subject: [PATCH 16/34] Workaround of realloc in node_buffer Fix nwjs/nw.js#4357 --- src/node_buffer.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 3a7181f4a26..3d5277fd3c1 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -279,12 +279,18 @@ MaybeLocal New(Isolate* isolate, CHECK(actual <= length); if (actual == 0) { - free(data); + isolate->array_buffer_allocator()->Free(data, length); data = nullptr; - } else if (actual < length) { + } +#if 0 //FIXME #4357: costs some extra bytes here. It shouldn't be + //significant because of the length calculation in + //StringBytes::Size() + //v8 buffer allocator doesn't support reallocate + else if (actual < length) { data = static_cast(realloc(data, actual)); CHECK_NE(data, nullptr); } +#endif } Local buf; From 33821ed1d222fac4761ee2f815bf7ff0cb66c7e7 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Sat, 2 Apr 2016 20:51:31 +0800 Subject: [PATCH 17/34] add KickNextTick back revert f1488bb24c74c436d59c785463c0c447fd1bf82c --- src/env.cc | 23 +++++++++++++++++++++++ src/env.h | 2 ++ src/node.cc | 18 +----------------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/env.cc b/src/env.cc index 90a1b8723d9..6fe1eab29b9 100644 --- a/src/env.cc +++ b/src/env.cc @@ -62,4 +62,27 @@ void Environment::PrintSyncTrace() const { fflush(stderr); } + +bool Environment::KickNextTick(Environment::AsyncCallbackScope* scope) { + TickInfo* info = tick_info(); + + if (scope->in_makecallback()) { + return true; + } + + if (info->length() == 0) { + isolate()->RunMicrotasks(); + } + + if (info->length() == 0) { + info->set_index(0); + return true; + } + + Local ret = + tick_callback_function()->Call(process_object(), 0, nullptr); + + return !ret.IsEmpty(); +} + } // namespace node diff --git a/src/env.h b/src/env.h index 4c38ddefe8c..fbd157d5587 100644 --- a/src/env.h +++ b/src/env.h @@ -483,6 +483,8 @@ class Environment { inline int64_t get_async_wrap_uid(); + bool KickNextTick(AsyncCallbackScope* scope); + inline uint32_t* heap_statistics_buffer() const; inline void set_heap_statistics_buffer(uint32_t* pointer); diff --git a/src/node.cc b/src/node.cc index 6d2a18b186f..880d17e18a7 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1327,23 +1327,7 @@ Local MakeCallback(Environment* env, } } - if (callback_scope.in_makecallback()) { - return ret; - } - - Environment::TickInfo* tick_info = env->tick_info(); - - if (tick_info->length() == 0) { - env->isolate()->RunMicrotasks(); - } - - Local process = env->process_object(); - - if (tick_info->length() == 0) { - tick_info->set_index(0); - } - - if (env->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) { + if (!env->KickNextTick(&callback_scope)) { return Undefined(env->isolate()); } From d9a5f66cade53eb04da7883c4e276193af7b63f9 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Sat, 7 May 2016 17:22:20 +0800 Subject: [PATCH 18/34] don't mark exiting upon uncaught exception --- lib/internal/bootstrap_node.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 92b3e67af0c..f7d3834e276 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -315,15 +315,6 @@ // If someone handled it, then great. otherwise, die in C++ land // since that means that we'll exit the process, emit the 'exit' event if (!caught) { - try { - if (!process._exiting) { - process._exiting = true; - process.emit('exit', 1); - } - } catch (er) { - // nothing to be done about it at this point. - } - // if we handled an error, then make sure any ticks get processed } else { NativeModule.require('timers').setImmediate(process._tickCallback); From 023a5810bfd7343584f0609e42d4c1502c6a991b Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Fri, 27 May 2016 06:47:00 +0800 Subject: [PATCH 19/34] fixup! chromium-integration --- deps/uv/uv.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 38152218098..c90fc6fa495 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -21,7 +21,7 @@ ], 'xcode_settings': { 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden - 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' , '-Wno-error=gnu-folding-constant'], + 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' , '-Wno-error=gnu-folding-constant', '-Wno-varargs'], 'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ], }, 'msvs_disabled_warnings': [4267], From 70d86212118c5eddbe6c11c41a018d2f446fa96e Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Fri, 27 May 2016 12:12:26 +0800 Subject: [PATCH 20/34] [WIN] disable warning for non official build --- deps/openssl/openssl.gyp | 1 + deps/uv/uv.gyp | 2 +- node.gyp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index 47a2cfd9b21..5ae63c0a913 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -161,6 +161,7 @@ 'link_settings': { 'libraries': ['<@(openssl_default_libraries_win)'], }, + 'msvs_disabled_warnings': [4311], }, { 'defines': ['<@(openssl_default_defines_not_win)'], 'cflags': ['-Wno-missing-field-initializers'], diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index c90fc6fa495..4c4603ce1ea 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -24,7 +24,7 @@ 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' , '-Wno-error=gnu-folding-constant', '-Wno-varargs'], 'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ], }, - 'msvs_disabled_warnings': [4267], + 'msvs_disabled_warnings': [4267, 4477], }, 'targets': [ diff --git a/node.gyp b/node.gyp index 7365977adae..70093c5cc09 100644 --- a/node.gyp +++ b/node.gyp @@ -144,7 +144,7 @@ '../../chrome/chrome.gyp:chrome_dll', ], - 'msvs_disabled_warnings': [4146, 4267, 4003, 4065], + 'msvs_disabled_warnings': [4146, 4267, 4003, 4065, 4477], 'xcode_settings': { 'WARNING_CFLAGS': [ '-Wno-error=deprecated-declarations' ], From 845f201c4a206826cf6d40350cb0c166a12f0e71 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Thu, 2 Jun 2016 14:23:14 +0800 Subject: [PATCH 21/34] fixup! chromium-integration --- src/node.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/node.cc b/src/node.cc index 880d17e18a7..c52e0d1968d 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2535,6 +2535,8 @@ void FatalException(Isolate* isolate, HandleScope scope(isolate); Environment* env = Environment::GetCurrent(isolate); + if (!env) //FIXME: check why env is null #4912 + return; Local process_object = env->process_object(); Local fatal_exception_string = env->fatal_exception_string(); Local fatal_exception_function = From d9d9f596e20b0f282c713d5e04851af5f6d4d91e Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Thu, 23 Jun 2016 13:07:06 +0800 Subject: [PATCH 22/34] fixup! content verification in node --- lib/module.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/module.js b/lib/module.js index 3b53b846d61..29f8815e32e 100644 --- a/lib/module.js +++ b/lib/module.js @@ -95,6 +95,12 @@ function readPackage(requestPath) { } const jsonPath = path.resolve(requestPath, 'package.json'); + if (global.__nwjs_cv) { + var url = extensionUrl(jsonPath); + var request = new global.XMLHttpRequest(); + request.open('GET', url, false); + request.send(null); + } const json = internalModuleReadFile(path._makeLong(jsonPath)); if (json === undefined) { From d350b95d78828570434c32511e34d048db9b7237 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Mon, 11 Jul 2016 10:33:22 +0800 Subject: [PATCH 23/34] fixup! chromium-integration --- config.gypi | 1 + lib/url.js | 8 ++++---- node.gyp | 17 +++++++++-------- src/node.cc | 1 - 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/config.gypi b/config.gypi index 64063131cc7..9ed89461b31 100644 --- a/config.gypi +++ b/config.gypi @@ -10,6 +10,7 @@ 'icu_small': 'false', 'node_install_npm': 'true', 'node_prefix': '', + 'node_shared': 'true', 'node_shared_http_parser': 'false', 'node_shared_libuv': 'false', 'node_shared_openssl': 'false', diff --git a/lib/url.js b/lib/url.js index 4a2a879bf34..74858e2c5c1 100644 --- a/lib/url.js +++ b/lib/url.js @@ -1,11 +1,11 @@ 'use strict'; function importPunycode() { - try { - return process.binding('icu'); - } catch (e) { + // try { + // return process.binding('icu'); + // } catch (e) { return require('punycode'); - } +// } } const { toASCII } = importPunycode(); diff --git a/node.gyp b/node.gyp index 70093c5cc09..48f04ce21a8 100644 --- a/node.gyp +++ b/node.gyp @@ -7,8 +7,9 @@ 'node_use_perfctr%': 'false', 'node_no_browser_globals%': 'false', 'node_use_v8_platform%': 'true', - 'node_use_bundled_v8%': 'true', - 'node_shared%': 'false', + 'node_use_bundled_v8': 'false', + 'node_shared': 'true', + 'v8_inspector': 'false', 'node_module_version%': '', 'node_shared_zlib%': 'false', 'node_shared_http_parser%': 'false', @@ -299,12 +300,12 @@ }], [ 'node_use_bundled_v8=="true"', { 'include_dirs': [ - 'deps/v8', # include/v8_platform.h + #'deps/v8', # include/v8_platform.h ], 'dependencies': [ - 'deps/v8/tools/gyp/v8.gyp:v8', - 'deps/v8/tools/gyp/v8.gyp:v8_libplatform' + #'deps/v8/tools/gyp/v8.gyp:v8', + #'deps/v8/tools/gyp/v8.gyp:v8_libplatform' ], }], [ 'node_use_v8_platform=="true"', { @@ -941,13 +942,13 @@ }], [ 'node_use_v8_platform=="true"', { 'dependencies': [ - 'deps/v8/tools/gyp/v8.gyp:v8_libplatform', + #'deps/v8/tools/gyp/v8.gyp:v8_libplatform', ], }], [ 'node_use_bundled_v8=="true"', { 'dependencies': [ - 'deps/v8/tools/gyp/v8.gyp:v8', - 'deps/v8/tools/gyp/v8.gyp:v8_libplatform' + #'deps/v8/tools/gyp/v8.gyp:v8', + #'deps/v8/tools/gyp/v8.gyp:v8_libplatform' ], }], ] diff --git a/src/node.cc b/src/node.cc index c52e0d1968d..227fb06715f 100644 --- a/src/node.cc +++ b/src/node.cc @@ -4993,7 +4993,6 @@ NODE_EXTERN void g_setup_nwnode(int argc, char** argv) { node::node_is_initialized = true; node::node_is_nwjs = true; node::ref_node_modules(); - CHECK_EQ(0, uv_mutex_init(&node::node_isolate_mutex)); node::node_isolate = v8::Isolate::GetCurrent(); } From 6fd0ab96cf5063af3aaf870e56c9005615643288 Mon Sep 17 00:00:00 2001 From: Cong Liu Date: Wed, 6 Jul 2016 20:31:27 +0800 Subject: [PATCH 24/34] fixed decoding hex & base64 from two bytes external strings Strings in DOM may be converted to two bytes representation, which should be processed as array of `uint16_t` when decoding hex or base64. base64 decoding in Node.js can fallback to a slow implementation to skip invalid characters (i.e. `\0` in this case). This patch can also keep base64 decoding running under the fast implementation. fixed nwjs/nw.js#5069 --- src/string_bytes.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 668a3b1efe2..5ce563c72c2 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -335,7 +335,7 @@ size_t StringBytes::Write(Isolate* isolate, } case BASE64: - if (is_extern) { + if (is_extern && str->IsExternalOneByte()) { nbytes = base64_decode(buf, buflen, data, external_nbytes); } else { String::Value value(str); @@ -347,7 +347,7 @@ size_t StringBytes::Write(Isolate* isolate, break; case HEX: - if (is_extern) { + if (is_extern && str->IsExternalOneByte()) { nbytes = hex_decode(buf, buflen, data, external_nbytes); } else { String::Value value(str); From 07bd0a9e460eca63535feb740ad7d99362eb760e Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 13 Jul 2016 06:49:10 +0800 Subject: [PATCH 25/34] fixup! chromium-integration --- node.gyp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node.gyp b/node.gyp index 48f04ce21a8..88ad9bcd065 100644 --- a/node.gyp +++ b/node.gyp @@ -15,8 +15,8 @@ 'node_shared_http_parser%': 'false', 'node_shared_cares%': 'false', 'node_shared_libuv%': 'false', - 'node_use_openssl%': 'true', - 'node_shared_openssl%': 'false', + 'node_use_openssl': 'true', + 'node_shared_openssl': 'false', 'openssl_fips%': '', 'node_v8_options%': '', 'node_enable_v8_vtunejit%': 'false', From 661c39d0db4ab7587e1d480d3ae199916b23e290 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 13 Jul 2016 15:44:59 +0800 Subject: [PATCH 26/34] fix unsigned long print in 32-bit build --- src/node_crypto.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 69b8facd244..0961ff8a49b 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -1460,7 +1460,7 @@ static Local X509ToObject(Environment* env, X509* cert) { (void) BIO_reset(bio); BN_ULONG exponent_word = BN_get_word(rsa->e); - BIO_printf(bio, "0x%lx", exponent_word); + BIO_printf(bio, "0x%lx", (unsigned long)exponent_word); BIO_get_mem_ptr(bio, &mem); info->Set(env->exponent_string(), From 97d0fb36b11f6546161ea4b494d10fc1368aa63d Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 8 Jun 2016 17:40:33 +0800 Subject: [PATCH 27/34] fixup! chromium-integration --- src/node_webkit.h | 51 +---------------------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/src/node_webkit.h b/src/node_webkit.h index 5f70ceec182..c9a18df00b1 100644 --- a/src/node_webkit.h +++ b/src/node_webkit.h @@ -1,56 +1,6 @@ #ifndef _NW_NODE_INTERFACE_H #define _NW_NODE_INTERFACE_H -#if 0 - -#include "v8.h" -#include "uv.h" - -#ifdef _WIN32 -# ifndef BUILDING_NODE_EXTENSION -# define NODE_EXTERN __declspec(dllexport) -# else -# define NODE_EXTERN __declspec(dllimport) -# endif -#else -# define NODE_EXTERN __attribute__((visibility("default"))) -#endif - -#ifdef BUILDING_NODE_EXTENSION -# undef BUILDING_V8_SHARED -# undef BUILDING_UV_SHARED -# define USING_V8_SHARED 1 -# define USING_UV_SHARED 1 -#endif -#ifdef _WIN32 -# ifdef BUILDING_NW_NODE -# define NW_EXTERN __declspec(dllexport) -# else -# define NW_EXTERN __declspec(dllimport) -# endif -#else -# define NW_EXTERN __attribute__((visibility("default"))) -#endif - -namespace node { -extern NODE_EXTERN v8::Persistent g_context; -extern NODE_EXTERN v8::Persistent g_dom_context; - -// Forward declaration -class Environment; -extern NODE_EXTERN Environment* g_env; - -extern NW_EXTERN void OnMessage(v8::Handle message, v8::Handle error); -extern NW_EXTERN v8::Handle CallNWTickCallback(Environment* env, const v8::Handle ret); - -extern NW_EXTERN void Shutdown(); - -extern NODE_EXTERN int (*g_nw_uv_run)(uv_loop_t* loop, uv_run_mode mode); - -} - -#endif - #include typedef struct _msg_pump_context_t { @@ -93,4 +43,5 @@ typedef void (*VoidPtr3Fn)(void*, void*, void*); typedef void (*VoidPtr4Fn)(void*, void*, void*, void*); typedef void (*VoidVoidFn)(); typedef int (*IntVoidFn)(); +typedef bool (*BoolPtrFn)(void*); #endif From 970d3e7d049376173b0b69a02d918c6a33a7cc11 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Wed, 8 Jun 2016 17:41:04 +0800 Subject: [PATCH 28/34] fixup! chromium-integration --- node.gyp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/node.gyp b/node.gyp index 88ad9bcd065..0bc89bb90f0 100644 --- a/node.gyp +++ b/node.gyp @@ -28,7 +28,8 @@ 'python%': 'python', 'icu_small%': 'false', 'v8_postmortem_support%' : 'false', - 'V8_BASE%': '<(PRODUCT_DIR)/obj/v8/tools/gyp/libv8_base.a', + 'V8_BASE%': '<(PRODUCT_DIR)/../nw/obj/v8/libv8_libbase.a', + 'V8_PLTFRM%': '<(PRODUCT_DIR)/../nw/obj/v8/libv8_libplatform.a', 'library_files': [ 'lib/internal/bootstrap_node.js', 'lib/_debug_agent.js', @@ -140,9 +141,9 @@ 'type': '<(node_target_type)', 'dependencies': [ 'node_js2c#host', - #'../../v8/tools/gyp/v8.gyp:v8', - '../../v8/src/v8.gyp:v8_libplatform', - '../../chrome/chrome.gyp:chrome_dll', + ##'../../v8/tools/gyp/v8.gyp:v8', + #'../../v8/src/v8.gyp:v8_libplatform', + #'../../chrome/chrome.gyp:chrome_dll', ], 'msvs_disabled_warnings': [4146, 4267, 4003, 4065, 4477], @@ -616,7 +617,11 @@ ], }], [ '(OS=="freebsd" or OS=="linux") and node_shared=="false"', { - #'ldflags': [ '-Wl,-z,noexecstack', + 'ldflags': [ '-L<(PRODUCT_DIR)/../nw/', '-lnw', + '-Wl,--whole-archive <(V8_BASE)', + '<(V8_PLTFRM)', + '-Wl,--no-whole-archive' ] + # 'ldflags': [ '-Wl,-z,noexecstack', # '-Wl,--whole-archive <(V8_BASE)', # '-Wl,--no-whole-archive' ] }], From ae2a444d88e35bfa44ba74889f1539e089ba341d Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Sun, 12 Jun 2016 17:39:48 +0800 Subject: [PATCH 29/34] fixup! chromium-integration --- deps/http_parser/http_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c index 7562a0217b9..72bf757ddbc 100644 --- a/deps/http_parser/http_parser.c +++ b/deps/http_parser/http_parser.c @@ -2391,7 +2391,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, break; default: - assert(!(int)"Unexpected state"); + assert(0 && "Unexpected state"); return 1; } From 81122ba22912e6b8670833b074825331db5862f5 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Sun, 12 Jun 2016 17:40:26 +0800 Subject: [PATCH 30/34] support GN build --- common.gypi | 14 ++++++++++++-- node.gyp | 22 ++++++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/common.gypi b/common.gypi index ef3c76cc812..9d720a80738 100644 --- a/common.gypi +++ b/common.gypi @@ -29,8 +29,18 @@ # Don't bake anything extra into the snapshot. 'v8_use_external_startup_data%': 0, + 'conditions': [ + ['OS=="win" and component=="shared_library"', { + # See http://msdn.microsoft.com/en-us/library/aa652367.aspx + 'win_release_RuntimeLibrary%': '2', # 2 = /MD (nondebug DLL) + 'win_debug_RuntimeLibrary%': '3', # 3 = /MDd (debug DLL) + }, { + # See http://msdn.microsoft.com/en-us/library/aa652367.aspx + 'win_release_RuntimeLibrary%': '0', # 0 = /MT (nondebug static) + 'win_debug_RuntimeLibrary%': '1', # 1 = /MTd (debug static) + }], ['OS == "win"', { 'os_posix': 0, 'v8_postmortem_support%': 'false', @@ -82,7 +92,7 @@ ], 'msvs_settings': { 'VCCLCompilerTool': { - 'RuntimeLibrary': 1, # static debug + 'RuntimeLibrary': '<(win_debug_RuntimeLibrary), # static debug 'Optimization': 0, # /Od, no optimization 'MinimalRebuild': 'false', 'OmitFramePointers': 'false', @@ -119,7 +129,7 @@ ], 'msvs_settings': { 'VCCLCompilerTool': { - 'RuntimeLibrary': 0, # static release + 'RuntimeLibrary': '<(win_release_RuntimeLibrary), # static release 'Optimization': 3, # /Ox, full optimization 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible diff --git a/node.gyp b/node.gyp index 0bc89bb90f0..30272f863d2 100644 --- a/node.gyp +++ b/node.gyp @@ -562,11 +562,14 @@ 'NODE_PLATFORM="win32"', '_UNICODE=1', ], - 'libraries': [ '-lpsapi.lib' ] + 'libraries': [ '-lpsapi.lib', '<(PRODUCT_DIR)/../nw/obj/v8/v8_libbase.lib', '<(PRODUCT_DIR)/../nw/obj/v8/v8_libplatform.lib', '<(PRODUCT_DIR)/../nw/nw.dll.lib' ] }, { # POSIX 'defines': [ '__POSIX__' ], 'sources': [ 'src/backtrace_posix.cc' ], }], + [ 'OS=="win" and component=="shared_library"', { + 'libraries': [ '<(PRODUCT_DIR)/../nw/v8.dll.lib' ] + }], [ 'OS=="mac"', { # linking Corefoundation is needed since certain OSX debugging tools # like Instruments require it for some features @@ -616,14 +619,21 @@ 'NODE_PLATFORM="sunos"', ], }], - [ '(OS=="freebsd" or OS=="linux") and node_shared=="false"', { - 'ldflags': [ '-L<(PRODUCT_DIR)/../nw/', '-lnw', + [ 'OS=="linux"', { + 'ldflags': [ '-L<(PRODUCT_DIR)/../nw/lib/', '-lnw', '-Wl,--whole-archive <(V8_BASE)', '<(V8_PLTFRM)', '-Wl,--no-whole-archive' ] - # 'ldflags': [ '-Wl,-z,noexecstack', - # '-Wl,--whole-archive <(V8_BASE)', - # '-Wl,--no-whole-archive' ] + }], + [ 'OS=="mac"', { + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + #'-L<(PRODUCT_DIR)/../nw/', '-lv8', + '<(PRODUCT_DIR)/../nw/nwjs\ Framework.framework/nwjs\ Framework', + '-Wl,-force_load <(V8_BASE)', + '-Wl,-force_load <(V8_PLTFRM)', + ], + }, }], [ 'OS=="sunos"', { 'ldflags': [ '-Wl,-M,/usr/lib/ld/map.noexstk' ], From 9de98d658fbd655fc23feca22242b95d3a1a320b Mon Sep 17 00:00:00 2001 From: Kevin Fan Date: Fri, 15 Jul 2016 14:26:19 +0800 Subject: [PATCH 31/34] fixup! chromium-integration --- node.gyp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index 30272f863d2..03084783761 100644 --- a/node.gyp +++ b/node.gyp @@ -619,7 +619,13 @@ 'NODE_PLATFORM="sunos"', ], }], - [ 'OS=="linux"', { + [ 'OS=="linux" and component == "shared_library"', { + 'ldflags': [ '-L<(PRODUCT_DIR)/../nw/lib/', '-lv8', + '-Wl,--whole-archive <(V8_BASE)', + '<(V8_PLTFRM)', + '-Wl,--no-whole-archive' ] + }], + [ 'OS=="linux" and component != "shared_library"', { 'ldflags': [ '-L<(PRODUCT_DIR)/../nw/lib/', '-lnw', '-Wl,--whole-archive <(V8_BASE)', '<(V8_PLTFRM)', From 71235ae244c42802edfe836edc749444e01e9491 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Fri, 22 Jul 2016 14:03:06 +0800 Subject: [PATCH 32/34] fixup! chromium-integration --- node.gyp | 1 + 1 file changed, 1 insertion(+) diff --git a/node.gyp b/node.gyp index 03084783761..c67e77dfa65 100644 --- a/node.gyp +++ b/node.gyp @@ -10,6 +10,7 @@ 'node_use_bundled_v8': 'false', 'node_shared': 'true', 'v8_inspector': 'false', + 'node_enable_d8': 'false', 'node_module_version%': '', 'node_shared_zlib%': 'false', 'node_shared_http_parser%': 'false', From 29ae5dba6b2f8ce6322583f78906f31c472e1e82 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Thu, 18 Aug 2016 08:58:48 +0800 Subject: [PATCH 33/34] fix build error: value vs v8::value --- src/env.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env.cc b/src/env.cc index 6fe1eab29b9..265b8972c4c 100644 --- a/src/env.cc +++ b/src/env.cc @@ -79,7 +79,7 @@ bool Environment::KickNextTick(Environment::AsyncCallbackScope* scope) { return true; } - Local ret = + Local ret = tick_callback_function()->Call(process_object(), 0, nullptr); return !ret.IsEmpty(); From 65d2416f220c28f2d89c5e630bb7c13e40abd2af Mon Sep 17 00:00:00 2001 From: Cong Liu Date: Thu, 18 Aug 2016 12:29:26 +0800 Subject: [PATCH 34/34] [win] removed exported zlib symbols zlib symbols was exported in c843e58 with zlib 1.2.8. Node.js in NW was built with chromium zlib 1.2.5 + google's patches, which didn't exported those symbols. --- node.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index c67e77dfa65..bc4cf2236e4 100644 --- a/node.gyp +++ b/node.gyp @@ -667,7 +667,7 @@ '-X^_', '-X^private_', # Base generated DEF on zlib.def - '-Bdeps/zlib/win32/zlib.def' + #'-Bdeps/zlib/win32/zlib.def' ], }, 'conditions': [