Index: runtime/bin/dartutils.cc |
=================================================================== |
--- runtime/bin/dartutils.cc (revision 20286) |
+++ runtime/bin/dartutils.cc (working copy) |
@@ -25,6 +25,7 @@ |
const char* DartUtils::kIdFieldName = "_id"; |
+uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc }; |
static bool IsWindowsHost() { |
#if defined(TARGET_OS_WINDOWS) |
@@ -187,31 +188,46 @@ |
} |
-Dart_Handle DartUtils::ReadStringFromFile(const char* filename) { |
+static const uint8_t* ReadFile(const char* filename, |
+ intptr_t* file_len, |
+ const char** error_msg) { |
File* file = File::Open(filename, File::kRead); |
if (file == NULL) { |
const char* format = "Unable to open file: %s"; |
intptr_t len = snprintf(NULL, 0, format, filename); |
// TODO(iposva): Allocate from the zone instead of leaking error string |
// here. On the other hand the binary is about the exit anyway. |
- char* error_msg = reinterpret_cast<char*>(malloc(len + 1)); |
- snprintf(error_msg, len + 1, format, filename); |
- return Dart_Error(error_msg); |
+ char* msg = reinterpret_cast<char*>(malloc(len + 1)); |
+ snprintf(msg, len + 1, format, filename); |
+ *error_msg = msg; |
+ return NULL; |
} |
- intptr_t len = file->Length(); |
- uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(len)); |
+ *file_len = file->Length(); |
+ uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*file_len)); |
if (text_buffer == NULL) { |
delete file; |
- return Dart_Error("Unable to allocate buffer"); |
+ *error_msg = "Unable to allocate buffer"; |
+ return NULL; |
} |
- if (!file->ReadFully(text_buffer, len)) { |
+ if (!file->ReadFully(text_buffer, *file_len)) { |
delete file; |
free(text_buffer); |
- return Dart_Error("Unable to fully read contents"); |
+ *error_msg = "Unable to fully read contents"; |
+ return NULL; |
} |
delete file; |
+ return text_buffer; |
+} |
+ |
+ |
+Dart_Handle DartUtils::ReadStringFromFile(const char* filename) { |
+ const char* error_msg = NULL; |
+ intptr_t len; |
+ const uint8_t* text_buffer = ReadFile(filename, &len, &error_msg); |
+ if (text_buffer == NULL) { |
+ return Dart_Error(error_msg); |
+ } |
Dart_Handle str = Dart_NewStringFromUTF8(text_buffer, len); |
- free(text_buffer); |
return str; |
} |
@@ -325,19 +341,27 @@ |
} |
-static Dart_Handle ReadSource(Dart_Handle script_uri, |
- Dart_Handle builtin_lib) { |
- Dart_Handle script_path = DartUtils::FilePathFromUri(script_uri, builtin_lib); |
- if (Dart_IsError(script_path)) { |
- return script_path; |
+const uint8_t* DartUtils::SniffForMagicNumber(const uint8_t* text_buffer, |
+ bool* is_snapshot) { |
+ intptr_t len = sizeof(magic_number); |
+ for (intptr_t i = 0; i < len; i++) { |
+ if (text_buffer[i] != magic_number[i]) { |
+ *is_snapshot = false; |
+ return text_buffer; |
+ } |
} |
- const char* script_path_cstr; |
- Dart_StringToCString(script_path, &script_path_cstr); |
- Dart_Handle source = DartUtils::ReadStringFromFile(script_path_cstr); |
- return source; |
+ *is_snapshot = true; |
+ return text_buffer + len; |
} |
+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)); |
+ ASSERT(bytes_written); |
+} |
+ |
+ |
Dart_Handle DartUtils::LoadScript(const char* script_uri, |
Dart_Handle builtin_lib) { |
Dart_Handle resolved_script_uri; |
@@ -345,11 +369,27 @@ |
if (Dart_IsError(resolved_script_uri)) { |
return resolved_script_uri; |
} |
- Dart_Handle source = ReadSource(resolved_script_uri, builtin_lib); |
- if (Dart_IsError(source)) { |
- return source; |
+ Dart_Handle script_path = DartUtils::FilePathFromUri(resolved_script_uri, |
+ builtin_lib); |
+ if (Dart_IsError(script_path)) { |
+ return script_path; |
} |
- return Dart_LoadScript(resolved_script_uri, source, 0, 0); |
+ const char* script_path_cstr; |
+ Dart_StringToCString(script_path, &script_path_cstr); |
+ const char* error_msg = NULL; |
+ intptr_t len; |
+ const uint8_t* text_buffer = ReadFile(script_path_cstr, &len, &error_msg); |
+ if (text_buffer == NULL) { |
+ return Dart_Error(error_msg); |
+ } |
+ bool is_snapshot = false; |
+ text_buffer = SniffForMagicNumber(text_buffer, &is_snapshot); |
+ if (is_snapshot) { |
+ return Dart_LoadScriptFromSnapshot(text_buffer, len); |
+ } else { |
+ Dart_Handle source = Dart_NewStringFromUTF8(text_buffer, len); |
+ return Dart_LoadScript(resolved_script_uri, source, 0, 0); |
+ } |
} |