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 | 5 |
6 #include "bin/loader.h" | 6 #include "bin/loader.h" |
7 | 7 |
8 #include "bin/builtin.h" | 8 #include "bin/builtin.h" |
9 #include "bin/dartutils.h" | 9 #include "bin/dartutils.h" |
10 #include "bin/extensions.h" | 10 #include "bin/extensions.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 if (pending_operations_ == 0) { | 205 if (pending_operations_ == 0) { |
206 break; | 206 break; |
207 } | 207 } |
208 | 208 |
209 // Wait to be notified about new I/O results. | 209 // Wait to be notified about new I/O results. |
210 ml.Wait(); | 210 ml.Wait(); |
211 } | 211 } |
212 } | 212 } |
213 | 213 |
214 | 214 |
| 215 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) { |
| 216 if (!Dart_IsNull(library) && !Dart_IsError(library)) { |
| 217 ASSERT(Dart_IsLibrary(library)); |
| 218 Dart_Handle res = Dart_LibraryHandleError(library, error); |
| 219 if (Dart_IsNull(res)) { |
| 220 // Error was handled by library. |
| 221 return true; |
| 222 } |
| 223 } |
| 224 return false; |
| 225 } |
| 226 |
| 227 |
215 bool Loader::ProcessResultLocked(Loader::IOResult* result) { | 228 bool Loader::ProcessResultLocked(Loader::IOResult* result) { |
216 // A negative result tag indicates a loading error occurred in the service | |
217 // isolate. The payload is a C string of the error message. | |
218 if (result->tag < 0) { | |
219 error_ = | |
220 Dart_NewUnhandledExceptionError( | |
221 Dart_NewStringFromUTF8(result->payload, | |
222 result->payload_length)); | |
223 | |
224 return false; | |
225 } | |
226 | |
227 // We have to copy everything we care about out of |result| because after | 229 // We have to copy everything we care about out of |result| because after |
228 // dropping the lock below |result| may no longer valid. | 230 // dropping the lock below |result| may no longer valid. |
229 Dart_Handle uri = | 231 Dart_Handle uri = |
230 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); | 232 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); |
231 Dart_Handle library_uri = Dart_Null(); | 233 Dart_Handle library_uri = Dart_Null(); |
232 if (result->library_uri != NULL) { | 234 if (result->library_uri != NULL) { |
233 library_uri = | 235 library_uri = |
234 Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri)); | 236 Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri)); |
235 } | 237 } |
| 238 |
| 239 // A negative result tag indicates a loading error occurred in the service |
| 240 // isolate. The payload is a C string of the error message. |
| 241 if (result->tag < 0) { |
| 242 Dart_Handle library = Dart_LookupLibrary(uri); |
| 243 Dart_Handle error = Dart_NewStringFromUTF8(result->payload, |
| 244 result->payload_length); |
| 245 // If a library with the given uri exists, give it a chance to handle |
| 246 // the error. If the load requests stems from a deferred library load, |
| 247 // an IO error is not fatal. |
| 248 if (LibraryHandleError(library, error)) { |
| 249 return true; |
| 250 } |
| 251 // Fall through |
| 252 error_ = Dart_NewUnhandledExceptionError(error); |
| 253 return false; |
| 254 } |
| 255 |
| 256 |
236 // Check for payload and load accordingly. | 257 // Check for payload and load accordingly. |
237 bool is_snapshot = false; | 258 bool is_snapshot = false; |
238 const uint8_t* payload = result->payload; | 259 const uint8_t* payload = result->payload; |
239 intptr_t payload_length = result->payload_length; | 260 intptr_t payload_length = result->payload_length; |
240 payload = | 261 payload = |
241 DartUtils::SniffForMagicNumber(payload, | 262 DartUtils::SniffForMagicNumber(payload, |
242 &payload_length, | 263 &payload_length, |
243 &is_snapshot); | 264 &is_snapshot); |
244 Dart_Handle source = Dart_Null(); | 265 Dart_Handle source = Dart_Null(); |
245 if (!is_snapshot) { | 266 if (!is_snapshot) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 416 |
396 IsolateData* isolate_data = | 417 IsolateData* isolate_data = |
397 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 418 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
398 ASSERT(isolate_data != NULL); | 419 ASSERT(isolate_data != NULL); |
399 | 420 |
400 // Grab this isolate's loader. | 421 // Grab this isolate's loader. |
401 Loader* loader = NULL; | 422 Loader* loader = NULL; |
402 | 423 |
403 // The outer invocation of the tag handler for this isolate. We make the outer | 424 // The outer invocation of the tag handler for this isolate. We make the outer |
404 // invocation block and allow any nested invocations to operate in parallel. | 425 // invocation block and allow any nested invocations to operate in parallel. |
405 bool blocking_call = !isolate_data->HasLoader(); | 426 const bool blocking_call = !isolate_data->HasLoader(); |
406 | 427 |
| 428 // If we are the outer invocation of the tag handler and the tag is an import |
| 429 // this means that we are starting a deferred library load. |
| 430 const bool is_deferred_import = blocking_call && (tag == Dart_kImportTag); |
407 if (!isolate_data->HasLoader()) { | 431 if (!isolate_data->HasLoader()) { |
408 // The isolate doesn't have a loader -- this is the outer invocation which | 432 // The isolate doesn't have a loader -- this is the outer invocation which |
409 // will block. | 433 // will block. |
410 | 434 |
411 // Setup the loader. The constructor does a bunch of leg work. | 435 // Setup the loader. The constructor does a bunch of leg work. |
412 loader = new Loader(isolate_data); | 436 loader = new Loader(isolate_data); |
413 loader->Init(isolate_data->package_root, | 437 loader->Init(isolate_data->package_root, |
414 isolate_data->packages_file, | 438 isolate_data->packages_file, |
415 DartUtils::original_working_directory, | 439 DartUtils::original_working_directory, |
416 (tag == Dart_kScriptTag) ? url_string : NULL); | 440 (tag == Dart_kScriptTag) ? url_string : NULL); |
(...skipping 16 matching lines...) Expand all Loading... |
433 // The outer invocation of the tag handler will block here until all nested | 457 // The outer invocation of the tag handler will block here until all nested |
434 // invocations complete. | 458 // invocations complete. |
435 loader->BlockUntilComplete(); | 459 loader->BlockUntilComplete(); |
436 | 460 |
437 // Remember the error (if any). | 461 // Remember the error (if any). |
438 Dart_Handle error = loader->error(); | 462 Dart_Handle error = loader->error(); |
439 // Destroy the loader. The destructor does a bunch of leg work. | 463 // Destroy the loader. The destructor does a bunch of leg work. |
440 delete loader; | 464 delete loader; |
441 | 465 |
442 // An error occurred during loading. | 466 // An error occurred during loading. |
443 if (Dart_IsError(error)) { | 467 if (!Dart_IsNull(error)) { |
444 return error; | 468 if (false && is_deferred_import) { |
| 469 // This blocks handles transitive load errors caused by a deferred |
| 470 // import. Non-transitive load errors are handled above (see callers of |
| 471 // |LibraryHandleError|). To handle the transitive case, we give the |
| 472 // originating deferred library an opportunity to handle it. |
| 473 Dart_Handle deferred_library = Dart_LookupLibrary(url); |
| 474 if (!LibraryHandleError(deferred_library, error)) { |
| 475 // Library did not handle it, return to caller as an unhandled |
| 476 // exception. |
| 477 return Dart_NewUnhandledExceptionError(error); |
| 478 } |
| 479 } else { |
| 480 // We got an error during loading but we aren't loading a deferred |
| 481 // library, return the error to the caller. |
| 482 return error; |
| 483 } |
445 } | 484 } |
446 | 485 |
447 // Finalize loading. This will complete any futures for completed deferred | 486 // Finalize loading. This will complete any futures for completed deferred |
448 // loads. | 487 // loads. |
449 error = Dart_FinalizeLoading(true); | 488 error = Dart_FinalizeLoading(true); |
450 if (Dart_IsError(error)) { | 489 if (Dart_IsError(error)) { |
451 return error; | 490 return error; |
452 } | 491 } |
453 } | 492 } |
454 return Dart_Null(); | 493 return Dart_Null(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 MutexLocker ml(&loader_infos_lock_); | 615 MutexLocker ml(&loader_infos_lock_); |
577 Loader* loader = LoaderForLocked(dest_port_id); | 616 Loader* loader = LoaderForLocked(dest_port_id); |
578 if (loader == NULL) { | 617 if (loader == NULL) { |
579 return; | 618 return; |
580 } | 619 } |
581 loader->QueueMessage(message); | 620 loader->QueueMessage(message); |
582 } | 621 } |
583 | 622 |
584 } // namespace bin | 623 } // namespace bin |
585 } // namespace dart | 624 } // namespace dart |
OLD | NEW |