| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include "include/dart_api.h" | 9 #include "include/dart_api.h" |
| 10 #include "include/dart_debugger_api.h" | 10 #include "include/dart_debugger_api.h" |
| 11 | 11 |
| 12 #include "bin/builtin.h" | 12 #include "bin/builtin.h" |
| 13 #include "bin/dartutils.h" | 13 #include "bin/dartutils.h" |
| 14 #include "bin/file.h" | 14 #include "bin/file.h" |
| 15 #include "bin/globals.h" | 15 #include "bin/globals.h" |
| 16 #include "bin/platform.h" | 16 #include "bin/platform.h" |
| 17 | 17 |
| 18 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise | 18 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise |
| 19 // it is initialized to NULL. | 19 // it is initialized to NULL. |
| 20 extern const uint8_t* snapshot_buffer; | 20 extern const uint8_t* snapshot_buffer; |
| 21 | 21 |
| 22 | 22 |
| 23 // Global state that stores a pointer to the application script file. | 23 // Global state that stores a pointer to the application script file. |
| 24 static char* canonical_script_name = NULL; | 24 static char* canonical_script_name = NULL; |
| 25 | 25 |
| 26 | 26 |
| 27 // Global state that stores a pointer to the application script snapshot. |
| 28 static bool use_script_snapshot = false; |
| 29 static uint8_t* script_snapshot_buffer = NULL; |
| 30 |
| 31 |
| 27 // Global state that indicates whether pprof symbol information is | 32 // Global state that indicates whether pprof symbol information is |
| 28 // to be generated or not. | 33 // to be generated or not. |
| 29 static const char* generate_pprof_symbols_filename = NULL; | 34 static const char* generate_pprof_symbols_filename = NULL; |
| 30 | 35 |
| 31 | 36 |
| 32 // Global state that indicates whether there is a debug breakpoint. | 37 // Global state that indicates whether there is a debug breakpoint. |
| 33 // This pointer points into an argv buffer and does not need to be | 38 // This pointer points into an argv buffer and does not need to be |
| 34 // free'd. | 39 // free'd. |
| 35 static const char* breakpoint_at = NULL; | 40 static const char* breakpoint_at = NULL; |
| 36 | 41 |
| 37 | 42 |
| 43 // Global flag that is used to indicate that we want to compile all the |
| 44 // dart functions and not run anything. |
| 45 static bool has_compile_all = false; |
| 46 |
| 47 |
| 38 static bool IsValidFlag(const char* name, | 48 static bool IsValidFlag(const char* name, |
| 39 const char* prefix, | 49 const char* prefix, |
| 40 intptr_t prefix_length) { | 50 intptr_t prefix_length) { |
| 41 intptr_t name_length = strlen(name); | 51 intptr_t name_length = strlen(name); |
| 42 return ((name_length > prefix_length) && | 52 return ((name_length > prefix_length) && |
| 43 (strncmp(name, prefix, prefix_length) == 0)); | 53 (strncmp(name, prefix, prefix_length) == 0)); |
| 44 } | 54 } |
| 45 | 55 |
| 46 | 56 |
| 47 static const char* ProcessOption(const char* option, const char* name) { | 57 static void ProcessBreakpointOption(const char* funcname) { |
| 48 const intptr_t length = strlen(name); | 58 ASSERT(funcname != NULL); |
| 49 if (strncmp(option, name, length) == 0) { | 59 breakpoint_at = funcname; |
| 50 return (option + length); | |
| 51 } | |
| 52 return NULL; | |
| 53 } | 60 } |
| 54 | 61 |
| 55 | 62 |
| 56 static bool ProcessPprofOption(const char* option) { | 63 static void ProcessCompileAllOption(const char* compile_all) { |
| 57 const char* kProfOption = "--generate_pprof_symbols="; | 64 ASSERT(compile_all != NULL); |
| 58 const char* filename = ProcessOption(option, kProfOption); | 65 has_compile_all = true; |
| 59 if (filename != NULL) { | |
| 60 generate_pprof_symbols_filename = filename; | |
| 61 } | |
| 62 return filename != NULL; | |
| 63 } | 66 } |
| 64 | 67 |
| 65 | 68 |
| 66 static bool ProcessDebugOption(const char* option) { | 69 static void ProcessPprofOption(const char* filename) { |
| 67 const char* kDebugOption = "--break_at="; | 70 ASSERT(filename != NULL); |
| 68 const char* func_name = ProcessOption(option, kDebugOption); | 71 generate_pprof_symbols_filename = filename; |
| 69 if (func_name != NULL) { | |
| 70 breakpoint_at = func_name; | |
| 71 } | |
| 72 return func_name != NULL; | |
| 73 } | 72 } |
| 74 | 73 |
| 75 | 74 |
| 75 static void ProcessSnapshotOption(const char* snapshot) { |
| 76 ASSERT(snapshot != NULL); |
| 77 use_script_snapshot = true; |
| 78 } |
| 79 |
| 80 |
| 81 static struct { |
| 82 const char* option_name; |
| 83 void (*process)(const char* option); |
| 84 } main_options[] = { |
| 85 { "--break_at=", ProcessBreakpointOption }, |
| 86 { "--compile_all", ProcessCompileAllOption }, |
| 87 { "--generate_pprof_symbols=", ProcessPprofOption }, |
| 88 { "--use_script_snapshot", ProcessSnapshotOption }, |
| 89 { NULL, NULL } |
| 90 }; |
| 91 |
| 92 |
| 93 static bool ProcessMainOptions(const char* option) { |
| 94 int i = 0; |
| 95 const char* name = main_options[0].option_name; |
| 96 while (name != NULL) { |
| 97 int length = strlen(name); |
| 98 if (strncmp(option, name, length) == 0) { |
| 99 main_options[i].process(option + length); |
| 100 return true; |
| 101 } |
| 102 i += 1; |
| 103 name = main_options[i].option_name; |
| 104 } |
| 105 return false; |
| 106 } |
| 107 |
| 108 |
| 76 // Parse out the command line arguments. Returns -1 if the arguments | 109 // Parse out the command line arguments. Returns -1 if the arguments |
| 77 // are incorrect, 0 otherwise. | 110 // are incorrect, 0 otherwise. |
| 78 static int ParseArguments(int argc, | 111 static int ParseArguments(int argc, |
| 79 char** argv, | 112 char** argv, |
| 80 CommandLineOptions* vm_options, | 113 CommandLineOptions* vm_options, |
| 81 char** script_name, | 114 char** script_name, |
| 82 CommandLineOptions* dart_options) { | 115 CommandLineOptions* dart_options) { |
| 83 const char* kPrefix = "--"; | 116 const char* kPrefix = "--"; |
| 84 const intptr_t kPrefixLen = strlen(kPrefix); | 117 const intptr_t kPrefixLen = strlen(kPrefix); |
| 85 | 118 |
| 86 // Skip the binary name. | 119 // Skip the binary name. |
| 87 int i = 1; | 120 int i = 1; |
| 88 | 121 |
| 89 // Parse out the vm options. | 122 // Parse out the vm options. |
| 90 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { | 123 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
| 91 if (ProcessPprofOption(argv[i])) { | 124 if (ProcessMainOptions(argv[i])) { |
| 92 i += 1; | |
| 93 } else if (ProcessDebugOption(argv[i])) { | |
| 94 i += 1; | 125 i += 1; |
| 95 } else { | 126 } else { |
| 96 vm_options->AddArgument(argv[i]); | 127 vm_options->AddArgument(argv[i]); |
| 97 i += 1; | 128 i += 1; |
| 98 } | 129 } |
| 99 } | 130 } |
| 100 if (generate_pprof_symbols_filename != NULL) { | 131 if (generate_pprof_symbols_filename != NULL) { |
| 101 Dart_InitPprofSupport(); | 132 Dart_InitPprofSupport(); |
| 102 } | 133 } |
| 103 | 134 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 static bool CreateIsolateAndSetup(void* data, char** error) { | 261 static bool CreateIsolateAndSetup(void* data, char** error) { |
| 231 Dart_Isolate isolate = Dart_CreateIsolate(snapshot_buffer, data, error); | 262 Dart_Isolate isolate = Dart_CreateIsolate(snapshot_buffer, data, error); |
| 232 if (isolate == NULL) { | 263 if (isolate == NULL) { |
| 233 return false; | 264 return false; |
| 234 } | 265 } |
| 235 | 266 |
| 236 Dart_Handle library; | 267 Dart_Handle library; |
| 237 Dart_EnterScope(); | 268 Dart_EnterScope(); |
| 238 | 269 |
| 239 // Load the specified application script into the newly created isolate. | 270 // Load the specified application script into the newly created isolate. |
| 240 library = LoadScript(canonical_script_name); | 271 if (script_snapshot_buffer != NULL) { |
| 272 library = Dart_LoadScriptFromSnapshot(script_snapshot_buffer); |
| 273 } else { |
| 274 library = LoadScript(canonical_script_name); |
| 275 } |
| 241 if (Dart_IsError(library)) { | 276 if (Dart_IsError(library)) { |
| 242 *error = strdup(Dart_GetError(library)); | 277 *error = strdup(Dart_GetError(library)); |
| 243 Dart_ExitScope(); | 278 Dart_ExitScope(); |
| 244 Dart_ShutdownIsolate(); | 279 Dart_ShutdownIsolate(); |
| 245 return false; | 280 return false; |
| 246 } | 281 } |
| 247 if (!Dart_IsLibrary(library)) { | 282 if (!Dart_IsLibrary(library)) { |
| 248 char errbuf[256]; | 283 char errbuf[256]; |
| 249 snprintf(errbuf, sizeof(errbuf), | 284 snprintf(errbuf, sizeof(errbuf), |
| 250 "Expected a library when loading script: %s", | 285 "Expected a library when loading script: %s", |
| 251 canonical_script_name); | 286 canonical_script_name); |
| 252 *error = strdup(errbuf); | 287 *error = strdup(errbuf); |
| 253 Dart_ExitScope(); | 288 Dart_ExitScope(); |
| 254 Dart_ShutdownIsolate(); | 289 Dart_ShutdownIsolate(); |
| 255 return false; | 290 return false; |
| 256 } | 291 } |
| 257 Builtin::ImportLibrary(library); // Implicitly import builtin into app. | 292 if (script_snapshot_buffer == NULL) { |
| 293 Builtin::ImportLibrary(library); // Implicitly import builtin into app. |
| 294 } |
| 258 if (snapshot_buffer != NULL) { | 295 if (snapshot_buffer != NULL) { |
| 259 // Setup the native resolver as the snapshot does not carry it. | 296 // Setup the native resolver as the snapshot does not carry it. |
| 260 Builtin::SetNativeResolver(); | 297 Builtin::SetNativeResolver(); |
| 261 } | 298 } |
| 262 Dart_ExitScope(); | 299 Dart_ExitScope(); |
| 263 return true; | 300 return true; |
| 264 } | 301 } |
| 265 | 302 |
| 266 | 303 |
| 304 static bool CaptureScriptSnapshot() { |
| 305 char* error = NULL; |
| 306 Dart_Handle result; |
| 307 |
| 308 // First create an isolate and load up the specified script in it. |
| 309 if (!CreateIsolateAndSetup(NULL, &error)) { |
| 310 fprintf(stderr, "%s\n", error); |
| 311 free(canonical_script_name); |
| 312 free(error); |
| 313 return false; // Indicates we encountered an error. |
| 314 } |
| 315 |
| 316 Dart_EnterScope(); |
| 317 |
| 318 #if 0 |
| 319 // Lookup the library of the main script. |
| 320 Dart_Handle script_url = Dart_NewString(canonical_script_name); |
| 321 Dart_Handle library = Dart_LookupLibrary(script_url); |
| 322 if (Dart_IsError(library)) { |
| 323 fprintf(stderr, "%s\n", Dart_GetError(library)); |
| 324 Dart_ExitScope(); |
| 325 Dart_ShutdownIsolate(); |
| 326 free(canonical_script_name); |
| 327 return false; // Indicates we encountered an error. |
| 328 } |
| 329 #endif |
| 330 |
| 331 // Now create the script snapshot and save into a buffer. |
| 332 uint8_t* buffer; |
| 333 intptr_t size; |
| 334 result = Dart_CreateScriptSnapshot(&buffer, &size); |
| 335 if (Dart_IsError(result)) { |
| 336 fprintf(stderr, "%s\n", Dart_GetError(result)); |
| 337 Dart_ExitScope(); |
| 338 Dart_ShutdownIsolate(); |
| 339 return false; // Indicates we encountered an error. |
| 340 } |
| 341 |
| 342 // Save the script snapshot as we are about to shutdown the isolate. |
| 343 script_snapshot_buffer = reinterpret_cast<uint8_t*>(malloc(size)); |
| 344 ASSERT(script_snapshot_buffer != NULL); |
| 345 memmove(script_snapshot_buffer, buffer, size); |
| 346 |
| 347 // Shutdown this isolate. |
| 348 Dart_ExitScope(); |
| 349 Dart_ShutdownIsolate(); |
| 350 return true; |
| 351 } |
| 352 |
| 353 |
| 267 static void PrintUsage() { | 354 static void PrintUsage() { |
| 268 fprintf(stderr, | 355 fprintf(stderr, |
| 269 "dart [<vm-flags>] <dart-script-file> [<dart-options>]\n"); | 356 "dart [<vm-flags>] <dart-script-file> [<dart-options>]\n"); |
| 270 } | 357 } |
| 271 | 358 |
| 272 | 359 |
| 273 static bool HasCompileAll(const CommandLineOptions& options) { | |
| 274 for (int i = 0; i < options.count(); i++) { | |
| 275 if (strcmp(options.GetArgument(i), "--compile_all") == 0) { | |
| 276 return true; | |
| 277 } | |
| 278 } | |
| 279 return false; | |
| 280 } | |
| 281 | |
| 282 | |
| 283 int main(int argc, char** argv) { | 360 int main(int argc, char** argv) { |
| 284 char* script_name; | 361 char* script_name; |
| 285 CommandLineOptions vm_options(argc); | 362 CommandLineOptions vm_options(argc); |
| 286 CommandLineOptions dart_options(argc); | 363 CommandLineOptions dart_options(argc); |
| 287 | 364 |
| 288 // Perform platform specific initialization. | 365 // Perform platform specific initialization. |
| 289 if (!Platform::Initialize()) { | 366 if (!Platform::Initialize()) { |
| 290 fprintf(stderr, "Initialization failed\n"); | 367 fprintf(stderr, "Initialization failed\n"); |
| 291 } | 368 } |
| 292 | 369 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 304 | 381 |
| 305 // Initialize the Dart VM. | 382 // Initialize the Dart VM. |
| 306 Dart_Initialize(CreateIsolateAndSetup, NULL); | 383 Dart_Initialize(CreateIsolateAndSetup, NULL); |
| 307 | 384 |
| 308 canonical_script_name = File::GetCanonicalPath(script_name); | 385 canonical_script_name = File::GetCanonicalPath(script_name); |
| 309 if (canonical_script_name == NULL) { | 386 if (canonical_script_name == NULL) { |
| 310 fprintf(stderr, "Unable to find '%s'\n", script_name); | 387 fprintf(stderr, "Unable to find '%s'\n", script_name); |
| 311 return 255; // Indicates we encountered an error. | 388 return 255; // Indicates we encountered an error. |
| 312 } | 389 } |
| 313 | 390 |
| 391 // If application snapshot option is specified, first create the |
| 392 // application snapshot and then load the script using the snapshot |
| 393 // created. |
| 394 if (use_script_snapshot) { |
| 395 if (!CaptureScriptSnapshot()) { |
| 396 return 255; // Error capturing script snapshot, error already reported. |
| 397 } |
| 398 } |
| 399 |
| 314 // Call CreateIsolateAndSetup which creates an isolate and loads up | 400 // Call CreateIsolateAndSetup which creates an isolate and loads up |
| 315 // the specified application script. | 401 // the specified application script. |
| 316 char* error = NULL; | 402 char* error = NULL; |
| 317 if (!CreateIsolateAndSetup(NULL, &error)) { | 403 if (!CreateIsolateAndSetup(NULL, &error)) { |
| 318 fprintf(stderr, "%s\n", error); | 404 fprintf(stderr, "%s\n", error); |
| 319 free(canonical_script_name); | 405 free(canonical_script_name); |
| 320 free(error); | 406 free(error); |
| 407 free(script_snapshot_buffer); |
| 321 return 255; // Indicates we encountered an error. | 408 return 255; // Indicates we encountered an error. |
| 322 } | 409 } |
| 323 | 410 |
| 411 free(script_snapshot_buffer); // Don't need it anymore. |
| 324 Dart_Isolate isolate = Dart_CurrentIsolate(); | 412 Dart_Isolate isolate = Dart_CurrentIsolate(); |
| 325 ASSERT(isolate != NULL); | 413 ASSERT(isolate != NULL); |
| 326 Dart_Handle result; | 414 Dart_Handle result; |
| 327 | 415 |
| 328 Dart_EnterScope(); | 416 Dart_EnterScope(); |
| 329 | 417 |
| 330 if (HasCompileAll(vm_options)) { | 418 if (has_compile_all) { |
| 331 result = Dart_CompileAll(); | 419 result = Dart_CompileAll(); |
| 332 if (Dart_IsError(result)) { | 420 if (Dart_IsError(result)) { |
| 333 fprintf(stderr, "%s\n", Dart_GetError(result)); | 421 fprintf(stderr, "%s\n", Dart_GetError(result)); |
| 334 Dart_ExitScope(); | 422 Dart_ExitScope(); |
| 335 Dart_ShutdownIsolate(); | 423 Dart_ShutdownIsolate(); |
| 336 free(canonical_script_name); | 424 free(canonical_script_name); |
| 337 return 255; // Indicates we encountered an error. | 425 return 255; // Indicates we encountered an error. |
| 338 } | 426 } |
| 339 } | 427 } |
| 340 | 428 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 return 255; // Indicates we encountered an error. | 497 return 255; // Indicates we encountered an error. |
| 410 } | 498 } |
| 411 free(canonical_script_name); | 499 free(canonical_script_name); |
| 412 Dart_ExitScope(); | 500 Dart_ExitScope(); |
| 413 // Dump symbol information for the profiler. | 501 // Dump symbol information for the profiler. |
| 414 DumpPprofSymbolInfo(); | 502 DumpPprofSymbolInfo(); |
| 415 // Shutdown the isolate. | 503 // Shutdown the isolate. |
| 416 Dart_ShutdownIsolate(); | 504 Dart_ShutdownIsolate(); |
| 417 return 0; | 505 return 0; |
| 418 } | 506 } |
| OLD | NEW |