| Index: runtime/bin/gen_snapshot.cc
|
| diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
|
| index 40d1877114b8f2a2a87fa41a4462c4869c438081..d17b0aae3e8f92d1e03ecfe916d0be92f406689b 100644
|
| --- a/runtime/bin/gen_snapshot.cc
|
| +++ b/runtime/bin/gen_snapshot.cc
|
| @@ -26,6 +26,7 @@
|
|
|
| #include "platform/hashmap.h"
|
| #include "platform/globals.h"
|
| +#include "platform/growable_array.h"
|
|
|
| namespace dart {
|
| namespace bin {
|
| @@ -66,6 +67,7 @@ const uint8_t* isolate_snapshot_data = NULL;
|
| // Global state that indicates whether a snapshot is to be created and
|
| // if so which file to write the snapshot into.
|
| enum SnapshotKind {
|
| + kNone,
|
| kCore,
|
| kScript,
|
| kAppAOTBlobs,
|
| @@ -78,6 +80,7 @@ static const char* isolate_snapshot_data_filename = NULL;
|
| static const char* isolate_snapshot_instructions_filename = NULL;
|
| static const char* assembly_filename = NULL;
|
| static const char* script_snapshot_filename = NULL;
|
| +static const char* dependencies_filename = NULL;
|
|
|
|
|
| // Value of the --package-root flag.
|
| @@ -207,7 +210,10 @@ static bool ProcessSnapshotKindOption(const char* option) {
|
| if (kind == NULL) {
|
| return false;
|
| }
|
| - if (strcmp(kind, "core") == 0) {
|
| + if (strcmp(kind, "none") == 0) {
|
| + snapshot_kind = kNone;
|
| + return true;
|
| + } else if (strcmp(kind, "core") == 0) {
|
| snapshot_kind = kCore;
|
| return true;
|
| } else if (strcmp(kind, "script") == 0) {
|
| @@ -288,6 +294,16 @@ static bool ProcessScriptSnapshotOption(const char* option) {
|
| }
|
|
|
|
|
| +static bool ProcessDependenciesOption(const char* option) {
|
| + const char* name = ProcessOption(option, "--dependencies=");
|
| + if (name != NULL) {
|
| + dependencies_filename = name;
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| static bool ProcessEmbedderEntryPointsManifestOption(const char* option) {
|
| const char* name = ProcessOption(option, "--embedder_entry_points_manifest=");
|
| if (name != NULL) {
|
| @@ -360,6 +376,7 @@ static int ParseArguments(int argc,
|
| ProcessIsolateSnapshotInstructionsOption(argv[i]) ||
|
| ProcessAssemblyOption(argv[i]) ||
|
| ProcessScriptSnapshotOption(argv[i]) ||
|
| + ProcessDependenciesOption(argv[i]) ||
|
| ProcessEmbedderEntryPointsManifestOption(argv[i]) ||
|
| ProcessURLmappingOption(argv[i]) || ProcessPackageRootOption(argv[i]) ||
|
| ProcessPackagesOption(argv[i]) || ProcessEnvironmentOption(argv[i])) {
|
| @@ -388,6 +405,15 @@ static int ParseArguments(int argc,
|
| }
|
|
|
| switch (snapshot_kind) {
|
| + case kNone: {
|
| + if (*script_name == NULL) {
|
| + Log::PrintErr(
|
| + "Building without snapshot generation requires a Dart "
|
| + "script.\n\n");
|
| + return -1;
|
| + }
|
| + break;
|
| + }
|
| case kCore: {
|
| if ((vm_snapshot_data_filename == NULL) ||
|
| (isolate_snapshot_data_filename == NULL)) {
|
| @@ -401,7 +427,7 @@ static int ParseArguments(int argc,
|
| case kScript: {
|
| if ((vm_snapshot_data_filename == NULL) ||
|
| (isolate_snapshot_data_filename == NULL) ||
|
| - (script_snapshot_filename == NULL) || (script_name == NULL)) {
|
| + (script_snapshot_filename == NULL) || (*script_name == NULL)) {
|
| Log::PrintErr(
|
| "Building a script snapshot requires specifying input files for "
|
| "--vm_snapshot_data and --isolate_snapshot_data, an output file "
|
| @@ -415,7 +441,7 @@ static int ParseArguments(int argc,
|
| (vm_snapshot_instructions_filename == NULL) ||
|
| (isolate_snapshot_data_filename == NULL) ||
|
| (isolate_snapshot_instructions_filename == NULL) ||
|
| - (script_name == NULL)) {
|
| + (*script_name == NULL)) {
|
| Log::PrintErr(
|
| "Building an AOT snapshot as blobs requires specifying output "
|
| "files for --vm_snapshot_data, --vm_snapshot_instructions, "
|
| @@ -426,7 +452,7 @@ static int ParseArguments(int argc,
|
| break;
|
| }
|
| case kAppAOTAssembly: {
|
| - if ((assembly_filename == NULL) || (script_name == NULL)) {
|
| + if ((assembly_filename == NULL) || (*script_name == NULL)) {
|
| Log::PrintErr(
|
| "Building an AOT snapshot as assembly requires specifying "
|
| "an output file for --assembly and a Dart script.\n\n");
|
| @@ -501,9 +527,36 @@ class UriResolverIsolateScope {
|
| Dart_Isolate UriResolverIsolateScope::isolate = NULL;
|
|
|
|
|
| +static char* ResolveAsFilePath(const char* uri_string) {
|
| + UriResolverIsolateScope scope;
|
| + uint8_t* scoped_file_path = NULL;
|
| + intptr_t scoped_file_path_length = -1;
|
| + Dart_Handle uri = Dart_NewStringFromCString(uri_string);
|
| + ASSERT(!Dart_IsError(uri));
|
| + Dart_Handle result = Loader::ResolveAsFilePath(uri, &scoped_file_path,
|
| + &scoped_file_path_length);
|
| + if (Dart_IsError(result)) {
|
| + Log::Print("Error resolving dependency: %s\n", Dart_GetError(result));
|
| + exit(kErrorExitCode);
|
| + }
|
| + return StringUtils::StrNDup(reinterpret_cast<const char*>(scoped_file_path),
|
| + scoped_file_path_length);
|
| +}
|
| +
|
| +
|
| +static void AddDependency(const char* uri_string) {
|
| + IsolateData* isolate_data =
|
| + reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
|
| + MallocGrowableArray<char*>* dependencies = isolate_data->dependencies();
|
| + if (dependencies != NULL) {
|
| + dependencies->Add(ResolveAsFilePath(uri_string));
|
| + }
|
| +}
|
| +
|
| +
|
| static Dart_Handle LoadUrlContents(const char* uri_string) {
|
| bool failed = false;
|
| - char* result_string = NULL;
|
| + char* error_string = NULL;
|
| uint8_t* payload = NULL;
|
| intptr_t payload_length = 0;
|
| // Switch to the UriResolver Isolate and load the script.
|
| @@ -515,9 +568,10 @@ static Dart_Handle LoadUrlContents(const char* uri_string) {
|
| Loader::LoadUrlContents(resolved_uri, &payload, &payload_length);
|
| if (Dart_IsError(result)) {
|
| failed = true;
|
| - result_string = strdup(Dart_GetError(result));
|
| + error_string = strdup(Dart_GetError(result));
|
| }
|
| }
|
| + AddDependency(uri_string);
|
| // Switch back to the isolate from which we generate the snapshot and
|
| // create the source string for the specified uri.
|
| Dart_Handle result;
|
| @@ -525,8 +579,8 @@ static Dart_Handle LoadUrlContents(const char* uri_string) {
|
| result = Dart_NewStringFromUTF8(payload, payload_length);
|
| free(payload);
|
| } else {
|
| - result = Dart_NewApiError(result_string);
|
| - free(result_string);
|
| + result = Dart_NewApiError(error_string);
|
| + free(error_string);
|
| }
|
| return result;
|
| }
|
| @@ -591,6 +645,69 @@ static Builtin::BuiltinLibraryId BuiltinId(const char* url) {
|
| }
|
|
|
|
|
| +static void CreateAndWriteDependenciesFile() {
|
| + IsolateData* isolate_data =
|
| + reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
|
| + MallocGrowableArray<char*>* dependencies = isolate_data->dependencies();
|
| + if (dependencies == NULL) {
|
| + return;
|
| + }
|
| +
|
| + ASSERT(dependencies_filename != NULL);
|
| + File* file = File::Open(dependencies_filename, File::kWriteTruncate);
|
| + if (file == NULL) {
|
| + Log::PrintErr("Error: Unable to open dependencies file: %s\n\n",
|
| + dependencies_filename);
|
| + exit(kErrorExitCode);
|
| + }
|
| + bool success = true;
|
| +
|
| + // Targets:
|
| + if (vm_snapshot_data_filename != NULL) {
|
| + success &=
|
| + file->Print("%s ", File::GetCanonicalPath(vm_snapshot_data_filename));
|
| + }
|
| + if (vm_snapshot_instructions_filename != NULL) {
|
| + success &= file->Print(
|
| + "%s ", File::GetCanonicalPath(vm_snapshot_instructions_filename));
|
| + }
|
| + if (isolate_snapshot_data_filename != NULL) {
|
| + success &= file->Print(
|
| + "%s ", File::GetCanonicalPath(isolate_snapshot_data_filename));
|
| + }
|
| + if (isolate_snapshot_instructions_filename != NULL) {
|
| + success &= file->Print(
|
| + "%s ", File::GetCanonicalPath(isolate_snapshot_instructions_filename));
|
| + }
|
| + if (assembly_filename != NULL) {
|
| + success &= file->Print("%s ", File::GetCanonicalPath(assembly_filename));
|
| + }
|
| + if (script_snapshot_filename != NULL) {
|
| + success &=
|
| + file->Print("%s ", File::GetCanonicalPath(script_snapshot_filename));
|
| + }
|
| +
|
| + success &= file->Print(": ");
|
| +
|
| + // Sources:
|
| + for (intptr_t i = 0; i < dependencies->length(); i++) {
|
| + char* dep = dependencies->At(i);
|
| + success &= file->Print("%s ", dep);
|
| + free(dep);
|
| + }
|
| + success &= file->Print("\n");
|
| +
|
| + if (!success) {
|
| + Log::PrintErr("Error: Unable to write dependencies file: %s\n\n",
|
| + dependencies_filename);
|
| + exit(kErrorExitCode);
|
| + }
|
| + file->Release();
|
| + delete dependencies;
|
| + isolate_data->set_dependencies(NULL);
|
| +}
|
| +
|
| +
|
| static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag,
|
| Dart_Handle library,
|
| Dart_Handle url) {
|
| @@ -692,14 +809,22 @@ static void PrintUsage() {
|
| " gen_snapshot [<vm-flags>] [<options>] [<dart-script-file>] \n"
|
| " \n"
|
| " Global options: \n"
|
| -" --package_root=<path> Where to find packages, that is, \n"
|
| -" package:... imports. \n"
|
| +" --package_root=<path> Where to find packages, that is, \n"
|
| +" package:... imports. \n"
|
| +" \n"
|
| +" --packages=<packages_file> Where to find a package spec file \n"
|
| " \n"
|
| -" --packages=<packages_file> Where to find a package spec file \n"
|
| +" --url_mapping=<mapping> Uses the URL mapping(s) specified on \n"
|
| +" the command line to load the \n"
|
| +" libraries. \n"
|
| +" --dependencies=<output-file> Generates a Makefile with snapshot output \n"
|
| +" files as targets and all transitive imports\n"
|
| +" as sources. \n"
|
| " \n"
|
| -" --url_mapping=<mapping> Uses the URL mapping(s) specified on \n"
|
| -" the command line to load the \n"
|
| -" libraries. \n"
|
| +" To discover dependencies without generating a snapshot: \n"
|
| +" --snapshot_kind=none \n"
|
| +" --dependencies=<output-file> \n"
|
| +" <dart-script-file> \n"
|
| " \n"
|
| " To create a core snapshot: \n"
|
| " --snapshot_kind=core \n"
|
| @@ -1343,7 +1468,7 @@ int main(int argc, char** argv) {
|
| Log::PrintErr("Failed to read: %s\n", vm_snapshot_data_filename);
|
| return kErrorExitCode;
|
| }
|
| - file->Close();
|
| + file->Release();
|
| init_params.vm_snapshot_data =
|
| reinterpret_cast<const uint8_t*>(mapped_vm_snapshot_data->address());
|
|
|
| @@ -1358,7 +1483,7 @@ int main(int argc, char** argv) {
|
| Log::PrintErr("Failed to read: %s\n", isolate_snapshot_data_filename);
|
| return kErrorExitCode;
|
| }
|
| - file->Close();
|
| + file->Release();
|
| isolate_snapshot_data = reinterpret_cast<const uint8_t*>(
|
| mapped_isolate_snapshot_data->address());
|
| }
|
| @@ -1425,6 +1550,10 @@ int main(int argc, char** argv) {
|
| const bool is_kernel_file =
|
| TryReadKernel(app_script_name, &kernel, &kernel_length);
|
|
|
| + if (dependencies_filename != NULL) {
|
| + isolate_data->set_dependencies(new MallocGrowableArray<char*>());
|
| + }
|
| +
|
| void* kernel_program = NULL;
|
| if (is_kernel_file) {
|
| kernel_program = Dart_ReadKernelBinary(kernel, kernel_length);
|
| @@ -1451,6 +1580,10 @@ int main(int argc, char** argv) {
|
| result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
|
| CHECK_RESULT(result);
|
|
|
| + if (commandline_packages_file != NULL) {
|
| + AddDependency(commandline_packages_file);
|
| + }
|
| +
|
| Dart_QualifiedFunctionName* entry_points =
|
| ParseEntryPointsManifestIfPresent();
|
|
|
| @@ -1481,6 +1614,8 @@ int main(int argc, char** argv) {
|
| CHECK_RESULT(result);
|
|
|
| switch (snapshot_kind) {
|
| + case kNone:
|
| + break;
|
| case kCore:
|
| CreateAndWriteCoreSnapshot();
|
| break;
|
| @@ -1495,6 +1630,8 @@ int main(int argc, char** argv) {
|
| UNREACHABLE();
|
| }
|
|
|
| + CreateAndWriteDependenciesFile();
|
| +
|
| Dart_ExitScope();
|
| Dart_ShutdownIsolate();
|
|
|
|
|