Chromium Code Reviews| Index: runtime/vm/snapshot.cc |
| diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
| index 33570ae8d4c29cf603116073a5913cf89435c7bc..8c1029c16e161a251663ea670b7d2b02e90c23db 100644 |
| --- a/runtime/vm/snapshot.cc |
| +++ b/runtime/vm/snapshot.cc |
| @@ -603,6 +603,10 @@ RawApiError* SnapshotReader::ReadFullSnapshot() { |
| if (error != ApiError::null()) { |
| return error; |
| } |
| + error = VerifyFeatures(); |
| + if (error != ApiError::null()) { |
| + return error; |
| + } |
| // The version string matches. Read the rest of the snapshot. |
| @@ -674,6 +678,10 @@ RawObject* SnapshotReader::ReadScriptSnapshot() { |
| if (error != ApiError::null()) { |
| return error; |
| } |
| + error = VerifyFeatures(); |
| + if (error != ApiError::null()) { |
| + return error; |
| + } |
| // The version string matches. Read the rest of the snapshot. |
| obj_ = ReadObject(); |
| @@ -706,7 +714,7 @@ RawApiError* SnapshotReader::VerifyVersion() { |
| OS::SNPrint(message_buffer, |
| kMessageBufferSize, |
| "No full snapshot version found, expected '%s'", |
| - Version::SnapshotString()); |
| + expected_version); |
| // This can also fail while bringing up the VM isolate, so make sure to |
| // allocate the error message in old space. |
| const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); |
| @@ -723,7 +731,7 @@ RawApiError* SnapshotReader::VerifyVersion() { |
| kMessageBufferSize, |
| "Wrong %s snapshot version, expected '%s' found '%s'", |
| (Snapshot::IsFull(kind_)) ? "full" : "script", |
| - Version::SnapshotString(), |
| + expected_version, |
| actual_version); |
| free(actual_version); |
| // This can also fail while bringing up the VM isolate, so make sure to |
| @@ -736,6 +744,41 @@ RawApiError* SnapshotReader::VerifyVersion() { |
| } |
| +RawApiError* SnapshotReader::VerifyFeatures() { |
| + // If the features string doesn't match, return an error. |
| + // Note: New things are allocated only if we're going to return an error. |
| + |
| + const char* expected_features = Dart::FeaturesString(kind_); |
| + ASSERT(expected_features != NULL); |
| + const intptr_t expected_len = strlen(expected_features); |
| + |
| + const char* features = reinterpret_cast<const char*>(CurrentBufferAddress()); |
| + ASSERT(features != NULL); |
| + intptr_t buffer_len = strnlen(features, PendingBytes()); |
| + if (strncmp(features, expected_features, |
| + expected_len < buffer_len ? expected_len : buffer_len)) { |
|
siva
2016/05/16 16:48:00
why not write this as
if ((expected_len > buffer_
rmacnak
2016/05/16 20:59:56
Done.
|
| + const intptr_t kMessageBufferSize = 256; |
| + char message_buffer[kMessageBufferSize]; |
| + char* actual_features = OS::StrNDup(features, buffer_len < 128 ? buffer_len |
| + : 128); |
| + OS::SNPrint(message_buffer, |
| + kMessageBufferSize, |
| + "Wrong features in snapshot, expected '%s' found '%s'", |
| + expected_features, |
| + actual_features); |
| + free(const_cast<char*>(expected_features)); |
| + free(actual_features); |
| + // This can also fail while bringing up the VM isolate, so make sure to |
| + // allocate the error message in old space. |
| + const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); |
| + return ApiError::New(msg, Heap::kOld); |
| + } |
| + free(const_cast<char*>(expected_features)); |
| + Advance(expected_len + 1); |
| + return ApiError::null(); |
| +} |
| + |
| + |
| #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ |
| ASSERT(Snapshot::IsFull(kind_)); \ |
| ASSERT_NO_SAFEPOINT_SCOPE(); \ |
| @@ -1719,6 +1762,10 @@ RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| if (error != ApiError::null()) { |
| return error; |
| } |
| + error = VerifyFeatures(); |
| + if (error != ApiError::null()) { |
| + return error; |
| + } |
| // The version string matches. Read the rest of the snapshot. |
| @@ -2114,6 +2161,7 @@ void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| // Write out the version string. |
| writer.WriteVersion(); |
| + writer.WriteFeatures(); |
| /* |
| * Now Write out the following |
| @@ -2165,6 +2213,7 @@ void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
| // Write out the version string. |
| writer.WriteVersion(); |
| + writer.WriteFeatures(); |
| // Write out the full snapshot. |
| @@ -2696,6 +2745,16 @@ void SnapshotWriter::WriteVersion() { |
| } |
| +void SnapshotWriter::WriteFeatures() { |
| + const char* expected_features = Dart::FeaturesString(kind_); |
| + ASSERT(expected_features != NULL); |
| + const intptr_t features_len = strlen(expected_features); |
| + WriteBytes(reinterpret_cast<const uint8_t*>(expected_features), |
| + features_len + 1); |
| + free(const_cast<char*>(expected_features)); |
| +} |
| + |
| + |
| ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| ReAlloc alloc) |
| : SnapshotWriter(Thread::Current(), |
| @@ -2727,6 +2786,7 @@ void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
| // Write out the version string. |
| WriteVersion(); |
| + WriteFeatures(); |
| // Write out the library object. |
| { |