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" |
11 #include "bin/file.h" | 11 #include "bin/file.h" |
12 #include "bin/lockers.h" | 12 #include "bin/lockers.h" |
13 #include "bin/utils.h" | 13 #include "bin/utils.h" |
| 14 #include "include/dart_tools_api.h" |
14 | 15 |
15 namespace dart { | 16 namespace dart { |
16 namespace bin { | 17 namespace bin { |
17 | 18 |
18 // Development flag. | 19 // Development flag. |
19 static bool trace_loader = false; | 20 static bool trace_loader = false; |
20 // Keep in sync with loader.dart. | 21 // Keep in sync with loader.dart. |
21 static const intptr_t _Dart_kImportExtension = 9; | 22 static const intptr_t _Dart_kImportExtension = 9; |
22 | 23 |
23 Loader::Loader(IsolateData* isolate_data) | 24 Loader::Loader(IsolateData* isolate_data) |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 intptr_t tag = result->tag; | 347 intptr_t tag = result->tag; |
347 | 348 |
348 // No touching. | 349 // No touching. |
349 result = NULL; | 350 result = NULL; |
350 | 351 |
351 // We must drop the lock here because the tag handler may be recursively | 352 // We must drop the lock here because the tag handler may be recursively |
352 // invoked and it will attempt to acquire the lock to queue more work. | 353 // invoked and it will attempt to acquire the lock to queue more work. |
353 loader->monitor_->Exit(); | 354 loader->monitor_->Exit(); |
354 | 355 |
355 Dart_Handle dart_result = Dart_Null(); | 356 Dart_Handle dart_result = Dart_Null(); |
| 357 bool reload_extensions = false; |
356 | 358 |
357 switch (tag) { | 359 switch (tag) { |
358 case Dart_kImportTag: | 360 case Dart_kImportTag: |
359 dart_result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0); | 361 dart_result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0); |
360 break; | 362 break; |
361 case Dart_kSourceTag: { | 363 case Dart_kSourceTag: { |
362 ASSERT(library_uri != Dart_Null()); | 364 ASSERT(library_uri != Dart_Null()); |
363 Dart_Handle library = Dart_LookupLibrary(library_uri); | 365 Dart_Handle library = Dart_LookupLibrary(library_uri); |
364 ASSERT(!Dart_IsError(library)); | 366 ASSERT(!Dart_IsError(library)); |
365 dart_result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0); | 367 dart_result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0); |
366 } break; | 368 } break; |
367 case Dart_kScriptTag: | 369 case Dart_kScriptTag: |
368 if (payload_type == DartUtils::kSnapshotMagicNumber) { | 370 if (payload_type == DartUtils::kSnapshotMagicNumber) { |
369 dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length); | 371 dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length); |
| 372 reload_extensions = true; |
370 } else if (payload_type == DartUtils::kKernelMagicNumber) { | 373 } else if (payload_type == DartUtils::kKernelMagicNumber) { |
371 dart_result = Dart_LoadKernel(payload, payload_length); | 374 dart_result = Dart_LoadKernel(payload, payload_length); |
372 } else { | 375 } else { |
373 dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0); | 376 dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0); |
374 } | 377 } |
375 break; | 378 break; |
376 default: | 379 default: |
377 UNREACHABLE(); | 380 UNREACHABLE(); |
378 } | 381 } |
379 | 382 |
380 // Re-acquire the lock before exiting the function (it was held before entry), | 383 // Re-acquire the lock before exiting the function (it was held before entry), |
381 loader->monitor_->Enter(); | 384 loader->monitor_->Enter(); |
382 if (Dart_IsError(dart_result)) { | 385 if (Dart_IsError(dart_result)) { |
383 // Remember the error if we encountered one. | 386 // Remember the error if we encountered one. |
384 loader->error_ = dart_result; | 387 loader->error_ = dart_result; |
385 return false; | 388 return false; |
386 } | 389 } |
387 | 390 |
| 391 if (reload_extensions) { |
| 392 dart_result = ReloadNativeExtensions(); |
| 393 if (Dart_IsError(dart_result)) { |
| 394 // Remember the error if we encountered one. |
| 395 loader->error_ = dart_result; |
| 396 return false; |
| 397 } |
| 398 } |
| 399 |
388 return true; | 400 return true; |
389 } | 401 } |
390 | 402 |
391 | 403 |
392 bool Loader::ProcessUrlLoadResultLocked(Loader* loader, | 404 bool Loader::ProcessUrlLoadResultLocked(Loader* loader, |
393 Loader::IOResult* result) { | 405 Loader::IOResult* result) { |
394 // A negative result tag indicates a loading error occurred in the service | 406 // A negative result tag indicates a loading error occurred in the service |
395 // isolate. The payload is a C string of the error message. | 407 // isolate. The payload is a C string of the error message. |
396 if (result->tag < 0) { | 408 if (result->tag < 0) { |
397 Dart_Handle error = | 409 Dart_Handle error = |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // Setup a loader. The constructor does a bunch of leg work. | 442 // Setup a loader. The constructor does a bunch of leg work. |
431 Loader* loader = new Loader(isolate_data); | 443 Loader* loader = new Loader(isolate_data); |
432 // Send the init message. | 444 // Send the init message. |
433 loader->Init(isolate_data->package_root, isolate_data->packages_file, | 445 loader->Init(isolate_data->package_root, isolate_data->packages_file, |
434 DartUtils::original_working_directory, snapshot_uri); | 446 DartUtils::original_working_directory, snapshot_uri); |
435 // Destroy the loader. The destructor does a bunch of leg work. | 447 // Destroy the loader. The destructor does a bunch of leg work. |
436 delete loader; | 448 delete loader; |
437 } | 449 } |
438 | 450 |
439 | 451 |
| 452 #define RETURN_ERROR(result) \ |
| 453 if (Dart_IsError(result)) return result; |
| 454 |
| 455 Dart_Handle Loader::ReloadNativeExtensions() { |
| 456 Dart_Handle scheme = |
| 457 Dart_NewStringFromCString(DartUtils::kDartExtensionScheme); |
| 458 Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme); |
| 459 RETURN_ERROR(extension_imports); |
| 460 |
| 461 intptr_t length = -1; |
| 462 Dart_Handle result = Dart_ListLength(extension_imports, &length); |
| 463 RETURN_ERROR(result); |
| 464 Dart_Handle* import_handles = reinterpret_cast<Dart_Handle*>( |
| 465 Dart_ScopeAllocate(sizeof(Dart_Handle) * length)); |
| 466 result = Dart_ListGetRange(extension_imports, 0, length, import_handles); |
| 467 RETURN_ERROR(result); |
| 468 for (intptr_t i = 0; i < length; i += 2) { |
| 469 Dart_Handle importer = import_handles[i]; |
| 470 Dart_Handle importee = import_handles[i + 1]; |
| 471 |
| 472 const char* extension_uri = NULL; |
| 473 result = Dart_StringToCString(Dart_LibraryUrl(importee), &extension_uri); |
| 474 RETURN_ERROR(result); |
| 475 const char* extension_path = DartUtils::RemoveScheme(extension_uri); |
| 476 |
| 477 const char* lib_uri = NULL; |
| 478 result = Dart_StringToCString(Dart_LibraryUrl(importer), &lib_uri); |
| 479 RETURN_ERROR(result); |
| 480 |
| 481 char* lib_path = NULL; |
| 482 if (strncmp(lib_uri, "file://", 7) == 0) { |
| 483 lib_path = DartUtils::DirName(DartUtils::RemoveScheme(lib_uri)); |
| 484 } else { |
| 485 lib_path = strdup(lib_uri); |
| 486 } |
| 487 |
| 488 result = Extensions::LoadExtension(lib_path, extension_path, importer); |
| 489 free(lib_path); |
| 490 RETURN_ERROR(result); |
| 491 } |
| 492 |
| 493 return Dart_True(); |
| 494 } |
| 495 |
| 496 |
440 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, | 497 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, |
441 uint8_t** payload, | 498 uint8_t** payload, |
442 intptr_t* payload_length) { | 499 intptr_t* payload_length) { |
443 IsolateData* isolate_data = | 500 IsolateData* isolate_data = |
444 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 501 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
445 ASSERT(isolate_data != NULL); | 502 ASSERT(isolate_data != NULL); |
446 ASSERT(!isolate_data->HasLoader()); | 503 ASSERT(!isolate_data->HasLoader()); |
447 Loader* loader = NULL; | 504 Loader* loader = NULL; |
448 | 505 |
449 // Setup the loader. The constructor does a bunch of leg work. | 506 // Setup the loader. The constructor does a bunch of leg work. |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 MutexLocker ml(loader_infos_lock_); | 795 MutexLocker ml(loader_infos_lock_); |
739 Loader* loader = LoaderForLocked(dest_port_id); | 796 Loader* loader = LoaderForLocked(dest_port_id); |
740 if (loader == NULL) { | 797 if (loader == NULL) { |
741 return; | 798 return; |
742 } | 799 } |
743 loader->QueueMessage(message); | 800 loader->QueueMessage(message); |
744 } | 801 } |
745 | 802 |
746 } // namespace bin | 803 } // namespace bin |
747 } // namespace dart | 804 } // namespace dart |
OLD | NEW |