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 |