GeezerVison is showing github.com — src: iterate over base objects to prepare for snapshot · nodejs/node@4ca398a
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/env-inl.h -11Lines changed: 0 additions & 11 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -835,17 +835,6 @@ void Environment::ForEachBaseObject(T&& iterator) { | 835 | 835 | } | 836 | 836 | } | 837 | 837 |
| 838 | | -template <typename T> | 839 | | -void Environment::ForEachBindingData(T&& iterator) { | 840 | | - BindingDataStore* map = static_cast<BindingDataStore*>( | 841 | | - context()->GetAlignedPointerFromEmbedderData( | 842 | | - ContextEmbedderIndex::kBindingListIndex)); | 843 | | - DCHECK_NOT_NULL(map); | 844 | | - for (auto& it : *map) { | 845 | | - iterator(it.first, it.second); | 846 | | - } | 847 | | -} | 848 | | - | 849 | 838 | void Environment::modify_base_object_count(int64_t delta) { | 850 | 839 | base_object_count_ += delta; | 851 | 840 | } | |
Collapse file Copy file name to clipboardExpand all lines: src/env.cc +8-5Lines changed: 8 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1669,7 +1669,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) { | 1669 | 1669 | EnvSerializeInfo info; | 1670 | 1670 | Local<Context> ctx = context(); | 1671 | 1671 |
| 1672 | | - SerializeBindingData(this, creator, &info); | 1673 | 1672 | // Currently all modules are compiled without cache in builtin snapshot | 1674 | 1673 | // builder. | 1675 | 1674 | info.builtins = std::vector<std::string>(builtins_without_cache.begin(), | @@ -1697,6 +1696,10 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) { | 1697 | 1696 | ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) | 1698 | 1697 | #undef V | 1699 | 1698 |
| | 1699 | + // Do this after other creator->AddData() calls so that Snapshotable objects | | 1700 | + // can use 0 to indicate that a SnapshotIndex is invalid. | | 1701 | + SerializeSnapshotableObjects(this, creator, &info); | | 1702 | + | 1700 | 1703 | info.context = creator->AddData(ctx, context()); | 1701 | 1704 | return info; | 1702 | 1705 | } | @@ -1729,9 +1732,9 @@ std::ostream& operator<<(std::ostream& output, | 1729 | 1732 |
| 1730 | 1733 | std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) { | 1731 | 1734 | output << "{\n" | 1732 | | - << "// -- bindings begins --\n" | 1733 | | - << i.bindings << ",\n" | 1734 | | - << "// -- bindings ends --\n" | | 1735 | + << "// -- native_objects begins --\n" | | 1736 | + << i.native_objects << ",\n" | | 1737 | + << "// -- native_objects ends --\n" | 1735 | 1738 | << "// -- builtins begins --\n" | 1736 | 1739 | << i.builtins << ",\n" | 1737 | 1740 | << "// -- builtins ends --\n" | @@ -1758,7 +1761,7 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) { | 1758 | 1761 | void Environment::EnqueueDeserializeRequest(DeserializeRequestCallback cb, | 1759 | 1762 | Local<Object> holder, | 1760 | 1763 | int index, | 1761 | | - InternalFieldInfo* info) { | | 1764 | + InternalFieldInfoBase* info) { | 1762 | 1765 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 1763 | 1766 | DeserializeRequest request{cb, {isolate(), holder}, index, info}; | 1764 | 1767 | deserialize_requests_.push_back(std::move(request)); | |
Collapse file Copy file name to clipboardExpand all lines: src/env.h +5-8Lines changed: 5 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -956,19 +956,19 @@ class CleanupHookCallback { | 956 | 956 | typedef void (*DeserializeRequestCallback)(v8::Local<v8::Context> context, | 957 | 957 | v8::Local<v8::Object> holder, | 958 | 958 | int index, | 959 | | - InternalFieldInfo* info); | | 959 | + InternalFieldInfoBase* info); | 960 | 960 | struct DeserializeRequest { | 961 | 961 | DeserializeRequestCallback cb; | 962 | 962 | v8::Global<v8::Object> holder; | 963 | 963 | int index; | 964 | | - InternalFieldInfo* info = nullptr; // Owned by the request | | 964 | + InternalFieldInfoBase* info = nullptr; // Owned by the request | 965 | 965 |
| 966 | 966 | // Move constructor | 967 | 967 | DeserializeRequest(DeserializeRequest&& other) = default; | 968 | 968 | }; | 969 | 969 |
| 970 | 970 | struct EnvSerializeInfo { | 971 | | - std::vector<PropInfo> bindings; | | 971 | + std::vector<PropInfo> native_objects; | 972 | 972 | std::vector<std::string> builtins; | 973 | 973 | AsyncHooks::SerializeInfo async_hooks; | 974 | 974 | TickInfo::SerializeInfo tick_info; | @@ -1062,7 +1062,7 @@ class Environment : public MemoryRetainer { | 1062 | 1062 | void EnqueueDeserializeRequest(DeserializeRequestCallback cb, | 1063 | 1063 | v8::Local<v8::Object> holder, | 1064 | 1064 | int index, | 1065 | | - InternalFieldInfo* info); | | 1065 | + InternalFieldInfoBase* info); | 1066 | 1066 | void RunDeserializeRequests(); | 1067 | 1067 | // Should be called before InitializeInspector() | 1068 | 1068 | void InitializeDiagnostics(); | @@ -1485,7 +1485,7 @@ class Environment : public MemoryRetainer { | 1485 | 1485 | void RemoveUnmanagedFd(int fd); | 1486 | 1486 |
| 1487 | 1487 | template <typename T> | 1488 | | - void ForEachBindingData(T&& iterator); | | 1488 | + void ForEachBaseObject(T&& iterator); | 1489 | 1489 |
| 1490 | 1490 | private: | 1491 | 1491 | inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), | @@ -1643,9 +1643,6 @@ class Environment : public MemoryRetainer { | 1643 | 1643 | std::function<void(Environment*, int)> process_exit_handler_ { | 1644 | 1644 | DefaultProcessExitHandler }; | 1645 | 1645 |
| 1646 | | - template <typename T> | 1647 | | - void ForEachBaseObject(T&& iterator); | 1648 | | - | 1649 | 1646 | #define V(PropertyName, TypeName) v8::Global<TypeName> PropertyName ## _; | 1650 | 1647 | ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) | 1651 | 1648 | #undef V | |
Collapse file Copy file name to clipboardExpand all lines: src/node_blob.cc +12-10Lines changed: 12 additions & 10 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -462,11 +462,10 @@ BlobBindingData::StoredDataObject BlobBindingData::get_data_object( | 462 | 462 | return entry->second; | 463 | 463 | } | 464 | 464 |
| 465 | | -void BlobBindingData::Deserialize( | 466 | | - Local<Context> context, | 467 | | - Local<Object> holder, | 468 | | - int index, | 469 | | - InternalFieldInfo* info) { | | 465 | +void BlobBindingData::Deserialize(Local<Context> context, | | 466 | + Local<Object> holder, | | 467 | + int index, | | 468 | + InternalFieldInfoBase* info) { | 470 | 469 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 471 | 470 | HandleScope scope(context->GetIsolate()); | 472 | 471 | Environment* env = Environment::GetCurrent(context); | @@ -475,15 +474,18 @@ void BlobBindingData::Deserialize( | 475 | 474 | CHECK_NOT_NULL(binding); | 476 | 475 | } | 477 | 476 |
| 478 | | -void BlobBindingData::PrepareForSerialization( | 479 | | - Local<Context> context, | 480 | | - v8::SnapshotCreator* creator) { | | 477 | +bool BlobBindingData::PrepareForSerialization(Local<Context> context, | | 478 | + v8::SnapshotCreator* creator) { | 481 | 479 | // Stored blob objects are not actually persisted. | | 480 | + // Return true because we need to maintain the reference to the binding from | | 481 | + // JS land. | | 482 | + return true; | 482 | 483 | } | 483 | 484 |
| 484 | | -InternalFieldInfo* BlobBindingData::Serialize(int index) { | | 485 | +InternalFieldInfoBase* BlobBindingData::Serialize(int index) { | 485 | 486 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 486 | | - InternalFieldInfo* info = InternalFieldInfo::New(type()); | | 487 | + InternalFieldInfo* info = | | 488 | + InternalFieldInfoBase::New<InternalFieldInfo>(type()); | 487 | 489 | return info; | 488 | 490 | } | 489 | 491 |
| |
Collapse file Copy file name to clipboardExpand all lines: src/node_blob.h +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -146,6 +146,8 @@ class BlobBindingData : public SnapshotableObject { | 146 | 146 | public: | 147 | 147 | explicit BlobBindingData(Environment* env, v8::Local<v8::Object> wrap); | 148 | 148 |
| | 149 | + using InternalFieldInfo = InternalFieldInfoBase; | | 150 | + | 149 | 151 | SERIALIZABLE_OBJECT_METHODS() | 150 | 152 |
| 151 | 153 | static constexpr FastStringKey type_name{"node::BlobBindingData"}; | |
Collapse file Copy file name to clipboardExpand all lines: src/node_file.cc +8-4Lines changed: 8 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2400,26 +2400,30 @@ BindingData::BindingData(Environment* env, v8::Local<v8::Object> wrap) | 2400 | 2400 | void BindingData::Deserialize(Local<Context> context, | 2401 | 2401 | Local<Object> holder, | 2402 | 2402 | int index, | 2403 | | - InternalFieldInfo* info) { | | 2403 | + InternalFieldInfoBase* info) { | 2404 | 2404 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 2405 | 2405 | HandleScope scope(context->GetIsolate()); | 2406 | 2406 | Environment* env = Environment::GetCurrent(context); | 2407 | 2407 | BindingData* binding = env->AddBindingData<BindingData>(context, holder); | 2408 | 2408 | CHECK_NOT_NULL(binding); | 2409 | 2409 | } | 2410 | 2410 |
| 2411 | | -void BindingData::PrepareForSerialization(Local<Context> context, | | 2411 | +bool BindingData::PrepareForSerialization(Local<Context> context, | 2412 | 2412 | v8::SnapshotCreator* creator) { | 2413 | 2413 | CHECK(file_handle_read_wrap_freelist.empty()); | 2414 | 2414 | // We'll just re-initialize the buffers in the constructor since their | 2415 | 2415 | // contents can be thrown away once consumed in the previous call. | 2416 | 2416 | stats_field_array.Release(); | 2417 | 2417 | stats_field_bigint_array.Release(); | | 2418 | + // Return true because we need to maintain the reference to the binding from | | 2419 | + // JS land. | | 2420 | + return true; | 2418 | 2421 | } | 2419 | 2422 |
| 2420 | | -InternalFieldInfo* BindingData::Serialize(int index) { | | 2423 | +InternalFieldInfoBase* BindingData::Serialize(int index) { | 2421 | 2424 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 2422 | | - InternalFieldInfo* info = InternalFieldInfo::New(type()); | | 2425 | + InternalFieldInfo* info = | | 2426 | + InternalFieldInfoBase::New<InternalFieldInfo>(type()); | 2423 | 2427 | return info; | 2424 | 2428 | } | 2425 | 2429 |
| |
Collapse file Copy file name to clipboardExpand all lines: src/node_file.h +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -23,6 +23,7 @@ class BindingData : public SnapshotableObject { | 23 | 23 | std::vector<BaseObjectPtr<FileHandleReadWrap>> | 24 | 24 | file_handle_read_wrap_freelist; | 25 | 25 |
| | 26 | + using InternalFieldInfo = InternalFieldInfoBase; | 26 | 27 | SERIALIZABLE_OBJECT_METHODS() | 27 | 28 | static constexpr FastStringKey type_name{"node::fs::BindingData"}; | 28 | 29 | static constexpr EmbedderObjectType type_int = | |
Collapse file Copy file name to clipboardExpand all lines: src/node_process.h +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -50,6 +50,8 @@ class BindingData : public SnapshotableObject { | 50 | 50 | void AddMethods(); | 51 | 51 | static void RegisterExternalReferences(ExternalReferenceRegistry* registry); | 52 | 52 |
| | 53 | + using InternalFieldInfo = InternalFieldInfoBase; | | 54 | + | 53 | 55 | SERIALIZABLE_OBJECT_METHODS() | 54 | 56 | static constexpr FastStringKey type_name{"node::process::BindingData"}; | 55 | 57 | static constexpr EmbedderObjectType type_int = | |
Collapse file Copy file name to clipboardExpand all lines: src/node_process_methods.cc +8-4Lines changed: 8 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -524,23 +524,27 @@ void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) { | 524 | 524 | NumberImpl(FromJSObject<BindingData>(args.Holder())); | 525 | 525 | } | 526 | 526 |
| 527 | | -void BindingData::PrepareForSerialization(Local<Context> context, | | 527 | +bool BindingData::PrepareForSerialization(Local<Context> context, | 528 | 528 | v8::SnapshotCreator* creator) { | 529 | 529 | // It's not worth keeping. | 530 | 530 | // Release it, we will recreate it when the instance is dehydrated. | 531 | 531 | array_buffer_.Reset(); | | 532 | + // Return true because we need to maintain the reference to the binding from | | 533 | + // JS land. | | 534 | + return true; | 532 | 535 | } | 533 | 536 |
| 534 | | -InternalFieldInfo* BindingData::Serialize(int index) { | | 537 | +InternalFieldInfoBase* BindingData::Serialize(int index) { | 535 | 538 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 536 | | - InternalFieldInfo* info = InternalFieldInfo::New(type()); | | 539 | + InternalFieldInfo* info = | | 540 | + InternalFieldInfoBase::New<InternalFieldInfo>(type()); | 537 | 541 | return info; | 538 | 542 | } | 539 | 543 |
| 540 | 544 | void BindingData::Deserialize(Local<Context> context, | 541 | 545 | Local<Object> holder, | 542 | 546 | int index, | 543 | | - InternalFieldInfo* info) { | | 547 | + InternalFieldInfoBase* info) { | 544 | 548 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 545 | 549 | v8::HandleScope scope(context->GetIsolate()); | 546 | 550 | Environment* env = Environment::GetCurrent(context); | |
Collapse file Copy file name to clipboardExpand all lines: src/node_snapshotable.cc +46-40Lines changed: 46 additions & 40 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -638,7 +638,7 @@ template <> | 638 | 638 | EnvSerializeInfo FileReader::Read() { | 639 | 639 | per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<EnvSerializeInfo>()\n"); | 640 | 640 | EnvSerializeInfo result; | 641 | | - result.bindings = ReadVector<PropInfo>(); | | 641 | + result.native_objects = ReadVector<PropInfo>(); | 642 | 642 | result.builtins = ReadVector<std::string>(); | 643 | 643 | result.async_hooks = Read<AsyncHooks::SerializeInfo>(); | 644 | 644 | result.tick_info = Read<TickInfo::SerializeInfo>(); | @@ -661,7 +661,7 @@ size_t FileWriter::Write(const EnvSerializeInfo& data) { | 661 | 661 | } | 662 | 662 |
| 663 | 663 | // Use += here to ensure order of evaluation. | 664 | | - size_t written_total = WriteVector<PropInfo>(data.bindings); | | 664 | + size_t written_total = WriteVector<PropInfo>(data.native_objects); | 665 | 665 | written_total += WriteVector<std::string>(data.builtins); | 666 | 666 | written_total += Write<AsyncHooks::SerializeInfo>(data.async_hooks); | 667 | 667 | written_total += Write<TickInfo::SerializeInfo>(data.tick_info); | @@ -1179,17 +1179,6 @@ const char* SnapshotableObject::GetTypeNameChars() const { | 1179 | 1179 | } | 1180 | 1180 | } | 1181 | 1181 |
| 1182 | | -bool IsSnapshotableType(FastStringKey key) { | 1183 | | -#define V(PropertyName, NativeTypeName) \ | 1184 | | - if (key == NativeTypeName::type_name) { \ | 1185 | | - return true; \ | 1186 | | - } | 1187 | | - SERIALIZABLE_OBJECT_TYPES(V) | 1188 | | -#undef V | 1189 | | - | 1190 | | - return false; | 1191 | | -} | 1192 | | - | 1193 | 1182 | void DeserializeNodeInternalFields(Local<Object> holder, | 1194 | 1183 | int index, | 1195 | 1184 | StartupData payload, | @@ -1212,10 +1201,10 @@ void DeserializeNodeInternalFields(Local<Object> holder, | 1212 | 1201 | DCHECK_EQ(index, BaseObject::kEmbedderType); | 1213 | 1202 |
| 1214 | 1203 | Environment* env_ptr = static_cast<Environment*>(env); | 1215 | | - const InternalFieldInfo* info = | 1216 | | - reinterpret_cast<const InternalFieldInfo*>(payload.data); | | 1204 | + const InternalFieldInfoBase* info = | | 1205 | + reinterpret_cast<const InternalFieldInfoBase*>(payload.data); | 1217 | 1206 | // TODO(joyeecheung): we can add a constant kNodeEmbedderId to the | 1218 | | - // beginning of every InternalFieldInfo to ensure that we don't | | 1207 | + // beginning of every InternalFieldInfoBase to ensure that we don't | 1219 | 1208 | // step on payloads that were not serialized by Node.js. | 1220 | 1209 | switch (info->type) { | 1221 | 1210 | #define V(PropertyName, NativeTypeName) \ | @@ -1225,12 +1214,25 @@ void DeserializeNodeInternalFields(Local<Object> holder, | 1225 | 1214 | (*holder), \ | 1226 | 1215 | NativeTypeName::type_name.c_str()); \ | 1227 | 1216 | env_ptr->EnqueueDeserializeRequest( \ | 1228 | | - NativeTypeName::Deserialize, holder, index, info->Copy()); \ | | 1217 | + NativeTypeName::Deserialize, \ | | 1218 | + holder, \ | | 1219 | + index, \ | | 1220 | + info->Copy<NativeTypeName::InternalFieldInfo>()); \ | 1229 | 1221 | break; \ | 1230 | 1222 | } | 1231 | 1223 | SERIALIZABLE_OBJECT_TYPES(V) | 1232 | 1224 | #undef V | 1233 | | - default: { UNREACHABLE(); } | | 1225 | + default: { | | 1226 | + // This should only be reachable during development when trying to | | 1227 | + // deserialize a snapshot blob built by a version of Node.js that | | 1228 | + // has more recognizable EmbedderObjectTypes than the deserializing | | 1229 | + // Node.js binary. | | 1230 | + fprintf(stderr, | | 1231 | + "Unknown embedder object type %" PRIu8 ", possibly caused by " | | 1232 | + "mismatched Node.js versions\n", | | 1233 | + static_cast<uint8_t>(info->type)); | | 1234 | + ABORT(); | | 1235 | + } | 1234 | 1236 | } | 1235 | 1237 | } | 1236 | 1238 |
| @@ -1263,17 +1265,17 @@ StartupData SerializeNodeContextInternalFields(Local<Object> holder, | 1263 | 1265 | static_cast<int>(index), | 1264 | 1266 | *holder); | 1265 | 1267 |
| 1266 | | - void* binding_ptr = | | 1268 | + void* native_ptr = | 1267 | 1269 | holder->GetAlignedPointerFromInternalField(BaseObject::kSlot); | 1268 | | - per_process::Debug(DebugCategory::MKSNAPSHOT, "binding = %p\n", binding_ptr); | 1269 | | - DCHECK(static_cast<BaseObject*>(binding_ptr)->is_snapshotable()); | 1270 | | - SnapshotableObject* obj = static_cast<SnapshotableObject*>(binding_ptr); | | 1270 | + per_process::Debug(DebugCategory::MKSNAPSHOT, "native = %p\n", native_ptr); | | 1271 | + DCHECK(static_cast<BaseObject*>(native_ptr)->is_snapshotable()); | | 1272 | + SnapshotableObject* obj = static_cast<SnapshotableObject*>(native_ptr); | 1271 | 1273 |
| 1272 | 1274 | per_process::Debug(DebugCategory::MKSNAPSHOT, | 1273 | 1275 | "Object %p is %s, ", | 1274 | 1276 | *holder, | 1275 | 1277 | obj->GetTypeNameChars()); | 1276 | | - InternalFieldInfo* info = obj->Serialize(index); | | 1278 | + InternalFieldInfoBase* info = obj->Serialize(index); | 1277 | 1279 |
| 1278 | 1280 | per_process::Debug(DebugCategory::MKSNAPSHOT, | 1279 | 1281 | "payload size=%d\n", | @@ -1282,31 +1284,35 @@ StartupData SerializeNodeContextInternalFields(Local<Object> holder, | 1282 | 1284 | static_cast<int>(info->length)}; | 1283 | 1285 | } | 1284 | 1286 |
| 1285 | | -void SerializeBindingData(Environment* env, | 1286 | | - SnapshotCreator* creator, | 1287 | | - EnvSerializeInfo* info) { | | 1287 | +void SerializeSnapshotableObjects(Environment* env, | | 1288 | + SnapshotCreator* creator, | | 1289 | + EnvSerializeInfo* info) { | 1288 | 1290 | uint32_t i = 0; | 1289 | | - env->ForEachBindingData([&](FastStringKey key, | 1290 | | - BaseObjectPtr<BaseObject> binding) { | | 1291 | + env->ForEachBaseObject([&](BaseObject* obj) { | | 1292 | + // If there are any BaseObjects that are not snapshotable left | | 1293 | + // during context serialization, V8 would crash due to unregistered | | 1294 | + // global handles and print detailed information about them. | | 1295 | + if (!obj->is_snapshotable()) { | | 1296 | + return; | | 1297 | + } | | 1298 | + SnapshotableObject* ptr = static_cast<SnapshotableObject*>(obj); | | 1299 | + | | 1300 | + const char* type_name = ptr->GetTypeNameChars(); | 1291 | 1301 | per_process::Debug(DebugCategory::MKSNAPSHOT, | 1292 | | - "Serialize binding %i (%p), object=%p, type=%s\n", | | 1302 | + "Serialize snapshotable object %i (%p), " | | 1303 | + "object=%p, type=%s\n", | 1293 | 1304 | static_cast<int>(i), | 1294 | | - binding.get(), | 1295 | | - *(binding->object()), | 1296 | | - key.c_str()); | | 1305 | + ptr, | | 1306 | + *(ptr->object()), | | 1307 | + type_name); | 1297 | 1308 |
| 1298 | | - if (IsSnapshotableType(key)) { | 1299 | | - SnapshotIndex index = creator->AddData(env->context(), binding->object()); | | 1309 | + if (ptr->PrepareForSerialization(env->context(), creator)) { | | 1310 | + SnapshotIndex index = creator->AddData(env->context(), obj->object()); | 1300 | 1311 | per_process::Debug(DebugCategory::MKSNAPSHOT, | 1301 | 1312 | "Serialized with index=%d\n", | 1302 | 1313 | static_cast<int>(index)); | 1303 | | - info->bindings.push_back({key.c_str(), i, index}); | 1304 | | - SnapshotableObject* ptr = static_cast<SnapshotableObject*>(binding.get()); | 1305 | | - ptr->PrepareForSerialization(env->context(), creator); | 1306 | | - } else { | 1307 | | - UNREACHABLE(); | | 1314 | + info->native_objects.push_back({type_name, i, index}); | 1308 | 1315 | } | 1309 | | - | 1310 | 1316 | i++; | 1311 | 1317 | }); | 1312 | 1318 | } | |
|