| 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)) {
|
|
|