@@ -380,10 +380,13 @@ void DeserializeNodeInternalFields(Local<Object> holder,
380380 return ;
381381 }
382382
383+ DCHECK_EQ (index, BaseObject::kEmbedderType );
383384 Environment* env_ptr = static_cast <Environment*>(env);
384385 const InternalFieldInfo* info =
385386 reinterpret_cast <const InternalFieldInfo*>(payload.data );
386-
387+ // TODO(joyeecheung): we can add a constant kNodeEmbedderId to the
388+ // beginning of every InternalFieldInfo to ensure that we don't
389+ // step on payloads that were not serialized by Node.js.
387390 switch (info->type ) {
388391#define V (PropertyName, NativeTypeName ) \
389392 case EmbedderObjectType::k_##PropertyName: { \
@@ -408,13 +411,32 @@ StartupData SerializeNodeContextInternalFields(Local<Object> holder,
408411 " Serialize internal field, index=%d, holder=%p\n " ,
409412 static_cast <int >(index),
410413 *holder);
411- void * ptr = holder->GetAlignedPointerFromInternalField (BaseObject::kSlot );
412- if (ptr == nullptr ) {
414+ // We only do one serialization for the kEmbedderType slot, the result
415+ // contains everything necessary for deserializing the entire object,
416+ // including the fields whose index is bigger than kEmbedderType
417+ // (most importantly, BaseObject::kSlot).
418+ // For Node.js this design is enough for all the native binding that are
419+ // serializable.
420+ if (index != BaseObject::kEmbedderType ) {
421+ return StartupData{nullptr , 0 };
422+ }
423+
424+ void * type_ptr = holder->GetAlignedPointerFromInternalField (index);
425+ if (type_ptr == nullptr ) {
426+ return StartupData{nullptr , 0 };
427+ }
428+
429+ uint16_t type = *(static_cast <uint16_t *>(type_ptr));
430+ per_process::Debug (DebugCategory::MKSNAPSHOT, " type = 0x%x\n " , type);
431+ if (type != kNodeEmbedderId ) {
413432 return StartupData{nullptr , 0 };
414433 }
415434
416- DCHECK (static_cast <BaseObject*>(ptr)->is_snapshotable ());
417- SnapshotableObject* obj = static_cast <SnapshotableObject*>(ptr);
435+ void * binding_ptr =
436+ holder->GetAlignedPointerFromInternalField (BaseObject::kSlot );
437+ per_process::Debug (DebugCategory::MKSNAPSHOT, " binding = %p\n " , binding_ptr);
438+ DCHECK (static_cast <BaseObject*>(binding_ptr)->is_snapshotable ());
439+ SnapshotableObject* obj = static_cast <SnapshotableObject*>(binding_ptr);
418440 per_process::Debug (DebugCategory::MKSNAPSHOT,
419441 " Object %p is %s, " ,
420442 *holder,
@@ -434,8 +456,9 @@ void SerializeBindingData(Environment* env,
434456 env->ForEachBindingData ([&](FastStringKey key,
435457 BaseObjectPtr<BaseObject> binding) {
436458 per_process::Debug (DebugCategory::MKSNAPSHOT,
437- " Serialize binding %i, %p, type=%s\n " ,
459+ " Serialize binding %i (%p), object= %p, type=%s\n " ,
438460 static_cast <int >(i),
461+ binding.get (),
439462 *(binding->object ()),
440463 key.c_str ());
441464
0 commit comments