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(); |