From e13127a24b5a0f2b01a22fdb3ef13785f6b6b90b Mon Sep 17 00:00:00 2001 From: cybran Date: Wed, 13 Dec 2023 15:21:00 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20=E6=96=B0=E5=A2=9E=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=AE=80=E6=98=93=E6=8A=A5=E9=94=99=E5=B9=B6=E4=BB=A5=E4=BB=A3?= =?UTF-8?q?=E7=A0=811=E9=80=80=E5=87=BA=E7=9A=84=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deps/miniv8/src/EmptyCFun.cpp | 40 +++++------ deps/miniv8/src/MiniV8Api.cpp | 121 +++++++++++++++++++++++---------- deps/miniv8/src/MiniV8Api.h | 56 ++++++++++++++- deps/miniv8/src/MiniV8Impl.cpp | 3 +- src/node_platform.cc | 9 ++- 5 files changed, 170 insertions(+), 59 deletions(-) diff --git a/deps/miniv8/src/EmptyCFun.cpp b/deps/miniv8/src/EmptyCFun.cpp index c7298776..b2fa8906 100644 --- a/deps/miniv8/src/EmptyCFun.cpp +++ b/deps/miniv8/src/EmptyCFun.cpp @@ -563,17 +563,17 @@ v8::Local v8::BigInt64Array::New(v8::Local, return v8::Local(); } -v8::Isolate* v8::Message::GetIsolate(void)const -{ - printEmptyFuncInfo(__FUNCTION__, true, true); - return nullptr; -} - -int v8::Message::ErrorLevel(void)const -{ - printEmptyFuncInfo(__FUNCTION__, true, true); - return 0; -} +//v8::Isolate* v8::Message::GetIsolate(void)const +//{ +// printEmptyFuncInfo(__FUNCTION__, true, true); +// return nullptr; +//} +// +//int v8::Message::ErrorLevel(void)const +//{ +// printEmptyFuncInfo(__FUNCTION__, true, true); +// return 0; +//} v8::Local v8::PropertyDescriptor::value(void)const { @@ -979,10 +979,10 @@ void v8::Isolate::SetHostCreateShadowRealmContextCallback(v8::MaybeLocal, v8::Local), int, v8::Local) -{ - printEmptyFuncInfo(__FUNCTION__, false, true); - return false; -} +//bool v8::Isolate::AddMessageListenerWithErrorLevel(void(__cdecl*)(v8::Local, v8::Local), int, v8::Local) +//{ +// printEmptyFuncInfo(__FUNCTION__, false, true); +// return false; +//} void v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(v8::Isolate*) { diff --git a/deps/miniv8/src/MiniV8Api.cpp b/deps/miniv8/src/MiniV8Api.cpp index 423ec085..1f281eb3 100644 --- a/deps/miniv8/src/MiniV8Api.cpp +++ b/deps/miniv8/src/MiniV8Api.cpp @@ -78,17 +78,26 @@ static JSValue jsPrint(JSContext* ctx, JSValueConst this_val, int argc, JSValueC return JS_UNDEFINED; } -void miniv8PrintWhenError(JSContext* ctx) +static v8::Local newError(v8::Local errorString, const char* type); + +void miniv8HandleError(miniv8::V8Isolate* isolate, JSContext* ctx) { JSValue exceptionVal = JS_GetException(ctx); BOOL isError = JS_IsError(ctx, exceptionVal); - jsPrint(ctx, JS_NULL, 1, &exceptionVal, nullptr, FALSE); + //jsPrint(ctx, JS_NULL, 1, &exceptionVal, nullptr, FALSE); + const char* error = JS_ToCString(ctx, exceptionVal); + OutputDebugStringA(error); + OutputDebugStringA("\n"); + std::string errorStr = error; + JS_FreeCString(ctx, exceptionVal, error); + std::string stackStr = ""; if (isError) { JSValue val = JS_GetPropertyStr(ctx, exceptionVal, "stack"); if (!JS_IsUndefined(val)) { const char* stack = JS_ToCString(ctx, val); + stackStr = stack; OutputDebugStringA(stack); OutputDebugStringA("\n"); JS_FreeCString(ctx, val, stack); @@ -96,6 +105,21 @@ void miniv8PrintWhenError(JSContext* ctx) JS_FreeValue(ctx, val); } JS_FreeValue(ctx, exceptionVal); + + const v8::MessageCallback errorCb = isolate->getErrorMessageCallback(); + if (!errorCb) { + return; + } + + const v8::HandleScope handle_scope((v8::Isolate*)isolate); + + miniv8::V8Message* msg = new miniv8::V8Message(); + msg->setIsolate(isolate); + msg->setMessageStr(std::move(errorStr)); + msg->setStackStr(std::move(stackStr)); + + errorCb(v8::Utils::convert(msg), + newError(v8::String::NewFromUtf8((v8::Isolate*)isolate, "error", v8::NewStringType::kNormal, -1).ToLocalChecked(), "")); } void miniv8ReleaseAssert(bool b, const char* info) @@ -3377,7 +3401,7 @@ v8::MaybeLocal v8::Function::Call(v8::Local context, v8: retV = JS_Call(ctx, self->v(self), funcObj ? funcObj->v(funcObj) : JS_NULL, argc, 0 != argc ? &argvWrap[0] : nullptr); if (JS_IsException(retV)) { - miniv8PrintWhenError(ctx); + miniv8HandleError(v8isolate, ctx); JS_FreeValue(ctx, retV); return v8::Undefined(isolate); } @@ -4760,13 +4784,6 @@ v8::Local v8::Isolate::ThrowException(v8::Local val) return v8::Utils::convert(new miniv8::V8Value(context, v)); } -v8::Local v8::Message::GetScriptResourceName(void) const -{ - printEmptyFuncInfo(__FUNCTION__, false, false); - DebugBreak(); - return v8::Local(); -} - v8::Local v8::NativeWeakMap::Get(v8::Local) { printEmptyFuncInfo(__FUNCTION__, false, false); @@ -4854,30 +4871,6 @@ v8::Maybe v8::Value::NumberValue(v8::Local context) const return v8::Just(0); } -v8::Maybe v8::Message::GetEndColumn(v8::Local) const -{ - printEmptyFuncInfo(__FUNCTION__, false, false); - v8::Maybe ret = v8::Just(0); - DebugBreak(); - return ret; -} - -v8::Maybe v8::Message::GetLineNumber(v8::Local) const -{ - printEmptyFuncInfo(__FUNCTION__, false, false); - v8::Maybe ret = v8::Just(0); - DebugBreak(); - return ret; -} - -v8::Maybe v8::Message::GetStartColumn(v8::Local) const -{ - printEmptyFuncInfo(__FUNCTION__, false, false); - v8::Maybe ret = v8::Just(0); - DebugBreak(); - return ret; -} - v8::Local v8::Promise::Resolver::GetPromise(void) { printEmptyFuncInfo(__FUNCTION__, false, false); @@ -5026,6 +5019,14 @@ v8::MaybeLocal v8::ScriptCompiler::Compile(v8::Local co return ret; } +bool v8::Isolate::AddMessageListenerWithErrorLevel(v8::MessageCallback listener, int, v8::Local) +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + miniv8::V8Isolate* isolate = (miniv8::V8Isolate*)this; + isolate->setErrorMessageCallback(listener); + return false; +} + void readFile(const wchar_t* path, std::vector* buffer) { HANDLE hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -5164,7 +5165,7 @@ v8::MaybeLocal v8::ScriptCompiler::CompileFunction( miniv8::V8Value* retVal = nullptr; if (JS_IsException(ret)) { - miniv8PrintWhenError(ctx->ctx()); + miniv8HandleError(isolate, ctx->ctx()); } else retVal = miniv8::V8Value::create(ctx, ret); JS_FreeValue(ctx->ctx(), ret); @@ -5392,7 +5393,7 @@ v8::MaybeLocal v8::Script::Run(v8::Local context) isolate->exitContext(); if (JS_IsException(ret)) { - miniv8PrintWhenError(ctx->ctx()); + miniv8HandleError(isolate, ctx->ctx()); } miniv8::V8Value* retVal = miniv8::V8Value::create(ctx, ret); @@ -6401,6 +6402,54 @@ void v8::internal::Internals::CheckInitializedImpl(v8::Isolate*) printEmptyFuncInfo(__FUNCTION__, false, false); } +v8::Isolate* v8::Message::GetIsolate(void)const +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + miniv8::V8Message* msg = v8::Utils::openHandle(this); + return (v8::Isolate*)(msg->getIsolate()); +} + +int v8::Message::ErrorLevel(void)const +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + miniv8::V8Message* msg = v8::Utils::openHandle(this); + return msg->getErrorLevel(); +} + +v8::Local v8::Message::GetScriptResourceName(void) const +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + miniv8::V8Message* msg = v8::Utils::openHandle(this); + + return v8::String::NewFromUtf8((v8::Isolate*)msg->getIsolate(), (msg->getMessageStr() + msg->getStackStr()).c_str()); +} + +v8::Maybe v8::Message::GetEndColumn(v8::Local) const +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + v8::Maybe ret = v8::Just(0); + return ret; +} + +v8::Maybe v8::Message::GetLineNumber(v8::Local) const +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + v8::Maybe ret = v8::Just(0); + return ret; +} + +v8::Maybe v8::Message::GetStartColumn(v8::Local) const +{ + printEmptyFuncInfo(__FUNCTION__, false, false); + v8::Maybe ret = v8::Just(0); + return ret; +} + +void v8::Isolate::DumpAndResetStats(void) +{ + printEmptyFuncInfo(__FUNCTION__, false, false); +} + namespace v8 { namespace platform { void SetTracingController(Platform*, platform::tracing::TracingController*) diff --git a/deps/miniv8/src/MiniV8Api.h b/deps/miniv8/src/MiniV8Api.h index 8f4525a7..c08b4f0b 100644 --- a/deps/miniv8/src/MiniV8Api.h +++ b/deps/miniv8/src/MiniV8Api.h @@ -25,7 +25,6 @@ void printEmptyFuncInfo(const char* fun, bool isBreak, bool isPrint); void miniv8ReleaseAssert(bool b, const char* info); -void miniv8PrintWhenError(JSContext* ctx); extern "C" void printDebug(const char* format, ...); #define V8CALL @@ -148,6 +147,9 @@ enum V8ObjectType : intptr_t { kOTObjectTemplate, kOTFunctionTemplate, kOTSignature, + + kOTMessage, + kOTMax }; @@ -289,6 +291,9 @@ public: const v8::Isolate::CreateParams& getCreateParams() const { return m_v8CreateParams; } + void setErrorMessageCallback(v8::MessageCallback cb) { m_errorMessageCallback = cb; } + v8::MessageCallback getErrorMessageCallback() const { return m_errorMessageCallback; } + static const int kSlotSize = 64 * 10; void* m_apiPointer[kSlotSize]; // 这个必须放最前面,v8的机制如此 void* m_eternals[kSlotSize]; // 这个好像是存放固定的v8::Value @@ -392,6 +397,8 @@ private: std::set m_activedObjectGroupId; // 哪些group是激活态 static TlsIndexType m_inst; + + v8::MessageCallback m_errorMessageCallback; }; class V8StackTrace { @@ -417,6 +424,51 @@ public: V8Head m_head; }; +class V8Message { +public: + V8Message() + { + m_head.m_type = kOTMessage; + m_head.m_refOrDeref = onV8HeadRefOrDerefOfV8Message; + m_head.m_refOrDerefCopy = m_head.m_refOrDeref; + // 目前只管 error 的情况, 也就是默认输出 stderr 并且退出的情况, warn 等暂时不考虑 + m_errorLevel = v8::Isolate::MessageErrorLevel::kMessageError; + m_isolate = nullptr; + } + + static void onV8HeadRefOrDerefOfV8Message(V8Head* head, bool ref) + { + V8StackTrace* self = (V8StackTrace*)head; + if (!ref) + delete self; + } + + v8::Isolate::MessageErrorLevel getErrorLevel() const { return m_errorLevel; } + + void setIsolate(V8Isolate* isolate) { m_isolate = isolate; } + V8Isolate* getIsolate() const { return m_isolate; } + + void setMessageStr(std::string&& str) { + m_messageStr = std::move(str); + str.clear(); + } + std::string getMessageStr() const { return m_messageStr; } + + void setStackStr(std::string&& str) { + m_stackStr = std::move(str); + str.clear(); + } + std::string getStackStr() const { return m_stackStr; } + +private: + + V8Head m_head; + v8::Isolate::MessageErrorLevel m_errorLevel; + V8Isolate* m_isolate; + std::string m_messageStr; + std::string m_stackStr; +}; + class V8Object; class V8Context { @@ -1670,3 +1722,5 @@ public: }; } // v8 + +void miniv8HandleError(miniv8::V8Isolate* isolate, JSContext* ctx); \ No newline at end of file diff --git a/deps/miniv8/src/MiniV8Impl.cpp b/deps/miniv8/src/MiniV8Impl.cpp index 314e0059..85639fc6 100644 --- a/deps/miniv8/src/MiniV8Impl.cpp +++ b/deps/miniv8/src/MiniV8Impl.cpp @@ -927,6 +927,7 @@ void V8Isolate::init(const v8::Isolate::CreateParams& params) m_scopeHandleIndex = 0; m_callReentryCount = 0; m_lastGcMilliseconds = 0; + m_errorMessageCallback = nullptr; m_globalizeHandles.resize(kHandlesSize); m_globalizeCountHandles.resize(kHandlesSize); m_scopeHandles.resize(kHandlesSize); @@ -1764,7 +1765,7 @@ bool V8Object::SetPrototype(JSContext* ctx, miniv8::V8Value* protoVal) //printDebug("v8::Object::SetPrototype: %x, selfV:%I64u, protoVal:%p, %I64u\n", ret, selfV, protoVal, protoV); if (-1 == ret) { // -1пprotoVԭϣѾvˡһglobal.prototypeprototypeʱ - miniv8PrintWhenError(ctx); + miniv8HandleError(V8Isolate::GetCurrent(), ctx); DebugBreak(); // JSValue global = JS_GetGlobalObject(ctx); // JSValue globalPrototype = JS_GetPrototypeFree(ctx, global); diff --git a/src/node_platform.cc b/src/node_platform.cc index 5c02e73f..c36f236d 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -285,7 +285,14 @@ void PerIsolatePlatformData::PostNonNestableDelayedTask( } PerIsolatePlatformData::~PerIsolatePlatformData() { - CHECK(!flush_tasks_); + // 쳣˳ʱ: + // node PerIsolatePlatformData::Shutdown, flush_tasks_ ʵ޷ + // ʱ node ִ per_isolate_.clear(), ü > 1, , ֱ˳ + // Ȼ mininode ȱһЩ, per_isolate_.clear() ʱִ, ± + // todo: 취 + // mininode begin + // CHECK(!flush_tasks_); + // mininode end } void PerIsolatePlatformData::AddShutdownCallback(void (*callback)(void*), -- Gitee