OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/isolate.h" | 5 #include "vm/isolate.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/json.h" | 9 #include "platform/json.h" |
10 #include "vm/code_observers.h" | 10 #include "vm/code_observers.h" |
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 bool is_spawn_uri = state->is_spawn_uri(); | 764 bool is_spawn_uri = state->is_spawn_uri(); |
765 if (result.IsError()) { | 765 if (result.IsError()) { |
766 StoreError(isolate, result); | 766 StoreError(isolate, result); |
767 return false; | 767 return false; |
768 } | 768 } |
769 ASSERT(result.IsFunction()); | 769 ASSERT(result.IsFunction()); |
770 Function& func = Function::Handle(isolate); | 770 Function& func = Function::Handle(isolate); |
771 func ^= result.raw(); | 771 func ^= result.raw(); |
772 func = func.ImplicitClosureFunction(); | 772 func = func.ImplicitClosureFunction(); |
773 | 773 |
| 774 const Array& capabilities = Array::Handle(Array::New(2)); |
| 775 Capability& capability = Capability::Handle(); |
| 776 capability = Capability::New(isolate->pause_capability()); |
| 777 capabilities.SetAt(0, capability); |
| 778 capability = Capability::New(isolate->terminate_capability()); |
| 779 capabilities.SetAt(1, capability); |
| 780 |
774 // Instead of directly invoking the entry point we call '_startIsolate' with | 781 // Instead of directly invoking the entry point we call '_startIsolate' with |
775 // the entry point as argument. The '_startIsolate' function will | 782 // the entry point as argument. |
776 // communicate with the spawner to receive the initial message before it | |
777 // executes the real entry point. | |
778 // Since this function ("RunIsolate") is used for both Isolate.spawn and | 783 // Since this function ("RunIsolate") is used for both Isolate.spawn and |
779 // Isolate.spawnUri we also send a boolean flag as argument so that the | 784 // Isolate.spawnUri we also send a boolean flag as argument so that the |
780 // "_startIsolate" function can act corresponding to how the isolate was | 785 // "_startIsolate" function can act corresponding to how the isolate was |
781 // created. | 786 // created. |
782 const Array& args = Array::Handle(Array::New(2)); | 787 const Array& args = Array::Handle(Array::New(7)); |
783 args.SetAt(0, Instance::Handle(func.ImplicitStaticClosure())); | 788 args.SetAt(0, SendPort::Handle(SendPort::New(state->parent_port()))); |
784 args.SetAt(1, is_spawn_uri ? Bool::True() : Bool::False()); | 789 args.SetAt(1, Instance::Handle(func.ImplicitStaticClosure())); |
| 790 args.SetAt(2, Instance::Handle(state->BuildArgs())); |
| 791 args.SetAt(3, Instance::Handle(state->BuildMessage())); |
| 792 args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False()); |
| 793 args.SetAt(5, ReceivePort::Handle( |
| 794 ReceivePort::New(isolate->main_port(), true /* control port */))); |
| 795 args.SetAt(6, capabilities); |
785 | 796 |
786 const Library& lib = Library::Handle(Library::IsolateLibrary()); | 797 const Library& lib = Library::Handle(Library::IsolateLibrary()); |
787 const String& entry_name = String::Handle(String::New("_startIsolate")); | 798 const String& entry_name = String::Handle(String::New("_startIsolate")); |
788 const Function& entry_point = | 799 const Function& entry_point = |
789 Function::Handle(lib.LookupLocalFunction(entry_name)); | 800 Function::Handle(lib.LookupLocalFunction(entry_name)); |
790 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); | 801 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); |
791 | 802 |
792 result = DartEntry::InvokeFunction(entry_point, args); | 803 result = DartEntry::InvokeFunction(entry_point, args); |
793 if (result.IsError()) { | 804 if (result.IsError()) { |
794 StoreError(isolate, result); | 805 StoreError(isolate, result); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 if (stack->Length() > 0) { | 1113 if (stack->Length() > 0) { |
1103 JSONObject jsframe(&jsobj, "topFrame"); | 1114 JSONObject jsframe(&jsobj, "topFrame"); |
1104 | 1115 |
1105 ActivationFrame* frame = stack->FrameAt(0); | 1116 ActivationFrame* frame = stack->FrameAt(0); |
1106 frame->PrintToJSONObject(&jsobj); | 1117 frame->PrintToJSONObject(&jsobj); |
1107 // TODO(turnidge): Implement depth differently -- differentiate | 1118 // TODO(turnidge): Implement depth differently -- differentiate |
1108 // inlined frames. | 1119 // inlined frames. |
1109 jsobj.AddProperty("depth", (intptr_t)0); | 1120 jsobj.AddProperty("depth", (intptr_t)0); |
1110 } | 1121 } |
1111 jsobj.AddProperty("livePorts", message_handler()->live_ports()); | 1122 jsobj.AddProperty("livePorts", message_handler()->live_ports()); |
1112 jsobj.AddProperty("controlPorts", message_handler()->control_ports()); | |
1113 jsobj.AddProperty("pauseOnExit", message_handler()->pause_on_exit()); | 1123 jsobj.AddProperty("pauseOnExit", message_handler()->pause_on_exit()); |
1114 | 1124 |
1115 // TODO(turnidge): Make the debugger support paused_on_start/exit. | 1125 // TODO(turnidge): Make the debugger support paused_on_start/exit. |
1116 if (message_handler()->paused_on_start()) { | 1126 if (message_handler()->paused_on_start()) { |
1117 ASSERT(debugger()->PauseEvent() == NULL); | 1127 ASSERT(debugger()->PauseEvent() == NULL); |
1118 DebuggerEvent pauseEvent(this, DebuggerEvent::kIsolateCreated); | 1128 DebuggerEvent pauseEvent(this, DebuggerEvent::kIsolateCreated); |
1119 jsobj.AddProperty("pauseEvent", &pauseEvent); | 1129 jsobj.AddProperty("pauseEvent", &pauseEvent); |
1120 } else if (message_handler()->paused_on_exit()) { | 1130 } else if (message_handler()->paused_on_exit()) { |
1121 ASSERT(debugger()->PauseEvent() == NULL); | 1131 ASSERT(debugger()->PauseEvent() == NULL); |
1122 DebuggerEvent pauseEvent(this, DebuggerEvent::kIsolateShutdown); | 1132 DebuggerEvent pauseEvent(this, DebuggerEvent::kIsolateShutdown); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 | 1307 |
1298 | 1308 |
1299 template<class T> | 1309 template<class T> |
1300 T* Isolate::AllocateReusableHandle() { | 1310 T* Isolate::AllocateReusableHandle() { |
1301 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); | 1311 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); |
1302 T::initializeHandle(handle, T::null()); | 1312 T::initializeHandle(handle, T::null()); |
1303 return handle; | 1313 return handle; |
1304 } | 1314 } |
1305 | 1315 |
1306 | 1316 |
1307 IsolateSpawnState::IsolateSpawnState(const Function& func) | 1317 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| 1318 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 1319 return reinterpret_cast<uint8_t*>(new_ptr); |
| 1320 } |
| 1321 |
| 1322 |
| 1323 static void SerializeObject(const Instance& obj, |
| 1324 uint8_t** obj_data, |
| 1325 intptr_t* obj_len) { |
| 1326 MessageWriter writer(obj_data, &allocator); |
| 1327 writer.WriteMessage(obj); |
| 1328 *obj_len = writer.BytesWritten(); |
| 1329 } |
| 1330 |
| 1331 |
| 1332 static RawInstance* DeserializeObject(Isolate* isolate, |
| 1333 uint8_t* obj_data, |
| 1334 intptr_t obj_len) { |
| 1335 if (obj_data == NULL) { |
| 1336 return Instance::null(); |
| 1337 } |
| 1338 SnapshotReader reader(obj_data, obj_len, Snapshot::kMessage, isolate); |
| 1339 const Object& obj = Object::Handle(isolate, reader.ReadObject()); |
| 1340 ASSERT(!obj.IsError()); |
| 1341 Instance& instance = Instance::Handle(isolate); |
| 1342 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. |
| 1343 return instance.raw(); |
| 1344 } |
| 1345 |
| 1346 |
| 1347 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
| 1348 const Function& func, |
| 1349 const Instance& message) |
1308 : isolate_(NULL), | 1350 : isolate_(NULL), |
| 1351 parent_port_(parent_port), |
1309 script_url_(NULL), | 1352 script_url_(NULL), |
1310 library_url_(NULL), | 1353 library_url_(NULL), |
1311 class_name_(NULL), | 1354 class_name_(NULL), |
1312 function_name_(NULL), | 1355 function_name_(NULL), |
1313 exception_callback_name_(NULL) { | 1356 exception_callback_name_(NULL), |
| 1357 serialized_args_(NULL), |
| 1358 serialized_args_len_(0), |
| 1359 serialized_message_(NULL), |
| 1360 serialized_message_len_(0) { |
1314 script_url_ = NULL; | 1361 script_url_ = NULL; |
1315 const Class& cls = Class::Handle(func.Owner()); | 1362 const Class& cls = Class::Handle(func.Owner()); |
1316 const Library& lib = Library::Handle(cls.library()); | 1363 const Library& lib = Library::Handle(cls.library()); |
1317 const String& lib_url = String::Handle(lib.url()); | 1364 const String& lib_url = String::Handle(lib.url()); |
1318 library_url_ = strdup(lib_url.ToCString()); | 1365 library_url_ = strdup(lib_url.ToCString()); |
1319 | 1366 |
1320 const String& func_name = String::Handle(func.name()); | 1367 const String& func_name = String::Handle(func.name()); |
1321 function_name_ = strdup(func_name.ToCString()); | 1368 function_name_ = strdup(func_name.ToCString()); |
1322 if (!cls.IsTopLevel()) { | 1369 if (!cls.IsTopLevel()) { |
1323 const String& class_name = String::Handle(cls.Name()); | 1370 const String& class_name = String::Handle(cls.Name()); |
1324 class_name_ = strdup(class_name.ToCString()); | 1371 class_name_ = strdup(class_name.ToCString()); |
1325 } | 1372 } |
1326 exception_callback_name_ = strdup("_unhandledExceptionCallback"); | 1373 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| 1374 SerializeObject(message, &serialized_message_, &serialized_message_len_); |
1327 } | 1375 } |
1328 | 1376 |
1329 | 1377 |
1330 IsolateSpawnState::IsolateSpawnState(const char* script_url) | 1378 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
| 1379 const char* script_url, |
| 1380 const Instance& args, |
| 1381 const Instance& message) |
1331 : isolate_(NULL), | 1382 : isolate_(NULL), |
| 1383 parent_port_(parent_port), |
1332 library_url_(NULL), | 1384 library_url_(NULL), |
1333 class_name_(NULL), | 1385 class_name_(NULL), |
1334 function_name_(NULL), | 1386 function_name_(NULL), |
1335 exception_callback_name_(NULL) { | 1387 exception_callback_name_(NULL), |
| 1388 serialized_args_(NULL), |
| 1389 serialized_args_len_(0), |
| 1390 serialized_message_(NULL), |
| 1391 serialized_message_len_(0) { |
1336 script_url_ = strdup(script_url); | 1392 script_url_ = strdup(script_url); |
1337 library_url_ = NULL; | 1393 library_url_ = NULL; |
1338 function_name_ = strdup("main"); | 1394 function_name_ = strdup("main"); |
1339 exception_callback_name_ = strdup("_unhandledExceptionCallback"); | 1395 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| 1396 SerializeObject(args, &serialized_args_, &serialized_args_len_); |
| 1397 SerializeObject(message, &serialized_message_, &serialized_message_len_); |
1340 } | 1398 } |
1341 | 1399 |
1342 | 1400 |
1343 IsolateSpawnState::~IsolateSpawnState() { | 1401 IsolateSpawnState::~IsolateSpawnState() { |
1344 free(script_url_); | 1402 free(script_url_); |
1345 free(library_url_); | 1403 free(library_url_); |
1346 free(function_name_); | 1404 free(function_name_); |
1347 free(class_name_); | 1405 free(class_name_); |
1348 free(exception_callback_name_); | 1406 free(exception_callback_name_); |
| 1407 free(serialized_args_); |
| 1408 free(serialized_message_); |
1349 } | 1409 } |
1350 | 1410 |
1351 | 1411 |
1352 RawObject* IsolateSpawnState::ResolveFunction() { | 1412 RawObject* IsolateSpawnState::ResolveFunction() { |
1353 // Resolve the library. | 1413 // Resolve the library. |
1354 Library& lib = Library::Handle(); | 1414 Library& lib = Library::Handle(); |
1355 if (library_url()) { | 1415 if (library_url()) { |
1356 const String& lib_url = String::Handle(String::New(library_url())); | 1416 const String& lib_url = String::Handle(String::New(library_url())); |
1357 lib = Library::LookupLibrary(lib_url); | 1417 lib = Library::LookupLibrary(lib_url); |
1358 if (lib.IsNull() || lib.IsError()) { | 1418 if (lib.IsNull() || lib.IsError()) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 const String& msg = String::Handle(String::NewFormatted( | 1455 const String& msg = String::Handle(String::NewFormatted( |
1396 "Unable to resolve static method '%s.%s' in library '%s'.", | 1456 "Unable to resolve static method '%s.%s' in library '%s'.", |
1397 class_name(), function_name(), | 1457 class_name(), function_name(), |
1398 (library_url() != NULL ? library_url() : script_url()))); | 1458 (library_url() != NULL ? library_url() : script_url()))); |
1399 return LanguageError::New(msg); | 1459 return LanguageError::New(msg); |
1400 } | 1460 } |
1401 return func.raw(); | 1461 return func.raw(); |
1402 } | 1462 } |
1403 | 1463 |
1404 | 1464 |
| 1465 RawInstance* IsolateSpawnState::BuildArgs() { |
| 1466 return DeserializeObject(isolate_, serialized_args_, serialized_args_len_); |
| 1467 } |
| 1468 |
| 1469 |
| 1470 RawInstance* IsolateSpawnState::BuildMessage() { |
| 1471 return DeserializeObject(isolate_, |
| 1472 serialized_message_, serialized_message_len_); |
| 1473 } |
| 1474 |
| 1475 |
1405 void IsolateSpawnState::Cleanup() { | 1476 void IsolateSpawnState::Cleanup() { |
1406 SwitchIsolateScope switch_scope(I); | 1477 SwitchIsolateScope switch_scope(I); |
1407 Dart::ShutdownIsolate(); | 1478 Dart::ShutdownIsolate(); |
1408 } | 1479 } |
1409 | 1480 |
1410 } // namespace dart | 1481 } // namespace dart |
OLD | NEW |