OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 | |
6 #include "bin/loader.h" | 5 #include "bin/loader.h" |
7 | 6 |
8 #include "bin/builtin.h" | 7 #include "bin/builtin.h" |
9 #include "bin/dartutils.h" | 8 #include "bin/dartutils.h" |
10 #include "bin/dfe.h" | 9 #include "bin/dfe.h" |
11 #include "bin/extensions.h" | 10 #include "bin/extensions.h" |
12 #include "bin/file.h" | 11 #include "bin/file.h" |
13 #include "bin/lockers.h" | 12 #include "bin/lockers.h" |
14 #include "bin/utils.h" | 13 #include "bin/utils.h" |
15 #include "include/dart_tools_api.h" | 14 #include "include/dart_tools_api.h" |
(...skipping 23 matching lines...) Expand all Loading... |
39 results_capacity_(0), | 38 results_capacity_(0), |
40 payload_(NULL), | 39 payload_(NULL), |
41 payload_length_(0) { | 40 payload_length_(0) { |
42 monitor_ = new Monitor(); | 41 monitor_ = new Monitor(); |
43 ASSERT(isolate_data_ != NULL); | 42 ASSERT(isolate_data_ != NULL); |
44 port_ = Dart_NewNativePort("Loader", Loader::NativeMessageHandler, false); | 43 port_ = Dart_NewNativePort("Loader", Loader::NativeMessageHandler, false); |
45 isolate_data_->set_loader(this); | 44 isolate_data_->set_loader(this); |
46 AddLoader(port_, isolate_data_); | 45 AddLoader(port_, isolate_data_); |
47 } | 46 } |
48 | 47 |
49 | |
50 Loader::~Loader() { | 48 Loader::~Loader() { |
51 ASSERT(port_ != ILLEGAL_PORT); | 49 ASSERT(port_ != ILLEGAL_PORT); |
52 // Enter the monitor while we close the Dart port. After the Dart port is | 50 // Enter the monitor while we close the Dart port. After the Dart port is |
53 // closed, no more results can be queued. | 51 // closed, no more results can be queued. |
54 monitor_->Enter(); | 52 monitor_->Enter(); |
55 Dart_CloseNativePort(port_); | 53 Dart_CloseNativePort(port_); |
56 monitor_->Exit(); | 54 monitor_->Exit(); |
57 RemoveLoader(port_); | 55 RemoveLoader(port_); |
58 port_ = ILLEGAL_PORT; | 56 port_ = ILLEGAL_PORT; |
59 isolate_data_->set_loader(NULL); | 57 isolate_data_->set_loader(NULL); |
60 isolate_data_ = NULL; | 58 isolate_data_ = NULL; |
61 delete monitor_; | 59 delete monitor_; |
62 monitor_ = NULL; | 60 monitor_ = NULL; |
63 for (intptr_t i = 0; i < results_length_; i++) { | 61 for (intptr_t i = 0; i < results_length_; i++) { |
64 results_[i].Cleanup(); | 62 results_[i].Cleanup(); |
65 } | 63 } |
66 free(results_); | 64 free(results_); |
67 results_ = NULL; | 65 results_ = NULL; |
68 payload_ = NULL; | 66 payload_ = NULL; |
69 payload_length_ = 0; | 67 payload_length_ = 0; |
70 } | 68 } |
71 | 69 |
72 | |
73 // Copy the contents of |message| into an |IOResult|. | 70 // Copy the contents of |message| into an |IOResult|. |
74 void Loader::IOResult::Setup(Dart_CObject* message) { | 71 void Loader::IOResult::Setup(Dart_CObject* message) { |
75 ASSERT(message->type == Dart_CObject_kArray); | 72 ASSERT(message->type == Dart_CObject_kArray); |
76 ASSERT(message->value.as_array.length == 5); | 73 ASSERT(message->value.as_array.length == 5); |
77 Dart_CObject* tag_message = message->value.as_array.values[0]; | 74 Dart_CObject* tag_message = message->value.as_array.values[0]; |
78 ASSERT(tag_message != NULL); | 75 ASSERT(tag_message != NULL); |
79 Dart_CObject* uri_message = message->value.as_array.values[1]; | 76 Dart_CObject* uri_message = message->value.as_array.values[1]; |
80 ASSERT(uri_message != NULL); | 77 ASSERT(uri_message != NULL); |
81 Dart_CObject* resolved_uri_message = message->value.as_array.values[2]; | 78 Dart_CObject* resolved_uri_message = message->value.as_array.values[2]; |
82 ASSERT(resolved_uri_message != NULL); | 79 ASSERT(resolved_uri_message != NULL); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 // Payload is the contents of a file. | 112 // Payload is the contents of a file. |
116 ASSERT(payload_message->type == Dart_CObject_kTypedData); | 113 ASSERT(payload_message->type == Dart_CObject_kTypedData); |
117 ASSERT(payload_message->value.as_typed_data.type == Dart_TypedData_kUint8); | 114 ASSERT(payload_message->value.as_typed_data.type == Dart_TypedData_kUint8); |
118 payload_length = payload_message->value.as_typed_data.length; | 115 payload_length = payload_message->value.as_typed_data.length; |
119 payload = reinterpret_cast<uint8_t*>(malloc(payload_length)); | 116 payload = reinterpret_cast<uint8_t*>(malloc(payload_length)); |
120 memmove(payload, payload_message->value.as_typed_data.values, | 117 memmove(payload, payload_message->value.as_typed_data.values, |
121 payload_length); | 118 payload_length); |
122 } | 119 } |
123 } | 120 } |
124 | 121 |
125 | |
126 void Loader::IOResult::Cleanup() { | 122 void Loader::IOResult::Cleanup() { |
127 free(uri); | 123 free(uri); |
128 free(resolved_uri); | 124 free(resolved_uri); |
129 free(library_uri); | 125 free(library_uri); |
130 free(payload); | 126 free(payload); |
131 } | 127 } |
132 | 128 |
133 | |
134 // Send the Loader Initialization message to the service isolate. This | 129 // Send the Loader Initialization message to the service isolate. This |
135 // message is sent the first time a loader is constructed for an isolate and | 130 // message is sent the first time a loader is constructed for an isolate and |
136 // seeds the service isolate with some initial state about this isolate. | 131 // seeds the service isolate with some initial state about this isolate. |
137 void Loader::Init(const char* package_root, | 132 void Loader::Init(const char* package_root, |
138 const char* packages_file, | 133 const char* packages_file, |
139 const char* working_directory, | 134 const char* working_directory, |
140 const char* root_script_uri) { | 135 const char* root_script_uri) { |
141 // This port delivers loading messages to the service isolate. | 136 // This port delivers loading messages to the service isolate. |
142 Dart_Port loader_port = Builtin::LoadPort(); | 137 Dart_Port loader_port = Builtin::LoadPort(); |
143 ASSERT(loader_port != ILLEGAL_PORT); | 138 ASSERT(loader_port != ILLEGAL_PORT); |
144 | 139 |
145 // Keep in sync with loader.dart. | 140 // Keep in sync with loader.dart. |
146 const intptr_t _Dart_kInitLoader = 4; | 141 const intptr_t _Dart_kInitLoader = 4; |
147 | 142 |
148 Dart_Handle request = Dart_NewList(9); | 143 Dart_Handle request = Dart_NewList(9); |
149 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); | 144 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); |
150 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); | 145 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); |
151 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kInitLoader)); | 146 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kInitLoader)); |
152 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); | 147 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); |
153 Dart_ListSetAt(request, 4, (package_root == NULL) | 148 Dart_ListSetAt(request, 4, |
154 ? Dart_Null() | 149 (package_root == NULL) |
155 : Dart_NewStringFromCString(package_root)); | 150 ? Dart_Null() |
156 Dart_ListSetAt(request, 5, (packages_file == NULL) | 151 : Dart_NewStringFromCString(package_root)); |
157 ? Dart_Null() | 152 Dart_ListSetAt(request, 5, |
158 : Dart_NewStringFromCString(packages_file)); | 153 (packages_file == NULL) |
| 154 ? Dart_Null() |
| 155 : Dart_NewStringFromCString(packages_file)); |
159 Dart_ListSetAt(request, 6, Dart_NewStringFromCString(working_directory)); | 156 Dart_ListSetAt(request, 6, Dart_NewStringFromCString(working_directory)); |
160 Dart_ListSetAt(request, 7, (root_script_uri == NULL) | 157 Dart_ListSetAt(request, 7, |
161 ? Dart_Null() | 158 (root_script_uri == NULL) |
162 : Dart_NewStringFromCString(root_script_uri)); | 159 ? Dart_Null() |
| 160 : Dart_NewStringFromCString(root_script_uri)); |
163 Dart_ListSetAt(request, 8, Dart_NewBoolean(Dart_IsReloading())); | 161 Dart_ListSetAt(request, 8, Dart_NewBoolean(Dart_IsReloading())); |
164 | 162 |
165 | |
166 bool success = Dart_Post(loader_port, request); | 163 bool success = Dart_Post(loader_port, request); |
167 ASSERT(success); | 164 ASSERT(success); |
168 } | 165 } |
169 | 166 |
170 | |
171 void Loader::SendImportExtensionRequest(Dart_Handle url, | 167 void Loader::SendImportExtensionRequest(Dart_Handle url, |
172 Dart_Handle library_url) { | 168 Dart_Handle library_url) { |
173 // This port delivers loading messages to the service isolate. | 169 // This port delivers loading messages to the service isolate. |
174 Dart_Port loader_port = Builtin::LoadPort(); | 170 Dart_Port loader_port = Builtin::LoadPort(); |
175 ASSERT(loader_port != ILLEGAL_PORT); | 171 ASSERT(loader_port != ILLEGAL_PORT); |
176 | 172 |
177 | |
178 Dart_Handle request = Dart_NewList(6); | 173 Dart_Handle request = Dart_NewList(6); |
179 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); | 174 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); |
180 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); | 175 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); |
181 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kImportExtension)); | 176 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kImportExtension)); |
182 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); | 177 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); |
183 | 178 |
184 Dart_ListSetAt(request, 4, url); | 179 Dart_ListSetAt(request, 4, url); |
185 Dart_ListSetAt(request, 5, library_url); | 180 Dart_ListSetAt(request, 5, library_url); |
186 | 181 |
187 if (Dart_Post(loader_port, request)) { | 182 if (Dart_Post(loader_port, request)) { |
188 MonitorLocker ml(monitor_); | 183 MonitorLocker ml(monitor_); |
189 pending_operations_++; | 184 pending_operations_++; |
190 } | 185 } |
191 } | 186 } |
192 | 187 |
193 | |
194 // Forward a request from the tag handler to the service isolate. | 188 // Forward a request from the tag handler to the service isolate. |
195 void Loader::SendRequest(intptr_t tag, | 189 void Loader::SendRequest(intptr_t tag, |
196 Dart_Handle url, | 190 Dart_Handle url, |
197 Dart_Handle library_url) { | 191 Dart_Handle library_url) { |
198 // This port delivers loading messages to the service isolate. | 192 // This port delivers loading messages to the service isolate. |
199 Dart_Port loader_port = Builtin::LoadPort(); | 193 Dart_Port loader_port = Builtin::LoadPort(); |
200 ASSERT(loader_port != ILLEGAL_PORT); | 194 ASSERT(loader_port != ILLEGAL_PORT); |
201 | 195 |
202 Dart_Handle request = Dart_NewList(6); | 196 Dart_Handle request = Dart_NewList(6); |
203 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); | 197 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); |
204 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); | 198 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); |
205 Dart_ListSetAt(request, 2, Dart_NewInteger(tag)); | 199 Dart_ListSetAt(request, 2, Dart_NewInteger(tag)); |
206 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); | 200 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); |
207 | 201 |
208 Dart_ListSetAt(request, 4, url); | 202 Dart_ListSetAt(request, 4, url); |
209 Dart_ListSetAt(request, 5, library_url); | 203 Dart_ListSetAt(request, 5, library_url); |
210 | 204 |
211 if (Dart_Post(loader_port, request)) { | 205 if (Dart_Post(loader_port, request)) { |
212 MonitorLocker ml(monitor_); | 206 MonitorLocker ml(monitor_); |
213 pending_operations_++; | 207 pending_operations_++; |
214 } | 208 } |
215 } | 209 } |
216 | 210 |
217 | |
218 // Forward a request from the tag handler to the kernel isolate. | 211 // Forward a request from the tag handler to the kernel isolate. |
219 // [ tag, send port, url ] | 212 // [ tag, send port, url ] |
220 void Loader::SendKernelRequest(Dart_LibraryTag tag, Dart_Handle url) { | 213 void Loader::SendKernelRequest(Dart_LibraryTag tag, Dart_Handle url) { |
221 // This port delivers loading messages to the Kernel isolate. | 214 // This port delivers loading messages to the Kernel isolate. |
222 Dart_Port kernel_port = Dart_KernelPort(); | 215 Dart_Port kernel_port = Dart_KernelPort(); |
223 ASSERT(kernel_port != ILLEGAL_PORT); | 216 ASSERT(kernel_port != ILLEGAL_PORT); |
224 | 217 |
225 Dart_Handle request = Dart_NewList(3); | 218 Dart_Handle request = Dart_NewList(3); |
226 Dart_ListSetAt(request, 0, Dart_NewInteger(tag)); | 219 Dart_ListSetAt(request, 0, Dart_NewInteger(tag)); |
227 Dart_ListSetAt(request, 1, Dart_NewSendPort(port_)); | 220 Dart_ListSetAt(request, 1, Dart_NewSendPort(port_)); |
228 Dart_ListSetAt(request, 2, url); | 221 Dart_ListSetAt(request, 2, url); |
229 if (Dart_Post(kernel_port, request)) { | 222 if (Dart_Post(kernel_port, request)) { |
230 MonitorLocker ml(monitor_); | 223 MonitorLocker ml(monitor_); |
231 pending_operations_++; | 224 pending_operations_++; |
232 } | 225 } |
233 } | 226 } |
234 | 227 |
235 | |
236 void Loader::QueueMessage(Dart_CObject* message) { | 228 void Loader::QueueMessage(Dart_CObject* message) { |
237 MonitorLocker ml(monitor_); | 229 MonitorLocker ml(monitor_); |
238 if (results_length_ == results_capacity_) { | 230 if (results_length_ == results_capacity_) { |
239 // Grow to an initial capacity or double in size. | 231 // Grow to an initial capacity or double in size. |
240 results_capacity_ = (results_capacity_ == 0) ? 4 : results_capacity_ * 2; | 232 results_capacity_ = (results_capacity_ == 0) ? 4 : results_capacity_ * 2; |
241 results_ = reinterpret_cast<IOResult*>( | 233 results_ = reinterpret_cast<IOResult*>( |
242 realloc(results_, sizeof(IOResult) * results_capacity_)); | 234 realloc(results_, sizeof(IOResult) * results_capacity_)); |
243 ASSERT(results_ != NULL); | 235 ASSERT(results_ != NULL); |
244 } | 236 } |
245 ASSERT(results_ != NULL); | 237 ASSERT(results_ != NULL); |
246 ASSERT(results_length_ < results_capacity_); | 238 ASSERT(results_length_ < results_capacity_); |
247 results_[results_length_].Setup(message); | 239 results_[results_length_].Setup(message); |
248 results_length_++; | 240 results_length_++; |
249 ml.Notify(); | 241 ml.Notify(); |
250 } | 242 } |
251 | 243 |
252 | |
253 void Loader::BlockUntilComplete(ProcessResult process_result) { | 244 void Loader::BlockUntilComplete(ProcessResult process_result) { |
254 MonitorLocker ml(monitor_); | 245 MonitorLocker ml(monitor_); |
255 | 246 |
256 while (true) { | 247 while (true) { |
257 // If |ProcessQueueLocked| returns false, we've hit an error and should | 248 // If |ProcessQueueLocked| returns false, we've hit an error and should |
258 // stop loading. | 249 // stop loading. |
259 if (!ProcessQueueLocked(process_result)) { | 250 if (!ProcessQueueLocked(process_result)) { |
260 break; | 251 break; |
261 } | 252 } |
262 | 253 |
263 // When |pending_operations_| hits 0, we are done loading. | 254 // When |pending_operations_| hits 0, we are done loading. |
264 if (pending_operations_ == 0) { | 255 if (pending_operations_ == 0) { |
265 break; | 256 break; |
266 } | 257 } |
267 | 258 |
268 // Wait to be notified about new I/O results. | 259 // Wait to be notified about new I/O results. |
269 ml.Wait(); | 260 ml.Wait(); |
270 } | 261 } |
271 } | 262 } |
272 | 263 |
273 | |
274 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) { | 264 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) { |
275 if (!Dart_IsNull(library) && !Dart_IsError(library)) { | 265 if (!Dart_IsNull(library) && !Dart_IsError(library)) { |
276 ASSERT(Dart_IsLibrary(library)); | 266 ASSERT(Dart_IsLibrary(library)); |
277 Dart_Handle res = Dart_LibraryHandleError(library, error); | 267 Dart_Handle res = Dart_LibraryHandleError(library, error); |
278 if (Dart_IsNull(res)) { | 268 if (Dart_IsNull(res)) { |
279 // Error was handled by library. | 269 // Error was handled by library. |
280 return true; | 270 return true; |
281 } | 271 } |
282 } | 272 } |
283 return false; | 273 return false; |
284 } | 274 } |
285 | 275 |
286 | |
287 static bool PathContainsSeparator(const char* path) { | 276 static bool PathContainsSeparator(const char* path) { |
288 return (strchr(path, '/') != NULL) || | 277 return (strchr(path, '/') != NULL) || |
289 ((strncmp(File::PathSeparator(), "/", 1) != 0) && | 278 ((strncmp(File::PathSeparator(), "/", 1) != 0) && |
290 (strstr(path, File::PathSeparator()) != NULL)); | 279 (strstr(path, File::PathSeparator()) != NULL)); |
291 } | 280 } |
292 | 281 |
293 | |
294 void Loader::AddDependencyLocked(Loader* loader, const char* resolved_uri) { | 282 void Loader::AddDependencyLocked(Loader* loader, const char* resolved_uri) { |
295 MallocGrowableArray<char*>* dependencies = | 283 MallocGrowableArray<char*>* dependencies = |
296 loader->isolate_data_->dependencies(); | 284 loader->isolate_data_->dependencies(); |
297 if (dependencies == NULL) { | 285 if (dependencies == NULL) { |
298 return; | 286 return; |
299 } | 287 } |
300 dependencies->Add(strdup(resolved_uri)); | 288 dependencies->Add(strdup(resolved_uri)); |
301 } | 289 } |
302 | 290 |
303 | |
304 void Loader::ResolveDependenciesAsFilePaths() { | 291 void Loader::ResolveDependenciesAsFilePaths() { |
305 IsolateData* isolate_data = | 292 IsolateData* isolate_data = |
306 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 293 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
307 ASSERT(isolate_data != NULL); | 294 ASSERT(isolate_data != NULL); |
308 MallocGrowableArray<char*>* dependencies = isolate_data->dependencies(); | 295 MallocGrowableArray<char*>* dependencies = isolate_data->dependencies(); |
309 if (dependencies == NULL) { | 296 if (dependencies == NULL) { |
310 return; | 297 return; |
311 } | 298 } |
312 | 299 |
313 for (intptr_t i = 0; i < dependencies->length(); i++) { | 300 for (intptr_t i = 0; i < dependencies->length(); i++) { |
(...skipping 10 matching lines...) Expand all Loading... |
324 return; | 311 return; |
325 } | 312 } |
326 | 313 |
327 (*dependencies)[i] = | 314 (*dependencies)[i] = |
328 StringUtils::StrNDup(reinterpret_cast<const char*>(scoped_file_path), | 315 StringUtils::StrNDup(reinterpret_cast<const char*>(scoped_file_path), |
329 scoped_file_path_length); | 316 scoped_file_path_length); |
330 free(resolved_uri); | 317 free(resolved_uri); |
331 } | 318 } |
332 } | 319 } |
333 | 320 |
334 | |
335 bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) { | 321 bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) { |
336 // We have to copy everything we care about out of |result| because after | 322 // We have to copy everything we care about out of |result| because after |
337 // dropping the lock below |result| may no longer valid. | 323 // dropping the lock below |result| may no longer valid. |
338 Dart_Handle uri = | 324 Dart_Handle uri = |
339 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); | 325 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); |
340 Dart_Handle resolved_uri = | 326 Dart_Handle resolved_uri = |
341 Dart_NewStringFromCString(reinterpret_cast<char*>(result->resolved_uri)); | 327 Dart_NewStringFromCString(reinterpret_cast<char*>(result->resolved_uri)); |
342 Dart_Handle library_uri = Dart_Null(); | 328 Dart_Handle library_uri = Dart_Null(); |
343 if (result->library_uri != NULL) { | 329 if (result->library_uri != NULL) { |
344 library_uri = | 330 library_uri = |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 if (Dart_IsError(dart_result)) { | 454 if (Dart_IsError(dart_result)) { |
469 // Remember the error if we encountered one. | 455 // Remember the error if we encountered one. |
470 loader->error_ = dart_result; | 456 loader->error_ = dart_result; |
471 return false; | 457 return false; |
472 } | 458 } |
473 } | 459 } |
474 | 460 |
475 return true; | 461 return true; |
476 } | 462 } |
477 | 463 |
478 | |
479 bool Loader::ProcessPayloadResultLocked(Loader* loader, | 464 bool Loader::ProcessPayloadResultLocked(Loader* loader, |
480 Loader::IOResult* result) { | 465 Loader::IOResult* result) { |
481 // A negative result tag indicates a loading error occurred in the service | 466 // A negative result tag indicates a loading error occurred in the service |
482 // isolate. The payload is a C string of the error message. | 467 // isolate. The payload is a C string of the error message. |
483 if (result->tag < 0) { | 468 if (result->tag < 0) { |
484 Dart_Handle error = | 469 Dart_Handle error = |
485 Dart_NewStringFromUTF8(result->payload, result->payload_length); | 470 Dart_NewStringFromUTF8(result->payload, result->payload_length); |
486 loader->error_ = Dart_NewUnhandledExceptionError(error); | 471 loader->error_ = Dart_NewUnhandledExceptionError(error); |
487 return false; | 472 return false; |
488 } | 473 } |
489 loader->payload_length_ = result->payload_length; | 474 loader->payload_length_ = result->payload_length; |
490 loader->payload_ = | 475 loader->payload_ = |
491 reinterpret_cast<uint8_t*>(::malloc(loader->payload_length_)); | 476 reinterpret_cast<uint8_t*>(::malloc(loader->payload_length_)); |
492 memmove(loader->payload_, result->payload, loader->payload_length_); | 477 memmove(loader->payload_, result->payload, loader->payload_length_); |
493 return true; | 478 return true; |
494 } | 479 } |
495 | 480 |
496 | |
497 bool Loader::ProcessQueueLocked(ProcessResult process_result) { | 481 bool Loader::ProcessQueueLocked(ProcessResult process_result) { |
498 bool hit_error = false; | 482 bool hit_error = false; |
499 for (intptr_t i = 0; i < results_length(); i++) { | 483 for (intptr_t i = 0; i < results_length(); i++) { |
500 if (!hit_error) { | 484 if (!hit_error) { |
501 hit_error = !(*process_result)(this, &results_[i]); | 485 hit_error = !(*process_result)(this, &results_[i]); |
502 } | 486 } |
503 pending_operations_--; | 487 pending_operations_--; |
504 ASSERT(hit_error || (pending_operations_ >= 0)); | 488 ASSERT(hit_error || (pending_operations_ >= 0)); |
505 results_[i].Cleanup(); | 489 results_[i].Cleanup(); |
506 } | 490 } |
507 results_length_ = 0; | 491 results_length_ = 0; |
508 return !hit_error; | 492 return !hit_error; |
509 } | 493 } |
510 | 494 |
511 | |
512 void Loader::InitForSnapshot(const char* snapshot_uri) { | 495 void Loader::InitForSnapshot(const char* snapshot_uri) { |
513 IsolateData* isolate_data = | 496 IsolateData* isolate_data = |
514 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 497 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
515 ASSERT(isolate_data != NULL); | 498 ASSERT(isolate_data != NULL); |
516 ASSERT(!isolate_data->HasLoader()); | 499 ASSERT(!isolate_data->HasLoader()); |
517 // Setup a loader. The constructor does a bunch of leg work. | 500 // Setup a loader. The constructor does a bunch of leg work. |
518 Loader* loader = new Loader(isolate_data); | 501 Loader* loader = new Loader(isolate_data); |
519 // Send the init message. | 502 // Send the init message. |
520 loader->Init(isolate_data->package_root, isolate_data->packages_file, | 503 loader->Init(isolate_data->package_root, isolate_data->packages_file, |
521 DartUtils::original_working_directory, snapshot_uri); | 504 DartUtils::original_working_directory, snapshot_uri); |
522 // Destroy the loader. The destructor does a bunch of leg work. | 505 // Destroy the loader. The destructor does a bunch of leg work. |
523 delete loader; | 506 delete loader; |
524 } | 507 } |
525 | 508 |
526 | |
527 #define RETURN_ERROR(result) \ | 509 #define RETURN_ERROR(result) \ |
528 if (Dart_IsError(result)) return result; | 510 if (Dart_IsError(result)) return result; |
529 | 511 |
530 Dart_Handle Loader::ReloadNativeExtensions() { | 512 Dart_Handle Loader::ReloadNativeExtensions() { |
531 Dart_Handle scheme = | 513 Dart_Handle scheme = |
532 Dart_NewStringFromCString(DartUtils::kDartExtensionScheme); | 514 Dart_NewStringFromCString(DartUtils::kDartExtensionScheme); |
533 Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme); | 515 Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme); |
534 RETURN_ERROR(extension_imports); | 516 RETURN_ERROR(extension_imports); |
535 | 517 |
536 intptr_t length = -1; | 518 intptr_t length = -1; |
(...skipping 24 matching lines...) Expand all Loading... |
561 } | 543 } |
562 | 544 |
563 result = Extensions::LoadExtension(lib_path, extension_path, importer); | 545 result = Extensions::LoadExtension(lib_path, extension_path, importer); |
564 free(lib_path); | 546 free(lib_path); |
565 RETURN_ERROR(result); | 547 RETURN_ERROR(result); |
566 } | 548 } |
567 | 549 |
568 return Dart_True(); | 550 return Dart_True(); |
569 } | 551 } |
570 | 552 |
571 | |
572 Dart_Handle Loader::SendAndProcessReply(intptr_t tag, | 553 Dart_Handle Loader::SendAndProcessReply(intptr_t tag, |
573 Dart_Handle url, | 554 Dart_Handle url, |
574 uint8_t** payload, | 555 uint8_t** payload, |
575 intptr_t* payload_length) { | 556 intptr_t* payload_length) { |
576 IsolateData* isolate_data = | 557 IsolateData* isolate_data = |
577 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 558 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
578 ASSERT(isolate_data != NULL); | 559 ASSERT(isolate_data != NULL); |
579 ASSERT(!isolate_data->HasLoader()); | 560 ASSERT(!isolate_data->HasLoader()); |
580 Loader* loader = NULL; | 561 Loader* loader = NULL; |
581 | 562 |
(...skipping 20 matching lines...) Expand all Loading... |
602 // Destroy the loader. The destructor does a bunch of leg work. | 583 // Destroy the loader. The destructor does a bunch of leg work. |
603 delete loader; | 584 delete loader; |
604 | 585 |
605 // An error occurred during loading. | 586 // An error occurred during loading. |
606 if (!Dart_IsNull(error)) { | 587 if (!Dart_IsNull(error)) { |
607 return error; | 588 return error; |
608 } | 589 } |
609 return Dart_Null(); | 590 return Dart_Null(); |
610 } | 591 } |
611 | 592 |
612 | |
613 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, | 593 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, |
614 uint8_t** payload, | 594 uint8_t** payload, |
615 intptr_t* payload_length) { | 595 intptr_t* payload_length) { |
616 return SendAndProcessReply(Dart_kScriptTag, url, payload, payload_length); | 596 return SendAndProcessReply(Dart_kScriptTag, url, payload, payload_length); |
617 } | 597 } |
618 | 598 |
619 | |
620 Dart_Handle Loader::ResolveAsFilePath(Dart_Handle url, | 599 Dart_Handle Loader::ResolveAsFilePath(Dart_Handle url, |
621 uint8_t** payload, | 600 uint8_t** payload, |
622 intptr_t* payload_length) { | 601 intptr_t* payload_length) { |
623 return SendAndProcessReply(_Dart_kResolveAsFilePath, url, payload, | 602 return SendAndProcessReply(_Dart_kResolveAsFilePath, url, payload, |
624 payload_length); | 603 payload_length); |
625 } | 604 } |
626 | 605 |
627 #if defined(DART_PRECOMPILED_RUNTIME) | 606 #if defined(DART_PRECOMPILED_RUNTIME) |
628 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, | 607 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, |
629 Dart_Handle library, | 608 Dart_Handle library, |
630 Dart_Handle url) { | 609 Dart_Handle url) { |
631 return Dart_Null(); | 610 return Dart_Null(); |
632 } | 611 } |
633 | 612 |
634 | |
635 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, | 613 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, |
636 Dart_Handle library, | 614 Dart_Handle library, |
637 Dart_Handle url, | 615 Dart_Handle url, |
638 const char* library_url_string, | 616 const char* library_url_string, |
639 const char* url_string) { | 617 const char* url_string) { |
640 return Dart_Null(); | 618 return Dart_Null(); |
641 } | 619 } |
642 #else | 620 #else |
643 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, | 621 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, |
644 Dart_Handle library, | 622 Dart_Handle library, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 } | 720 } |
743 ASSERT(loader != NULL); | 721 ASSERT(loader != NULL); |
744 ASSERT(isolate_data->HasLoader()); | 722 ASSERT(isolate_data->HasLoader()); |
745 | 723 |
746 if (DartUtils::IsDartExtensionSchemeURL(url_string)) { | 724 if (DartUtils::IsDartExtensionSchemeURL(url_string)) { |
747 loader->SendImportExtensionRequest(url, Dart_LibraryUrl(library)); | 725 loader->SendImportExtensionRequest(url, Dart_LibraryUrl(library)); |
748 } else { | 726 } else { |
749 if (Dart_KernelIsolateIsRunning()) { | 727 if (Dart_KernelIsolateIsRunning()) { |
750 loader->SendKernelRequest(tag, url); | 728 loader->SendKernelRequest(tag, url); |
751 } else { | 729 } else { |
752 loader->SendRequest(tag, url, (library != Dart_Null()) | 730 loader->SendRequest( |
753 ? Dart_LibraryUrl(library) | 731 tag, url, |
754 : Dart_Null()); | 732 (library != Dart_Null()) ? Dart_LibraryUrl(library) : Dart_Null()); |
755 } | 733 } |
756 } | 734 } |
757 | 735 |
758 if (blocking_call) { | 736 if (blocking_call) { |
759 // The outer invocation of the tag handler will block here until all nested | 737 // The outer invocation of the tag handler will block here until all nested |
760 // invocations complete. | 738 // invocations complete. |
761 loader->BlockUntilComplete(ProcessResultLocked); | 739 loader->BlockUntilComplete(ProcessResultLocked); |
762 | 740 |
763 // Remember the error (if any). | 741 // Remember the error (if any). |
764 Dart_Handle error = loader->error(); | 742 Dart_Handle error = loader->error(); |
(...skipping 23 matching lines...) Expand all Loading... |
788 // Finalize loading. This will complete any futures for completed deferred | 766 // Finalize loading. This will complete any futures for completed deferred |
789 // loads. | 767 // loads. |
790 error = Dart_FinalizeLoading(true); | 768 error = Dart_FinalizeLoading(true); |
791 if (Dart_IsError(error)) { | 769 if (Dart_IsError(error)) { |
792 return error; | 770 return error; |
793 } | 771 } |
794 } | 772 } |
795 return Dart_Null(); | 773 return Dart_Null(); |
796 } | 774 } |
797 | 775 |
798 | |
799 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, | 776 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, |
800 Dart_Handle library, | 777 Dart_Handle library, |
801 Dart_Handle url, | 778 Dart_Handle url, |
802 const char* library_url_string, | 779 const char* library_url_string, |
803 const char* url_string) { | 780 const char* url_string) { |
804 // Handle canonicalization, 'import' and 'part' of 'dart:' libraries. | 781 // Handle canonicalization, 'import' and 'part' of 'dart:' libraries. |
805 if (tag == Dart_kCanonicalizeUrl) { | 782 if (tag == Dart_kCanonicalizeUrl) { |
806 // These will be handled internally. | 783 // These will be handled internally. |
807 return url; | 784 return url; |
808 } else if (tag == Dart_kImportTag) { | 785 } else if (tag == Dart_kImportTag) { |
(...skipping 23 matching lines...) Expand all Loading... |
832 free(part_uri); | 809 free(part_uri); |
833 return Dart_LoadSource(library, part_uri_obj, Dart_Null(), | 810 return Dart_LoadSource(library, part_uri_obj, Dart_Null(), |
834 Builtin::PartSource(id, url_string), 0, 0); | 811 Builtin::PartSource(id, url_string), 0, 0); |
835 } | 812 } |
836 // All cases should have been handled above. | 813 // All cases should have been handled above. |
837 UNREACHABLE(); | 814 UNREACHABLE(); |
838 return Dart_Null(); | 815 return Dart_Null(); |
839 } | 816 } |
840 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 817 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
841 | 818 |
842 | |
843 void Loader::InitOnce() { | 819 void Loader::InitOnce() { |
844 loader_infos_lock_ = new Mutex(); | 820 loader_infos_lock_ = new Mutex(); |
845 } | 821 } |
846 | 822 |
847 | |
848 Mutex* Loader::loader_infos_lock_; | 823 Mutex* Loader::loader_infos_lock_; |
849 Loader::LoaderInfo* Loader::loader_infos_ = NULL; | 824 Loader::LoaderInfo* Loader::loader_infos_ = NULL; |
850 intptr_t Loader::loader_infos_length_ = 0; | 825 intptr_t Loader::loader_infos_length_ = 0; |
851 intptr_t Loader::loader_infos_capacity_ = 0; | 826 intptr_t Loader::loader_infos_capacity_ = 0; |
852 | 827 |
853 | |
854 // Add a mapping from |port| to |isolate_data| (really the loader). When a | 828 // Add a mapping from |port| to |isolate_data| (really the loader). When a |
855 // native message arrives, we use this map to report the I/O result to the | 829 // native message arrives, we use this map to report the I/O result to the |
856 // correct loader. | 830 // correct loader. |
857 // This happens whenever an isolate begins loading. | 831 // This happens whenever an isolate begins loading. |
858 void Loader::AddLoader(Dart_Port port, IsolateData* isolate_data) { | 832 void Loader::AddLoader(Dart_Port port, IsolateData* isolate_data) { |
859 MutexLocker ml(loader_infos_lock_); | 833 MutexLocker ml(loader_infos_lock_); |
860 ASSERT(LoaderForLocked(port) == NULL); | 834 ASSERT(LoaderForLocked(port) == NULL); |
861 if (loader_infos_length_ == loader_infos_capacity_) { | 835 if (loader_infos_length_ == loader_infos_capacity_) { |
862 // Grow to an initial capacity or double in size. | 836 // Grow to an initial capacity or double in size. |
863 loader_infos_capacity_ = | 837 loader_infos_capacity_ = |
864 (loader_infos_capacity_ == 0) ? 4 : loader_infos_capacity_ * 2; | 838 (loader_infos_capacity_ == 0) ? 4 : loader_infos_capacity_ * 2; |
865 loader_infos_ = reinterpret_cast<Loader::LoaderInfo*>(realloc( | 839 loader_infos_ = reinterpret_cast<Loader::LoaderInfo*>(realloc( |
866 loader_infos_, sizeof(Loader::LoaderInfo) * loader_infos_capacity_)); | 840 loader_infos_, sizeof(Loader::LoaderInfo) * loader_infos_capacity_)); |
867 ASSERT(loader_infos_ != NULL); | 841 ASSERT(loader_infos_ != NULL); |
868 // Initialize new entries. | 842 // Initialize new entries. |
869 for (intptr_t i = loader_infos_length_; i < loader_infos_capacity_; i++) { | 843 for (intptr_t i = loader_infos_length_; i < loader_infos_capacity_; i++) { |
870 loader_infos_[i].port = ILLEGAL_PORT; | 844 loader_infos_[i].port = ILLEGAL_PORT; |
871 loader_infos_[i].isolate_data = NULL; | 845 loader_infos_[i].isolate_data = NULL; |
872 } | 846 } |
873 } | 847 } |
874 ASSERT(loader_infos_length_ < loader_infos_capacity_); | 848 ASSERT(loader_infos_length_ < loader_infos_capacity_); |
875 loader_infos_[loader_infos_length_].port = port; | 849 loader_infos_[loader_infos_length_].port = port; |
876 loader_infos_[loader_infos_length_].isolate_data = isolate_data; | 850 loader_infos_[loader_infos_length_].isolate_data = isolate_data; |
877 loader_infos_length_++; | 851 loader_infos_length_++; |
878 ASSERT(LoaderForLocked(port) != NULL); | 852 ASSERT(LoaderForLocked(port) != NULL); |
879 } | 853 } |
880 | 854 |
881 | |
882 // Remove |port| from the map. | 855 // Remove |port| from the map. |
883 // This happens once an isolate has finished loading. | 856 // This happens once an isolate has finished loading. |
884 void Loader::RemoveLoader(Dart_Port port) { | 857 void Loader::RemoveLoader(Dart_Port port) { |
885 MutexLocker ml(loader_infos_lock_); | 858 MutexLocker ml(loader_infos_lock_); |
886 const intptr_t index = LoaderIndexFor(port); | 859 const intptr_t index = LoaderIndexFor(port); |
887 ASSERT(index >= 0); | 860 ASSERT(index >= 0); |
888 const intptr_t last = loader_infos_length_ - 1; | 861 const intptr_t last = loader_infos_length_ - 1; |
889 ASSERT(last >= 0); | 862 ASSERT(last >= 0); |
890 if (index != last) { | 863 if (index != last) { |
891 // Swap with the tail. | 864 // Swap with the tail. |
892 loader_infos_[index] = loader_infos_[last]; | 865 loader_infos_[index] = loader_infos_[last]; |
893 } | 866 } |
894 loader_infos_length_--; | 867 loader_infos_length_--; |
895 } | 868 } |
896 | 869 |
897 | |
898 intptr_t Loader::LoaderIndexFor(Dart_Port port) { | 870 intptr_t Loader::LoaderIndexFor(Dart_Port port) { |
899 for (intptr_t i = 0; i < loader_infos_length_; i++) { | 871 for (intptr_t i = 0; i < loader_infos_length_; i++) { |
900 if (loader_infos_[i].port == port) { | 872 if (loader_infos_[i].port == port) { |
901 return i; | 873 return i; |
902 } | 874 } |
903 } | 875 } |
904 return -1; | 876 return -1; |
905 } | 877 } |
906 | 878 |
907 | |
908 Loader* Loader::LoaderForLocked(Dart_Port port) { | 879 Loader* Loader::LoaderForLocked(Dart_Port port) { |
909 intptr_t index = LoaderIndexFor(port); | 880 intptr_t index = LoaderIndexFor(port); |
910 if (index < 0) { | 881 if (index < 0) { |
911 return NULL; | 882 return NULL; |
912 } | 883 } |
913 return loader_infos_[index].isolate_data->loader(); | 884 return loader_infos_[index].isolate_data->loader(); |
914 } | 885 } |
915 | 886 |
916 | |
917 Loader* Loader::LoaderFor(Dart_Port port) { | 887 Loader* Loader::LoaderFor(Dart_Port port) { |
918 MutexLocker ml(loader_infos_lock_); | 888 MutexLocker ml(loader_infos_lock_); |
919 return LoaderForLocked(port); | 889 return LoaderForLocked(port); |
920 } | 890 } |
921 | 891 |
922 | |
923 void Loader::NativeMessageHandler(Dart_Port dest_port_id, | 892 void Loader::NativeMessageHandler(Dart_Port dest_port_id, |
924 Dart_CObject* message) { | 893 Dart_CObject* message) { |
925 MutexLocker ml(loader_infos_lock_); | 894 MutexLocker ml(loader_infos_lock_); |
926 Loader* loader = LoaderForLocked(dest_port_id); | 895 Loader* loader = LoaderForLocked(dest_port_id); |
927 if (loader == NULL) { | 896 if (loader == NULL) { |
928 return; | 897 return; |
929 } | 898 } |
930 loader->QueueMessage(message); | 899 loader->QueueMessage(message); |
931 } | 900 } |
932 | 901 |
933 } // namespace bin | 902 } // namespace bin |
934 } // namespace dart | 903 } // namespace dart |
OLD | NEW |