GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — src: fix cppgc incompatibility in v8 · nodejs/node@f071028

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • src
    • base_object.h
    • env.cc
    • node_blob.cc
    • node_file.cc
    • node_process_methods.cc
    • node_snapshotable.cc
    • node_snapshotable.h
    • node_v8.cc
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/base_object.h‎

Copy file name to clipboardExpand all lines: src/base_object.h
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ namespace worker {
3838
class TransferData;
3939
}
4040

41+
extern uint16_t kNodeEmbedderId;
42+
4143
class BaseObject : public MemoryRetainer {
4244
public:
43-
enum InternalFields { kSlot, kInternalFieldCount };
45+
enum InternalFields { kEmbedderType, kSlot, kInternalFieldCount };
4446

45-
// Associates this object with `object`. It uses the 0th internal field for
47+
// Associates this object with `object`. It uses the 1st internal field for
4648
// that, and in particular aborts if there is no such field.
4749
BaseObject(Environment* env, v8::Local<v8::Object> object);
4850
~BaseObject() override;
Collapse file

‎src/env.cc‎

Copy file name to clipboardExpand all lines: src/env.cc
+14-2Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,7 @@ void Environment::EnqueueDeserializeRequest(DeserializeRequestCallback cb,
17381738
Local<Object> holder,
17391739
int index,
17401740
InternalFieldInfo* info) {
1741+
DCHECK_EQ(index, BaseObject::kEmbedderType);
17411742
DeserializeRequest request{cb, {isolate(), holder}, index, info};
17421743
deserialize_requests_.push_back(std::move(request));
17431744
}
@@ -2017,7 +2018,9 @@ void Environment::RunWeakRefCleanup() {
20172018
BaseObject::BaseObject(Environment* env, Local<Object> object)
20182019
: persistent_handle_(env->isolate(), object), env_(env) {
20192020
CHECK_EQ(false, object.IsEmpty());
2020-
CHECK_GT(object->InternalFieldCount(), 0);
2021+
CHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount);
2022+
object->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
2023+
&kNodeEmbedderId);
20212024
object->SetAlignedPointerInInternalField(BaseObject::kSlot,
20222025
static_cast<void*>(this));
20232026
env->AddCleanupHook(DeleteMe, static_cast<void*>(this));
@@ -2068,10 +2071,19 @@ void BaseObject::MakeWeak() {
20682071
WeakCallbackType::kParameter);
20692072
}
20702073

2074+
// This just has to be different from the Chromium ones:
2075+
// https://source.chromium.org/chromium/chromium/src/+/main:gin/public/gin_embedders.h;l=18-23;drc=5a758a97032f0b656c3c36a3497560762495501a
2076+
// Otherwise, when Node is loaded in an isolate which uses cppgc, cppgc will
2077+
// misinterpret the data stored in the embedder fields and try to garbage
2078+
// collect them.
2079+
uint16_t kNodeEmbedderId = 0x90de;
2080+
20712081
void BaseObject::LazilyInitializedJSTemplateConstructor(
20722082
const FunctionCallbackInfo<Value>& args) {
20732083
DCHECK(args.IsConstructCall());
2074-
DCHECK_GT(args.This()->InternalFieldCount(), 0);
2084+
CHECK_GE(args.This()->InternalFieldCount(), BaseObject::kInternalFieldCount);
2085+
args.This()->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
2086+
&kNodeEmbedderId);
20752087
args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr);
20762088
}
20772089

Collapse file

‎src/node_blob.cc‎

