@@ -1119,10 +1119,20 @@ void DeserializeNodeInternalFields(Local<Object> holder,
1119
1119
static_cast <int >(index ),
1120
1120
(*holder),
1121
1121
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
+
1122
1130
Environment* env_ptr = static_cast <Environment*>(env);
1123
1131
const InternalFieldInfo* info =
1124
1132
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.
1126
1136
switch (info->type ) {
1127
1137
#define V (PropertyName, NativeTypeName ) \
1128
1138
case EmbedderObjectType::k_##PropertyName: { \
@@ -1143,21 +1153,44 @@ void DeserializeNodeInternalFields(Local<Object> holder,
1143
1153
StartupData SerializeNodeContextInternalFields (Local<Object> holder,
1144
1154
int index,
1145
1155
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 ) {
1148
1174
return StartupData{nullptr , 0 };
1149
1175
}
1176
+
1150
1177
per_process::Debug (DebugCategory::MKSNAPSHOT,
1151
1178
" Serialize internal field, index=%d, holder=%p\n " ,
1152
1179
static_cast <int >(index ),
1153
1180
*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
+
1156
1188
per_process::Debug (DebugCategory::MKSNAPSHOT,
1157
1189
" Object %p is %s, " ,
1158
1190
*holder,
1159
1191
obj->GetTypeNameChars ());
1160
1192
InternalFieldInfo* info = obj->Serialize (index );
1193
+
1161
1194
per_process::Debug (DebugCategory::MKSNAPSHOT,
1162
1195
" payload size=%d\n " ,
1163
1196
static_cast <int >(info->length ));
@@ -1172,8 +1205,9 @@ void SerializeBindingData(Environment* env,
1172
1205
env->ForEachBindingData ([&](FastStringKey key,
1173
1206
BaseObjectPtr<BaseObject> binding) {
1174
1207
per_process::Debug (DebugCategory::MKSNAPSHOT,
1175
- " Serialize binding %i, %p, type=%s\n " ,
1208
+ " Serialize binding %i (%p), object= %p, type=%s\n " ,
1176
1209
static_cast <int >(i),
1210
+ binding.get (),
1177
1211
*(binding->object ()),
1178
1212
key.c_str ());
1179
1213
0 commit comments