Index: runtime/bin/dartutils.cc |
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc |
index e7237641bb8d0b94897ea46d154758fed0e3f50b..8d1fb11f2b6eff4a5b55b6a1ef74820d2a43335f 100644 |
--- a/runtime/bin/dartutils.cc |
+++ b/runtime/bin/dartutils.cc |
@@ -46,7 +46,47 @@ const char* const DartUtils::kUriLibURL = "dart:uri"; |
const char* const DartUtils::kHttpScheme = "http:"; |
const char* const DartUtils::kVMServiceLibURL = "dart:vmservice"; |
-const uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc }; |
+ |
+struct MagicNumberData { |
+ static const intptr_t kLength = 4; |
+ |
+ const uint8_t bytes[kLength]; |
+ bool should_skip; |
+}; |
+ |
+ |
+MagicNumberData snapshot_magic_number = { { 0xf5, 0xf5, 0xdc, 0xdc }, true }; |
+MagicNumberData kernel_magic_number = { {0x90, 0xab, 0xcd, 0xef}, false }; |
+ |
+ |
+bool TryReadKernel(const char* script_uri, |
+ const uint8_t** kernel_file, |
+ intptr_t* kernel_length) { |
+ *kernel_file = NULL; |
+ *kernel_length = -1; |
+ bool is_kernel_file = false; |
+ void* script_file = DartUtils::OpenFile(script_uri, false); |
+ if (script_file != NULL) { |
+ const uint8_t* buffer = NULL; |
+ DartUtils::ReadFile(&buffer, kernel_length, script_file); |
+ DartUtils::CloseFile(script_file); |
+ if (*kernel_length > 0 && buffer != NULL) { |
+ *kernel_file = buffer; |
+ if (DartUtils::SniffForMagicNumber(&buffer, kernel_length) != |
+ DartUtils::kKernelMagicNumber) { |
+ free(const_cast<uint8_t*>(buffer)); |
+ *kernel_file = NULL; |
+ } else { |
+ // Do not free buffer if this is a kernel file - kernel_file will be |
+ // backed by the same memory as the buffer and caller will own it. |
+ // Caller is responsible for freeing the buffer when this function |
+ // returns true. |
+ is_kernel_file = true; |
+ } |
+ } |
+ } |
+ return is_kernel_file; |
+} |
static bool IsWindowsHost() { |
@@ -467,30 +507,39 @@ Dart_Handle DartUtils::LibraryTagHandler(Dart_LibraryTag tag, |
} |
-const uint8_t* DartUtils::SniffForMagicNumber(const uint8_t* text_buffer, |
- intptr_t* buffer_len, |
- bool* is_snapshot) { |
- intptr_t len = sizeof(magic_number); |
- if (*buffer_len <= len) { |
- *is_snapshot = false; |
- return text_buffer; |
- } |
- for (intptr_t i = 0; i < len; i++) { |
- if (text_buffer[i] != magic_number[i]) { |
- *is_snapshot = false; |
- return text_buffer; |
+static bool CheckMagicNumber(const uint8_t** buf, |
+ intptr_t* len, |
+ const MagicNumberData& magic_number) { |
+ if ((*len >= MagicNumberData::kLength) && |
+ (memcmp(*buf, magic_number.bytes, MagicNumberData::kLength) == 0)) { |
+ if (magic_number.should_skip) { |
+ *buf += MagicNumberData::kLength; |
+ *len -= MagicNumberData::kLength; |
} |
+ return true; |
} |
- *is_snapshot = true; |
- ASSERT(*buffer_len > len); |
- *buffer_len -= len; |
- return text_buffer + len; |
+ return false; |
+} |
+ |
+ |
+DartUtils::MagicNumber DartUtils::SniffForMagicNumber(const uint8_t** buf, |
+ intptr_t* len) { |
+ if (CheckMagicNumber(buf, len, snapshot_magic_number)) { |
+ return kSnapshotMagicNumber; |
+ } |
+ |
+ if (CheckMagicNumber(buf, len, kernel_magic_number)) { |
+ return kKernelMagicNumber; |
+ } |
+ |
+ return kUnknownMagicNumber; |
} |
void DartUtils::WriteMagicNumber(File* file) { |
// Write a magic number and version information into the snapshot file. |
- bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number)); |
+ bool bytes_written = file->WriteFully(snapshot_magic_number.bytes, |
+ MagicNumberData::kLength); |
ASSERT(bytes_written); |
} |
@@ -558,12 +607,14 @@ void FUNCTION_NAME(Builtin_LoadSource)(Dart_NativeArguments args) { |
if (Dart_IsNull(tag_in) && Dart_IsNull(library_uri)) { |
// Entry file. Check for payload and load accordingly. |
- bool is_snapshot = false; |
- const uint8_t *payload = |
- DartUtils::SniffForMagicNumber(data, &num_bytes, &is_snapshot); |
+ const uint8_t* payload = data; |
+ const DartUtils::MagicNumber payload_type = |
+ DartUtils::SniffForMagicNumber(&payload, &num_bytes); |
- if (is_snapshot) { |
+ if (payload_type == DartUtils::kSnapshotMagicNumber) { |
result = Dart_LoadScriptFromSnapshot(payload, num_bytes); |
+ } else if (payload_type == DartUtils::kKernelMagicNumber) { |
+ UNREACHABLE(); |
} else { |
Dart_Handle source = Dart_NewStringFromUTF8(data, num_bytes); |
if (Dart_IsError(source)) { |