@@ -1089,10 +1089,20 @@ void DeserializeNodeInternalFields(Local<Object> holder,
1089
1089
static_cast <int >(index ),
1090
1090
(*holder),
1091
1091
static_cast <int >(payload.raw_size ));
1092
+
1093
+ if (payload.raw_size == 0 ) {
1094
+ holder->SetAlignedPointerInInternalField (index , nullptr );
1095
+ return ;
1096
+ }
1097
+
1098
+ DCHECK_EQ (index , BaseObject::kEmbedderType );
1099
+
1092
1100
Environment* env_ptr = static_cast <Environment*>(env);
1093
1101
const InternalFieldInfo* info =
1094
1102
reinterpret_cast <const InternalFieldInfo*>(payload.data );
1095
-
1103
+ // TODO(joyeecheung): we can add a constant kNodeEmbedderId to the
1104
+ // beginning of every InternalFieldInfo to ensure that we don't
1105
+ // step on payloads that were not serialized by Node.js.
1096
1106
switch (info->type ) {
1097
1107
#define V (PropertyName, NativeTypeName ) \
1098
1108
case EmbedderObjectType::k_##PropertyName: { \
@@ -1113,21 +1123,44 @@ void DeserializeNodeInternalFields(Local<Object> holder,
1113
1123
StartupData SerializeNodeContextInternalFields (Local<Object> holder,
1114
1124
int index,
1115
1125
void * env) {
1116
- void * ptr = holder->GetAlignedPointerFromInternalField (BaseObject::kSlot );
1117
- if (ptr == nullptr ) {
1126
+ // We only do one serialization for the kEmbedderType slot, the result
1127
+ // contains everything necessary for deserializing the entire object,
1128
+ // including the fields whose index is bigger than kEmbedderType
1129
+ // (most importantly, BaseObject::kSlot).
1130
+ // For Node.js this design is enough for all the native binding that are
1131
+ // serializable.
1132
+ if (index != BaseObject::kEmbedderType ) {
1133
+ return StartupData{nullptr , 0 };
1134
+ }
1135
+
1136
+ void * type_ptr = holder->GetAlignedPointerFromInternalField (index );
1137
+ if (type_ptr == nullptr ) {
1138
+ return StartupData{nullptr , 0 };
1139
+ }
1140
+
1141
+ uint16_t type = *(static_cast <uint16_t *>(type_ptr));
1142
+ per_process::Debug (DebugCategory::MKSNAPSHOT, " type = 0x%x\n " , type);
1143
+ if (type != kNodeEmbedderId ) {
1118
1144
return StartupData{nullptr , 0 };
1119
1145
}
1146
+
1120
1147
per_process::Debug (DebugCategory::MKSNAPSHOT,
1121
1148
" Serialize internal field, index=%d, holder=%p\n " ,
1122
1149
static_cast <int >(index ),
1123
1150
*holder);
1124
- DCHECK (static_cast <BaseObject*>(ptr)->is_snapshotable ());
1125
- SnapshotableObject* obj = static_cast <SnapshotableObject*>(ptr);
1151
+
1152
+ void * binding_ptr =
1153
+ holder->GetAlignedPointerFromInternalField (BaseObject::kSlot );
1154
+ per_process::Debug (DebugCategory::MKSNAPSHOT, " binding = %p\n " , binding_ptr);
1155
+ DCHECK (static_cast <BaseObject*>(binding_ptr)->is_snapshotable ());
1156
+ SnapshotableObject* obj = static_cast <SnapshotableObject*>(binding_ptr);
1157
+
1126
1158
per_process::Debug (DebugCategory::MKSNAPSHOT,
1127
1159
" Object %p is %s, " ,
1128
1160
*holder,
1129
1161
obj->GetTypeNameChars ());
1130
1162
InternalFieldInfo* info = obj->Serialize (index );
1163
+
1131
1164
per_process::Debug (DebugCategory::MKSNAPSHOT,
1132
1165
" payload size=%d\n " ,
1133
1166
static_cast <int >(info->length ));
@@ -1142,8 +1175,9 @@ void SerializeBindingData(Environment* env,
1142
1175
env->ForEachBindingData ([&](FastStringKey key,
1143
1176
BaseObjectPtr<BaseObject> binding) {
1144
1177
per_process::Debug (DebugCategory::MKSNAPSHOT,
1145
- " Serialize binding %i, %p, type=%s\n " ,
1178
+ " Serialize binding %i (%p), object= %p, type=%s\n " ,
1146
1179
static_cast <int >(i),
1180
+ binding.get (),
1147
1181
*(binding->object ()),
1148
1182
key.c_str ());
1149
1183
0 commit comments