| 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 "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/dart.h" | 8 #include "vm/dart.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| 11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/longjump.h" | 12 #include "vm/longjump.h" |
| 13 #include "vm/message_handler.h" | 13 #include "vm/message_handler.h" |
| 14 #include "vm/object.h" | 14 #include "vm/object.h" |
| 15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 16 #include "vm/port.h" | 16 #include "vm/port.h" |
| 17 #include "vm/resolver.h" | 17 #include "vm/resolver.h" |
| 18 #include "vm/snapshot.h" | 18 #include "vm/snapshot.h" |
| 19 #include "vm/symbols.h" | 19 #include "vm/symbols.h" |
| 20 #include "vm/thread.h" | 20 #include "vm/thread.h" |
| 21 | 21 |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 24 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| 25 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 25 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 26 return reinterpret_cast<uint8_t*>(new_ptr); | 26 return reinterpret_cast<uint8_t*>(new_ptr); |
| 27 } | 27 } |
| 28 | 28 |
| 29 | 29 |
| 30 // TODO(turnidge): Move to DartLibraryCalls. | 30 DEFINE_NATIVE_ENTRY(CapabilityImpl_factory, 1) { |
| 31 static RawObject* ReceivePortCreate(Dart_Port port_id) { | 31 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); |
| 32 Isolate* isolate = Isolate::Current(); | 32 uint64_t id = isolate->random()->NextUInt64(); |
| 33 Function& func = | 33 return Capability::New(id); |
| 34 Function::Handle(isolate, | |
| 35 isolate->object_store()->receive_port_create_function()); | |
| 36 const int kNumArguments = 1; | |
| 37 if (func.IsNull()) { | |
| 38 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); | |
| 39 ASSERT(!isolate_lib.IsNull()); | |
| 40 const String& class_name = | |
| 41 String::Handle(isolate_lib.PrivateName(Symbols::_RawReceivePortImpl())); | |
| 42 const String& function_name = | |
| 43 String::Handle(isolate_lib.PrivateName(Symbols::_create())); | |
| 44 func = Resolver::ResolveStatic(isolate_lib, | |
| 45 class_name, | |
| 46 function_name, | |
| 47 kNumArguments, | |
| 48 Object::empty_array()); | |
| 49 ASSERT(!func.IsNull()); | |
| 50 isolate->object_store()->set_receive_port_create_function(func); | |
| 51 } | |
| 52 const Array& args = Array::Handle(isolate, Array::New(kNumArguments)); | |
| 53 args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id))); | |
| 54 const Object& result = | |
| 55 Object::Handle(isolate, DartEntry::InvokeFunction(func, args)); | |
| 56 if (!result.IsError()) { | |
| 57 PortMap::SetLive(port_id); | |
| 58 } | |
| 59 return result.raw(); | |
| 60 } | 34 } |
| 61 | 35 |
| 62 | 36 |
| 63 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) { | 37 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) { |
| 64 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); | 38 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); |
| 65 Dart_Port port_id = | 39 Dart_Port port_id = |
| 66 PortMap::CreatePort(arguments->isolate()->message_handler()); | 40 PortMap::CreatePort(arguments->isolate()->message_handler()); |
| 67 const Object& port = Object::Handle(ReceivePortCreate(port_id)); | 41 return ReceivePort::New(port_id); |
| 68 if (port.IsError()) { | 42 } |
| 69 Exceptions::PropagateError(Error::Cast(port)); | 43 |
| 70 } | 44 |
| 71 return port.raw(); | 45 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_id, 1) { |
| 46 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); |
| 47 return Integer::NewFromUint64(port.Id()); |
| 48 } |
| 49 |
| 50 |
| 51 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_sendport, 1) { |
| 52 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); |
| 53 return port.send_port(); |
| 72 } | 54 } |
| 73 | 55 |
| 74 | 56 |
| 75 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 1) { | 57 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 1) { |
| 76 GET_NON_NULL_NATIVE_ARGUMENT(Smi, id, arguments->NativeArgAt(0)); | 58 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0)); |
| 77 PortMap::ClosePort(id.Value()); | 59 Dart_Port id = port.Id(); |
| 78 return Object::null(); | 60 PortMap::ClosePort(id); |
| 61 return Integer::NewFromUint64(id); |
| 62 } |
| 63 |
| 64 |
| 65 DEFINE_NATIVE_ENTRY(SendPortImpl_get_id, 1) { |
| 66 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
| 67 return Integer::NewFromUint64(port.Id()); |
| 68 } |
| 69 |
| 70 |
| 71 DEFINE_NATIVE_ENTRY(SendPortImpl_get_hashcode, 1) { |
| 72 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
| 73 int64_t id = port.Id(); |
| 74 int32_t hi = static_cast<int32_t>(id >> 32); |
| 75 int32_t lo = static_cast<int32_t>(id); |
| 76 int32_t hash = (hi ^ lo) & kSmiMax; |
| 77 return Smi::New(hash); |
| 79 } | 78 } |
| 80 | 79 |
| 81 | 80 |
| 82 DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 2) { | 81 DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 2) { |
| 83 GET_NON_NULL_NATIVE_ARGUMENT(Smi, send_id, arguments->NativeArgAt(0)); | 82 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
| 84 // TODO(iposva): Allow for arbitrary messages to be sent. | 83 // TODO(iposva): Allow for arbitrary messages to be sent. |
| 85 GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1)); | 84 GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1)); |
| 86 | 85 |
| 87 uint8_t* data = NULL; | 86 uint8_t* data = NULL; |
| 88 MessageWriter writer(&data, &allocator); | 87 MessageWriter writer(&data, &allocator); |
| 89 writer.WriteMessage(obj); | 88 writer.WriteMessage(obj); |
| 90 | 89 |
| 91 // TODO(turnidge): Throw an exception when the return value is false? | 90 // TODO(turnidge): Throw an exception when the return value is false? |
| 92 PortMap::PostMessage(new Message(send_id.Value(), | 91 PortMap::PostMessage(new Message(port.Id(), |
| 93 data, writer.BytesWritten(), | 92 data, writer.BytesWritten(), |
| 94 Message::kNormalPriority)); | 93 Message::kNormalPriority)); |
| 95 return Object::null(); | 94 return Object::null(); |
| 96 } | 95 } |
| 97 | 96 |
| 98 | 97 |
| 99 static void ThrowIsolateSpawnException(const String& message) { | 98 static void ThrowIsolateSpawnException(const String& message) { |
| 100 const Array& args = Array::Handle(Array::New(1)); | 99 const Array& args = Array::Handle(Array::New(1)); |
| 101 args.SetAt(0, message); | 100 args.SetAt(0, message); |
| 102 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); | 101 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 // Create a new isolate. | 170 // Create a new isolate. |
| 172 char* error = NULL; | 171 char* error = NULL; |
| 173 if (!CreateIsolate(state, &error)) { | 172 if (!CreateIsolate(state, &error)) { |
| 174 delete state; | 173 delete state; |
| 175 const String& msg = String::Handle(String::New(error)); | 174 const String& msg = String::Handle(String::New(error)); |
| 176 free(error); | 175 free(error); |
| 177 ThrowIsolateSpawnException(msg); | 176 ThrowIsolateSpawnException(msg); |
| 178 } | 177 } |
| 179 | 178 |
| 180 // Try to create a SendPort for the new isolate. | 179 // Try to create a SendPort for the new isolate. |
| 181 const Object& port = Object::Handle( | 180 const SendPort& port = SendPort::Handle( |
| 182 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); | 181 SendPort::New(state->isolate()->main_port())); |
| 183 if (port.IsError()) { | |
| 184 state->Cleanup(); | |
| 185 delete state; | |
| 186 Exceptions::PropagateError(Error::Cast(port)); | |
| 187 } | |
| 188 | 182 |
| 189 // Start the new isolate if it is already marked as runnable. | 183 // Start the new isolate if it is already marked as runnable. |
| 190 MutexLocker ml(state->isolate()->mutex()); | 184 MutexLocker ml(state->isolate()->mutex()); |
| 191 state->isolate()->set_spawn_state(state); | 185 state->isolate()->set_spawn_state(state); |
| 192 if (state->isolate()->is_runnable()) { | 186 if (state->isolate()->is_runnable()) { |
| 193 state->isolate()->Run(); | 187 state->isolate()->Run(); |
| 194 } | 188 } |
| 195 | 189 |
| 196 return port.raw(); | 190 return port.raw(); |
| 197 } | 191 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 &canonical_uri, &error)) { | 224 &canonical_uri, &error)) { |
| 231 const String& msg = String::Handle(String::New(error)); | 225 const String& msg = String::Handle(String::New(error)); |
| 232 ThrowIsolateSpawnException(msg); | 226 ThrowIsolateSpawnException(msg); |
| 233 } | 227 } |
| 234 | 228 |
| 235 return Spawn(arguments, new IsolateSpawnState(canonical_uri)); | 229 return Spawn(arguments, new IsolateSpawnState(canonical_uri)); |
| 236 } | 230 } |
| 237 | 231 |
| 238 | 232 |
| 239 DEFINE_NATIVE_ENTRY(Isolate_mainPort, 0) { | 233 DEFINE_NATIVE_ENTRY(Isolate_mainPort, 0) { |
| 240 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); | |
| 241 if (port.IsError()) { | |
| 242 Exceptions::PropagateError(Error::Cast(port)); | |
| 243 } | |
| 244 | |
| 245 // The control port is being accessed as a regular port from Dart code. This | 234 // The control port is being accessed as a regular port from Dart code. This |
| 246 // is most likely due to the _startIsolate code in dart:isolate. Account for | 235 // is most likely due to the _startIsolate code in dart:isolate. Account for |
| 247 // this by increasing the number of open control ports. | 236 // this by increasing the number of open control ports. |
| 248 isolate->message_handler()->increment_control_ports(); | 237 isolate->message_handler()->increment_control_ports(); |
| 249 | 238 |
| 250 return port.raw(); | 239 return ReceivePort::New(isolate->main_port()); |
| 251 } | 240 } |
| 252 | 241 |
| 253 } // namespace dart | 242 } // namespace dart |
| OLD | NEW |