@@ -1089,10 +1089,20 @@ void DeserializeNodeInternalFields(Local<Object> holder,
10891089 static_cast <int >(index),
10901090 (*holder),
10911091 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+
10921100 Environment* env_ptr = static_cast <Environment*>(env);
10931101 const InternalFieldInfo* info =
10941102 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.
10961106 switch (info->type ) {
10971107#define V (PropertyName, NativeTypeName ) \
10981108 case EmbedderObjectType::k_##PropertyName: { \
@@ -1113,21 +1123,44 @@ void DeserializeNodeInternalFields(Local<Object> holder,
11131123StartupData SerializeNodeContextInternalFields (Local<Object> holder,
11141124 int index,
11151125 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 ) {
11181144 return StartupData{nullptr , 0 };
11191145 }
1146+
11201147 per_process::Debug (DebugCategory::MKSNAPSHOT,
11211148 " Serialize internal field, index=%d, holder=%p\n " ,
11221149 static_cast <int >(index),
11231150 *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+
11261158 per_process::Debug (DebugCategory::MKSNAPSHOT,
11271159 " Object %p is %s, " ,
11281160 *holder,
11291161 obj->GetTypeNameChars ());
11301162 InternalFieldInfo* info = obj->Serialize (index);
1163+
11311164 per_process::Debug (DebugCategory::MKSNAPSHOT,
11321165 " payload size=%d\n " ,
11331166 static_cast <int >(info->length ));
@@ -1142,8 +1175,9 @@ void SerializeBindingData(Environment* env,
11421175 env->ForEachBindingData ([&](FastStringKey key,
11431176 BaseObjectPtr<BaseObject> binding) {
11441177 per_process::Debug (DebugCategory::MKSNAPSHOT,
1145- " Serialize binding %i, %p, type=%s\n " ,
1178+ " Serialize binding %i (%p), object= %p, type=%s\n " ,
11461179 static_cast <int >(i),
1180+ binding.get (),
11471181 *(binding->object ()),
11481182 key.c_str ());
11491183
0 commit comments