| Index: runtime/bin/gen_snapshot.cc
|
| diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
|
| index ac50f47cd82336cc93b62317c6bd93835d78ed6d..f99f8a8512fa49bf6dde97b4e6e474a89022f2e4 100644
|
| --- a/runtime/bin/gen_snapshot.cc
|
| +++ b/runtime/bin/gen_snapshot.cc
|
| @@ -149,45 +149,196 @@ static void WriteSnapshotFile(const uint8_t* buffer, const intptr_t size) {
|
| }
|
|
|
|
|
| +class UriResolverIsolateScope {
|
| + public:
|
| + UriResolverIsolateScope() {
|
| + ASSERT(isolate != NULL);
|
| + snapshotted_isolate_ = Dart_CurrentIsolate();
|
| + Dart_ExitIsolate();
|
| + Dart_EnterIsolate(isolate);
|
| + Dart_EnterScope();
|
| + }
|
| +
|
| + ~UriResolverIsolateScope() {
|
| + ASSERT(snapshotted_isolate_ != NULL);
|
| + Dart_ExitScope();
|
| + Dart_ExitIsolate();
|
| + Dart_EnterIsolate(snapshotted_isolate_);
|
| + }
|
| +
|
| + static Dart_Isolate isolate;
|
| +
|
| + private:
|
| + Dart_Isolate snapshotted_isolate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(UriResolverIsolateScope);
|
| +};
|
| +
|
| +Dart_Isolate UriResolverIsolateScope::isolate = NULL;
|
| +
|
| +
|
| +static Dart_Handle ResolveScriptUri(const char* script_uri) {
|
| + bool failed = false;
|
| + char* result_string = NULL;
|
| +
|
| + {
|
| + UriResolverIsolateScope scope;
|
| +
|
| + // Run DartUtils::ResolveScriptUri in context of uri resolver isolate.
|
| + Dart_Handle builtin_lib =
|
| + Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
| + CHECK_RESULT(builtin_lib);
|
| +
|
| + Dart_Handle result = DartUtils::ResolveScriptUri(
|
| + DartUtils::NewString(script_uri), builtin_lib);
|
| + if (Dart_IsError(result)) {
|
| + failed = true;
|
| + result_string = strdup(Dart_GetError(result));
|
| + } else {
|
| + result_string = strdup(DartUtils::GetStringValue(result));
|
| + }
|
| + }
|
| +
|
| + Dart_Handle result = failed ? Dart_NewApiError(result_string) :
|
| + DartUtils::NewString(result_string);
|
| + free(result_string);
|
| + return result;
|
| +}
|
| +
|
| +
|
| +static Dart_Handle FilePathFromUri(const char* script_uri) {
|
| + bool failed = false;
|
| + char* result_string = NULL;
|
| +
|
| + {
|
| + UriResolverIsolateScope scope;
|
| +
|
| + // Run DartUtils::FilePathFromUri in context of uri resolver isolate.
|
| + Dart_Handle builtin_lib =
|
| + Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
| + CHECK_RESULT(builtin_lib);
|
| +
|
| + Dart_Handle result = DartUtils::FilePathFromUri(
|
| + DartUtils::NewString(script_uri), builtin_lib);
|
| + if (Dart_IsError(result)) {
|
| + failed = true;
|
| + result_string = strdup(Dart_GetError(result));
|
| + } else {
|
| + result_string = strdup(DartUtils::GetStringValue(result));
|
| + }
|
| + }
|
| +
|
| + Dart_Handle result = failed ? Dart_NewApiError(result_string) :
|
| + DartUtils::NewString(result_string);
|
| + free(result_string);
|
| + return result;
|
| +}
|
| +
|
| +
|
| +static Dart_Handle ResolveUri(const char* library_uri, const char* uri) {
|
| + bool failed = false;
|
| + char* result_string = NULL;
|
| +
|
| + {
|
| + UriResolverIsolateScope scope;
|
| +
|
| + // Run DartUtils::ResolveUri in context of uri resolver isolate.
|
| + Dart_Handle builtin_lib =
|
| + Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
| + CHECK_RESULT(builtin_lib);
|
| +
|
| + Dart_Handle result = DartUtils::ResolveUri(
|
| + DartUtils::NewString(library_uri),
|
| + DartUtils::NewString(uri),
|
| + builtin_lib);
|
| + if (Dart_IsError(result)) {
|
| + failed = true;
|
| + result_string = strdup(Dart_GetError(result));
|
| + } else {
|
| + result_string = strdup(DartUtils::GetStringValue(result));
|
| + }
|
| + }
|
| +
|
| + Dart_Handle result = failed ? Dart_NewApiError(result_string) :
|
| + DartUtils::NewString(result_string);
|
| + free(result_string);
|
| + return result;
|
| +}
|
| +
|
| +
|
| static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag,
|
| Dart_Handle library,
|
| Dart_Handle url) {
|
| if (!Dart_IsLibrary(library)) {
|
| return Dart_Error("not a library");
|
| }
|
| + Dart_Handle library_url = Dart_LibraryUrl(library);
|
| + if (Dart_IsError(library_url)) {
|
| + return Dart_Error("accessing library url failed");
|
| + }
|
| + const char* library_url_string = DartUtils::GetStringValue(library_url);
|
| + const char* mapped_library_url_string = DartUtils::MapLibraryUrl(
|
| + url_mapping, library_url_string);
|
| + if (mapped_library_url_string != NULL) {
|
| + library_url = ResolveScriptUri(mapped_library_url_string);
|
| + library_url_string = DartUtils::GetStringValue(library_url);
|
| + }
|
| +
|
| if (!Dart_IsString(url)) {
|
| return Dart_Error("url is not a string");
|
| }
|
| - const char* url_string = NULL;
|
| - Dart_Handle result = Dart_StringToCString(url, &url_string);
|
| - if (Dart_IsError(result)) {
|
| - return result;
|
| - }
|
| + const char* url_string = DartUtils::GetStringValue(url);
|
| + const char* mapped_url_string = DartUtils::MapLibraryUrl(url_mapping,
|
| + url_string);
|
|
|
| - // If the URL starts with "dart:" then it is handled specially.
|
| - bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string);
|
| if (tag == kCanonicalizeUrl) {
|
| - if (is_dart_scheme_url) {
|
| + // Keep original names for libraries that have a mapping (e.g. dart:io).
|
| + if (mapped_url_string) {
|
| return url;
|
| }
|
| - return DartUtils::CanonicalizeURL(url_mapping, library, url_string);
|
| + return ResolveUri(library_url_string, url_string);
|
| }
|
| - return DartUtils::LoadSource(url_mapping,
|
| +
|
| + Dart_Handle resolved_url = url;
|
| + if (mapped_url_string != NULL) {
|
| + // Mapped urls are relative to working directory.
|
| + resolved_url = ResolveScriptUri(mapped_url_string);
|
| + if (Dart_IsError(resolved_url)) {
|
| + return resolved_url;
|
| + }
|
| + }
|
| +
|
| + // Get the file path out of the url.
|
| + Dart_Handle file_path = FilePathFromUri(
|
| + DartUtils::GetStringValue(resolved_url));
|
| + if (Dart_IsError(file_path)) {
|
| + return file_path;
|
| + }
|
| +
|
| + return DartUtils::LoadSource(NULL,
|
| library,
|
| url,
|
| tag,
|
| - url_string);
|
| + DartUtils::GetStringValue(file_path));
|
| }
|
|
|
|
|
| static Dart_Handle LoadSnapshotCreationScript(const char* script_name) {
|
| - Dart_Handle source = DartUtils::ReadStringFromFile(script_name);
|
| + Dart_Handle resolved_script_uri = ResolveScriptUri(script_name);
|
| + if (Dart_IsError(resolved_script_uri)) {
|
| + return resolved_script_uri;
|
| + }
|
| + Dart_Handle script_path = FilePathFromUri(
|
| + DartUtils::GetStringValue(resolved_script_uri));
|
| + if (Dart_IsError(script_path)) {
|
| + return script_path;
|
| + }
|
| + Dart_Handle source = DartUtils::ReadStringFromFile(
|
| + DartUtils::GetStringValue(script_path));
|
| if (Dart_IsError(source)) {
|
| - return source; // source contains the error string.
|
| + return source;
|
| }
|
| - Dart_Handle url = DartUtils::NewString(script_name);
|
| -
|
| - return Dart_LoadScript(url, source);
|
| + return Dart_LoadScript(resolved_script_uri, source);
|
| }
|
|
|
|
|
| @@ -247,7 +398,7 @@ static void CreateAndWriteSnapshot(bool script_snapshot) {
|
| }
|
|
|
|
|
| -static void SetupForGenericSnapshotCreation() {
|
| +static void SetupForUriResolution() {
|
| // Set up the library tag handler for this isolate.
|
| Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
|
| if (Dart_IsError(result)) {
|
| @@ -260,16 +411,23 @@ static void SetupForGenericSnapshotCreation() {
|
| Dart_Handle library =
|
| LoadGenericSnapshotCreationScript(Builtin::kBuiltinLibrary);
|
| VerifyLoaded(library);
|
| - library = LoadGenericSnapshotCreationScript(Builtin::kJsonLibrary);
|
| - VerifyLoaded(library);
|
| library = LoadGenericSnapshotCreationScript(Builtin::kUriLibrary);
|
| VerifyLoaded(library);
|
| + library = LoadGenericSnapshotCreationScript(Builtin::kUtfLibrary);
|
| + VerifyLoaded(library);
|
| +}
|
| +
|
| +
|
| +static void SetupForGenericSnapshotCreation() {
|
| + SetupForUriResolution();
|
| +
|
| + Dart_Handle library =
|
| + LoadGenericSnapshotCreationScript(Builtin::kJsonLibrary);
|
| + VerifyLoaded(library);
|
| library = LoadGenericSnapshotCreationScript(Builtin::kCryptoLibrary);
|
| VerifyLoaded(library);
|
| library = LoadGenericSnapshotCreationScript(Builtin::kIOLibrary);
|
| VerifyLoaded(library);
|
| - library = LoadGenericSnapshotCreationScript(Builtin::kUtfLibrary);
|
| - VerifyLoaded(library);
|
| }
|
|
|
|
|
| @@ -323,15 +481,45 @@ int main(int argc, char** argv) {
|
| if (app_script_name != NULL) {
|
| if (!script_snapshot) {
|
| // This is the case of a custom embedder (e.g: dartium) trying to
|
| - // create a full snapshot. Set up the library tag handler for this case
|
| - // in such a manner that it will use the URL mapping specified on the
|
| - // command line to load the libraries.
|
| + // create a full snapshot. The current isolate is set up so that we can
|
| + // invoke the dart uri resolution code like _resolveURI. App script is
|
| + // loaded into a separate isolate.
|
| +
|
| + SetupForUriResolution();
|
| +
|
| + // Get handle to builtin library.
|
| + Dart_Handle builtin_lib =
|
| + Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
| + CHECK_RESULT(builtin_lib);
|
| +
|
| + // Prepare for script loading by setting up the 'print' and 'timer'
|
| + // closures and setting up 'package root' for URI resolution.
|
| + result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
|
| + CHECK_RESULT(result);
|
| + Dart_ExitScope();
|
| +
|
| + UriResolverIsolateScope::isolate = isolate;
|
| +
|
| + // Now we create an isolate into which we load all the code that needs to
|
| + // be in the snapshot.
|
| + if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error) == NULL) {
|
| + fprintf(stderr, "%s", error);
|
| + free(error);
|
| + exit(255);
|
| + }
|
| + Dart_EnterScope();
|
| +
|
| + // Set up the library tag handler in such a manner that it will use the
|
| + // URL mapping specified on the command line to load the libraries.
|
| result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
|
| CHECK_RESULT(result);
|
| // Load the specified script.
|
| library = LoadSnapshotCreationScript(app_script_name);
|
| VerifyLoaded(library);
|
| CreateAndWriteSnapshot(false);
|
| +
|
| + Dart_EnterIsolate(UriResolverIsolateScope::isolate);
|
| + Dart_ShutdownIsolate();
|
| } else {
|
| // This is the case where we want to create a script snapshot of
|
| // the specified script. There will be no URL mapping specified for
|
| @@ -354,12 +542,8 @@ int main(int argc, char** argv) {
|
| Dart_ShutdownIsolate();
|
|
|
| // Now load the specified script and create a script snapshot.
|
| - Dart_Isolate isolate = Dart_CreateIsolate(NULL,
|
| - NULL,
|
| - snapshot_buffer,
|
| - NULL,
|
| - &error);
|
| - if (isolate == NULL) {
|
| + if (Dart_CreateIsolate(
|
| + NULL, NULL, snapshot_buffer, NULL, &error) == NULL) {
|
| Log::PrintErr("%s", error);
|
| free(error);
|
| free(snapshot_buffer);
|
|
|