| 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 |