diff --git a/build.c b/build.c index 3be2548..7eefa97 100644 --- a/build.c +++ b/build.c @@ -33,10 +33,7 @@ struct node_version { char *name; char *abi; } versions[] = { - {"v10.17.0", "64"}, - {"v11.15.0", "67"}, {"v12.13.0", "72"}, - {"v13.1.0", "79"}, {"v14.0.0", "83"}, {"v15.0.0", "88"} }; @@ -101,14 +98,14 @@ int main() { "-undefined dynamic_lookup", OS, "x64"); - + /* Try and build for arm64 macOS 11 */ build("clang -target arm64-apple-macos11", "clang++ -stdlib=libc++ -target arm64-apple-macos11", "-undefined dynamic_lookup", OS, "arm64"); - + #else /* Linux */ build("clang", diff --git a/src/AppWrapper.h b/src/AppWrapper.h index 4c5edf9..09c454a 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -1,5 +1,5 @@ /* - * Authored by Alex Hultman, 2018-2020. + * Authored by Alex Hultman, 2018-2021. * Intellectual property of third-party. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,7 +35,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { APP *app = (APP *) args.Holder()->GetAlignedPointerFromInternalField(0); /* This one is default constructed with defaults */ - typename APP::WebSocketBehavior behavior = {}; + typename APP::template WebSocketBehavior behavior = {}; NativeString pattern(args.GetIsolate(), args[0]); if (pattern.isInvalid(args)) { @@ -65,7 +65,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { if (!maybeIdleTimeout.IsEmpty() && !maybeIdleTimeout.ToLocalChecked()->IsUndefined()) { behavior.idleTimeout = maybeIdleTimeout.ToLocalChecked()->Int32Value(isolate->GetCurrentContext()).ToChecked(); } - + /* closeOnBackpressureLimit or default */ MaybeLocal maybeCloseOnBackpressureLimit = behaviorObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "closeOnBackpressureLimit", NewStringType::kNormal).ToLocalChecked()); if (!maybeCloseOnBackpressureLimit.IsEmpty() && !maybeCloseOnBackpressureLimit.ToLocalChecked()->IsUndefined()) { @@ -179,7 +179,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { CallJS(isolate, Local::New(isolate, messagePf), 3, argv); /* Important: we clear the ArrayBuffer to make sure it is not invalidly used after return */ - NeuterArrayBuffer(messageArrayBuffer); + messageArrayBuffer->Detach(); }; } @@ -197,7 +197,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { /* Ping handler is always optional */ if (pingPf != Undefined(isolate)) { - behavior.ping = [pingPf = std::move(pingPf), isolate](auto *ws) { + behavior.ping = [pingPf = std::move(pingPf), isolate](auto *ws, std::string_view message) { HandleScope hs(isolate); PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); @@ -208,7 +208,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { /* Pong handler is always optional */ if (pongPf != Undefined(isolate)) { - behavior.pong = [pongPf = std::move(pongPf), isolate](auto *ws) { + behavior.pong = [pongPf = std::move(pongPf), isolate](auto *ws, std::string_view message) { HandleScope hs(isolate); PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); @@ -239,7 +239,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { perSocketData->socketPf.Reset(); /* Again, here we clear the buffer to avoid strange bugs */ - NeuterArrayBuffer(messageArrayBuffer); + messageArrayBuffer->Detach(); }; app->template ws(std::string(pattern.getString()), std::move(behavior)); @@ -355,7 +355,7 @@ void uWS_App_publish(const FunctionCallbackInfo &args) { return; } - app->publish(topic.getString(), message.getString(), BooleanValue(isolate, args[2]) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, BooleanValue(isolate, args[3])); + app->publish(topic.getString(), message.getString(), args[2]->BooleanValue(isolate) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, args[3]->BooleanValue(isolate)); } /* This one modified per-thread static strings temporarily */ @@ -419,7 +419,7 @@ std::pair readOptionsObject(const FunctionCallb } /* ssl_prefer_low_memory_usage */ - options.ssl_prefer_low_memory_usage = BooleanValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ssl_prefer_low_memory_usage", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + options.ssl_prefer_low_memory_usage = optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ssl_prefer_low_memory_usage", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()->BooleanValue(isolate); } return {options, true}; diff --git a/src/HttpRequestWrapper.h b/src/HttpRequestWrapper.h index 53e5934..969f5e8 100644 --- a/src/HttpRequestWrapper.h +++ b/src/HttpRequestWrapper.h @@ -95,7 +95,7 @@ struct HttpRequestWrapper { Isolate *isolate = args.GetIsolate(); auto *req = getHttpRequest(args); if (req) { - bool yield = BooleanValue(args.GetIsolate(), args[0]); + bool yield = args[0]->BooleanValue(isolate); req->setYield(yield); args.GetReturnValue().Set(args.Holder()); diff --git a/src/HttpResponseWrapper.h b/src/HttpResponseWrapper.h index dec0f7e..440bbd9 100644 --- a/src/HttpResponseWrapper.h +++ b/src/HttpResponseWrapper.h @@ -66,7 +66,7 @@ struct HttpResponseWrapper { Local argv[] = {dataArrayBuffer, Boolean::New(isolate, last)}; CallJS(isolate, Local::New(isolate, p), 2, argv); - NeuterArrayBuffer(dataArrayBuffer); + dataArrayBuffer->Detach(); }); args.GetReturnValue().Set(args.Holder()); @@ -181,7 +181,7 @@ struct HttpResponseWrapper { exit(-1); } - return BooleanValue(isolate, maybeBoolean.ToLocalChecked()); + return maybeBoolean.ToLocalChecked()->BooleanValue(isolate); /* How important is this return? */ }); @@ -216,7 +216,7 @@ struct HttpResponseWrapper { bool closeConnection = false; if (args.Length() >= 2) { - closeConnection = BooleanValue(args.GetIsolate(), args[1]); + closeConnection = args[1]->BooleanValue(args.GetIsolate()); } invalidateResObject(args); diff --git a/src/Utilities.h b/src/Utilities.h index 1f0238a..eb2037d 100644 --- a/src/Utilities.h +++ b/src/Utilities.h @@ -1,5 +1,5 @@ /* - * Authored by Alex Hultman, 2018-2020. + * Authored by Alex Hultman, 2018-2021. * Intellectual property of third-party. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,13 +25,8 @@ using namespace v8; #include MaybeLocal CallJS(Isolate *isolate, Local f, int argc, Local *argv) { - if (experimental_fastcall) { - /* Fast path */ - return f->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), argc, argv); - } else { - /* Slow path */ - return node::MakeCallback(isolate, isolate->GetCurrentContext()->Global(), f, argc, argv, {0, 0}); - } + /* Slow path */ + return node::MakeCallback(isolate, isolate->GetCurrentContext()->Global(), f, argc, argv, {0, 0}); } struct PerSocketData { diff --git a/src/WebSocketWrapper.h b/src/WebSocketWrapper.h index f872620..4afcc9f 100644 --- a/src/WebSocketWrapper.h +++ b/src/WebSocketWrapper.h @@ -26,9 +26,9 @@ using namespace v8; struct WebSocketWrapper { template - static inline uWS::WebSocket *getWebSocket(const FunctionCallbackInfo &args) { + static inline uWS::WebSocket *getWebSocket(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); - auto *ws = (uWS::WebSocket *) args.Holder()->GetAlignedPointerFromInternalField(0); + auto *ws = (uWS::WebSocket *) args.Holder()->GetAlignedPointerFromInternalField(0); if (!ws) { args.GetReturnValue().Set(isolate->ThrowException(String::NewFromUtf8(isolate, "Invalid access of closed uWS.WebSocket/SSLWebSocket.", NewStringType::kNormal).ToLocalChecked())); } @@ -49,7 +49,7 @@ struct WebSocketWrapper { if (topic.isInvalid(args)) { return; } - bool nonStrict = args.Length() > 1 && BooleanValue(isolate, args[1]); + bool nonStrict = args.Length() > 1 && args[1]->BooleanValue(isolate); ws->subscribe(topic.getString(), nonStrict); } } @@ -64,7 +64,7 @@ struct WebSocketWrapper { if (topic.isInvalid(args)) { return; } - bool nonStrict = args.Length() > 1 && BooleanValue(isolate, args[1]); + bool nonStrict = args.Length() > 1 && args[1]->BooleanValue(isolate); bool success = ws->unsubscribe(topic.getString(), nonStrict); args.GetReturnValue().Set(Boolean::New(isolate, success)); } @@ -89,7 +89,7 @@ struct WebSocketWrapper { return; } - ws->publish(topic.getString(), message.getString(), BooleanValue(isolate, args[2]) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, BooleanValue(isolate, args[3])); + ws->publish(topic.getString(), message.getString(), args[2]->BooleanValue(isolate) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, args[3]->BooleanValue(isolate)); } } @@ -175,7 +175,7 @@ struct WebSocketWrapper { return; } - bool ok = ws->send(message.getString(), BooleanValue(isolate, args[1]) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, BooleanValue(isolate, args[2])); + bool ok = ws->send(message.getString(), args[1]->BooleanValue(isolate) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, args[2]->BooleanValue(isolate)); args.GetReturnValue().Set(Boolean::New(isolate, ok)); } @@ -199,17 +199,6 @@ struct WebSocketWrapper { } } - /* Takes nothing, returns this */ - template - static void uWS_WebSocket_unsubscribeAll(const FunctionCallbackInfo &args) { - Isolate *isolate = args.GetIsolate(); - auto *ws = getWebSocket(args); - if (ws) { - ws->unsubscribeAll(); - args.GetReturnValue().Set(args.Holder()); - } - } - /* Takes function, returns this */ template static void uWS_WebSocket_cork(const FunctionCallbackInfo &args) { @@ -245,7 +234,6 @@ struct WebSocketWrapper { wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "subscribe", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_subscribe)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "unsubscribe", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_unsubscribe)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "publish", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_publish)); - wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "unsubscribeAll", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_unsubscribeAll)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "cork", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_cork)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "ping", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_ping)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getRemoteAddressAsText", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_WebSocket_getRemoteAddressAsText)); diff --git a/src/addon.cpp b/src/addon.cpp index 690dcf0..53b2bc3 100644 --- a/src/addon.cpp +++ b/src/addon.cpp @@ -22,34 +22,9 @@ #include #include -/* This one can never change for the duration of this process, so never mind per context data:ing it, yes that is a word now */ -bool experimental_fastcall = 0; - #include using namespace v8; -/* Compatibility for V8 7.0 and earlier */ -#include -bool BooleanValue(Isolate *isolate, Local value) { - #if V8_MAJOR_VERSION < 7 || (V8_MAJOR_VERSION == 7 && V8_MINOR_VERSION == 0) - /* Old */ - return value->BooleanValue(isolate->GetCurrentContext()).ToChecked(); - #else - /* Node.js 12, 13 */ - return value->BooleanValue(isolate); - #endif -} - -void NeuterArrayBuffer(Local ab) { - #if V8_MAJOR_VERSION < 7 || (V8_MAJOR_VERSION == 7 && V8_MINOR_VERSION == 0) - /* Old */ - ab->Neuter(); - #else - /* Node.js 12, 13 */ - ab->Detach(); - #endif -} - #include "Utilities.h" #include "WebSocketWrapper.h" #include "HttpResponseWrapper.h" @@ -351,18 +326,9 @@ void uWS_unlock(const FunctionCallbackInfo &args) { PerContextData *Main(Local exports) { - /* We only care if it is defined, not what it says */ - experimental_fastcall = getenv("EXPERIMENTAL_FASTCALL") != nullptr; - /* We pass isolate everywhere */ Isolate *isolate = exports->GetIsolate(); - if (experimental_fastcall) { - /* We want this so that we can redefine process.nextTick to using the V8 native microtask queue */ - /* Settings this crashes Node.js while debugging with breakpoints */ - isolate->SetMicrotasksPolicy(MicrotasksPolicy::kAuto); - } - /* Init the template objects, SSL and non-SSL, store it in per context data */ PerContextData *perContextData = new PerContextData; perContextData->isolate = isolate; diff --git a/src/uws.js b/src/uws.js index 079baea..f7658c8 100644 --- a/src/uws.js +++ b/src/uws.js @@ -1,5 +1,5 @@ /* - * Authored by Alex Hultman, 2018-2020. + * Authored by Alex Hultman, 2018-2021. * Intellectual property of third-party. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,15 +17,7 @@ module.exports = (() => { try { - const uWS = require('./uws_' + process.platform + '_' + process.arch + '_' + process.versions.modules + '.node'); - if (process.env.EXPERIMENTAL_FASTCALL) { - process.nextTick = (f, ...args) => { - Promise.resolve().then(() => { - f(...args); - }); - }; - } - return uWS; + return require('./uws_' + process.platform + '_' + process.arch + '_' + process.versions.modules + '.node'); } catch (e) { throw new Error('This version of µWS is not compatible with your Node.js build:\n\n' + e.toString()); } diff --git a/uWebSockets b/uWebSockets index a17a6a7..65d1498 160000 --- a/uWebSockets +++ b/uWebSockets @@ -1 +1 @@ -Subproject commit a17a6a7268ee6d17c7aec51afa27264c1981aec6 +Subproject commit 65d1498774af82b201ad15e42a43554a583de147