Copy file name to clipboardExpand all lines: src/node_blob.cc
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ void BlobBindingData::Deserialize(
465465
Local<Object> holder,
466466
int index,
467467
InternalFieldInfo* info) {
468-
DCHECK_EQ(index, BaseObject::kSlot);
468+
DCHECK_EQ(index, BaseObject::kEmbedderType);
469469
HandleScope scope(context->GetIsolate());
470470
Environment* env = Environment::GetCurrent(context);
471471
BlobBindingData* binding =
@@ -480,7 +480,7 @@ void BlobBindingData::PrepareForSerialization(
480480
}
481481

482482
InternalFieldInfo* BlobBindingData::Serialize(int index) {
483-
DCHECK_EQ(index, BaseObject::kSlot);
483+
DCHECK_EQ(index, BaseObject::kEmbedderType);
484484
InternalFieldInfo* info = InternalFieldInfo::New(type());
485485
return info;
486486
}
Collapse file

‎src/node_file.cc‎

Copy file name to clipboardExpand all lines: src/node_file.cc
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,7 +2567,7 @@ void BindingData::Deserialize(Local<Context> context,
25672567
Local<Object> holder,
25682568
int index,
25692569
InternalFieldInfo* info) {
2570-
DCHECK_EQ(index, BaseObject::kSlot);
2570+
DCHECK_EQ(index, BaseObject::kEmbedderType);
25712571
HandleScope scope(context->GetIsolate());
25722572
Environment* env = Environment::GetCurrent(context);
25732573
BindingData* binding = env->AddBindingData<BindingData>(context, holder);
@@ -2584,7 +2584,7 @@ void BindingData::PrepareForSerialization(Local<Context> context,
25842584
}
25852585

25862586
InternalFieldInfo* BindingData::Serialize(int index) {
2587-
DCHECK_EQ(index, BaseObject::kSlot);
2587+
DCHECK_EQ(index, BaseObject::kEmbedderType);
25882588
InternalFieldInfo* info = InternalFieldInfo::New(type());
25892589
return info;
25902590
}
Collapse file

‎src/node_process_methods.cc‎

Copy file name to clipboardExpand all lines: src/node_process_methods.cc
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ void BindingData::PrepareForSerialization(Local<Context> context,
532532
}
533533

534534
InternalFieldInfo* BindingData::Serialize(int index) {
535-
DCHECK_EQ(index, BaseObject::kSlot);
535+
DCHECK_EQ(index, BaseObject::kEmbedderType);
536536
InternalFieldInfo* info = InternalFieldInfo::New(type());
537537
return info;
538538
}
@@ -541,7 +541,7 @@ void BindingData::Deserialize(Local<Context> context,
541541
Local<Object> holder,
542542
int index,
543543
InternalFieldInfo* info) {
544-
DCHECK_EQ(index, BaseObject::kSlot);
544+
DCHECK_EQ(index, BaseObject::kEmbedderType);
545545
v8::HandleScope scope(context->GetIsolate());
546546
Environment* env = Environment::GetCurrent(context);
547547
// Recreate the buffer in the constructor.
Collapse file

‎src/node_snapshotable.cc‎

Copy file name to clipboardExpand all lines: src/node_snapshotable.cc
+40-6Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,10 +1119,20 @@ void DeserializeNodeInternalFields(Local<Object> holder,
11191119
static_cast<int>(index),
11201120
(*holder),
11211121
static_cast<int>(payload.raw_size));
1122+
1123+
if (payload.raw_size == 0) {
1124+
holder->SetAlignedPointerInInternalField(index, nullptr);
1125+
return;
1126+
}
1127+
1128+
DCHECK_EQ(index, BaseObject::kEmbedderType);
1129+
11221130
Environment* env_ptr = static_cast<Environment*>(env);
11231131
const InternalFieldInfo* info =
11241132
reinterpret_cast<const InternalFieldInfo*>(payload.data);
1125-
1133+
// TODO(joyeecheung): we can add a constant kNodeEmbedderId to the
1134+
// beginning of every InternalFieldInfo to ensure that we don't
1135+
// step on payloads that were not serialized by Node.js.
11261136
switch (info->type) {
11271137
#define V(PropertyName, NativeTypeName) \
11281138
case EmbedderObjectType::k_##PropertyName: { \
@@ -1143,21 +1153,44 @@ void DeserializeNodeInternalFields(Local<Object> holder,
11431153
StartupData SerializeNodeContextInternalFields(Local<Object> holder,
11441154
int index,
11451155
void* env) {
1146-
void* ptr = holder->GetAlignedPointerFromInternalField(BaseObject::kSlot);
1147-
if (ptr == nullptr) {
1156+
// We only do one serialization for the kEmbedderType slot, the result
1157+
// contains everything necessary for deserializing the entire object,
1158+
// including the fields whose index is bigger than kEmbedderType
1159+
// (most importantly, BaseObject::kSlot).
1160+
// For Node.js this design is enough for all the native binding that are
1161+
// serializable.
1162+
if (index != BaseObject::kEmbedderType) {
1163+
return StartupData{nullptr, 0};
1164+
}
1165+
1166+
void* type_ptr = holder->GetAlignedPointerFromInternalField(index);
1167+
if (type_ptr == nullptr) {
1168+
return StartupData{nullptr, 0};
1169+
}
1170+
1171+
uint16_t type = *(static_cast<uint16_t*>(type_ptr));
1172+
per_process::Debug(DebugCategory::MKSNAPSHOT, "type = 0x%x\n", type);
1173+
if (type != kNodeEmbedderId) {
11481174
return StartupData{nullptr, 0};
11491175
}
1176+
11501177
per_process::Debug(DebugCategory::MKSNAPSHOT,
11511178
"Serialize internal field, index=%d, holder=%p\n",
11521179
static_cast<int>(index),
11531180
*holder);
1154-
DCHECK(static_cast<BaseObject*>(ptr)->is_snapshotable());
1155-
SnapshotableObject* obj = static_cast<SnapshotableObject*>(ptr);
1181+
1182+
void* binding_ptr =
1183+
holder->GetAlignedPointerFromInternalField(BaseObject::kSlot);
1184+
per_process::Debug(DebugCategory::MKSNAPSHOT, "binding = %p\n", binding_ptr);
1185+
DCHECK(static_cast<BaseObject*>(binding_ptr)->is_snapshotable());
1186+
SnapshotableObject* obj = static_cast<SnapshotableObject*>(binding_ptr);
1187+
11561188
per_process::Debug(DebugCategory::MKSNAPSHOT,
11571189
"Object %p is %s, ",
11581190
*holder,
11591191
obj->GetTypeNameChars());
11601192
InternalFieldInfo* info = obj->Serialize(index);
1193+
11611194
per_process::Debug(DebugCategory::MKSNAPSHOT,
11621195
"payload size=%d\n",
11631196
static_cast<int>(info->length));
@@ -1172,8 +1205,9 @@ void SerializeBindingData(Environment* env,
11721205
env->ForEachBindingData([&](FastStringKey key,
11731206
BaseObjectPtr<BaseObject> binding) {
11741207
per_process::Debug(DebugCategory::MKSNAPSHOT,
1175-
"Serialize binding %i, %p, type=%s\n",
1208+
"Serialize binding %i (%p), object=%p, type=%s\n",
11761209
static_cast<int>(i),
1210+
binding.get(),
11771211
*(binding->object()),
11781212
key.c_str());
11791213

Collapse file

‎src/node_snapshotable.h‎

Copy file name to clipboardExpand all lines: src/node_snapshotable.h
-5Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ enum class EmbedderObjectType : uint8_t {
3030
// When serializing an embedder object, we'll serialize the native states
3131
// into a chunk that can be mapped into a subclass of InternalFieldInfo,
3232
// and pass it into the V8 callback as the payload of StartupData.
33-
// TODO(joyeecheung): the classification of types seem to be wrong.
34-
// We'd need a type for each field of each class of native object.
35-
// Maybe it's fine - we'll just use the type to invoke BaseObject constructors
36-
// and specify that the BaseObject has only one field for us to serialize.
37-
// And for non-BaseObject embedder objects, we'll use field-wise types.
3833
// The memory chunk looks like this:
3934
//
4035
// [ type ] - EmbedderObjectType (a uint8_t)
Collapse file

‎src/node_v8.cc‎

Copy file name to clipboardExpand all lines: src/node_v8.cc
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ void BindingData::Deserialize(Local<Context> context,
124124
Local<Object> holder,
125125
int index,
126126
InternalFieldInfo* info) {
127-
DCHECK_EQ(index, BaseObject::kSlot);
127+
DCHECK_EQ(index, BaseObject::kEmbedderType);
128128
HandleScope scope(context->GetIsolate());
129129
Environment* env = Environment::GetCurrent(context);
130130
BindingData* binding = env->AddBindingData<BindingData>(context, holder);
131131
CHECK_NOT_NULL(binding);
132132
}
133133

134134
InternalFieldInfo* BindingData::Serialize(int index) {
135-
DCHECK_EQ(index, BaseObject::kSlot);
135+
DCHECK_EQ(index, BaseObject::kEmbedderType);
136136
InternalFieldInfo* info = InternalFieldInfo::New(type());
137137
return info;
138138
}

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.