| Index: runtime/bin/main.cc
|
| diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
|
| index 459775215493ec212b3e1fbba2d6cb92a0ddea2e..d829587c59589dec5a673a598426aecf7591af58 100644
|
| --- a/runtime/bin/main.cc
|
| +++ b/runtime/bin/main.cc
|
| @@ -114,6 +114,8 @@ static const int kApiErrorExitCode = 253;
|
| static const int kCompilationErrorExitCode = 254;
|
| // Exit code indicating an unhandled error that is not a compilation error.
|
| static const int kErrorExitCode = 255;
|
| +// Exit code indicating a vm restart request. Never returned to the user.
|
| +static const int kRestartRequestExitCode = 1000;
|
|
|
| extern bool do_vm_shutdown; // Defined in bin/process.cc
|
| static void ErrorExit(int exit_code, const char* format, ...) {
|
| @@ -685,8 +687,15 @@ static Dart_Handle EnvironmentCallback(Dart_Handle name) {
|
| #define CHECK_RESULT(result) \
|
| if (Dart_IsError(result)) { \
|
| *error = strdup(Dart_GetError(result)); \
|
| - *exit_code = Dart_IsCompilationError(result) ? kCompilationErrorExitCode : \
|
| - (Dart_IsApiError(result) ? kApiErrorExitCode : kErrorExitCode); \
|
| + if (Dart_IsCompilationError(result)) { \
|
| + *exit_code = kCompilationErrorExitCode; \
|
| + } else if (Dart_IsApiError(result)) { \
|
| + *exit_code = kApiErrorExitCode; \
|
| + } else if (Dart_IsVMRestartRequest(result)) { \
|
| + *exit_code = kRestartRequestExitCode; \
|
| + } else { \
|
| + *exit_code = kErrorExitCode; \
|
| + } \
|
| Dart_ExitScope(); \
|
| Dart_ShutdownIsolate(); \
|
| return NULL; \
|
| @@ -802,6 +811,7 @@ static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
|
|
|
| #undef CHECK_RESULT
|
|
|
| +
|
| static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
|
| const char* main,
|
| const char* package_root,
|
| @@ -950,16 +960,6 @@ char* BuildIsolateName(const char* script_name,
|
| return buffer;
|
| }
|
|
|
| -static void DartExitOnError(Dart_Handle error) {
|
| - if (!Dart_IsError(error)) {
|
| - return;
|
| - }
|
| - const int exit_code = Dart_IsCompilationError(error) ?
|
| - kCompilationErrorExitCode : kErrorExitCode;
|
| - ErrorExit(exit_code, "%s\n", Dart_GetError(error));
|
| -}
|
| -
|
| -
|
| static void ShutdownIsolate(void* callback_data) {
|
| IsolateData* isolate_data = reinterpret_cast<IsolateData*>(callback_data);
|
| delete isolate_data;
|
| @@ -1094,114 +1094,23 @@ static void* LoadLibrarySymbol(const char* libname, const char* symname) {
|
| }
|
|
|
|
|
| -void main(int argc, char** argv) {
|
| - char* script_name;
|
| - const int EXTRA_VM_ARGUMENTS = 2;
|
| - CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
|
| - CommandLineOptions dart_options(argc);
|
| - bool print_flags_seen = false;
|
| - bool verbose_debug_seen = false;
|
| -
|
| - vm_options.AddArgument("--no_write_protect_code");
|
| - // Perform platform specific initialization.
|
| - if (!Platform::Initialize()) {
|
| - Log::PrintErr("Initialization failed\n");
|
| - }
|
| -
|
| - // On Windows, the argv strings are code page encoded and not
|
| - // utf8. We need to convert them to utf8.
|
| - bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);
|
| -
|
| - // Parse command line arguments.
|
| - if (ParseArguments(argc,
|
| - argv,
|
| - &vm_options,
|
| - &script_name,
|
| - &dart_options,
|
| - &print_flags_seen,
|
| - &verbose_debug_seen) < 0) {
|
| - if (has_help_option) {
|
| - PrintUsage();
|
| - exit(0);
|
| - } else if (has_version_option) {
|
| - PrintVersion();
|
| - exit(0);
|
| - } else if (print_flags_seen) {
|
| - // Will set the VM flags, print them out and then we exit as no
|
| - // script was specified on the command line.
|
| - Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
|
| - exit(0);
|
| - } else {
|
| - PrintUsage();
|
| - exit(kErrorExitCode);
|
| - }
|
| - }
|
| -
|
| - Thread::InitOnce();
|
| -
|
| - if (!DartUtils::SetOriginalWorkingDirectory()) {
|
| - OSError err;
|
| - fprintf(stderr, "Error determining current directory: %s\n", err.message());
|
| - fflush(stderr);
|
| - exit(kErrorExitCode);
|
| - }
|
| -
|
| - if (generate_script_snapshot) {
|
| - vm_options.AddArgument("--load_deferred_eagerly");
|
| - }
|
| -
|
| - Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
|
| -
|
| - // Start event handler.
|
| - EventHandler::Start();
|
| -
|
| - // Start the debugger wire protocol handler if necessary.
|
| - if (start_debugger) {
|
| - ASSERT(debug_port >= 0);
|
| - bool print_msg = verbose_debug_seen || (debug_port == 0);
|
| - debug_port = DebuggerConnectionHandler::StartHandler(debug_ip, debug_port);
|
| - if (print_msg) {
|
| - Log::Print("Debugger listening on port %d\n", debug_port);
|
| - }
|
| - } else {
|
| - DebuggerConnectionHandler::InitForVmService();
|
| - }
|
| -
|
| - const uint8_t* instructions_snapshot = NULL;
|
| - if (has_run_precompiled_snapshot) {
|
| - instructions_snapshot = reinterpret_cast<const uint8_t*>(
|
| - LoadLibrarySymbol(kPrecompiledLibraryName, kPrecompiledSymbolName));
|
| - ReadSnapshotFile(kPrecompiledVmIsolateName, &vm_isolate_snapshot_buffer);
|
| - ReadSnapshotFile(kPrecompiledIsolateName, &isolate_snapshot_buffer);
|
| - }
|
| -
|
| - // Initialize the Dart VM.
|
| - char* error = Dart_Initialize(
|
| - vm_isolate_snapshot_buffer, instructions_snapshot,
|
| - CreateIsolateAndSetup, NULL, NULL, ShutdownIsolate,
|
| - DartUtils::OpenFile,
|
| - DartUtils::ReadFile,
|
| - DartUtils::WriteFile,
|
| - DartUtils::CloseFile,
|
| - DartUtils::EntropySource);
|
| - if (error != NULL) {
|
| - if (do_vm_shutdown) {
|
| - DebuggerConnectionHandler::StopHandler();
|
| - EventHandler::Stop();
|
| - }
|
| - fprintf(stderr, "VM initialization failed: %s\n", error);
|
| - fflush(stderr);
|
| - free(error);
|
| - exit(kErrorExitCode);
|
| - }
|
| -
|
| - Dart_RegisterIsolateServiceRequestCallback(
|
| - "getIO", &ServiceGetIOHandler, NULL);
|
| - Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
|
| - &ServiceStreamCancelCallback);
|
| -
|
| +#define CHECK_RESULT(result) \
|
| + if (Dart_IsError(result)) { \
|
| + if (Dart_IsVMRestartRequest(result)) { \
|
| + Dart_ExitScope(); \
|
| + Dart_ShutdownIsolate(); \
|
| + return true; \
|
| + } \
|
| + const int exit_code = Dart_IsCompilationError(result) ? \
|
| + kCompilationErrorExitCode : kErrorExitCode; \
|
| + ErrorExit(exit_code, "%s\n", Dart_GetError(result)); \
|
| + }
|
| +
|
| +bool RunMainIsolate(const char* script_name,
|
| + CommandLineOptions* dart_options) {
|
| // Call CreateIsolateAndSetup which creates an isolate and loads up
|
| // the specified application script.
|
| + char* error = NULL;
|
| int exit_code = 0;
|
| char* isolate_name = BuildIsolateName(script_name, "main");
|
| Dart_Isolate isolate = CreateIsolateAndSetupHelper(script_name,
|
| @@ -1212,10 +1121,14 @@ void main(int argc, char** argv) {
|
| &error,
|
| &exit_code);
|
| if (isolate == NULL) {
|
| + delete [] isolate_name;
|
| + if (exit_code == kRestartRequestExitCode) {
|
| + free(error);
|
| + return true;
|
| + }
|
| Log::PrintErr("%s\n", error);
|
| free(error);
|
| error = NULL;
|
| - delete [] isolate_name;
|
| Process::TerminateExitCodeHandler();
|
| error = Dart_Cleanup();
|
| if (error != NULL) {
|
| @@ -1243,7 +1156,7 @@ void main(int argc, char** argv) {
|
| uint8_t* buffer = NULL;
|
| intptr_t size = 0;
|
| result = Dart_CreateScriptSnapshot(&buffer, &size);
|
| - DartExitOnError(result);
|
| + CHECK_RESULT(result);
|
|
|
| // Open the snapshot file.
|
| File* snapshot_file = File::Open(snapshot_filename, File::kWriteTruncate);
|
| @@ -1299,7 +1212,7 @@ void main(int argc, char** argv) {
|
|
|
| const bool reset_fields = has_gen_precompiled_snapshot;
|
| result = Dart_Precompile(standalone_entry_points, reset_fields);
|
| - DartExitOnError(result);
|
| + CHECK_RESULT(result);
|
| }
|
|
|
| if (has_gen_precompiled_snapshot) {
|
| @@ -1315,7 +1228,7 @@ void main(int argc, char** argv) {
|
| &isolate_size,
|
| &instructions_buffer,
|
| &instructions_size);
|
| - DartExitOnError(result);
|
| + CHECK_RESULT(result);
|
| WriteSnapshotFile(kPrecompiledVmIsolateName,
|
| vm_isolate_buffer,
|
| vm_isolate_size);
|
| @@ -1328,7 +1241,7 @@ void main(int argc, char** argv) {
|
| } else {
|
| if (has_compile_all) {
|
| result = Dart_CompileAll();
|
| - DartExitOnError(result);
|
| + CHECK_RESULT(result);
|
| }
|
|
|
| if (Dart_IsNull(root_lib)) {
|
| @@ -1342,7 +1255,7 @@ void main(int argc, char** argv) {
|
| // root library.
|
| Dart_Handle main_closure = Dart_Invoke(builtin_lib,
|
| Dart_NewStringFromCString("_getMainClosure"), 0, NULL);
|
| - DartExitOnError(main_closure);
|
| + CHECK_RESULT(main_closure);
|
|
|
| // Set debug breakpoint if specified on the command line before calling
|
| // the main function.
|
| @@ -1360,25 +1273,144 @@ void main(int argc, char** argv) {
|
| // initial startup message.
|
| const intptr_t kNumIsolateArgs = 2;
|
| Dart_Handle isolate_args[kNumIsolateArgs];
|
| - isolate_args[0] = main_closure; // entryPoint
|
| - isolate_args[1] = CreateRuntimeOptions(&dart_options); // args
|
| + isolate_args[0] = main_closure; // entryPoint
|
| + isolate_args[1] = CreateRuntimeOptions(dart_options); // args
|
|
|
| Dart_Handle isolate_lib =
|
| Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
|
| result = Dart_Invoke(isolate_lib,
|
| Dart_NewStringFromCString("_startMainIsolate"),
|
| kNumIsolateArgs, isolate_args);
|
| - DartExitOnError(result);
|
| + CHECK_RESULT(result);
|
|
|
| // Keep handling messages until the last active receive port is closed.
|
| result = Dart_RunLoop();
|
| - DartExitOnError(result);
|
| + CHECK_RESULT(result);
|
| }
|
| }
|
|
|
| Dart_ExitScope();
|
| // Shutdown the isolate.
|
| Dart_ShutdownIsolate();
|
| +
|
| + // No restart.
|
| + return false;
|
| +}
|
| +
|
| +#undef CHECK_RESULT
|
| +
|
| +
|
| +void main(int argc, char** argv) {
|
| + char* script_name;
|
| + const int EXTRA_VM_ARGUMENTS = 2;
|
| + CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
|
| + CommandLineOptions dart_options(argc);
|
| + bool print_flags_seen = false;
|
| + bool verbose_debug_seen = false;
|
| +
|
| + vm_options.AddArgument("--no_write_protect_code");
|
| + // Perform platform specific initialization.
|
| + if (!Platform::Initialize()) {
|
| + Log::PrintErr("Initialization failed\n");
|
| + }
|
| +
|
| + // On Windows, the argv strings are code page encoded and not
|
| + // utf8. We need to convert them to utf8.
|
| + bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);
|
| +
|
| + // Parse command line arguments.
|
| + if (ParseArguments(argc,
|
| + argv,
|
| + &vm_options,
|
| + &script_name,
|
| + &dart_options,
|
| + &print_flags_seen,
|
| + &verbose_debug_seen) < 0) {
|
| + if (has_help_option) {
|
| + PrintUsage();
|
| + exit(0);
|
| + } else if (has_version_option) {
|
| + PrintVersion();
|
| + exit(0);
|
| + } else if (print_flags_seen) {
|
| + // Will set the VM flags, print them out and then we exit as no
|
| + // script was specified on the command line.
|
| + Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
|
| + exit(0);
|
| + } else {
|
| + PrintUsage();
|
| + exit(kErrorExitCode);
|
| + }
|
| + }
|
| +
|
| + Thread::InitOnce();
|
| +
|
| + if (!DartUtils::SetOriginalWorkingDirectory()) {
|
| + OSError err;
|
| + fprintf(stderr, "Error determining current directory: %s\n", err.message());
|
| + fflush(stderr);
|
| + exit(kErrorExitCode);
|
| + }
|
| +
|
| + if (generate_script_snapshot) {
|
| + vm_options.AddArgument("--load_deferred_eagerly");
|
| + }
|
| +
|
| + Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
|
| +
|
| + // Start event handler.
|
| + EventHandler::Start();
|
| +
|
| + // Start the debugger wire protocol handler if necessary.
|
| + if (start_debugger) {
|
| + ASSERT(debug_port >= 0);
|
| + bool print_msg = verbose_debug_seen || (debug_port == 0);
|
| + debug_port = DebuggerConnectionHandler::StartHandler(debug_ip, debug_port);
|
| + if (print_msg) {
|
| + Log::Print("Debugger listening on port %d\n", debug_port);
|
| + }
|
| + } else {
|
| + DebuggerConnectionHandler::InitForVmService();
|
| + }
|
| +
|
| + const uint8_t* instructions_snapshot = NULL;
|
| + if (has_run_precompiled_snapshot) {
|
| + instructions_snapshot = reinterpret_cast<const uint8_t*>(
|
| + LoadLibrarySymbol(kPrecompiledLibraryName, kPrecompiledSymbolName));
|
| + ReadSnapshotFile(kPrecompiledVmIsolateName, &vm_isolate_snapshot_buffer);
|
| + ReadSnapshotFile(kPrecompiledIsolateName, &isolate_snapshot_buffer);
|
| + }
|
| +
|
| + // Initialize the Dart VM.
|
| + char* error = Dart_Initialize(
|
| + vm_isolate_snapshot_buffer, instructions_snapshot,
|
| + CreateIsolateAndSetup, NULL, NULL, ShutdownIsolate,
|
| + DartUtils::OpenFile,
|
| + DartUtils::ReadFile,
|
| + DartUtils::WriteFile,
|
| + DartUtils::CloseFile,
|
| + DartUtils::EntropySource);
|
| + if (error != NULL) {
|
| + if (do_vm_shutdown) {
|
| + DebuggerConnectionHandler::StopHandler();
|
| + EventHandler::Stop();
|
| + }
|
| + fprintf(stderr, "VM initialization failed: %s\n", error);
|
| + fflush(stderr);
|
| + free(error);
|
| + exit(kErrorExitCode);
|
| + }
|
| +
|
| + Dart_RegisterIsolateServiceRequestCallback(
|
| + "getIO", &ServiceGetIOHandler, NULL);
|
| + Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
|
| + &ServiceStreamCancelCallback);
|
| +
|
| + // Run the main isolate until we aren't told to restart.
|
| + while (RunMainIsolate(script_name, &dart_options)) {
|
| + Log::PrintErr("Restarting VM\n");
|
| + }
|
| +
|
| // Terminate process exit-code handler.
|
| Process::TerminateExitCodeHandler();
|
|
|
|
|