diff --git a/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch b/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch index 042769fc0f..3b203ed601 100644 --- a/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch +++ b/patches/chromium/chore_add_electron_objects_to_wrappablepointertag.patch @@ -8,10 +8,10 @@ electron objects that extend gin::Wrappable and gets allocated on the cpp heap diff --git a/gin/public/wrappable_pointer_tags.h b/gin/public/wrappable_pointer_tags.h -index 573bcb2e56068a2ade6d8ab28964b077487874fd..0321ca6d3c7e1ed541cc1beffb20b1db3d03a0c8 100644 +index 573bcb2e56068a2ade6d8ab28964b077487874fd..42add73062b723b03fc15ddcce905e4d5061c384 100644 --- a/gin/public/wrappable_pointer_tags.h +++ b/gin/public/wrappable_pointer_tags.h -@@ -74,7 +74,14 @@ enum WrappablePointerTag : uint16_t { +@@ -74,7 +74,15 @@ enum WrappablePointerTag : uint16_t { kTextInputControllerBindings, // content::TextInputControllerBindings kWebAXObjectProxy, // content::WebAXObjectProxy kWrappedExceptionHandler, // extensions::WrappedExceptionHandler @@ -21,6 +21,7 @@ index 573bcb2e56068a2ade6d8ab28964b077487874fd..0321ca6d3c7e1ed541cc1beffb20b1db + kElectronEvent, // gin_helper::internal::Event + kElectronMenu, // electron::api::Menu + kElectronNetLog, // electron::api::NetLog ++ kElectronReplyChannel, // gin_helper::internal::ReplyChannel + kElectronSession, // electron::api::Session + kElectronWebRequest, // electron::api::WebRequest + kLastPointerTag = kElectronWebRequest, diff --git a/shell/common/gin_helper/reply_channel.cc b/shell/common/gin_helper/reply_channel.cc index 9a4c7c4288..e1a4c96e80 100644 --- a/shell/common/gin_helper/reply_channel.cc +++ b/shell/common/gin_helper/reply_channel.cc @@ -4,42 +4,24 @@ #include "shell/common/gin_helper/reply_channel.h" -#include "base/debug/stack_trace.h" #include "gin/data_object_builder.h" #include "gin/object_template_builder.h" #include "shell/browser/javascript_environment.h" #include "shell/common/gin_converters/blink_converter.h" #include "shell/common/gin_helper/handle.h" +#include "v8/include/cppgc/allocation.h" +#include "v8/include/v8-cppgc.h" namespace gin_helper::internal { -// static -using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback; -gin_helper::Handle ReplyChannel::Create(v8::Isolate* isolate, - InvokeCallback callback) { - return gin_helper::CreateHandle(isolate, - new ReplyChannel(std::move(callback))); -} +const gin::WrapperInfo ReplyChannel::kWrapperInfo = { + {gin::kEmbedderNativeGin}, + gin::kElectronReplyChannel}; -gin::ObjectTemplateBuilder ReplyChannel::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return gin_helper::DeprecatedWrappable< - ReplyChannel>::GetObjectTemplateBuilder(isolate) - .SetMethod("sendReply", &ReplyChannel::SendReply); -} +ReplyChannel::ReplyChannel(v8::Isolate* isolate, InvokeCallback callback) + : callback_{std::move(callback)} {} -const char* ReplyChannel::GetTypeName() { - return "ReplyChannel"; -} - -ReplyChannel::ReplyChannel(InvokeCallback callback) - : callback_(std::move(callback)) {} - -ReplyChannel::~ReplyChannel() { - if (callback_) - SendError(electron::JavascriptEnvironment::GetIsolate(), - std::move(callback_), "reply was never sent"); -} +ReplyChannel::~ReplyChannel() = default; // static void ReplyChannel::SendError(v8::Isolate* isolate, @@ -73,11 +55,43 @@ bool ReplyChannel::SendReplyImpl(v8::Isolate* isolate, return true; } +// static +ReplyChannel* ReplyChannel::Create(v8::Isolate* isolate, + InvokeCallback callback) { + return cppgc::MakeGarbageCollected( + isolate->GetCppHeap()->GetAllocationHandle(), isolate, + std::move(callback)); +} + +const gin::WrapperInfo* ReplyChannel::wrapper_info() const { + return &kWrapperInfo; +} + +const char* ReplyChannel::GetHumanReadableName() const { + return "Electron / ReplyChannel"; +} + +gin::ObjectTemplateBuilder ReplyChannel::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return gin::Wrappable::GetObjectTemplateBuilder(isolate) + .SetMethod("sendReply", &ReplyChannel::SendReply); +} + bool ReplyChannel::SendReply(v8::Isolate* isolate, v8::Local arg) { return SendReplyImpl(isolate, std::move(callback_), std::move(arg)); } -gin::DeprecatedWrapperInfo ReplyChannel::kWrapperInfo = { - gin::kEmbedderNativeGin}; +void ReplyChannel::EnsureReplySent() { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + if (callback_) { + DCHECK(isolate); + // Create a task since we cannot allocate on V8 heap during GC + // which is needed by ReplyChannel::SendError implementation. + base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, + base::BindOnce(&ReplyChannel::SendError, isolate, std::move(callback_), + "reply was never sent")); + } +} } // namespace gin_helper::internal diff --git a/shell/common/gin_helper/reply_channel.h b/shell/common/gin_helper/reply_channel.h index 861e89a7d5..f6479551f3 100644 --- a/shell/common/gin_helper/reply_channel.h +++ b/shell/common/gin_helper/reply_channel.h @@ -7,8 +7,9 @@ #include +#include "gin/wrappable.h" #include "shell/common/api/api.mojom.h" -#include "shell/common/gin_helper/wrappable.h" +#include "v8/include/cppgc/prefinalizer.h" namespace gin_helper { template @@ -28,27 +29,38 @@ namespace gin_helper::internal { // This object wraps the InvokeCallback so that if it gets GC'd by V8, we can // still call the callback and send an error. Not doing so causes a Mojo DCHECK, // since Mojo requires callbacks to be called before they are destroyed. -class ReplyChannel : public gin_helper::DeprecatedWrappable { +class ReplyChannel : public gin::Wrappable { + CPPGC_USING_PRE_FINALIZER(ReplyChannel, EnsureReplySent); + public: using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback; - static gin_helper::Handle Create(v8::Isolate* isolate, - InvokeCallback callback); + + static ReplyChannel* Create(v8::Isolate* isolate, InvokeCallback callback); + + // Constructor is public only to satisfy cppgc::MakeGarbageCollected. + // Callers should use Create() instead. + explicit ReplyChannel(v8::Isolate* isolate, InvokeCallback callback); + ~ReplyChannel() override; + + // disable copy + ReplyChannel(const ReplyChannel&) = delete; + ReplyChannel& operator=(const ReplyChannel&) = delete; // gin_helper::Wrappable - static gin::DeprecatedWrapperInfo kWrapperInfo; + static const gin::WrapperInfo kWrapperInfo; + const gin::WrapperInfo* wrapper_info() const override; + const char* GetHumanReadableName() const override; gin::ObjectTemplateBuilder GetObjectTemplateBuilder( v8::Isolate* isolate) override; - const char* GetTypeName() override; // Invokes `callback` (if it's non-null) with `errmsg` as an arg. static void SendError(v8::Isolate* isolate, InvokeCallback callback, std::string_view errmsg); - private: - explicit ReplyChannel(InvokeCallback callback); - ~ReplyChannel() override; + void EnsureReplySent(); + private: static bool SendReplyImpl(v8::Isolate* isolate, InvokeCallback callback, v8::Local arg);