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 |