From 01380e2d2843df5e09b590fc726176fd0a666b0f Mon Sep 17 00:00:00 2001 From: wangyimin Date: Mon, 24 Mar 2025 21:21:49 +0800 Subject: [PATCH] fix regression Signed-off-by: wangyimin --- src/js_native_api_v8.cpp | 6 ++- src/jsvm_env.cpp | 1 + src/jsvm_env.h | 3 +- src/jsvm_reference-inl.h | 112 +++++++++++++++++++++++++++++++++++++++ src/jsvm_reference.cpp | 85 +---------------------------- src/jsvm_reference.h | 18 ++----- 6 files changed, 124 insertions(+), 101 deletions(-) create mode 100644 src/jsvm_reference-inl.h diff --git a/src/js_native_api_v8.cpp b/src/js_native_api_v8.cpp index 1efcc74..a3a042e 100644 --- a/src/js_native_api_v8.cpp +++ b/src/js_native_api_v8.cpp @@ -32,7 +32,7 @@ #include "jsvm.h" #include "jsvm_env.h" #include "jsvm_log.h" -#include "jsvm_reference.h" +#include "jsvm_reference-inl.h" #include "jsvm_util.h" #include "libplatform/libplatform.h" #include "libplatform/v8-tracing.h" @@ -3258,7 +3258,9 @@ JSVM_Status OH_JSVM_CreateExternal(JSVM_Env env, v8::Local externalValue = v8::External::New(isolate, data); - v8impl::RuntimeReference::New(env, externalValue, finalizeCb, data, finalizeHint); + if (finalizeCb) { + v8impl::RuntimeReference::New(env, externalValue, finalizeCb, data, finalizeHint); + } *result = v8impl::JsValueFromV8LocalValue(externalValue); diff --git a/src/jsvm_env.cpp b/src/jsvm_env.cpp index 7226973..b69ab52 100644 --- a/src/jsvm_env.cpp +++ b/src/jsvm_env.cpp @@ -14,6 +14,7 @@ */ #include "jsvm_env.h" +#include "jsvm_reference-inl.h" #include "libplatform/libplatform.h" diff --git a/src/jsvm_env.h b/src/jsvm_env.h index 05e8724..2a3bd3c 100644 --- a/src/jsvm_env.h +++ b/src/jsvm_env.h @@ -158,7 +158,6 @@ public: v8impl::Persistent contextPersistent; // Error info and execption - JSVM_ExtendedErrorInfo lastError; v8impl::Persistent lastException; // We store references in two different lists, depending on whether they have @@ -167,6 +166,8 @@ public: v8impl::RefList userReferenceList; v8impl::RefList finalizerList; + JSVM_ExtendedErrorInfo lastError; + // Store v8::Data std::stack>> dataStack; diff --git a/src/jsvm_reference-inl.h b/src/jsvm_reference-inl.h new file mode 100644 index 0000000..3fafec2 --- /dev/null +++ b/src/jsvm_reference-inl.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JSVM_REFERENCE_INL_H +#define JSVM_REFERENCE_INL_H +#include "jsvm_env.h" +#include "jsvm_reference.h" + +namespace v8impl { +inline bool CanBeHeldWeakly(v8::Local value) +{ + return value->IsObject() || value->IsSymbol(); +} + +// RefTracker +inline void RefTracker::Link(RefList* list) +{ + DCHECK(list != nullptr); + prev = list; + next = list->next; + if (next != nullptr) { + next->prev = this; + } + list->next = this; +} + +inline void RefTracker::Unlink() +{ + if (prev != nullptr) { + prev->next = next; + } + if (next != nullptr) { + next->prev = prev; + } + prev = nullptr; + next = nullptr; +} + +// UserReference +inline void UserReference::SetWeak() +{ + if (canBeWeak) { + persistent.SetWeak(); + } else { + persistent.Reset(); + } +} + +inline uint32_t UserReference::Ref() +{ + // If persistent is cleared by GC, return 0 unconditionally. + if (persistent.IsEmpty()) { + return 0; + } + + if (++refcount == 1) { + // If persistent can not be weak, it will be cleared in SetWeak(). + DCHECK(canBeWeak); + persistent.ClearWeak(); + } + + return refcount; +} + +inline uint32_t UserReference::Unref() +{ + // If persistent is cleared by GC, return 0 unconditionally. + if (persistent.IsEmpty() || refcount == 0) { + return 0; + } + + if (--refcount == 0) { + SetWeak(); + } + + return refcount; +} + +inline v8::Local UserReference::Get() +{ + DCHECK(isValue); + if (persistent.IsEmpty()) { + return v8::Local(); + } else { + return v8::Local::New(env->isolate, persistent).As(); + } +} + +inline v8::Local UserReference::GetData() +{ + if (persistent.IsEmpty()) { + return v8::Local(); + } else { + return v8::Local::New(env->isolate, persistent); + } +} + +} // namespace v8impl + +#endif \ No newline at end of file diff --git a/src/jsvm_reference.cpp b/src/jsvm_reference.cpp index 69d5bb8..ad917b2 100644 --- a/src/jsvm_reference.cpp +++ b/src/jsvm_reference.cpp @@ -13,35 +13,10 @@ * limitations under the License. */ -#include "jsvm_reference.h" - #include "js_native_api_v8.h" +#include "jsvm_reference-inl.h" namespace v8impl { -namespace { -// In JavaScript, weak references can be created for object types (Object, -// Function, and external Object) and for local symbols that are created with -// the `Symbol` function call. Global symbols created with the `Symbol.for` -// method cannot be weak references because they are never collected. -// Currently, V8 has no API to detect if a symbol is local or global. -// Until we have a V8 API for it, we consider that all symbols can be weak. -inline bool CanBeHeldWeakly(v8::Local value) -{ - return value->IsObject() || value->IsSymbol(); -} -} // namespace - -// RefTracker -inline void RefTracker::Link(RefList* list) -{ - DCHECK(list != nullptr); - prev = list; - next = list->next; - if (next != nullptr) { - next->prev = this; - } - list->next = this; -} void RefTracker::FinalizeAll(RefList* list) { @@ -93,64 +68,6 @@ void UserReference::Finalize() Unlink(); } -v8::Local UserReference::Get() -{ - DCHECK(isValue); - if (persistent.IsEmpty()) { - return v8::Local(); - } else { - return v8::Local::New(env->isolate, persistent).As(); - } -} - -v8::Local UserReference::GetData() -{ - if (persistent.IsEmpty()) { - return v8::Local(); - } else { - return v8::Local::New(env->isolate, persistent); - } -} - -void UserReference::SetWeak() -{ - if (canBeWeak) { - persistent.SetWeak(); - } else { - persistent.Reset(); - } -} - -uint32_t UserReference::Ref() -{ - // If persistent is cleared by GC, return 0 unconditionally. - if (persistent.IsEmpty()) { - return 0; - } - - if (++refcount == 1) { - // If persistent can not be weak, it will be cleared in SetWeak(). - DCHECK(canBeWeak); - persistent.ClearWeak(); - } - - return refcount; -} - -uint32_t UserReference::Unref() -{ - // If persistent is cleared by GC, return 0 unconditionally. - if (persistent.IsEmpty() || refcount == 0) { - return 0; - } - - if (--refcount == 0) { - SetWeak(); - } - - return refcount; -} - uint32_t UserReference::RefCount() { return refcount; diff --git a/src/jsvm_reference.h b/src/jsvm_reference.h index a0d9a4f..db4e59e 100644 --- a/src/jsvm_reference.h +++ b/src/jsvm_reference.h @@ -37,17 +37,7 @@ protected: inline void Link(RefList* list); - inline void Unlink() - { - if (prev != nullptr) { - prev->next = next; - } - if (next != nullptr) { - next->prev = prev; - } - prev = nullptr; - next = nullptr; - } + inline void Unlink(); private: RefList* next; @@ -68,8 +58,8 @@ public: uint32_t RefCount(); // Get v8::Local value - v8::Local Get(); - v8::Local GetData(); + inline v8::Local Get(); + inline v8::Local GetData(); bool IsValue() { @@ -86,9 +76,9 @@ private: private: v8impl::Persistent persistent; - bool isValue; JSVM_Env env; uint32_t refcount; + bool isValue; bool canBeWeak; }; -- Gitee