From 84113716d13906e385e780e5e59ca7e85737b83d Mon Sep 17 00:00:00 2001 From: etkmao Date: Wed, 9 Aug 2023 13:04:06 +0800 Subject: [PATCH] fix(jsc): fix gc finalize private data invalid crash --- driver/js/include/driver/vm/jsc/jsc_vm.h | 9 ++++++++- driver/js/src/napi/jsc/jsc_ctx.cc | 5 +++++ driver/js/src/vm/jsc/jsc_vm.cc | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/driver/js/include/driver/vm/jsc/jsc_vm.h b/driver/js/include/driver/vm/jsc/jsc_vm.h index 36ceafb90fc..d235163e76a 100644 --- a/driver/js/include/driver/vm/jsc/jsc_vm.h +++ b/driver/js/include/driver/vm/jsc/jsc_vm.h @@ -23,7 +23,7 @@ #pragma once #include "driver/vm/js_vm.h" - +#include #include #include "footstone/string_view.h" @@ -49,6 +49,13 @@ class JSCVM : public VM, public std::enable_shared_from_this { std::unordered_map>> constructor_data_holder_; JSContextGroupRef vm_; + static void SaveConstructorDataPtr(void* ptr); + static void ClearConstructorDataPtr(void* ptr); + static bool IsValidConstructorDataPtr(void* ptr); + + static std::set constructor_data_ptr_set_; + static std::mutex mutex_; + virtual std::shared_ptr ParseJson(const std::shared_ptr& ctx, const string_view& json) override; virtual std::shared_ptr CreateContext() override; diff --git a/driver/js/src/napi/jsc/jsc_ctx.cc b/driver/js/src/napi/jsc/jsc_ctx.cc index 0c79151d32e..54007a88d01 100644 --- a/driver/js/src/napi/jsc/jsc_ctx.cc +++ b/driver/js/src/napi/jsc/jsc_ctx.cc @@ -70,6 +70,7 @@ JSCCtx::~JSCCtx() { auto& holder = jsc_vm->constructor_data_holder_[this]; for (auto& [key, item] : holder) { item->prototype = nullptr; + JSCVM::ClearConstructorDataPtr(item.get()); } } @@ -262,6 +263,9 @@ std::shared_ptr JSCCtx::DefineClass(const string_view& name, if (!private_data) { return; } + if (!JSCVM::IsValidConstructorDataPtr(private_data)) { + return; + } auto constructor_data = reinterpret_cast(private_data); auto weak_callback_wrapper = constructor_data->weak_callback_wrapper; if (weak_callback_wrapper) { @@ -974,6 +978,7 @@ void JSCCtx::SaveConstructorData(std::unique_ptr constructor_da if (it == holder.end()) { holder[this] = std::unordered_map>{}; } + JSCVM::SaveConstructorDataPtr(constructor_data.get()); holder[this][constructor_data->class_ref] = std::move(constructor_data); } diff --git a/driver/js/src/vm/jsc/jsc_vm.cc b/driver/js/src/vm/jsc/jsc_vm.cc index 6e92f5c3d40..eceeb8d1a97 100644 --- a/driver/js/src/vm/jsc/jsc_vm.cc +++ b/driver/js/src/vm/jsc/jsc_vm.cc @@ -37,6 +37,9 @@ namespace hippy { inline namespace driver { inline namespace vm { +std::set JSCVM::constructor_data_ptr_set_; +std::mutex JSCVM::mutex_; + std::shared_ptr JSCVM::ParseJson(const std::shared_ptr& ctx, const string_view& json) { if (footstone::StringViewUtils::IsEmpty(json)) { return nullptr; @@ -90,6 +93,21 @@ JSStringRef JSCVM::CreateJSCString(const string_view& str_view) { return ret; } +void JSCVM::SaveConstructorDataPtr(void* ptr) { + std::lock_guard lock(mutex_); + constructor_data_ptr_set_.insert(ptr); +} + +void JSCVM::ClearConstructorDataPtr(void* ptr) { + std::lock_guard lock(mutex_); + constructor_data_ptr_set_.erase(ptr); +} + +bool JSCVM::IsValidConstructorDataPtr(void* ptr) { + std::lock_guard lock(mutex_); + return constructor_data_ptr_set_.find(ptr) != constructor_data_ptr_set_.end(); +} + } } }