Files
electron/patches/node/src_remove_dependency_on_wrapper-descriptor-based_cppheap.patch
electron-roller[bot] 5d5e672f17 chore: bump chromium to 141.0.7361.0 (main) (#48054)
* chore: bump chromium in DEPS to 141.0.7352.0

* chore: update patches

* 6830573: Revert 'Migrate WrappableWithNamedPropertyInterceptor to gin::Wrappable' | https://chromium-review.googlesource.com/c/chromium/src/+/6830573

* chore: bump chromium in DEPS to 141.0.7354.0

* chore: bump chromium in DEPS to 141.0.7356.0

* chore: bump chromium in DEPS to 141.0.7357.0

* chore: bump chromium in DEPS to 141.0.7359.0

* chore: bump chromium in DEPS to 141.0.7361.0

* 6838518: [Mac] Correctly deallocate sandbox error buffers and prevent crash resulting from nullptr assignment | https://chromium-review.googlesource.com/c/chromium/src/+/6838518

* 6850973: Reland "Use base::ByteCount in base::SysInfo." | https://chromium-review.googlesource.com/c/chromium/src/+/6850973

* 6506565: [FPF-CI] Create initial NoiseHash in the browser. | https://chromium-review.googlesource.com/c/chromium/src/+/6506565

* chore: update patches

* fixup! 6850973: Reland "Use base::ByteCount in base::SysInfo." | https://chromium-review.googlesource.com/c/chromium/src/+/6850973

* fixup! 6506565: [FPF-CI] Create initial NoiseHash in the browser. | https://chromium-review.googlesource.com/c/chromium/src/+/6506565

* fix: unsafe buffer warning in fix_properly_honor_printing_page_ranges.patch

* fix: FTBFS in src_remove_dependency_on_wrapper-descriptor-based_cppheap.patch

This change should be upstreamed.

Fixes this error:

../../third_party/electron_node/src/env.cc:606:3: error: no matching function for call to 'Wrap'
  606 |   v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../v8/include/v8-object.h:1076:14: note: candidate function template not viable: cannot convert argument of incomplete type 'void *' to 'v8::Object::Wrappable *' for 3rd argument
 1076 | void Object::Wrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper,
      |              ^
 1077 |                   v8::Object::Wrappable* wrappable) {
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../v8/include/v8-object.h:1084:14: note: candidate function template not viable: no known conversion from 'Local<Object>' to 'const PersistentBase<Object>' for 2nd argument
 1084 | void Object::Wrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper,
      |              ^                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../v8/include/v8-object.h:1093:14: note: candidate function template not viable: no known conversion from 'Local<Object>' to 'const BasicTracedReference<Object>' for 2nd argument
 1093 | void Object::Wrap(v8::Isolate* isolate,
      |              ^
 1094 |                   const BasicTracedReference<Object>& wrapper,
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

* [v8-init] Access crash key only from main thread | https://chromium-review.googlesource.com/c/chromium/src/+/6827167

* chore: e patches all

* chore: remove chore_restore_some_deprecated_wrapper_utility_in_gin.patch from patches

this remove line got re-added when rebasing roller/chromium/main

* chore: e patches all

* fix: include base/time/time.h when using base::Time

* chore: update patches

* Make --host-rules an alias for --host-resolver-rules.

Refs https://chromium-review.googlesource.com/c/chromium/src/+/4867872

* ci: update BUILD_TOOLS_SHA

Refs https://github.com/electron/build-tools/pull/746

* [Fontations] Remove Fontations suffix from font names

Refs https://chromium-review.googlesource.com/c/chromium/src/+/6835930

* temp: debug macOS addon build failure

* Revert "temp: debug macOS addon build failure"

This reverts commit 40bc8abab65dc83e17c4ab97cb6e7522a193fb44.

* test: run tests with Xcode 16.4

* ci: fix tccdb update for macOS 15

* spec: disable opening external application for loadURL

on macOS opening unknown external application will bring
up dialog to choose apps from application store which will
break our other test suites that want to capture screen
for pixel matching.

The loadURL spec that tests bad-scheme://foo is sufficient
that we hit the permission handler for openExternal since
at that point we already know the runtime gave up on handling
the scheme.

* chore: rebase patches

* chore: disable codesiging tests

* ci: update ScreenCaptureApprovals.plist for /bin/bash

* ci: try updating tcc permissions

* ci: update TCC permissions

Refs https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive

* chore: test with 1st quadrant of the window

* chore: adjust for macOS 15 menubar height

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-08-29 12:31:47 +09:00

309 lines
13 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joyee Cheung <joyeec9h3@gmail.com>
Date: Wed, 29 May 2024 19:59:19 +0200
Subject: src: remove dependency on wrapper-descriptor-based CppHeap
As V8 has moved away from wrapper-descriptor-based CppHeap, this
patch:
1. Create the CppHeap without using wrapper descirptors.
2. Deprecates node::SetCppgcReference() in favor of
v8::Object::Wrap() since the wrapper descriptor is no longer
relevant. It is still kept as a compatibility layer for addons
that need to also work on Node.js versions without
v8::Object::Wrap().
(cherry picked from commit 30329d06235a9f9733b1d4da479b403462d1b326)
diff --git a/src/env-inl.h b/src/env-inl.h
index 0d32d9f5a55da257a5e5a895a2ff002b780f96fe..9567d9499c62ea44cca651e87ab912ad55e2d90b 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -62,31 +62,6 @@ inline uv_loop_t* IsolateData::event_loop() const {
return event_loop_;
}
-inline void IsolateData::SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable) {
- v8::CppHeap* heap = isolate->GetCppHeap();
- CHECK_NOT_NULL(heap);
- v8::WrapperDescriptor descriptor = heap->wrapper_descriptor();
- uint16_t required_size = std::max(descriptor.wrappable_instance_index,
- descriptor.wrappable_type_index);
- CHECK_GT(object->InternalFieldCount(), required_size);
-
- uint16_t* id_ptr = nullptr;
- {
- Mutex::ScopedLock lock(isolate_data_mutex_);
- auto it =
- wrapper_data_map_.find(descriptor.embedder_id_for_garbage_collected);
- CHECK_NE(it, wrapper_data_map_.end());
- id_ptr = &(it->second->cppgc_id);
- }
-
- object->SetAlignedPointerInInternalField(descriptor.wrappable_type_index,
- id_ptr);
- object->SetAlignedPointerInInternalField(descriptor.wrappable_instance_index,
- wrappable);
-}
-
inline uint16_t* IsolateData::embedder_id_for_cppgc() const {
return &(wrapper_data_->cppgc_id);
}
diff --git a/src/env.cc b/src/env.cc
index 63fdeeb26ba89284e74ca37050dfd170e7963331..56eb42643f26f3ebb447cb625d5422dcfa872189 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -23,6 +23,7 @@
#include "util-inl.h"
#include "v8-cppgc.h"
#include "v8-profiler.h"
+#include "v8-sandbox.h" // v8::Object::Wrap(), v8::Object::Unwrap()
#include <algorithm>
#include <atomic>
@@ -72,7 +73,6 @@ using v8::TryCatch;
using v8::Uint32;
using v8::Undefined;
using v8::Value;
-using v8::WrapperDescriptor;
using worker::Worker;
int const ContextEmbedderTag::kNodeContextTag = 0x6e6f64;
@@ -529,6 +529,14 @@ void IsolateData::CreateProperties() {
CreateEnvProxyTemplate(this);
}
+// Previously, the general convention of the wrappable layout for cppgc in
+// the ecosystem is:
+// [ 0 ] -> embedder id
+// [ 1 ] -> wrappable instance
+// Now V8 has deprecated this layout-based tracing enablement, embedders
+// should simply use v8::Object::Wrap() and v8::Object::Unwrap(). We preserve
+// this layout only to distinguish internally how the memory of a Node.js
+// wrapper is managed or whether a wrapper is managed by Node.js.
constexpr uint16_t kDefaultCppGCEmbedderID = 0x90de;
Mutex IsolateData::isolate_data_mutex_;
std::unordered_map<uint16_t, std::unique_ptr<PerIsolateWrapperData>>
@@ -566,36 +574,16 @@ IsolateData::IsolateData(Isolate* isolate,
v8::CppHeap* cpp_heap = isolate->GetCppHeap();
uint16_t cppgc_id = kDefaultCppGCEmbedderID;
- if (cpp_heap != nullptr) {
- // The general convention of the wrappable layout for cppgc in the
- // ecosystem is:
- // [ 0 ] -> embedder id
- // [ 1 ] -> wrappable instance
- // If the Isolate includes a CppHeap attached by another embedder,
- // And if they also use the field 0 for the ID, we DCHECK that
- // the layout matches our layout, and record the embedder ID for cppgc
- // to avoid accidentally enabling cppgc on non-cppgc-managed wrappers .
- v8::WrapperDescriptor descriptor = cpp_heap->wrapper_descriptor();
- if (descriptor.wrappable_type_index == BaseObject::kEmbedderType) {
- cppgc_id = descriptor.embedder_id_for_garbage_collected;
- DCHECK_EQ(descriptor.wrappable_instance_index, BaseObject::kSlot);
- }
- // If the CppHeap uses the slot we use to put non-cppgc-traced BaseObject
- // for embedder ID, V8 could accidentally enable cppgc on them. So
- // safe guard against this.
- DCHECK_NE(descriptor.wrappable_type_index, BaseObject::kSlot);
- } else {
- cpp_heap_ = CppHeap::Create(
- platform,
- CppHeapCreateParams{
- {},
- WrapperDescriptor(
- BaseObject::kEmbedderType, BaseObject::kSlot, cppgc_id)});
- isolate->AttachCppHeap(cpp_heap_.get());
- }
// We do not care about overflow since we just want this to be different
// from the cppgc id.
uint16_t non_cppgc_id = cppgc_id + 1;
+ if (cpp_heap == nullptr) {
+ cpp_heap_ = CppHeap::Create(platform, v8::CppHeapCreateParams{{}});
+ // TODO(joyeecheung): pass it into v8::Isolate::CreateParams and let V8
+ // own it when we can keep the isolate registered/task runner discoverable
+ // during isolate disposal.
+ isolate->AttachCppHeap(cpp_heap_.get());
+ }
{
// GC could still be run after the IsolateData is destroyed, so we store
@@ -628,11 +616,12 @@ IsolateData::~IsolateData() {
}
}
-// Public API
+// Deprecated API, embedders should use v8::Object::Wrap() directly instead.
void SetCppgcReference(Isolate* isolate,
Local<Object> object,
void* wrappable) {
- IsolateData::SetCppgcReference(isolate, object, wrappable);
+ v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(
+ isolate, object, static_cast<v8::Object::Wrappable*>(wrappable));
}
void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
diff --git a/src/env.h b/src/env.h
index 07accfbcca491966c6c8ad9c20e146dbd22347f0..1079e3beb02e5f5d71a15fd2db65cb93ebd175d6 100644
--- a/src/env.h
+++ b/src/env.h
@@ -175,10 +175,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
uint16_t* embedder_id_for_cppgc() const;
uint16_t* embedder_id_for_non_cppgc() const;
- static inline void SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable);
-
inline uv_loop_t* event_loop() const;
inline MultiIsolatePlatform* platform() const;
inline const SnapshotData* snapshot_data() const;
diff --git a/src/node.h b/src/node.h
index 174fd4d1af4c8cd75aec09f4548a674fd5539fb2..42d55d24bd0770795ae0c0e19241d25a6350ae08 100644
--- a/src/node.h
+++ b/src/node.h
@@ -1560,24 +1560,14 @@ void RegisterSignalHandler(int signal,
bool reset_handler = false);
#endif // _WIN32
-// Configure the layout of the JavaScript object with a cppgc::GarbageCollected
-// instance so that when the JavaScript object is reachable, the garbage
-// collected instance would have its Trace() method invoked per the cppgc
-// contract. To make it work, the process must have called
-// cppgc::InitializeProcess() before, which is usually the case for addons
-// loaded by the stand-alone Node.js executable. Embedders of Node.js can use
-// either need to call it themselves or make sure that
-// ProcessInitializationFlags::kNoInitializeCppgc is *not* set for cppgc to
-// work.
-// If the CppHeap is owned by Node.js, which is usually the case for addon,
-// the object must be created with at least two internal fields available,
-// and the first two internal fields would be configured by Node.js.
-// This may be superseded by a V8 API in the future, see
-// https://bugs.chromium.org/p/v8/issues/detail?id=13960. Until then this
-// serves as a helper for Node.js isolates.
-NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable);
+// This is kept as a compatibility layer for addons to wrap cppgc-managed
+// objects on Node.js versions without v8::Object::Wrap(). Addons created to
+// work with only Node.js versions with v8::Object::Wrap() should use that
+// instead.
+NODE_DEPRECATED("Use v8::Object::Wrap()",
+ NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate,
+ v8::Local<v8::Object> object,
+ void* wrappable));
} // namespace node
diff --git a/test/addons/cppgc-object/binding.cc b/test/addons/cppgc-object/binding.cc
index 1b70ff11dc561abdc5ac794f6280557d5c428239..7fc16a87b843ce0626ee137a07c3ccb7f4cc6493 100644
--- a/test/addons/cppgc-object/binding.cc
+++ b/test/addons/cppgc-object/binding.cc
@@ -1,8 +1,10 @@
+#include <assert.h>
#include <cppgc/allocation.h>
#include <cppgc/garbage-collected.h>
#include <cppgc/heap.h>
#include <node.h>
#include <v8-cppgc.h>
+#include <v8-sandbox.h>
#include <v8.h>
#include <algorithm>
@@ -15,8 +17,10 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static void New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::Local<v8::Object> js_object = args.This();
- CppGCed* gc_object = cppgc::MakeGarbageCollected<CppGCed>(
- isolate->GetCppHeap()->GetAllocationHandle());
+ auto* heap = isolate->GetCppHeap();
+ assert(heap != nullptr);
+ CppGCed* gc_object =
+ cppgc::MakeGarbageCollected<CppGCed>(heap->GetAllocationHandle());
node::SetCppgcReference(isolate, js_object, gc_object);
args.GetReturnValue().Set(js_object);
}
@@ -24,12 +28,6 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static v8::Local<v8::Function> GetConstructor(
v8::Local<v8::Context> context) {
auto ft = v8::FunctionTemplate::New(context->GetIsolate(), New);
- auto ot = ft->InstanceTemplate();
- v8::WrapperDescriptor descriptor =
- context->GetIsolate()->GetCppHeap()->wrapper_descriptor();
- uint16_t required_size = std::max(descriptor.wrappable_instance_index,
- descriptor.wrappable_type_index);
- ot->SetInternalFieldCount(required_size + 1);
return ft->GetFunction(context).ToLocalChecked();
}
diff --git a/test/cctest/test_cppgc.cc b/test/cctest/test_cppgc.cc
index 49665174615870b4f70529b1d548e593846140a1..edd413ae9b956b2e59e8166785adef6a8ff06d51 100644
--- a/test/cctest/test_cppgc.cc
+++ b/test/cctest/test_cppgc.cc
@@ -3,16 +3,12 @@
#include <cppgc/heap.h>
#include <node.h>
#include <v8-cppgc.h>
+#include <v8-sandbox.h>
#include <v8.h>
#include "node_test_fixture.h"
// This tests that Node.js can work with an existing CppHeap.
-// Mimic the Blink layout.
-static int kWrappableTypeIndex = 0;
-static int kWrappableInstanceIndex = 1;
-static uint16_t kEmbedderID = 0x1;
-
// Mimic a class that does not know about Node.js.
class CppGCed : public cppgc::GarbageCollected<CppGCed> {
public:
@@ -23,12 +19,11 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static void New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::Local<v8::Object> js_object = args.This();
- CppGCed* gc_object = cppgc::MakeGarbageCollected<CppGCed>(
- isolate->GetCppHeap()->GetAllocationHandle());
- js_object->SetAlignedPointerInInternalField(kWrappableTypeIndex,
- &kEmbedderID);
- js_object->SetAlignedPointerInInternalField(kWrappableInstanceIndex,
- gc_object);
+ auto* heap = isolate->GetCppHeap();
+ CHECK_NOT_NULL(heap);
+ CppGCed* gc_object =
+ cppgc::MakeGarbageCollected<CppGCed>(heap->GetAllocationHandle());
+ node::SetCppgcReference(isolate, js_object, gc_object);
kConstructCount++;
args.GetReturnValue().Set(js_object);
}
@@ -36,8 +31,6 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static v8::Local<v8::Function> GetConstructor(
v8::Local<v8::Context> context) {
auto ft = v8::FunctionTemplate::New(context->GetIsolate(), New);
- auto ot = ft->InstanceTemplate();
- ot->SetInternalFieldCount(2);
return ft->GetFunction(context).ToLocalChecked();
}
@@ -58,12 +51,12 @@ TEST_F(NodeZeroIsolateTestFixture, ExistingCppHeapTest) {
// Create and attach the CppHeap before we set up the IsolateData so that
// it recognizes the existing heap.
- std::unique_ptr<v8::CppHeap> cpp_heap = v8::CppHeap::Create(
- platform.get(),
- v8::CppHeapCreateParams(
- {},
- v8::WrapperDescriptor(
- kWrappableTypeIndex, kWrappableInstanceIndex, kEmbedderID)));
+ std::unique_ptr<v8::CppHeap> cpp_heap =
+ v8::CppHeap::Create(platform.get(), v8::CppHeapCreateParams{{}});
+
+ // TODO(joyeecheung): pass it into v8::Isolate::CreateParams and let V8
+ // own it when we can keep the isolate registered/task runner discoverable
+ // during isolate disposal.
isolate->AttachCppHeap(cpp_heap.get());
// Try creating Context + IsolateData + Environment.