Introduce CallJS and corresponding PERFORM_LIKE_GARBAGE flag
This commit is contained in:
parent
68fde105e6
commit
df4aeb8274
@ -88,7 +88,7 @@ void uWS_App_ws(const FunctionCallbackInfo<Value> &args) {
|
||||
Local<Function> openLf = Local<Function>::New(isolate, openPf);
|
||||
if (!openLf->IsUndefined()) {
|
||||
Local<Value> argv[] = {wsObject, reqObject};
|
||||
openLf->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 2, argv).IsEmpty();
|
||||
CallJS(isolate, openLf, 2, argv);
|
||||
}
|
||||
};
|
||||
|
||||
@ -103,7 +103,8 @@ void uWS_App_ws(const FunctionCallbackInfo<Value> &args) {
|
||||
Local<Value> argv[3] = {Local<Object>::New(isolate, *(perSocketData->socketPf)),
|
||||
messageArrayBuffer,
|
||||
Boolean::New(isolate, opCode == uWS::OpCode::BINARY)};
|
||||
Local<Function>::New(isolate, messagePf)->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 3, argv).IsEmpty();
|
||||
|
||||
CallJS(isolate, Local<Function>::New(isolate, messagePf), 3, argv);
|
||||
|
||||
/* Important: we clear the ArrayBuffer to make sure it is not invalidly used after return */
|
||||
messageArrayBuffer->Neuter();
|
||||
@ -118,7 +119,7 @@ void uWS_App_ws(const FunctionCallbackInfo<Value> &args) {
|
||||
PerSocketData *perSocketData = (PerSocketData *) ws->getUserData();
|
||||
Local<Value> argv[1] = {Local<Object>::New(isolate, *(perSocketData->socketPf))
|
||||
};
|
||||
Local<Function>::New(isolate, drainPf)->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 1, argv).IsEmpty();
|
||||
CallJS(isolate, Local<Function>::New(isolate, drainPf), 1, argv);
|
||||
};
|
||||
}
|
||||
|
||||
@ -146,7 +147,7 @@ void uWS_App_ws(const FunctionCallbackInfo<Value> &args) {
|
||||
Local<Function> closeLf = Local<Function>::New(isolate, closePf);
|
||||
if (!closeLf->IsUndefined()) {
|
||||
Local<Value> argv[3] = {wsObject, Integer::New(isolate, code), messageArrayBuffer};
|
||||
closeLf->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 3, argv).IsEmpty();
|
||||
CallJS(isolate, closeLf, 3, argv);
|
||||
}
|
||||
|
||||
delete perSocketData->socketPf;
|
||||
@ -186,7 +187,7 @@ void uWS_App_get(F f, const FunctionCallbackInfo<Value> &args) {
|
||||
reqObject->SetAlignedPointerInInternalField(0, req);
|
||||
|
||||
Local<Value> argv[] = {resObject, reqObject};
|
||||
cb.Get(isolate)->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 2, argv).IsEmpty();
|
||||
CallJS(isolate, cb.Get(isolate), 2, argv);
|
||||
|
||||
/* Properly invalidate req */
|
||||
reqObject->SetAlignedPointerInInternalField(0, nullptr);
|
||||
@ -215,7 +216,7 @@ void uWS_App_listen(const FunctionCallbackInfo<Value> &args) {
|
||||
auto cb = [&args, isolate](auto *token) {
|
||||
/* Return a false boolean if listen failed */
|
||||
Local<Value> argv[] = {token ? Local<Value>::Cast(External::New(isolate, token)) : Local<Value>::Cast(Boolean::New(isolate, false))};
|
||||
Local<Function>::Cast(args[args.Length() - 1])->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 1, argv).IsEmpty();
|
||||
CallJS(isolate, Local<Function>::Cast(args[args.Length() - 1]), 1, argv);
|
||||
};
|
||||
|
||||
/* Host is first, if present */
|
||||
|
@ -28,6 +28,7 @@ struct HttpRequestWrapper {
|
||||
for (auto p : *req) {
|
||||
Local<Value> argv[] = {String::NewFromUtf8(isolate, p.first.data(), NewStringType::kNormal, p.first.length()).ToLocalChecked(),
|
||||
String::NewFromUtf8(isolate, p.second.data(), NewStringType::kNormal, p.second.length()).ToLocalChecked()};
|
||||
/* This one is also called from JS so no need for CallJS */
|
||||
cb->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 2, argv).IsEmpty();
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ struct HttpResponseWrapper {
|
||||
Local<ArrayBuffer> dataArrayBuffer = ArrayBuffer::New(isolate, (void *) data.data(), data.length());
|
||||
|
||||
Local<Value> argv[] = {dataArrayBuffer, Boolean::New(isolate, last)};
|
||||
Local<Function>::New(isolate, p)->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 2, argv).IsEmpty();
|
||||
CallJS(isolate, Local<Function>::New(isolate, p), 2, argv);
|
||||
|
||||
dataArrayBuffer->Neuter();
|
||||
});
|
||||
@ -74,7 +74,7 @@ struct HttpResponseWrapper {
|
||||
/* Mark this resObject invalid */
|
||||
Local<Object>::New(isolate, resObject)->SetAlignedPointerInInternalField(0, nullptr);
|
||||
|
||||
Local<Function>::New(isolate, p)->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 0, nullptr).IsEmpty();
|
||||
CallJS(isolate, Local<Function>::New(isolate, p), 0, nullptr);
|
||||
});
|
||||
|
||||
args.GetReturnValue().Set(args.Holder());
|
||||
@ -119,7 +119,7 @@ struct HttpResponseWrapper {
|
||||
Local<Value> argv[] = {Integer::NewFromUnsigned(isolate, offset)};
|
||||
|
||||
/* We should check if this is really here! */
|
||||
MaybeLocal<Value> maybeBoolean = Local<Function>::New(isolate, p)->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 1, argv);
|
||||
MaybeLocal<Value> maybeBoolean = CallJS(isolate, Local<Function>::New(isolate, p), 1, argv);
|
||||
if (maybeBoolean.IsEmpty()) {
|
||||
std::cerr << "ERROR! onWritable must return a boolean value according to documentation!" << std::endl;
|
||||
exit(-1);
|
||||
@ -240,6 +240,7 @@ struct HttpResponseWrapper {
|
||||
if (res) {
|
||||
|
||||
res->cork([cb = Local<Function>::Cast(args[0]), isolate]() {
|
||||
/* This one is called from JS so we don't need CallJS */
|
||||
cb->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 0, nullptr).IsEmpty();
|
||||
});
|
||||
|
||||
|
@ -4,6 +4,23 @@
|
||||
#include <v8.h>
|
||||
using namespace v8;
|
||||
|
||||
/* Unfortunately we have to perform like garbage to be friends with Node.js */
|
||||
#define PERFORM_LIKE_GARBAGE
|
||||
|
||||
/* Unfortunately we have to depend on Node.js garbage */
|
||||
#include <node.h>
|
||||
|
||||
/* This is a very hot function ruined by illiteracy */
|
||||
MaybeLocal<Value> CallJS(Isolate *isolate, Local<Function> f, int argc, Local<Value> *argv) {
|
||||
#ifdef PERFORM_LIKE_GARBAGE
|
||||
/* Node.js is built by incompetent people who should never have touched a computer in the first place */
|
||||
return node::MakeCallback(isolate, isolate->GetCurrentContext()->Global(), f, argc, argv, {0, 0});
|
||||
#else
|
||||
/* Google LLC don't hire incompetent people to work on their stuff */
|
||||
return f->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), argc, argv);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct PerContextData {
|
||||
Isolate *isolate;
|
||||
UniquePersistent<Object> reqTemplate;
|
||||
|
@ -157,6 +157,7 @@ struct WebSocketWrapper {
|
||||
if (ws) {
|
||||
|
||||
ws->cork([cb = Local<Function>::Cast(args[0]), isolate]() {
|
||||
/* No need for CallJS here */
|
||||
cb->Call(isolate->GetCurrentContext(), isolate->GetCurrentContext()->Global(), 0, nullptr).IsEmpty();
|
||||
});
|
||||
|
||||
|
@ -82,9 +82,11 @@ void Main(Local<Object> exports) {
|
||||
/* We pass isolate everywhere */
|
||||
Isolate *isolate = exports->GetIsolate();
|
||||
|
||||
#ifndef PERFORM_LIKE_GARBAGE
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
/* Init the template objects, SSL and non-SSL, store it in per context data */
|
||||
PerContextData *perContextData = new PerContextData;
|
||||
|
@ -18,11 +18,6 @@
|
||||
module.exports = (() => {
|
||||
try {
|
||||
const uWS = require('./uws_' + process.platform + '_' + process.arch + '_' + process.versions.modules + '.node');
|
||||
process.nextTick = (f, ...args) => {
|
||||
Promise.resolve().then(() => {
|
||||
f(...args);
|
||||
});
|
||||
};
|
||||
process.on('exit', uWS.free);
|
||||
return uWS;
|
||||
} catch (e) {
|
||||
|
Loading…
Reference in New Issue
Block a user