| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Generate a snapshot file after loading all the scripts specified on the | 5 // Generate a snapshot file after loading all the scripts specified on the |
| 6 // command line. | 6 // command line. |
| 7 | 7 |
| 8 #include <stdio.h> | 8 #include <stdio.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 #include "platform/globals.h" | 28 #include "platform/globals.h" |
| 29 #include "platform/growable_array.h" | 29 #include "platform/growable_array.h" |
| 30 #include "platform/hashmap.h" | 30 #include "platform/hashmap.h" |
| 31 | 31 |
| 32 namespace dart { | 32 namespace dart { |
| 33 namespace bin { | 33 namespace bin { |
| 34 | 34 |
| 35 DFE dfe; | 35 DFE dfe; |
| 36 | 36 |
| 37 // Option processing helpers. |
| 38 // TODO(dartbug.com/30534) share option processing between main.cc and |
| 39 // gen_snapshot.cc |
| 40 |
| 41 static const char* ProcessOption(const char* option, const char* name) { |
| 42 const intptr_t length = strlen(name); |
| 43 for (intptr_t i = 0; i < length; i++) { |
| 44 if (option[i] != name[i]) { |
| 45 if (name[i] == '_' && option[i] == '-') { |
| 46 continue; |
| 47 } |
| 48 return NULL; |
| 49 } |
| 50 } |
| 51 return option + length; |
| 52 } |
| 53 |
| 54 typedef bool (*OptionProcessorCallback)(const char* arg); |
| 55 |
| 56 class OptionProcessor { |
| 57 public: |
| 58 OptionProcessor() : next_(first_) { first_ = this; } |
| 59 |
| 60 virtual ~OptionProcessor() {} |
| 61 |
| 62 virtual bool Process(const char* option) = 0; |
| 63 |
| 64 static bool TryProcess(const char* option) { |
| 65 for (OptionProcessor* p = first_; p != NULL; p = p->next_) { |
| 66 if (p->Process(option)) { |
| 67 return true; |
| 68 } |
| 69 } |
| 70 return false; |
| 71 } |
| 72 |
| 73 private: |
| 74 static OptionProcessor* first_; |
| 75 OptionProcessor* next_; |
| 76 }; |
| 77 |
| 78 class CallbackOptionProcessor : public OptionProcessor { |
| 79 public: |
| 80 explicit CallbackOptionProcessor(OptionProcessorCallback cb) : cb_(cb) {} |
| 81 virtual bool Process(const char* option) { return cb_(option); } |
| 82 |
| 83 private: |
| 84 OptionProcessorCallback cb_; |
| 85 }; |
| 86 |
| 87 OptionProcessor* OptionProcessor::first_ = NULL; |
| 88 |
| 89 #define DEFINE_CB_OPTION(callback) \ |
| 90 static CallbackOptionProcessor option_##callback(&callback); |
| 91 |
| 92 #define DEFINE_STRING_OPTION_CB(name, callback) \ |
| 93 class OptionProcessor_##name : public OptionProcessor { \ |
| 94 public: \ |
| 95 virtual bool Process(const char* option) { \ |
| 96 const char* value = ProcessOption(option, "--" #name "="); \ |
| 97 if (value == NULL) { \ |
| 98 return false; \ |
| 99 } \ |
| 100 if (*value == '\0') { \ |
| 101 Log::PrintErr("Empty value for option " #name "\n"); \ |
| 102 return false; \ |
| 103 } \ |
| 104 callback; \ |
| 105 return true; \ |
| 106 } \ |
| 107 }; \ |
| 108 static OptionProcessor_##name option_##name; |
| 109 |
| 110 #define DEFINE_ENUM_OPTION(name, enum_name, variable) \ |
| 111 DEFINE_STRING_OPTION_CB(name, { \ |
| 112 const char** kNames = k##enum_name##Names; \ |
| 113 for (intptr_t i = 0; kNames[i] != NULL; i++) { \ |
| 114 if (strcmp(value, kNames[i]) == 0) { \ |
| 115 variable = static_cast<enum_name>(i); \ |
| 116 return true; \ |
| 117 } \ |
| 118 } \ |
| 119 Log::PrintErr( \ |
| 120 "Unrecognized value for " #name ": '%s'\nValid values are: ", value); \ |
| 121 for (intptr_t i = 0; kNames[i] != NULL; i++) { \ |
| 122 Log::PrintErr("%s%s", i > 0 ? ", " : "", kNames[i]); \ |
| 123 } \ |
| 124 Log::PrintErr("\n"); \ |
| 125 }) |
| 126 |
| 127 #define DEFINE_STRING_OPTION(name, variable) \ |
| 128 static const char* variable = NULL; \ |
| 129 DEFINE_STRING_OPTION_CB(name, { variable = value; }) |
| 130 |
| 131 #define DEFINE_BOOL_OPTION(name, variable) \ |
| 132 static bool variable = false; \ |
| 133 class OptionProcessor_##name : public OptionProcessor { \ |
| 134 public: \ |
| 135 virtual bool Process(const char* option) { \ |
| 136 const char* value = ProcessOption(option, "--" #name); \ |
| 137 if (value == NULL) { \ |
| 138 return false; \ |
| 139 } \ |
| 140 if (*value == '=') { \ |
| 141 Log::PrintErr("Non-empty value for option " #name "\n"); \ |
| 142 return false; \ |
| 143 } \ |
| 144 if (*value != '\0') { \ |
| 145 return false; \ |
| 146 } \ |
| 147 variable = true; \ |
| 148 return true; \ |
| 149 } \ |
| 150 }; \ |
| 151 static OptionProcessor_##name option_##name; |
| 152 |
| 37 // Exit code indicating an API error. | 153 // Exit code indicating an API error. |
| 38 static const int kApiErrorExitCode = 253; | 154 static const int kApiErrorExitCode = 253; |
| 39 // Exit code indicating a compilation error. | 155 // Exit code indicating a compilation error. |
| 40 static const int kCompilationErrorExitCode = 254; | 156 static const int kCompilationErrorExitCode = 254; |
| 41 // Exit code indicating an unhandled error that is not a compilation error. | 157 // Exit code indicating an unhandled error that is not a compilation error. |
| 42 static const int kErrorExitCode = 255; | 158 static const int kErrorExitCode = 255; |
| 43 | 159 |
| 44 #define CHECK_RESULT(result) \ | 160 #define CHECK_RESULT(result) \ |
| 45 if (Dart_IsError(result)) { \ | 161 if (Dart_IsError(result)) { \ |
| 46 intptr_t exit_code = 0; \ | 162 intptr_t exit_code = 0; \ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 65 // Global state that indicates whether a snapshot is to be created and | 181 // Global state that indicates whether a snapshot is to be created and |
| 66 // if so which file to write the snapshot into. | 182 // if so which file to write the snapshot into. |
| 67 enum SnapshotKind { | 183 enum SnapshotKind { |
| 68 kCore, | 184 kCore, |
| 69 kCoreJIT, | 185 kCoreJIT, |
| 70 kScript, | 186 kScript, |
| 71 kAppAOTBlobs, | 187 kAppAOTBlobs, |
| 72 kAppAOTAssembly, | 188 kAppAOTAssembly, |
| 73 }; | 189 }; |
| 74 static SnapshotKind snapshot_kind = kCore; | 190 static SnapshotKind snapshot_kind = kCore; |
| 75 static const char* vm_snapshot_data_filename = NULL; | |
| 76 static const char* vm_snapshot_instructions_filename = NULL; | |
| 77 static const char* isolate_snapshot_data_filename = NULL; | |
| 78 static const char* isolate_snapshot_instructions_filename = NULL; | |
| 79 static const char* assembly_filename = NULL; | |
| 80 static const char* script_snapshot_filename = NULL; | |
| 81 static bool dependencies_only = false; | |
| 82 static bool print_dependencies = false; | |
| 83 static const char* dependencies_filename = NULL; | |
| 84 | |
| 85 // Value of the --load-compilation-trace flag. | |
| 86 // (This pointer points into an argv buffer and does not need to be | |
| 87 // free'd.) | |
| 88 static const char* load_compilation_trace_filename = NULL; | |
| 89 | |
| 90 // Value of the --package-root flag. | |
| 91 // (This pointer points into an argv buffer and does not need to be | |
| 92 // free'd.) | |
| 93 static const char* commandline_package_root = NULL; | |
| 94 | |
| 95 // Value of the --packages flag. | |
| 96 // (This pointer points into an argv buffer and does not need to be | |
| 97 // free'd.) | |
| 98 static const char* commandline_packages_file = NULL; | |
| 99 | 191 |
| 100 // Global state which contains a pointer to the script name for which | 192 // Global state which contains a pointer to the script name for which |
| 101 // a snapshot needs to be created (NULL would result in the creation | 193 // a snapshot needs to be created (NULL would result in the creation |
| 102 // of a generic snapshot that contains only the corelibs). | 194 // of a generic snapshot that contains only the corelibs). |
| 103 static char* app_script_name = NULL; | 195 static char* app_script_name = NULL; |
| 104 | 196 |
| 105 // Global state that captures the entry point manifest files specified on the | 197 // Global state that captures the entry point manifest files specified on the |
| 106 // command line. | 198 // command line. |
| 107 static CommandLineOptions* entry_points_files = NULL; | 199 static CommandLineOptions* entry_points_files = NULL; |
| 108 | 200 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } | 281 } |
| 190 if (value != NULL) { | 282 if (value != NULL) { |
| 191 result = Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(value), | 283 result = Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(value), |
| 192 strlen(value)); | 284 strlen(value)); |
| 193 } | 285 } |
| 194 free(name_chars); | 286 free(name_chars); |
| 195 } | 287 } |
| 196 return result; | 288 return result; |
| 197 } | 289 } |
| 198 | 290 |
| 199 static const char* ProcessOption(const char* option, const char* name) { | 291 static const char* kSnapshotKindNames[] = { |
| 200 const intptr_t length = strlen(name); | 292 "core", "core-jit", "script", "app-aot-blobs", "app-aot-assembly", NULL, |
| 201 if (strncmp(option, name, length) == 0) { | 293 }; |
| 202 return (option + length); | |
| 203 } | |
| 204 return NULL; | |
| 205 } | |
| 206 | 294 |
| 207 static bool ProcessSnapshotKindOption(const char* option) { | 295 DEFINE_ENUM_OPTION(snapshot_kind, SnapshotKind, snapshot_kind); |
| 208 const char* kind = ProcessOption(option, "--snapshot_kind="); | 296 DEFINE_STRING_OPTION(vm_snapshot_data, vm_snapshot_data_filename); |
| 209 if (kind == NULL) { | 297 DEFINE_STRING_OPTION(vm_snapshot_instructions, |
| 210 kind = ProcessOption(option, "--snapshot-kind="); | 298 vm_snapshot_instructions_filename); |
| 211 } | 299 DEFINE_STRING_OPTION(isolate_snapshot_data, isolate_snapshot_data_filename); |
| 212 if (kind == NULL) { | 300 DEFINE_STRING_OPTION(isolate_snapshot_instructions, |
| 213 return false; | 301 isolate_snapshot_instructions_filename); |
| 214 } | 302 DEFINE_STRING_OPTION(assembly, assembly_filename); |
| 215 if (strcmp(kind, "core-jit") == 0) { | 303 DEFINE_STRING_OPTION(script_snapshot, script_snapshot_filename); |
| 216 snapshot_kind = kCoreJIT; | 304 DEFINE_STRING_OPTION(dependencies, dependencies_filename); |
| 217 return true; | 305 DEFINE_BOOL_OPTION(dependencies_only, dependencies_only); |
| 218 } else if (strcmp(kind, "core") == 0) { | 306 DEFINE_BOOL_OPTION(print_dependencies, print_dependencies); |
| 219 snapshot_kind = kCore; | 307 DEFINE_STRING_OPTION_CB(embedder_entry_points_manifest, |
| 220 return true; | 308 { entry_points_files->AddArgument(value); }); |
| 221 } else if (strcmp(kind, "script") == 0) { | 309 DEFINE_STRING_OPTION(load_compilation_trace, load_compilation_trace_filename); |
| 222 snapshot_kind = kScript; | 310 DEFINE_STRING_OPTION(package_root, commandline_package_root); |
| 223 return true; | 311 DEFINE_STRING_OPTION(packages, commandline_packages_file); |
| 224 } else if (strcmp(kind, "app-aot-blobs") == 0) { | 312 DEFINE_STRING_OPTION_CB(url_mapping, |
| 225 snapshot_kind = kAppAOTBlobs; | 313 { DartUtils::url_mapping->AddArgument(value); }); |
| 226 return true; | 314 DEFINE_CB_OPTION(ProcessEnvironmentOption); |
| 227 } else if (strcmp(kind, "app-aot-assembly") == 0) { | 315 DEFINE_BOOL_OPTION(obfuscate, obfuscate); |
| 228 snapshot_kind = kAppAOTAssembly; | 316 DEFINE_STRING_OPTION(save_obfuscation_map, obfuscation_map_filename); |
| 229 return true; | |
| 230 } | |
| 231 Log::PrintErr( | |
| 232 "Unrecognized snapshot kind: '%s'\nValid kinds are: " | |
| 233 "core, script, app-aot-blobs, app-aot-assembly\n", | |
| 234 kind); | |
| 235 return false; | |
| 236 } | |
| 237 | |
| 238 static bool ProcessVmSnapshotDataOption(const char* option) { | |
| 239 const char* name = ProcessOption(option, "--vm_snapshot_data="); | |
| 240 if (name == NULL) { | |
| 241 name = ProcessOption(option, "--vm-snapshot-data="); | |
| 242 } | |
| 243 if (name != NULL) { | |
| 244 vm_snapshot_data_filename = name; | |
| 245 return true; | |
| 246 } | |
| 247 return false; | |
| 248 } | |
| 249 | |
| 250 static bool ProcessVmSnapshotInstructionsOption(const char* option) { | |
| 251 const char* name = ProcessOption(option, "--vm_snapshot_instructions="); | |
| 252 if (name == NULL) { | |
| 253 name = ProcessOption(option, "--vm-snapshot-instructions="); | |
| 254 } | |
| 255 if (name != NULL) { | |
| 256 vm_snapshot_instructions_filename = name; | |
| 257 return true; | |
| 258 } | |
| 259 return false; | |
| 260 } | |
| 261 | |
| 262 static bool ProcessIsolateSnapshotDataOption(const char* option) { | |
| 263 const char* name = ProcessOption(option, "--isolate_snapshot_data="); | |
| 264 if (name == NULL) { | |
| 265 name = ProcessOption(option, "--isolate-snapshot-data="); | |
| 266 } | |
| 267 if (name != NULL) { | |
| 268 isolate_snapshot_data_filename = name; | |
| 269 return true; | |
| 270 } | |
| 271 return false; | |
| 272 } | |
| 273 | |
| 274 static bool ProcessIsolateSnapshotInstructionsOption(const char* option) { | |
| 275 const char* name = ProcessOption(option, "--isolate_snapshot_instructions="); | |
| 276 if (name == NULL) { | |
| 277 name = ProcessOption(option, "--isolate-snapshot-instructions="); | |
| 278 } | |
| 279 if (name != NULL) { | |
| 280 isolate_snapshot_instructions_filename = name; | |
| 281 return true; | |
| 282 } | |
| 283 return false; | |
| 284 } | |
| 285 | |
| 286 static bool ProcessAssemblyOption(const char* option) { | |
| 287 const char* name = ProcessOption(option, "--assembly="); | |
| 288 if (name != NULL) { | |
| 289 assembly_filename = name; | |
| 290 return true; | |
| 291 } | |
| 292 return false; | |
| 293 } | |
| 294 | |
| 295 static bool ProcessScriptSnapshotOption(const char* option) { | |
| 296 const char* name = ProcessOption(option, "--script_snapshot="); | |
| 297 if (name == NULL) { | |
| 298 name = ProcessOption(option, "--script-snapshot="); | |
| 299 } | |
| 300 if (name != NULL) { | |
| 301 script_snapshot_filename = name; | |
| 302 return true; | |
| 303 } | |
| 304 return false; | |
| 305 } | |
| 306 | |
| 307 static bool ProcessDependenciesOption(const char* option) { | |
| 308 const char* name = ProcessOption(option, "--dependencies="); | |
| 309 if (name != NULL) { | |
| 310 dependencies_filename = name; | |
| 311 return true; | |
| 312 } | |
| 313 return false; | |
| 314 } | |
| 315 | |
| 316 static bool ProcessDependenciesOnlyOption(const char* option) { | |
| 317 const char* name = ProcessOption(option, "--dependencies_only"); | |
| 318 if (name == NULL) { | |
| 319 name = ProcessOption(option, "--dependencies-only"); | |
| 320 } | |
| 321 if (name != NULL) { | |
| 322 dependencies_only = true; | |
| 323 return true; | |
| 324 } | |
| 325 return false; | |
| 326 } | |
| 327 | |
| 328 static bool ProcessPrintDependenciesOption(const char* option) { | |
| 329 const char* name = ProcessOption(option, "--print_dependencies"); | |
| 330 if (name == NULL) { | |
| 331 name = ProcessOption(option, "--print-dependencies"); | |
| 332 } | |
| 333 if (name != NULL) { | |
| 334 print_dependencies = true; | |
| 335 return true; | |
| 336 } | |
| 337 return false; | |
| 338 } | |
| 339 | |
| 340 static bool ProcessEmbedderEntryPointsManifestOption(const char* option) { | |
| 341 const char* name = ProcessOption(option, "--embedder_entry_points_manifest="); | |
| 342 if (name == NULL) { | |
| 343 name = ProcessOption(option, "--embedder-entry-points-manifest="); | |
| 344 } | |
| 345 if (name != NULL) { | |
| 346 entry_points_files->AddArgument(name); | |
| 347 return true; | |
| 348 } | |
| 349 return false; | |
| 350 } | |
| 351 | |
| 352 static bool ProcessLoadCompilationTraceOption(const char* option) { | |
| 353 const char* name = ProcessOption(option, "--load_compilation_trace="); | |
| 354 if (name == NULL) { | |
| 355 name = ProcessOption(option, "--load-compilation-trace="); | |
| 356 } | |
| 357 if (name != NULL) { | |
| 358 load_compilation_trace_filename = name; | |
| 359 return true; | |
| 360 } | |
| 361 return false; | |
| 362 } | |
| 363 | |
| 364 static bool ProcessPackageRootOption(const char* option) { | |
| 365 const char* name = ProcessOption(option, "--package_root="); | |
| 366 if (name == NULL) { | |
| 367 name = ProcessOption(option, "--package-root="); | |
| 368 } | |
| 369 if (name != NULL) { | |
| 370 commandline_package_root = name; | |
| 371 return true; | |
| 372 } | |
| 373 return false; | |
| 374 } | |
| 375 | |
| 376 static bool ProcessPackagesOption(const char* option) { | |
| 377 const char* name = ProcessOption(option, "--packages="); | |
| 378 if (name != NULL) { | |
| 379 commandline_packages_file = name; | |
| 380 return true; | |
| 381 } | |
| 382 return false; | |
| 383 } | |
| 384 | |
| 385 static bool ProcessURLmappingOption(const char* option) { | |
| 386 const char* mapping = ProcessOption(option, "--url_mapping="); | |
| 387 if (mapping == NULL) { | |
| 388 mapping = ProcessOption(option, "--url-mapping="); | |
| 389 } | |
| 390 if (mapping != NULL) { | |
| 391 DartUtils::url_mapping->AddArgument(mapping); | |
| 392 return true; | |
| 393 } | |
| 394 return false; | |
| 395 } | |
| 396 | 317 |
| 397 static bool IsSnapshottingForPrecompilation() { | 318 static bool IsSnapshottingForPrecompilation() { |
| 398 return (snapshot_kind == kAppAOTBlobs) || (snapshot_kind == kAppAOTAssembly); | 319 return (snapshot_kind == kAppAOTBlobs) || (snapshot_kind == kAppAOTAssembly); |
| 399 } | 320 } |
| 400 | 321 |
| 401 // Parse out the command line arguments. Returns -1 if the arguments | 322 // Parse out the command line arguments. Returns -1 if the arguments |
| 402 // are incorrect, 0 otherwise. | 323 // are incorrect, 0 otherwise. |
| 403 static int ParseArguments(int argc, | 324 static int ParseArguments(int argc, |
| 404 char** argv, | 325 char** argv, |
| 405 CommandLineOptions* vm_options, | 326 CommandLineOptions* vm_options, |
| 406 char** script_name) { | 327 char** script_name) { |
| 407 const char* kPrefix = "-"; | 328 const char* kPrefix = "-"; |
| 408 const intptr_t kPrefixLen = strlen(kPrefix); | 329 const intptr_t kPrefixLen = strlen(kPrefix); |
| 409 | 330 |
| 410 // Skip the binary name. | 331 // Skip the binary name. |
| 411 int i = 1; | 332 int i = 1; |
| 412 | 333 |
| 413 // Parse out the vm options. | 334 // Parse out the vm options. |
| 414 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { | 335 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
| 415 if (ProcessSnapshotKindOption(argv[i]) || | 336 if (OptionProcessor::TryProcess(argv[i])) { |
| 416 ProcessVmSnapshotDataOption(argv[i]) || | |
| 417 ProcessVmSnapshotInstructionsOption(argv[i]) || | |
| 418 ProcessIsolateSnapshotDataOption(argv[i]) || | |
| 419 ProcessIsolateSnapshotInstructionsOption(argv[i]) || | |
| 420 ProcessAssemblyOption(argv[i]) || | |
| 421 ProcessScriptSnapshotOption(argv[i]) || | |
| 422 ProcessDependenciesOption(argv[i]) || | |
| 423 ProcessDependenciesOnlyOption(argv[i]) || | |
| 424 ProcessPrintDependenciesOption(argv[i]) || | |
| 425 ProcessEmbedderEntryPointsManifestOption(argv[i]) || | |
| 426 ProcessURLmappingOption(argv[i]) || | |
| 427 ProcessLoadCompilationTraceOption(argv[i]) || | |
| 428 ProcessPackageRootOption(argv[i]) || ProcessPackagesOption(argv[i]) || | |
| 429 ProcessEnvironmentOption(argv[i])) { | |
| 430 i += 1; | 337 i += 1; |
| 431 continue; | 338 continue; |
| 432 } | 339 } |
| 433 vm_options->AddArgument(argv[i]); | 340 vm_options->AddArgument(argv[i]); |
| 434 i += 1; | 341 i += 1; |
| 435 } | 342 } |
| 436 | 343 |
| 437 // Get the script name. | 344 // Get the script name. |
| 438 if (i < argc) { | 345 if (i < argc) { |
| 439 *script_name = argv[i]; | 346 *script_name = argv[i]; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 } | 420 } |
| 514 } | 421 } |
| 515 | 422 |
| 516 if (IsSnapshottingForPrecompilation() && (entry_points_files->count() == 0)) { | 423 if (IsSnapshottingForPrecompilation() && (entry_points_files->count() == 0)) { |
| 517 Log::PrintErr( | 424 Log::PrintErr( |
| 518 "Building an AOT snapshot requires at least one embedder " | 425 "Building an AOT snapshot requires at least one embedder " |
| 519 "entry points manifest.\n\n"); | 426 "entry points manifest.\n\n"); |
| 520 return -1; | 427 return -1; |
| 521 } | 428 } |
| 522 | 429 |
| 430 if (!obfuscate && obfuscation_map_filename != NULL) { |
| 431 Log::PrintErr( |
| 432 "--obfuscation_map=<...> should only be specified when obfuscation is " |
| 433 "enabled by --obfuscate flag.\n\n"); |
| 434 return -1; |
| 435 } |
| 436 |
| 437 if (obfuscate && !IsSnapshottingForPrecompilation()) { |
| 438 Log::PrintErr( |
| 439 "Obfuscation can only be enabled when building AOT snapshot.\n\n"); |
| 440 return -1; |
| 441 } |
| 442 |
| 523 return 0; | 443 return 0; |
| 524 } | 444 } |
| 525 | 445 |
| 526 static void WriteFile(const char* filename, | 446 static void WriteFile(const char* filename, |
| 527 const uint8_t* buffer, | 447 const uint8_t* buffer, |
| 528 const intptr_t size) { | 448 const intptr_t size) { |
| 529 File* file = File::Open(filename, File::kWriteTruncate); | 449 File* file = File::Open(filename, File::kWriteTruncate); |
| 530 if (file == NULL) { | 450 if (file == NULL) { |
| 531 Log::PrintErr("Error: Unable to write snapshot file: %s\n\n", filename); | 451 Log::PrintErr("Error: Unable to write snapshot file: %s\n\n", filename); |
| 532 Dart_ExitScope(); | 452 Dart_ExitScope(); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 " is created. \n" | 883 " is created. \n" |
| 964 " \n" | 884 " \n" |
| 965 " To create an AOT application snapshot as blobs suitable for loading with \n" | 885 " To create an AOT application snapshot as blobs suitable for loading with \n" |
| 966 " mmap: \n" | 886 " mmap: \n" |
| 967 " --snapshot_kind=app-aot-blobs \n" | 887 " --snapshot_kind=app-aot-blobs \n" |
| 968 " --vm_snapshot_data=<output-file> \n" | 888 " --vm_snapshot_data=<output-file> \n" |
| 969 " --vm_snapshot_instructions=<output-file> \n" | 889 " --vm_snapshot_instructions=<output-file> \n" |
| 970 " --isolate_snapshot_data=<output-file> \n" | 890 " --isolate_snapshot_data=<output-file> \n" |
| 971 " --isolate_snapshot_instructions=<output-file> \n" | 891 " --isolate_snapshot_instructions=<output-file> \n" |
| 972 " {--embedder_entry_points_manifest=<input-file>} \n" | 892 " {--embedder_entry_points_manifest=<input-file>} \n" |
| 893 " [--obfuscate] \n" |
| 894 " [--save-obfuscation-map=<map-filename>] \n" |
| 973 " <dart-script-file> \n" | 895 " <dart-script-file> \n" |
| 974 " \n" | 896 " \n" |
| 975 " To create an AOT application snapshot as assembly suitable for compilation \n" | 897 " To create an AOT application snapshot as assembly suitable for compilation \n" |
| 976 " as a static or dynamic library: \n" | 898 " as a static or dynamic library: \n" |
| 977 " mmap: \n" | 899 " mmap: \n" |
| 978 " --snapshot_kind=app-aot-blobs \n" | 900 " --snapshot_kind=app-aot-blobs \n" |
| 979 " --assembly=<output-file> \n" | 901 " --assembly=<output-file> \n" |
| 980 " {--embedder_entry_points_manifest=<input-file>} \n" | 902 " {--embedder_entry_points_manifest=<input-file>} \n" |
| 903 " [--obfuscate] \n" |
| 904 " [--save-obfuscation-map=<map-filename>] \n" |
| 981 " <dart-script-file> \n" | 905 " <dart-script-file> \n" |
| 982 " \n" | 906 " \n" |
| 983 " AOT snapshots require entry points manifest files, which list the places \n" | 907 " AOT snapshots require entry points manifest files, which list the places \n" |
| 984 " in the Dart program the embedder calls from the C API (Dart_Invoke, etc). \n" | 908 " in the Dart program the embedder calls from the C API (Dart_Invoke, etc). \n" |
| 985 " Not specifying these may cause the tree shaker to remove them from the \n" | 909 " Not specifying these may cause the tree shaker to remove them from the \n" |
| 986 " program. The format of this manifest is as follows. Each line in the \n" | 910 " program. The format of this manifest is as follows. Each line in the \n" |
| 987 " manifest is a comma separated list of three elements. The first entry is \n" | 911 " manifest is a comma separated list of three elements. The first entry is \n" |
| 988 " the library URI, the second entry is the class name and the final entry \n" | 912 " the library URI, the second entry is the class name and the final entry \n" |
| 989 " the function name. The file must be terminated with a newline character. \n" | 913 " the function name. The file must be terminated with a newline character. \n" |
| 990 " \n" | 914 " \n" |
| 991 " Example: \n" | 915 " Example: \n" |
| 992 " dart:something,SomeClass,doSomething \n" | 916 " dart:something,SomeClass,doSomething \n" |
| 917 " \n" |
| 918 " AOT snapshots can be obfuscated: that is all identifiers will be renamed \n" |
| 919 " during compilation. This mode is enabled with --obfuscate flag. Mapping \n" |
| 920 " between original and obfuscated names can be serialized as a JSON array \n" |
| 921 " using --save-obfuscation-map=<filename> option. See dartbug.com/30524 \n" |
| 922 " for implementation details and limitations of the obfuscation pass. \n" |
| 923 " \n" |
| 993 "\n"); | 924 "\n"); |
| 994 } | 925 } |
| 995 // clang-format on | 926 // clang-format on |
| 996 | 927 |
| 997 static const char StubNativeFunctionName[] = "StubNativeFunction"; | 928 static const char StubNativeFunctionName[] = "StubNativeFunction"; |
| 998 | 929 |
| 999 void StubNativeFunction(Dart_NativeArguments arguments) { | 930 void StubNativeFunction(Dart_NativeArguments arguments) { |
| 1000 // This is a stub function for the resolver | 931 // This is a stub function for the resolver |
| 1001 Dart_SetReturnValue( | 932 Dart_SetReturnValue( |
| 1002 arguments, Dart_NewApiError("<EMBEDDER DID NOT SETUP NATIVE RESOLVER>")); | 933 arguments, Dart_NewApiError("<EMBEDDER DID NOT SETUP NATIVE RESOLVER>")); |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1460 WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer, | 1391 WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer, |
| 1461 vm_snapshot_data_size); | 1392 vm_snapshot_data_size); |
| 1462 WriteFile(vm_snapshot_instructions_filename, | 1393 WriteFile(vm_snapshot_instructions_filename, |
| 1463 vm_snapshot_instructions_buffer, vm_snapshot_instructions_size); | 1394 vm_snapshot_instructions_buffer, vm_snapshot_instructions_size); |
| 1464 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer, | 1395 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer, |
| 1465 isolate_snapshot_data_size); | 1396 isolate_snapshot_data_size); |
| 1466 WriteFile(isolate_snapshot_instructions_filename, | 1397 WriteFile(isolate_snapshot_instructions_filename, |
| 1467 isolate_snapshot_instructions_buffer, | 1398 isolate_snapshot_instructions_buffer, |
| 1468 isolate_snapshot_instructions_size); | 1399 isolate_snapshot_instructions_size); |
| 1469 } | 1400 } |
| 1401 |
| 1402 // Serialize obfuscation map if requested. |
| 1403 if (obfuscation_map_filename != NULL) { |
| 1404 ASSERT(obfuscate); |
| 1405 uint8_t* buffer = NULL; |
| 1406 intptr_t size = 0; |
| 1407 result = Dart_GetObfuscationMap(&buffer, &size); |
| 1408 CHECK_RESULT(result); |
| 1409 WriteFile(obfuscation_map_filename, buffer, size); |
| 1410 } |
| 1470 } | 1411 } |
| 1471 | 1412 |
| 1472 static void SetupForUriResolution() { | 1413 static void SetupForUriResolution() { |
| 1473 // Set up the library tag handler for this isolate. | 1414 // Set up the library tag handler for this isolate. |
| 1474 Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler); | 1415 Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler); |
| 1475 if (Dart_IsError(result)) { | 1416 if (Dart_IsError(result)) { |
| 1476 Log::PrintErr("%s\n", Dart_GetError(result)); | 1417 Log::PrintErr("%s\n", Dart_GetError(result)); |
| 1477 Dart_ExitScope(); | 1418 Dart_ExitScope(); |
| 1478 Dart_ShutdownIsolate(); | 1419 Dart_ShutdownIsolate(); |
| 1479 exit(kErrorExitCode); | 1420 exit(kErrorExitCode); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 } | 1598 } |
| 1658 } | 1599 } |
| 1659 | 1600 |
| 1660 char* error = Dart_Initialize(&init_params); | 1601 char* error = Dart_Initialize(&init_params); |
| 1661 if (error != NULL) { | 1602 if (error != NULL) { |
| 1662 Log::PrintErr("VM initialization failed: %s\n", error); | 1603 Log::PrintErr("VM initialization failed: %s\n", error); |
| 1663 free(error); | 1604 free(error); |
| 1664 return kErrorExitCode; | 1605 return kErrorExitCode; |
| 1665 } | 1606 } |
| 1666 | 1607 |
| 1608 Dart_IsolateFlags flags; |
| 1609 Dart_IsolateFlagsInitialize(&flags); |
| 1610 |
| 1611 Dart_QualifiedFunctionName* entry_points = |
| 1612 ParseEntryPointsManifestIfPresent(); |
| 1613 |
| 1667 IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root, | 1614 IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root, |
| 1668 commandline_packages_file, NULL); | 1615 commandline_packages_file, NULL); |
| 1669 Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, | 1616 Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, |
| 1670 isolate_snapshot_instructions, NULL, | 1617 isolate_snapshot_instructions, NULL, |
| 1671 isolate_data, &error); | 1618 isolate_data, &error); |
| 1672 if (isolate == NULL) { | 1619 if (isolate == NULL) { |
| 1673 Log::PrintErr("Error: %s\n", error); | 1620 Log::PrintErr("Error: %s\n", error); |
| 1674 free(error); | 1621 free(error); |
| 1675 exit(kErrorExitCode); | 1622 exit(kErrorExitCode); |
| 1676 } | 1623 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 Dart_ExitIsolate(); | 1658 Dart_ExitIsolate(); |
| 1712 | 1659 |
| 1713 // Now we create an isolate into which we load all the code that needs to | 1660 // Now we create an isolate into which we load all the code that needs to |
| 1714 // be in the snapshot. | 1661 // be in the snapshot. |
| 1715 isolate_data = new IsolateData(app_script_name, commandline_package_root, | 1662 isolate_data = new IsolateData(app_script_name, commandline_package_root, |
| 1716 commandline_packages_file, NULL); | 1663 commandline_packages_file, NULL); |
| 1717 if ((dependencies_filename != NULL) || print_dependencies) { | 1664 if ((dependencies_filename != NULL) || print_dependencies) { |
| 1718 isolate_data->set_dependencies(new MallocGrowableArray<char*>()); | 1665 isolate_data->set_dependencies(new MallocGrowableArray<char*>()); |
| 1719 } | 1666 } |
| 1720 | 1667 |
| 1668 if (IsSnapshottingForPrecompilation()) { |
| 1669 flags.obfuscate = obfuscate; |
| 1670 flags.entry_points = entry_points; |
| 1671 } |
| 1672 |
| 1721 Dart_Isolate isolate = NULL; | 1673 Dart_Isolate isolate = NULL; |
| 1722 void* kernel_program = dfe.ReadScript(app_script_name); | 1674 void* kernel_program = dfe.ReadScript(app_script_name); |
| 1723 if (kernel_program != NULL) { | 1675 if (kernel_program != NULL) { |
| 1724 isolate = Dart_CreateIsolateFromKernel(NULL, NULL, kernel_program, NULL, | 1676 isolate = Dart_CreateIsolateFromKernel(NULL, NULL, kernel_program, NULL, |
| 1725 isolate_data, &error); | 1677 isolate_data, &error); |
| 1726 } else { | 1678 } else { |
| 1727 isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, | 1679 isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, |
| 1728 isolate_snapshot_instructions, NULL, | 1680 isolate_snapshot_instructions, &flags, |
| 1729 isolate_data, &error); | 1681 isolate_data, &error); |
| 1730 } | 1682 } |
| 1731 if (isolate == NULL) { | 1683 if (isolate == NULL) { |
| 1732 Log::PrintErr("%s\n", error); | 1684 Log::PrintErr("%s\n", error); |
| 1733 free(error); | 1685 free(error); |
| 1734 exit(kErrorExitCode); | 1686 exit(kErrorExitCode); |
| 1735 } | 1687 } |
| 1736 Dart_EnterScope(); | 1688 Dart_EnterScope(); |
| 1737 result = Dart_SetEnvironmentCallback(EnvironmentCallback); | 1689 result = Dart_SetEnvironmentCallback(EnvironmentCallback); |
| 1738 CHECK_RESULT(result); | 1690 CHECK_RESULT(result); |
| 1739 | 1691 |
| 1740 // Set up the library tag handler in such a manner that it will use the | 1692 // Set up the library tag handler in such a manner that it will use the |
| 1741 // URL mapping specified on the command line to load the libraries. | 1693 // URL mapping specified on the command line to load the libraries. |
| 1742 result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler); | 1694 result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler); |
| 1743 CHECK_RESULT(result); | 1695 CHECK_RESULT(result); |
| 1744 | 1696 |
| 1745 if (commandline_packages_file != NULL) { | 1697 if (commandline_packages_file != NULL) { |
| 1746 AddDependency(commandline_packages_file); | 1698 AddDependency(commandline_packages_file); |
| 1747 } | 1699 } |
| 1748 | 1700 |
| 1749 Dart_QualifiedFunctionName* entry_points = | |
| 1750 ParseEntryPointsManifestIfPresent(); | |
| 1751 | |
| 1752 if (kernel_program != NULL) { | 1701 if (kernel_program != NULL) { |
| 1753 Dart_Handle resolved_uri = ResolveUriInWorkingDirectory(app_script_name); | 1702 Dart_Handle resolved_uri = ResolveUriInWorkingDirectory(app_script_name); |
| 1754 CHECK_RESULT(resolved_uri); | 1703 CHECK_RESULT(resolved_uri); |
| 1755 Dart_Handle library = | 1704 Dart_Handle library = |
| 1756 Dart_LoadScript(resolved_uri, Dart_Null(), | 1705 Dart_LoadScript(resolved_uri, Dart_Null(), |
| 1757 reinterpret_cast<Dart_Handle>(kernel_program), 0, 0); | 1706 reinterpret_cast<Dart_Handle>(kernel_program), 0, 0); |
| 1758 CHECK_RESULT(library); | 1707 CHECK_RESULT(library); |
| 1759 } else { | 1708 } else { |
| 1760 // Set up the library tag handler in such a manner that it will use the | 1709 // Set up the library tag handler in such a manner that it will use the |
| 1761 // URL mapping specified on the command line to load the libraries. | 1710 // URL mapping specified on the command line to load the libraries. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1840 delete mapped_isolate_snapshot_instructions; | 1789 delete mapped_isolate_snapshot_instructions; |
| 1841 return 0; | 1790 return 0; |
| 1842 } | 1791 } |
| 1843 | 1792 |
| 1844 } // namespace bin | 1793 } // namespace bin |
| 1845 } // namespace dart | 1794 } // namespace dart |
| 1846 | 1795 |
| 1847 int main(int argc, char** argv) { | 1796 int main(int argc, char** argv) { |
| 1848 return dart::bin::main(argc, argv); | 1797 return dart::bin::main(argc, argv); |
| 1849 } | 1798 } |
| OLD | NEW |