Chromium Code Reviews| Index: bin/gen_snapshot.cc |
| =================================================================== |
| --- bin/gen_snapshot.cc (revision 1494) |
| +++ bin/gen_snapshot.cc (working copy) |
| @@ -20,6 +20,9 @@ |
| // if so which file to write the snapshot into. |
| static const char* snapshot_filename = NULL; |
| +// Global state that captures the URL mappings specified on the command line. |
| +static CommandLineOptions* url_mapping = NULL; |
| + |
| static bool IsValidFlag(const char* name, |
| const char* prefix, |
| intptr_t prefix_length) { |
| @@ -40,11 +43,26 @@ |
| static bool ProcessSnapshotOption(const char* option) { |
| const char* kSnapshotOption = "--snapshot="; |
| - snapshot_filename = ProcessOption(option, kSnapshotOption); |
| - return snapshot_filename != NULL; |
| + const char* name = ProcessOption(option, kSnapshotOption); |
| + if (name != NULL) { |
| + snapshot_filename = name; |
| + return true; |
| + } |
| + return false; |
| } |
| +static bool ProcessURLmappingOption(const char* option) { |
| + const char* kURLmappingOption = "--url_mapping="; |
| + const char* mapping = ProcessOption(option, kURLmappingOption); |
| + if (mapping != NULL) { |
| + url_mapping->AddArgument(mapping); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| + |
| // Parse out the command line arguments. Returns -1 if the arguments |
| // are incorrect, 0 otherwise. |
| static int ParseArguments(int argc, |
| @@ -59,7 +77,7 @@ |
| // Parse out the vm options. |
| while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
| - if (ProcessSnapshotOption(argv[i])) { |
| + if (ProcessSnapshotOption(argv[i]) || ProcessURLmappingOption(argv[i])) { |
| i += 1; |
| continue; |
| } |
| @@ -90,6 +108,141 @@ |
| } |
| +static const char* MapLibraryUrl(const char* library_url_chars) { |
| + const char* mapped_url_chars = library_url_chars; |
| + if (url_mapping != NULL) { |
| + // We need to check if the passed in url is found in the url_mapping array, |
| + // in that case use the mapped entry. |
| + for (int idx = 0; idx < url_mapping->count(); idx++) { |
| + const char* url_name = url_mapping->GetArgument(idx); |
| + int len = strlen(library_url_chars); |
|
Anton Muhin
2011/11/14 14:02:14
hoist len out of for loop?
siva
2011/11/14 22:17:09
Done.
|
| + if (!strncmp(library_url_chars, url_name, len) && |
| + (url_name[len] == ',')) { |
|
Anton Muhin
2011/11/14 14:02:14
should we protect from that? if yes, we may need
siva
2011/11/14 22:17:09
Not sure I understand what we should protect again
|
| + const char* url_mapped_name = url_name + len + 1; |
| + if (strlen(url_mapped_name) != 0) { |
|
Anton Muhin
2011/11/14 14:02:14
ditto.
siva
2011/11/14 22:17:09
Ditto.
On 2011/11/14 14:02:14, antonmuhin wrote:
|
| + mapped_url_chars = url_mapped_name; |
| + } |
| + break; |
| + } |
| + } |
| + } |
| + return mapped_url_chars; |
| +} |
| + |
| + |
| +static Dart_Handle CanonicalizeUrl(const char* library_url_chars, |
|
Anton Muhin
2011/11/14 14:02:14
doesn't we have pretty similar code in process_scr
siva
2011/11/14 22:17:09
I have refactored this to avoid the duplication.
|
| + const char* url_chars) { |
| + // Create the full path based on the including library and the url. |
| + |
| + // Calculate the path. |
| + |
| + if (File::IsAbsolutePath(url_chars)) { |
| + return Dart_NewString(url_chars); |
| + } |
| + char* path = strdup(library_url_chars); |
| + if (path == NULL) { |
| + return Dart_Error("Unable to duplicate string : possibly out of memory"); |
| + } |
| + char* path_sep = strrchr(path, File::PathSeparator()[0]); |
| + if (path_sep == NULL) { |
| + // No separator found: Reference is a file in local directory. |
| + free(path); |
| + return Dart_NewString(url_chars); |
| + } |
| + *path_sep = '\0'; |
| + intptr_t len = snprintf(NULL, 0, "%s%s%s", |
| + path, File::PathSeparator(), url_chars); |
| + char* absolute_filename = reinterpret_cast<char*>(malloc(len + 1)); |
| + ASSERT(absolute_filename != NULL); |
| + snprintf(absolute_filename, len + 1, "%s%s%s", |
| + path, File::PathSeparator(), url_chars); |
| + free(path); |
| + char* canonical_filename = File::GetCanonicalPath(absolute_filename); |
| + if (canonical_filename == NULL) { |
| + return Dart_NewString(absolute_filename); |
| + } |
| + free(absolute_filename); |
| + Dart_Handle canon_url = Dart_NewString(canonical_filename); |
| + free(const_cast<char*>(canonical_filename)); |
| + return canon_url; |
| +} |
| + |
| + |
| +static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag, |
| + Dart_Handle library, |
| + Dart_Handle url) { |
| + if (!Dart_IsLibrary(library)) { |
| + return Dart_Error("not a library"); |
| + } |
| + if (!Dart_IsString8(url)) { |
| + return Dart_Error("url is not a string"); |
| + } |
| + const char* url_chars = NULL; |
| + Dart_Handle result = Dart_StringToCString(url, &url_chars); |
| + if (Dart_IsError(result)) { |
| + return Dart_Error("accessing url characters failed"); |
| + } |
| + |
| + // If the URL starts with "dart:" then it is handled specially. |
| + static const char* kDartScheme = "dart:"; |
| + static const intptr_t kDartSchemeLen = strlen(kDartScheme); |
| + if (strncmp(url_chars, kDartScheme, kDartSchemeLen) == 0) { |
| + if (tag == kCanonicalizeUrl) { |
| + return Dart_NewString(url_chars); |
| + } |
| + url_chars = MapLibraryUrl(url_chars); |
|
Anton Muhin
2011/11/14 14:02:14
If I import mapped lib in mapped lib, won't we hav
Anton Muhin
2011/11/14 16:44:05
Sorry, I now think you handle this case correctly
siva
2011/11/14 22:17:09
Yes the canonicalization part just returns the URL
|
| + } |
| + // Get the url of the calling library. |
| + Dart_Handle library_url = Dart_LibraryUrl(library); |
| + if (Dart_IsError(library_url)) { |
| + return Dart_Error("accessing library url failed"); |
| + } |
| + if (!Dart_IsString8(library_url)) { |
| + return Dart_Error("library url is not a string"); |
| + } |
| + const char* library_url_chars = NULL; |
| + result = Dart_StringToCString(library_url, &library_url_chars); |
| + if (Dart_IsError(result)) { |
| + return Dart_Error("accessing library url characters failed"); |
| + } |
| + library_url_chars = MapLibraryUrl(library_url_chars); |
| + Dart_Handle canon_url = CanonicalizeUrl(library_url_chars, url_chars); |
| + if (Dart_IsError(canon_url)) { |
| + return canon_url; // canon_url contains the error string. |
| + } |
| + if (tag == kCanonicalizeUrl) { |
| + return canon_url; |
| + } |
| + result = Dart_StringToCString(canon_url, &url_chars); |
| + if (Dart_IsError(result)) { |
| + return Dart_Error("accessing canon url characters failed"); |
| + } |
| + // The tag is either an import or a source tag. Read the file based on the |
| + // url chars. |
| + Dart_Handle source = ReadStringFromFile(url_chars); |
| + if (Dart_IsError(source)) { |
| + return source; // source contains the error string. |
| + } |
| + if (tag == kImportTag) { |
| + return Dart_LoadLibrary(url, source); |
| + } else if (tag == kSourceTag) { |
| + return Dart_LoadSource(library, url, source); |
| + } |
| + return Dart_Error("wrong tag"); |
| +} |
| + |
| + |
| +static Dart_Handle LoadSnapshotCreationScript(const char* script_name) { |
| + Dart_Handle source = ReadStringFromFile(script_name); |
| + if (Dart_IsError(source)) { |
| + return source; // source contains the error string. |
| + } |
| + Dart_Handle url = Dart_NewString(script_name); |
| + |
| + return Dart_LoadScript(url, source, CreateSnapshotLibraryTagHandler); |
| +} |
| + |
| + |
| static void* SnapshotCreateCallback(void* data) { |
| const char* script_name = reinterpret_cast<const char*>(data); |
| Dart_Handle result; |
| @@ -151,6 +304,10 @@ |
| CommandLineOptions vm_options(argc); |
| char* script_name; |
| + // Initialize the URL mapping array. |
| + CommandLineOptions url_mapping_array(argc); |
| + url_mapping = &url_mapping_array; |
| + |
| // Parse command line arguments. |
| if (ParseArguments(argc, |
| argv, |