Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "bin/builtin.h" | 5 #include "bin/builtin.h" |
| 6 #include "include/dart_api.h" | 6 #include "include/dart_api.h" |
| 7 #include "include/dart_mirrors_api.h" | 7 #include "include/dart_mirrors_api.h" |
| 8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
| 9 #include "include/dart_tools_api.h" | 9 #include "include/dart_tools_api.h" |
| 10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
| 11 #include "platform/json.h" | 11 #include "platform/text_buffer.h" |
| 12 #include "platform/utils.h" | 12 #include "platform/utils.h" |
| 13 #include "vm/class_finalizer.h" | 13 #include "vm/class_finalizer.h" |
| 14 #include "vm/dart_api_impl.h" | 14 #include "vm/dart_api_impl.h" |
| 15 #include "vm/dart_api_state.h" | 15 #include "vm/dart_api_state.h" |
| 16 #include "vm/lockers.h" | 16 #include "vm/lockers.h" |
| 17 #include "vm/unit_test.h" | 17 #include "vm/unit_test.h" |
| 18 #include "vm/verifier.h" | 18 #include "vm/verifier.h" |
| 19 | 19 |
| 20 namespace dart { | 20 namespace dart { |
| 21 | 21 |
| (...skipping 7048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7070 static Dart_Isolate RunLoopTestCallback(const char* script_name, | 7070 static Dart_Isolate RunLoopTestCallback(const char* script_name, |
| 7071 const char* main, | 7071 const char* main, |
| 7072 const char* package_root, | 7072 const char* package_root, |
| 7073 const char** package_map, | 7073 const char** package_map, |
| 7074 Dart_IsolateFlags* flags, | 7074 Dart_IsolateFlags* flags, |
| 7075 void* data, | 7075 void* data, |
| 7076 char** error) { | 7076 char** error) { |
| 7077 const char* kScriptChars = | 7077 const char* kScriptChars = |
| 7078 "import 'builtin';\n" | 7078 "import 'builtin';\n" |
| 7079 "import 'dart:isolate';\n" | 7079 "import 'dart:isolate';\n" |
| 7080 "void entry(message) {\n" | 7080 "void main(exception) {\n" |
|
rmacnak
2015/12/04 00:41:24
bool throwException
Ivan Posva
2015/12/04 01:44:57
Done.
| |
| 7081 " var data = message[0];\n" | 7081 " var rp = new RawReceivePort();\n" |
| 7082 " var replyTo = message[1];\n" | 7082 " rp.handler = (msg) {\n" |
| 7083 " if (data) {\n" | 7083 " rp.close();\n" |
| 7084 " throw new Exception('MakeChildExit');\n" | 7084 " if (exception) {\n" |
| 7085 " } else {\n" | 7085 " throw new Exception('ExceptionFromTimer');\n" |
| 7086 " replyTo.send('hello');\n" | 7086 " }\n" |
| 7087 " }\n" | |
| 7088 "}\n" | |
| 7089 "\n" | |
| 7090 "void main(exc_child, exc_parent) {\n" | |
| 7091 " var receivePort = new RawReceivePort();\n" | |
| 7092 " Isolate.spawn(entry, [exc_child, receivePort.sendPort]);\n" | |
| 7093 " receivePort.handler = (message) {\n" | |
| 7094 " receivePort.close();\n" | |
| 7095 " if (message != 'hello') throw new Exception('ShouldNotHappen');\n" | |
| 7096 " if (exc_parent) throw new Exception('MakeParentExit');\n" | |
| 7097 " };\n" | 7087 " };\n" |
| 7088 " rp.sendPort.send(1);\n" | |
| 7098 "}\n"; | 7089 "}\n"; |
| 7099 | 7090 |
| 7100 if (Dart_CurrentIsolate() != NULL) { | 7091 if (Dart_CurrentIsolate() != NULL) { |
| 7101 Dart_ExitIsolate(); | 7092 Dart_ExitIsolate(); |
| 7102 } | 7093 } |
| 7103 Dart_Isolate isolate = TestCase::CreateTestIsolate(script_name); | 7094 Dart_Isolate isolate = TestCase::CreateTestIsolate(script_name); |
| 7104 ASSERT(isolate != NULL); | 7095 ASSERT(isolate != NULL); |
| 7105 if (Dart_IsServiceIsolate(isolate)) { | 7096 if (Dart_IsServiceIsolate(isolate)) { |
| 7106 return isolate; | 7097 return isolate; |
| 7107 } | 7098 } |
| 7108 Dart_EnterScope(); | 7099 Dart_EnterScope(); |
| 7109 Dart_Handle url = NewString(TestCase::url()); | 7100 Dart_Handle url = NewString(TestCase::url()); |
| 7110 Dart_Handle source = NewString(kScriptChars); | 7101 Dart_Handle source = NewString(kScriptChars); |
| 7111 Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler); | 7102 Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler); |
| 7112 EXPECT_VALID(result); | 7103 EXPECT_VALID(result); |
| 7113 Dart_Handle lib = Dart_LoadScript(url, source, 0, 0); | 7104 Dart_Handle lib = Dart_LoadScript(url, source, 0, 0); |
| 7114 EXPECT_VALID(lib); | 7105 EXPECT_VALID(lib); |
| 7115 result = Dart_FinalizeLoading(false); | 7106 result = Dart_FinalizeLoading(false); |
| 7116 EXPECT_VALID(result); | 7107 EXPECT_VALID(result); |
| 7117 Dart_ExitScope(); | 7108 Dart_ExitScope(); |
| 7118 Dart_ExitIsolate(); | 7109 Dart_ExitIsolate(); |
| 7119 bool retval = Dart_IsolateMakeRunnable(isolate); | 7110 bool retval = Dart_IsolateMakeRunnable(isolate); |
| 7120 EXPECT(retval); | 7111 EXPECT(retval); |
| 7121 return isolate; | 7112 return isolate; |
| 7122 } | 7113 } |
| 7123 | 7114 |
| 7124 | 7115 |
| 7125 // The error string from the last unhandled exception. This value is only | |
| 7126 // valid until the next Dart_ExitScope(). | |
| 7127 static char* last_exception = NULL; | |
| 7128 | |
| 7129 | |
| 7130 static void RunLoopUnhandledExceptionCallback(Dart_Handle exception) { | |
| 7131 Dart_Handle error_string = Dart_ToString(exception); | |
| 7132 EXPECT_VALID(error_string); | |
| 7133 const char* error_text; | |
| 7134 Dart_Handle result = Dart_StringToCString(error_string, &error_text); | |
| 7135 // Duplicate the string since error text is freed when callback is finished. | |
| 7136 last_exception = strdup(error_text); | |
| 7137 EXPECT_VALID(result); | |
| 7138 } | |
| 7139 | |
| 7140 | |
| 7141 // Common code for RunLoop_Success/RunLoop_Failure. | 7116 // Common code for RunLoop_Success/RunLoop_Failure. |
| 7142 static void RunLoopTest(bool throw_exception_child, | 7117 static void RunLoopTest(bool throw_exception) { |
| 7143 bool throw_exception_parent) { | |
| 7144 Dart_IsolateCreateCallback saved = Isolate::CreateCallback(); | 7118 Dart_IsolateCreateCallback saved = Isolate::CreateCallback(); |
| 7145 Isolate::SetCreateCallback(RunLoopTestCallback); | 7119 Isolate::SetCreateCallback(RunLoopTestCallback); |
| 7146 Isolate::SetUnhandledExceptionCallback(RunLoopUnhandledExceptionCallback); | |
| 7147 Dart_Isolate isolate = RunLoopTestCallback( | 7120 Dart_Isolate isolate = RunLoopTestCallback( |
| 7148 NULL, NULL, NULL, NULL, NULL, NULL, NULL); | 7121 NULL, NULL, NULL, NULL, NULL, NULL, NULL); |
| 7149 | 7122 |
| 7150 Dart_EnterIsolate(isolate); | 7123 Dart_EnterIsolate(isolate); |
| 7151 Dart_EnterScope(); | 7124 Dart_EnterScope(); |
| 7152 Dart_Handle lib = Dart_LookupLibrary(NewString(TestCase::url())); | 7125 Dart_Handle lib = Dart_LookupLibrary(NewString(TestCase::url())); |
| 7153 EXPECT_VALID(lib); | 7126 EXPECT_VALID(lib); |
| 7154 | 7127 |
| 7155 Dart_Handle result; | 7128 Dart_Handle result; |
| 7156 Dart_Handle args[2]; | 7129 Dart_Handle args[1]; |
| 7157 args[0] = (throw_exception_child ? Dart_True() : Dart_False()); | 7130 args[0] = (throw_exception ? Dart_True() : Dart_False()); |
| 7158 args[1] = (throw_exception_parent ? Dart_True() : Dart_False()); | 7131 result = Dart_Invoke(lib, NewString("main"), 1, args); |
| 7159 result = Dart_Invoke(lib, NewString("main"), 2, args); | |
| 7160 EXPECT_VALID(result); | 7132 EXPECT_VALID(result); |
| 7161 if (throw_exception_child) { | 7133 result = Dart_RunLoop(); |
| 7162 // TODO(tball): fix race-condition | 7134 if (throw_exception) { |
| 7163 // EXPECT_NOTNULL(last_exception); | 7135 EXPECT_ERROR(result, "Exception: ExceptionFromTimer"); |
| 7164 // EXPECT_STREQ("UnhandledException", last_exception); | |
| 7165 } else { | 7136 } else { |
| 7166 result = Dart_RunLoop(); | 7137 EXPECT_VALID(result); |
| 7167 if (throw_exception_parent) { | |
| 7168 EXPECT_ERROR(result, "Exception: MakeParentExit"); | |
| 7169 EXPECT_NOTNULL(last_exception); | |
| 7170 EXPECT_STREQ("UnhandledException", last_exception); | |
| 7171 } else { | |
| 7172 EXPECT_VALID(result); | |
| 7173 EXPECT(last_exception == NULL); | |
| 7174 } | |
| 7175 } | |
| 7176 if (last_exception != NULL) { | |
| 7177 free(last_exception); | |
| 7178 last_exception = NULL; | |
| 7179 } | 7138 } |
| 7180 | 7139 |
| 7181 Dart_ExitScope(); | 7140 Dart_ExitScope(); |
| 7182 Dart_ShutdownIsolate(); | 7141 Dart_ShutdownIsolate(); |
| 7183 | 7142 |
| 7184 Isolate::SetCreateCallback(saved); | 7143 Isolate::SetCreateCallback(saved); |
| 7185 } | 7144 } |
| 7186 | 7145 |
| 7187 | 7146 |
| 7188 UNIT_TEST_CASE(RunLoop_Success) { | 7147 UNIT_TEST_CASE(RunLoop_Success) { |
| 7189 RunLoopTest(false, false); | 7148 RunLoopTest(false); |
| 7190 } | 7149 } |
| 7191 | 7150 |
| 7192 | 7151 |
| 7193 // This test exits the vm. Listed as FAIL in vm.status. | 7152 UNIT_TEST_CASE(RunLoop_Exception) { |
| 7194 UNIT_TEST_CASE(RunLoop_ExceptionChild) { | 7153 RunLoopTest(true); |
| 7195 RunLoopTest(true, false); | |
| 7196 } | 7154 } |
| 7197 | 7155 |
| 7198 | 7156 |
| 7199 UNIT_TEST_CASE(RunLoop_ExceptionParent) { | |
| 7200 RunLoopTest(false, true); | |
| 7201 } | |
| 7202 | |
| 7203 | |
| 7204 // Utility functions and variables for test case IsolateInterrupt starts here. | 7157 // Utility functions and variables for test case IsolateInterrupt starts here. |
| 7205 static Monitor* sync = NULL; | 7158 static Monitor* sync = NULL; |
| 7206 static Dart_Isolate shared_isolate = NULL; | 7159 static Dart_Isolate shared_isolate = NULL; |
| 7207 static bool main_entered = false; | 7160 static bool main_entered = false; |
| 7208 | 7161 |
| 7209 | 7162 |
| 7210 void MarkMainEntered(Dart_NativeArguments args) { | 7163 void MarkMainEntered(Dart_NativeArguments args) { |
| 7211 Dart_EnterScope(); // Start a Dart API scope for invoking API functions. | 7164 Dart_EnterScope(); // Start a Dart API scope for invoking API functions. |
| 7212 // Indicate that main has been entered. | 7165 // Indicate that main has been entered. |
| 7213 { | 7166 { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7277 | 7230 |
| 7278 // Tell the other thread that we are done. | 7231 // Tell the other thread that we are done. |
| 7279 { | 7232 { |
| 7280 MonitorLocker ml(sync); | 7233 MonitorLocker ml(sync); |
| 7281 shared_isolate = NULL; | 7234 shared_isolate = NULL; |
| 7282 ml.Notify(); | 7235 ml.Notify(); |
| 7283 } | 7236 } |
| 7284 } | 7237 } |
| 7285 | 7238 |
| 7286 | 7239 |
| 7287 // This callback handles isolate interrupts for the IsolateInterrupt | |
| 7288 // test. It ignores the first two interrupts and throws an exception | |
| 7289 // on the third interrupt. | |
| 7290 const int kInterruptCount = 10; | |
| 7291 static int interrupt_count = 0; | |
| 7292 static bool IsolateInterruptTestCallback() { | |
| 7293 OS::Print(" ========== Interrupt callback called #%d\n", interrupt_count + 1); | |
| 7294 { | |
| 7295 MonitorLocker ml(sync); | |
| 7296 interrupt_count++; | |
| 7297 ml.Notify(); | |
| 7298 } | |
| 7299 if (interrupt_count == kInterruptCount) { | |
| 7300 Dart_EnterScope(); | |
| 7301 Dart_Handle lib = Dart_LookupLibrary(NewString(TestCase::url())); | |
| 7302 EXPECT_VALID(lib); | |
| 7303 Dart_Handle exc = NewString("foo"); | |
| 7304 EXPECT_VALID(exc); | |
| 7305 Dart_Handle result = Dart_ThrowException(exc); | |
| 7306 EXPECT_VALID(result); | |
| 7307 UNREACHABLE(); // Dart_ThrowException only returns if it gets an error. | |
| 7308 return false; | |
| 7309 } | |
| 7310 ASSERT(interrupt_count < kInterruptCount); | |
| 7311 return true; | |
| 7312 } | |
| 7313 | |
| 7314 | |
| 7315 TEST_CASE(IsolateInterrupt) { | |
| 7316 Dart_IsolateInterruptCallback saved = Isolate::InterruptCallback(); | |
| 7317 Isolate::SetInterruptCallback(IsolateInterruptTestCallback); | |
| 7318 | |
| 7319 sync = new Monitor(); | |
| 7320 int result = OSThread::Start("IsolateInterrupt", BusyLoop_start, 0); | |
| 7321 EXPECT_EQ(0, result); | |
| 7322 | |
| 7323 { | |
| 7324 MonitorLocker ml(sync); | |
| 7325 // Wait for the other isolate to enter main. | |
| 7326 while (!main_entered) { | |
| 7327 ml.Wait(); | |
| 7328 } | |
| 7329 } | |
| 7330 | |
| 7331 // Send a number of interrupts to the other isolate. All but the | |
| 7332 // last allow execution to continue. The last causes an exception in | |
| 7333 // the isolate. | |
| 7334 for (int i = 0; i < kInterruptCount; i++) { | |
| 7335 // Space out the interrupts a bit. | |
| 7336 OS::Sleep(i + 1); | |
| 7337 Dart_InterruptIsolate(shared_isolate); | |
| 7338 { | |
| 7339 MonitorLocker ml(sync); | |
| 7340 // Wait for interrupt_count to be increased. | |
| 7341 while (interrupt_count == i) { | |
| 7342 ml.Wait(); | |
| 7343 } | |
| 7344 OS::Print(" ========== Interrupt processed #%d\n", interrupt_count); | |
| 7345 } | |
| 7346 } | |
| 7347 | |
| 7348 { | |
| 7349 MonitorLocker ml(sync); | |
| 7350 // Wait for our isolate to finish. | |
| 7351 while (shared_isolate != NULL) { | |
| 7352 ml.Wait(); | |
| 7353 } | |
| 7354 } | |
| 7355 | |
| 7356 // We should have received the expected number of interrupts. | |
| 7357 EXPECT_EQ(kInterruptCount, interrupt_count); | |
| 7358 | |
| 7359 Isolate::SetInterruptCallback(saved); | |
| 7360 } | |
| 7361 | |
| 7362 static void* saved_callback_data; | 7240 static void* saved_callback_data; |
| 7363 static void IsolateShutdownTestCallback(void* callback_data) { | 7241 static void IsolateShutdownTestCallback(void* callback_data) { |
| 7364 saved_callback_data = callback_data; | 7242 saved_callback_data = callback_data; |
| 7365 } | 7243 } |
| 7366 | 7244 |
| 7367 UNIT_TEST_CASE(IsolateShutdown) { | 7245 UNIT_TEST_CASE(IsolateShutdown) { |
| 7368 Dart_IsolateShutdownCallback saved = Isolate::ShutdownCallback(); | 7246 Dart_IsolateShutdownCallback saved = Isolate::ShutdownCallback(); |
| 7369 Isolate::SetShutdownCallback(IsolateShutdownTestCallback); | 7247 Isolate::SetShutdownCallback(IsolateShutdownTestCallback); |
| 7370 | 7248 |
| 7371 saved_callback_data = NULL; | 7249 saved_callback_data = NULL; |
| (...skipping 2121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9493 EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer); | 9371 EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer); |
| 9494 EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer); | 9372 EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer); |
| 9495 EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer); | 9373 EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer); |
| 9496 | 9374 |
| 9497 // Heartbeat test for new events. | 9375 // Heartbeat test for new events. |
| 9498 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); | 9376 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); |
| 9499 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); | 9377 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); |
| 9500 } | 9378 } |
| 9501 | 9379 |
| 9502 } // namespace dart | 9380 } // namespace dart |
| OLD | NEW |