mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Key fixes: - Replace `base::WeakPtrFactory` with `gin::WeakCellFactory` in MenuMac, MenuViews, and NetLog, since weak pointers to cppgc-managed objects must go through weak cells - Replace `v8::Global<v8::Value>` with `cppgc::Persistent<Menu>` for the menu reference in BaseWindow - Stop using `gin_helper::Handle<T>` with cppgc types; use raw `T*` and add a `static_assert` to prevent future misuse - Add proper `Trace()` overrides for Menu, MenuMac, MenuViews, and NetLog to ensure cppgc members are visited during garbage collection - Replace `SelfKeepAlive` prevent-GC mechanism in Menu with a `cppgc::Persistent` prevent-GC captured in `BindSelfToClosure` - Introduce `GC_PLUGIN_IGNORE` macro to suppress known-safe violations: mojo::Remote fields, ObjC bridging pointers, and intentional persistent self-references - Mark `ArgumentHolder` as `CPPGC_STACK_ALLOCATED()` in both Electron's and gin's function_template.h to silence raw-pointer-to-GC-type warnings
111 lines
3.4 KiB
C++
111 lines
3.4 KiB
C++
// Copyright (c) 2020 Samuel Maddock <sam@samuelmaddock.com>.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "shell/common/gin_converters/frame_converter.h"
|
|
|
|
#include "content/public/browser/render_frame_host.h"
|
|
#include "content/public/browser/render_process_host.h"
|
|
#include "shell/browser/api/electron_api_web_frame_main.h"
|
|
#include "shell/common/gin_helper/accessor.h"
|
|
#include "shell/common/gin_helper/handle.h"
|
|
#include "shell/common/node_util.h"
|
|
|
|
namespace gin {
|
|
|
|
// static
|
|
v8::Local<v8::Value> Converter<content::FrameTreeNodeId>::ToV8(
|
|
v8::Isolate* isolate,
|
|
const content::FrameTreeNodeId& val) {
|
|
return v8::Number::New(isolate, val.value());
|
|
}
|
|
|
|
// static
|
|
v8::Local<v8::Value> Converter<content::RenderFrameHost*>::ToV8(
|
|
v8::Isolate* isolate,
|
|
content::RenderFrameHost* val) {
|
|
if (!val)
|
|
return v8::Null(isolate);
|
|
return electron::api::WebFrameMain::From(isolate, val).ToV8();
|
|
}
|
|
|
|
// static
|
|
bool Converter<content::RenderFrameHost*>::FromV8(
|
|
v8::Isolate* isolate,
|
|
v8::Local<v8::Value> val,
|
|
content::RenderFrameHost** out) {
|
|
electron::api::WebFrameMain* web_frame_main = nullptr;
|
|
if (!ConvertFromV8(isolate, val, &web_frame_main))
|
|
return false;
|
|
*out = web_frame_main->render_frame_host();
|
|
|
|
return true;
|
|
}
|
|
|
|
// static
|
|
v8::Local<v8::Value>
|
|
Converter<gin_helper::AccessorValue<content::RenderFrameHost*>>::ToV8(
|
|
v8::Isolate* isolate,
|
|
gin_helper::AccessorValue<content::RenderFrameHost*> val) {
|
|
content::RenderFrameHost* rfh = val.Value;
|
|
if (!rfh)
|
|
return v8::Null(isolate);
|
|
|
|
const int32_t process_id = rfh->GetProcess()->GetID().GetUnsafeValue();
|
|
const int routing_id = rfh->GetRoutingID();
|
|
|
|
v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
|
|
templ->SetInternalFieldCount(2);
|
|
|
|
v8::Local<v8::Object> rfh_obj =
|
|
templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
|
|
|
|
rfh_obj->SetInternalField(0, v8::Number::New(isolate, process_id));
|
|
rfh_obj->SetInternalField(1, v8::Number::New(isolate, routing_id));
|
|
|
|
return rfh_obj;
|
|
}
|
|
|
|
// static
|
|
bool Converter<gin_helper::AccessorValue<content::RenderFrameHost*>>::FromV8(
|
|
v8::Isolate* isolate,
|
|
v8::Local<v8::Value> val,
|
|
gin_helper::AccessorValue<content::RenderFrameHost*>* out) {
|
|
v8::Local<v8::Object> rfh_obj;
|
|
if (!ConvertFromV8(isolate, val, &rfh_obj))
|
|
return false;
|
|
|
|
if (rfh_obj->InternalFieldCount() != 2)
|
|
return false;
|
|
|
|
v8::Local<v8::Value> process_id_wrapper =
|
|
rfh_obj->GetInternalField(0).As<v8::Value>();
|
|
v8::Local<v8::Value> routing_id_wrapper =
|
|
rfh_obj->GetInternalField(1).As<v8::Value>();
|
|
|
|
if (process_id_wrapper.IsEmpty() || !process_id_wrapper->IsNumber() ||
|
|
routing_id_wrapper.IsEmpty() || !routing_id_wrapper->IsNumber())
|
|
return false;
|
|
|
|
const int process_id = process_id_wrapper.As<v8::Number>()->Value();
|
|
const int routing_id = routing_id_wrapper.As<v8::Number>()->Value();
|
|
|
|
auto* rfh = content::RenderFrameHost::FromID(process_id, routing_id);
|
|
|
|
if (!rfh) {
|
|
// Lazily evaluated property accessed after RFH has been destroyed.
|
|
// Continue to return nullptr, but emit warning to inform developers
|
|
// what occurred.
|
|
electron::util::EmitWarning(
|
|
isolate,
|
|
"Frame property was accessed after it navigated or was destroyed. "
|
|
"Avoid asynchronous tasks prior to indexing.",
|
|
"electron");
|
|
}
|
|
|
|
out->Value = rfh;
|
|
return true;
|
|
}
|
|
|
|
} // namespace gin
|