| 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 "bin/dartutils.h" | 5 #include "bin/dartutils.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
| 9 | 9 |
| 10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 236 |
| 237 // TODO(iposva): Allocate from the zone instead of leaking error string | 237 // TODO(iposva): Allocate from the zone instead of leaking error string |
| 238 // here. On the other hand the binary is about to exit anyway. | 238 // here. On the other hand the binary is about to exit anyway. |
| 239 #define SET_ERROR_MSG(error_msg, format, ...) \ | 239 #define SET_ERROR_MSG(error_msg, format, ...) \ |
| 240 intptr_t len = snprintf(NULL, 0, format, __VA_ARGS__); \ | 240 intptr_t len = snprintf(NULL, 0, format, __VA_ARGS__); \ |
| 241 char* msg = reinterpret_cast<char*>(malloc(len + 1)); \ | 241 char* msg = reinterpret_cast<char*>(malloc(len + 1)); \ |
| 242 snprintf(msg, len + 1, format, __VA_ARGS__); \ | 242 snprintf(msg, len + 1, format, __VA_ARGS__); \ |
| 243 *error_msg = msg | 243 *error_msg = msg |
| 244 | 244 |
| 245 | 245 |
| 246 Dart_Handle MakeHttpRequest(Dart_Handle uri, Dart_Handle builtin_lib, | |
| 247 uint8_t** buffer, intptr_t* buffer_len) { | |
| 248 const intptr_t HttpResponseCodeOK = 200; | |
| 249 ASSERT(buffer != NULL); | |
| 250 ASSERT(buffer_len != NULL); | |
| 251 ASSERT(!Dart_HasLivePorts()); | |
| 252 | |
| 253 // MakeHttpRequest uses the event loop (Dart_RunLoop) to handle the | |
| 254 // asynchronous request. This interferes with the use of Dart_RunLoop | |
| 255 // for asynchronous loading. | |
| 256 ASSERT(!Dart_IsVMFlagSet("load_async")); | |
| 257 | |
| 258 SingleArgDart_Invoke(builtin_lib, "_makeHttpRequest", uri); | |
| 259 // Run until all ports to isolate are closed. | |
| 260 Dart_Handle result = Dart_RunLoop(); | |
| 261 if (Dart_IsError(result)) { | |
| 262 return result; | |
| 263 } | |
| 264 result = Dart_Invoke(builtin_lib, | |
| 265 DartUtils::NewString("_getHttpRequestResponseCode"), | |
| 266 0, | |
| 267 NULL); | |
| 268 if (Dart_IsError(result)) { | |
| 269 return result; | |
| 270 } | |
| 271 int64_t responseCode = DartUtils::GetIntegerValue(result); | |
| 272 if (responseCode != HttpResponseCodeOK) { | |
| 273 // Return error. | |
| 274 Dart_Handle responseStatus = | |
| 275 Dart_Invoke(builtin_lib, | |
| 276 DartUtils::NewString("_getHttpRequestStatusString"), | |
| 277 0, | |
| 278 NULL); | |
| 279 if (Dart_IsError(responseStatus)) { | |
| 280 return responseStatus; | |
| 281 } | |
| 282 if (Dart_IsNull(responseStatus)) { | |
| 283 return Dart_NewApiError("HTTP error."); | |
| 284 } | |
| 285 return Dart_NewApiError(DartUtils::GetStringValue(responseStatus)); | |
| 286 } | |
| 287 Dart_Handle response = | |
| 288 Dart_Invoke(builtin_lib, DartUtils::NewString("_getHttpRequestResponse"), | |
| 289 0, NULL); | |
| 290 if (Dart_IsError(response)) { | |
| 291 return response; | |
| 292 } | |
| 293 if (Dart_IsString(response)) { | |
| 294 // Received response as string. | |
| 295 uint8_t* responseString = NULL; | |
| 296 intptr_t responseStringLength; | |
| 297 Dart_Handle r = Dart_StringToUTF8(response, &responseString, | |
| 298 &responseStringLength); | |
| 299 if (Dart_IsError(r)) { | |
| 300 *buffer = NULL; | |
| 301 *buffer_len = 0; | |
| 302 return r; | |
| 303 } | |
| 304 // Get payload as bytes. | |
| 305 *buffer_len = responseStringLength; | |
| 306 *buffer = reinterpret_cast<uint8_t*>(malloc(responseStringLength)); | |
| 307 memmove(*buffer, responseString, responseStringLength); | |
| 308 } else { | |
| 309 // Received response as list of bytes. | |
| 310 ASSERT(Dart_IsList(response)); | |
| 311 // Query list length. | |
| 312 result = Dart_ListLength(response, buffer_len); | |
| 313 if (Dart_IsError(result)) { | |
| 314 *buffer_len = 0; | |
| 315 *buffer = NULL; | |
| 316 return result; | |
| 317 } | |
| 318 // Get payload as bytes. | |
| 319 *buffer = reinterpret_cast<uint8_t*>(malloc(*buffer_len)); | |
| 320 result = Dart_ListGetAsBytes(response, 0, *buffer, *buffer_len); | |
| 321 if (Dart_IsError(result)) { | |
| 322 free(*buffer); | |
| 323 *buffer_len = 0; | |
| 324 *buffer = NULL; | |
| 325 return result; | |
| 326 } | |
| 327 } | |
| 328 return result; | |
| 329 } | |
| 330 | |
| 331 | |
| 332 Dart_Handle DartUtils::ReadStringFromHttp(const char* script_uri) { | |
| 333 Dart_Handle uri = NewString(script_uri); | |
| 334 if (Dart_IsError(uri)) { | |
| 335 return uri; | |
| 336 } | |
| 337 Dart_Handle builtin_lib = | |
| 338 Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); | |
| 339 uint8_t* buffer; | |
| 340 intptr_t bufferLen; | |
| 341 Dart_Handle result = MakeHttpRequest(uri, builtin_lib, &buffer, &bufferLen); | |
| 342 if (Dart_IsError(result)) { | |
| 343 return result; | |
| 344 } | |
| 345 Dart_Handle str = Dart_NewStringFromUTF8(buffer, | |
| 346 bufferLen); | |
| 347 free(buffer); | |
| 348 return str; | |
| 349 } | |
| 350 | |
| 351 | |
| 352 static const uint8_t* ReadFileFully(const char* filename, | 246 static const uint8_t* ReadFileFully(const char* filename, |
| 353 intptr_t* file_len, | 247 intptr_t* file_len, |
| 354 const char** error_msg) { | 248 const char** error_msg) { |
| 355 *file_len = -1; | 249 *file_len = -1; |
| 356 void* stream = DartUtils::OpenFile(filename, false); | 250 void* stream = DartUtils::OpenFile(filename, false); |
| 357 if (stream == NULL) { | 251 if (stream == NULL) { |
| 358 SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename); | 252 SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename); |
| 359 return NULL; | 253 return NULL; |
| 360 } | 254 } |
| 361 const uint8_t* text_buffer = NULL; | 255 const uint8_t* text_buffer = NULL; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 Dart_Handle builtin_lib) { | 323 Dart_Handle builtin_lib) { |
| 430 const int kNumArgs = 2; | 324 const int kNumArgs = 2; |
| 431 Dart_Handle dart_args[kNumArgs]; | 325 Dart_Handle dart_args[kNumArgs]; |
| 432 dart_args[0] = library_url; | 326 dart_args[0] = library_url; |
| 433 dart_args[1] = url; | 327 dart_args[1] = url; |
| 434 return Dart_Invoke( | 328 return Dart_Invoke( |
| 435 builtin_lib, NewString("_resolveUri"), kNumArgs, dart_args); | 329 builtin_lib, NewString("_resolveUri"), kNumArgs, dart_args); |
| 436 } | 330 } |
| 437 | 331 |
| 438 | 332 |
| 333 static Dart_Handle LoadDataAsync_Invoke(Dart_Handle tag, |
| 334 Dart_Handle url, |
| 335 Dart_Handle library_url, |
| 336 Dart_Handle builtin_lib) { |
| 337 const int kNumArgs = 3; |
| 338 Dart_Handle dart_args[kNumArgs]; |
| 339 dart_args[0] = tag; |
| 340 dart_args[1] = url; |
| 341 dart_args[2] = library_url; |
| 342 return Dart_Invoke(builtin_lib, |
| 343 DartUtils::NewString("_loadDataAsync"), |
| 344 kNumArgs, |
| 345 dart_args); |
| 346 } |
| 347 |
| 348 |
| 439 Dart_Handle DartUtils::LibraryTagHandler(Dart_LibraryTag tag, | 349 Dart_Handle DartUtils::LibraryTagHandler(Dart_LibraryTag tag, |
| 440 Dart_Handle library, | 350 Dart_Handle library, |
| 441 Dart_Handle url) { | 351 Dart_Handle url) { |
| 442 if (!Dart_IsLibrary(library)) { | 352 if (!Dart_IsLibrary(library)) { |
| 443 return Dart_NewApiError("not a library"); | 353 return Dart_NewApiError("not a library"); |
| 444 } | 354 } |
| 445 if (!Dart_IsString(url)) { | 355 if (!Dart_IsString(url)) { |
| 446 return Dart_NewApiError("url is not a string"); | 356 return Dart_NewApiError("url is not a string"); |
| 447 } | 357 } |
| 448 const char* url_string = NULL; | 358 const char* url_string = NULL; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 Dart_StringToCString(Dart_ListGetAt(path_parts, 0), &extension_directory); | 436 Dart_StringToCString(Dart_ListGetAt(path_parts, 0), &extension_directory); |
| 527 const char* extension_filename = NULL; | 437 const char* extension_filename = NULL; |
| 528 Dart_StringToCString(Dart_ListGetAt(path_parts, 1), &extension_filename); | 438 Dart_StringToCString(Dart_ListGetAt(path_parts, 1), &extension_filename); |
| 529 const char* extension_name = NULL; | 439 const char* extension_name = NULL; |
| 530 Dart_StringToCString(Dart_ListGetAt(path_parts, 2), &extension_name); | 440 Dart_StringToCString(Dart_ListGetAt(path_parts, 2), &extension_name); |
| 531 | 441 |
| 532 return Extensions::LoadExtension(extension_directory, | 442 return Extensions::LoadExtension(extension_directory, |
| 533 extension_filename, | 443 extension_filename, |
| 534 extension_name, | 444 extension_name, |
| 535 library); | 445 library); |
| 536 } else { | 446 } |
| 537 // Handle 'import' or 'part' requests for all other URIs. | |
| 538 | 447 |
| 539 if (Dart_IsVMFlagSet("load_async")) { | 448 // Handle 'import' or 'part' requests for all other URIs. Call dart code to |
| 540 // Call dart code to read the source code asynchronously. | 449 // read the source code asynchronously. |
| 541 const int kNumArgs = 3; | 450 return LoadDataAsync_Invoke(Dart_NewInteger(tag), |
| 542 Dart_Handle dart_args[kNumArgs]; | 451 url, |
| 543 dart_args[0] = Dart_NewInteger(tag); | 452 library_url, |
| 544 dart_args[1] = url; | 453 builtin_lib); |
| 545 dart_args[2] = library_url; | |
| 546 return Dart_Invoke(builtin_lib, | |
| 547 NewString("_loadSourceAsync"), | |
| 548 kNumArgs, | |
| 549 dart_args); | |
| 550 } | |
| 551 | |
| 552 // Get the file path out of the url. | |
| 553 Dart_Handle file_path = DartUtils::FilePathFromUri(url, builtin_lib); | |
| 554 if (Dart_IsError(file_path)) { | |
| 555 return file_path; | |
| 556 } | |
| 557 const char* final_path = NULL; | |
| 558 Dart_StringToCString(file_path, &final_path); | |
| 559 result = DartUtils::LoadSource(library, url, tag, final_path); | |
| 560 return result; | |
| 561 } | |
| 562 } | 454 } |
| 563 | 455 |
| 564 | 456 |
| 565 const uint8_t* DartUtils::SniffForMagicNumber(const uint8_t* text_buffer, | 457 const uint8_t* DartUtils::SniffForMagicNumber(const uint8_t* text_buffer, |
| 566 intptr_t* buffer_len, | 458 intptr_t* buffer_len, |
| 567 bool* is_snapshot) { | 459 bool* is_snapshot) { |
| 568 intptr_t len = sizeof(magic_number); | 460 intptr_t len = sizeof(magic_number); |
| 569 for (intptr_t i = 0; i < len; i++) { | 461 for (intptr_t i = 0; i < len; i++) { |
| 570 if (text_buffer[i] != magic_number[i]) { | 462 if (text_buffer[i] != magic_number[i]) { |
| 571 *is_snapshot = false; | 463 *is_snapshot = false; |
| 572 return text_buffer; | 464 return text_buffer; |
| 573 } | 465 } |
| 574 } | 466 } |
| 575 *is_snapshot = true; | 467 *is_snapshot = true; |
| 576 ASSERT(*buffer_len > len); | 468 ASSERT(*buffer_len > len); |
| 577 *buffer_len -= len; | 469 *buffer_len -= len; |
| 578 return text_buffer + len; | 470 return text_buffer + len; |
| 579 } | 471 } |
| 580 | 472 |
| 581 | 473 |
| 582 void DartUtils::WriteMagicNumber(File* file) { | 474 void DartUtils::WriteMagicNumber(File* file) { |
| 583 // Write a magic number and version information into the snapshot file. | 475 // Write a magic number and version information into the snapshot file. |
| 584 bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number)); | 476 bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number)); |
| 585 ASSERT(bytes_written); | 477 ASSERT(bytes_written); |
| 586 } | 478 } |
| 587 | 479 |
| 588 | 480 |
| 589 Dart_Handle DartUtils::LoadScriptHttp(Dart_Handle uri, | |
| 590 Dart_Handle builtin_lib) { | |
| 591 intptr_t len = 0; | |
| 592 uint8_t* buffer = NULL; | |
| 593 Dart_Handle result = MakeHttpRequest(uri, builtin_lib, &buffer, &len); | |
| 594 if (Dart_IsError(result)) { | |
| 595 return result; | |
| 596 } | |
| 597 const uint8_t* payload = buffer; | |
| 598 bool is_snapshot = false; | |
| 599 payload = SniffForMagicNumber(payload, &len, &is_snapshot); | |
| 600 if (is_snapshot) { | |
| 601 return Dart_LoadScriptFromSnapshot(payload, len); | |
| 602 } else { | |
| 603 Dart_Handle source = Dart_NewStringFromUTF8(payload, len); | |
| 604 free(buffer); | |
| 605 if (Dart_IsError(source)) { | |
| 606 return source; | |
| 607 } | |
| 608 return Dart_LoadScript(uri, source, 0, 0); | |
| 609 } | |
| 610 } | |
| 611 | |
| 612 | |
| 613 Dart_Handle DartUtils::LoadScriptDataAsync(Dart_Handle script_uri, | |
| 614 Dart_Handle builtin_lib) { | |
| 615 const int kNumArgs = 1; | |
| 616 Dart_Handle dart_args[kNumArgs]; | |
| 617 dart_args[0] = script_uri; | |
| 618 return Dart_Invoke(builtin_lib, | |
| 619 NewString("_loadDataAsync"), | |
| 620 kNumArgs, | |
| 621 dart_args); | |
| 622 } | |
| 623 | |
| 624 | |
| 625 Dart_Handle DartUtils::LoadScript(const char* script_uri, | 481 Dart_Handle DartUtils::LoadScript(const char* script_uri, |
| 626 Dart_Handle builtin_lib) { | 482 Dart_Handle builtin_lib) { |
| 627 if (Dart_IsVMFlagSet("load_async")) { | 483 Dart_Handle uri = Dart_NewStringFromCString(script_uri); |
| 628 Dart_Handle uri_handle = Dart_NewStringFromCString(script_uri); | 484 return LoadDataAsync_Invoke(Dart_Null(), uri, Dart_Null(), builtin_lib); |
| 629 return LoadScriptDataAsync(uri_handle, builtin_lib); | |
| 630 } | |
| 631 | |
| 632 Dart_Handle resolved_script_uri = | |
| 633 ResolveScriptUri(NewString(script_uri), builtin_lib); | |
| 634 if (Dart_IsError(resolved_script_uri)) { | |
| 635 return resolved_script_uri; | |
| 636 } | |
| 637 // Handle http: requests separately. | |
| 638 if (DartUtils::IsHttpSchemeURL(script_uri)) { | |
| 639 return LoadScriptHttp(resolved_script_uri, builtin_lib); | |
| 640 } | |
| 641 Dart_Handle script_path = DartUtils::FilePathFromUri(resolved_script_uri, | |
| 642 builtin_lib); | |
| 643 if (Dart_IsError(script_path)) { | |
| 644 return script_path; | |
| 645 } | |
| 646 const char* script_path_cstr; | |
| 647 Dart_StringToCString(script_path, &script_path_cstr); | |
| 648 const char* error_msg = NULL; | |
| 649 intptr_t len; | |
| 650 const uint8_t* buffer = ReadFileFully(script_path_cstr, | |
| 651 &len, | |
| 652 &error_msg); | |
| 653 if (buffer == NULL) { | |
| 654 return Dart_NewApiError(error_msg); | |
| 655 } | |
| 656 bool is_snapshot = false; | |
| 657 const uint8_t *payload = SniffForMagicNumber(buffer, &len, &is_snapshot); | |
| 658 Dart_Handle returnValue; | |
| 659 if (is_snapshot) { | |
| 660 returnValue = Dart_LoadScriptFromSnapshot(payload, len); | |
| 661 } else { | |
| 662 Dart_Handle source = Dart_NewStringFromUTF8(buffer, len); | |
| 663 if (Dart_IsError(source)) { | |
| 664 returnValue = NewError("%s is not a valid UTF-8 script", script_uri); | |
| 665 } else { | |
| 666 returnValue = Dart_LoadScript(resolved_script_uri, source, 0, 0); | |
| 667 } | |
| 668 } | |
| 669 free(const_cast<uint8_t *>(buffer)); | |
| 670 return returnValue; | |
| 671 } | 485 } |
| 672 | 486 |
| 673 | 487 |
| 674 // Callback function that gets called from asynchronous script loading code | |
| 675 // when the data has been read. Loads the script or snapshot into the VM. | |
| 676 void FUNCTION_NAME(Builtin_LoadScript)(Dart_NativeArguments args) { | |
| 677 Dart_Handle resolved_script_uri = Dart_GetNativeArgument(args, 0); | |
| 678 Dart_Handle data = Dart_GetNativeArgument(args, 1); | |
| 679 | |
| 680 intptr_t num_bytes = 0; | |
| 681 Dart_Handle result = Dart_ListLength(data, &num_bytes); | |
| 682 if (Dart_IsError(result)) { | |
| 683 Dart_PropagateError(result); | |
| 684 } | |
| 685 | |
| 686 uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(num_bytes)); | |
| 687 Dart_ListGetAsBytes(data, 0, buffer, num_bytes); | |
| 688 | |
| 689 bool is_snapshot = false; | |
| 690 const uint8_t *payload = | |
| 691 DartUtils::SniffForMagicNumber(buffer, &num_bytes, &is_snapshot); | |
| 692 | |
| 693 if (is_snapshot) { | |
| 694 result = Dart_LoadScriptFromSnapshot(payload, num_bytes); | |
| 695 } else { | |
| 696 Dart_Handle source = Dart_NewStringFromUTF8(buffer, num_bytes); | |
| 697 if (Dart_IsError(source)) { | |
| 698 result = DartUtils::NewError("%s is not a valid UTF-8 script", | |
| 699 resolved_script_uri); | |
| 700 } else { | |
| 701 result = Dart_LoadScript(resolved_script_uri, source, 0, 0); | |
| 702 } | |
| 703 } | |
| 704 free(const_cast<uint8_t *>(buffer)); | |
| 705 if (Dart_IsError(result)) { | |
| 706 Dart_PropagateError(result); | |
| 707 } | |
| 708 } | |
| 709 | |
| 710 | |
| 711 // Callback function, gets called from asynchronous script and library | 488 // Callback function, gets called from asynchronous script and library |
| 712 // reading code when there is an i/o error. | 489 // reading code when there is an i/o error. |
| 713 void FUNCTION_NAME(Builtin_AsyncLoadError)(Dart_NativeArguments args) { | 490 void FUNCTION_NAME(Builtin_AsyncLoadError)(Dart_NativeArguments args) { |
| 714 // Dart_Handle source_uri = Dart_GetNativeArgument(args, 0); | 491 // Dart_Handle source_uri = Dart_GetNativeArgument(args, 0); |
| 715 Dart_Handle library_uri = Dart_GetNativeArgument(args, 1); | 492 Dart_Handle library_uri = Dart_GetNativeArgument(args, 1); |
| 716 Dart_Handle error = Dart_GetNativeArgument(args, 2); | 493 Dart_Handle error = Dart_GetNativeArgument(args, 2); |
| 717 | 494 |
| 718 Dart_Handle library = Dart_LookupLibrary(library_uri); | 495 Dart_Handle library = Dart_LookupLibrary(library_uri); |
| 719 // If a library with the given uri exists, give it a chance to handle | 496 // If a library with the given uri exists, give it a chance to handle |
| 720 // the error. If the load requests stems from a deferred library load, | 497 // the error. If the load requests stems from a deferred library load, |
| 721 // an IO error is not fatal. | 498 // an IO error is not fatal. |
| 722 if (!Dart_IsError(library)) { | 499 if (!Dart_IsError(library)) { |
| 723 ASSERT(Dart_IsLibrary(library)); | 500 ASSERT(Dart_IsLibrary(library)); |
| 724 Dart_Handle res = Dart_LibraryHandleError(library, error); | 501 Dart_Handle res = Dart_LibraryHandleError(library, error); |
| 725 if (Dart_IsNull(res)) { | 502 if (Dart_IsNull(res)) { |
| 726 return; | 503 return; |
| 727 } | 504 } |
| 728 } | 505 } |
| 729 // The error was not handled above. Propagate an unhandled exception. | 506 // The error was not handled above. Propagate an unhandled exception. |
| 730 error = Dart_NewUnhandledExceptionError(error); | 507 error = Dart_NewUnhandledExceptionError(error); |
| 731 Dart_PropagateError(error); | 508 Dart_PropagateError(error); |
| 732 } | 509 } |
| 733 | 510 |
| 734 | 511 |
| 735 // Callback function that gets called from dartutils when the library | 512 // Callback function that gets called from dartutils when the library |
| 736 // source has been read. Loads the library or part into the VM. | 513 // source has been read. Loads the library or part into the VM. |
| 737 void FUNCTION_NAME(Builtin_LoadLibrarySource)(Dart_NativeArguments args) { | 514 void FUNCTION_NAME(Builtin_LoadScript)(Dart_NativeArguments args) { |
| 738 Dart_Handle tag_in = Dart_GetNativeArgument(args, 0); | 515 Dart_Handle tag_in = Dart_GetNativeArgument(args, 0); |
| 739 Dart_Handle resolved_script_uri = Dart_GetNativeArgument(args, 1); | 516 Dart_Handle resolved_script_uri = Dart_GetNativeArgument(args, 1); |
| 740 Dart_Handle library_uri = Dart_GetNativeArgument(args, 2); | 517 Dart_Handle library_uri = Dart_GetNativeArgument(args, 2); |
| 741 Dart_Handle sourceText = Dart_GetNativeArgument(args, 3); | 518 Dart_Handle source_data = Dart_GetNativeArgument(args, 3); |
| 742 | 519 |
| 743 int64_t tag = DartUtils::GetIntegerValue(tag_in); | 520 Dart_TypedData_Type type = Dart_GetTypeOfExternalTypedData(source_data); |
| 521 bool external = type == Dart_TypedData_kUint8; |
| 522 uint8_t* data = NULL; |
| 523 intptr_t num_bytes; |
| 524 Dart_Handle result = Dart_TypedDataAcquireData( |
| 525 source_data, &type, reinterpret_cast<void**>(&data), &num_bytes); |
| 526 if (Dart_IsError(result)) Dart_PropagateError(result); |
| 744 | 527 |
| 745 Dart_Handle result; | 528 uint8_t* buffer_copy = NULL; |
| 746 if (tag == Dart_kImportTag) { | 529 if (!external) { |
| 747 result = Dart_LoadLibrary(resolved_script_uri, sourceText, 0, 0); | 530 // If the buffer is not external, take a copy. |
| 531 buffer_copy = reinterpret_cast<uint8_t*>(malloc(num_bytes)); |
| 532 memmove(buffer_copy, data, num_bytes); |
| 533 data = buffer_copy; |
| 534 } |
| 535 |
| 536 Dart_TypedDataReleaseData(source_data); |
| 537 |
| 538 if (Dart_IsNull(tag_in) && Dart_IsNull(library_uri)) { |
| 539 // Entry file. Check for payload and load accordingly. |
| 540 bool is_snapshot = false; |
| 541 const uint8_t *payload = |
| 542 DartUtils::SniffForMagicNumber(data, &num_bytes, &is_snapshot); |
| 543 |
| 544 if (is_snapshot) { |
| 545 result = Dart_LoadScriptFromSnapshot(payload, num_bytes); |
| 546 } else { |
| 547 Dart_Handle source = Dart_NewStringFromUTF8(data, num_bytes); |
| 548 if (Dart_IsError(source)) { |
| 549 result = DartUtils::NewError("%s is not a valid UTF-8 script", |
| 550 resolved_script_uri); |
| 551 } else { |
| 552 result = Dart_LoadScript(resolved_script_uri, source, 0, 0); |
| 553 } |
| 554 } |
| 748 } else { | 555 } else { |
| 749 ASSERT(tag == Dart_kSourceTag); | 556 int64_t tag = DartUtils::GetIntegerValue(tag_in); |
| 750 Dart_Handle library = Dart_LookupLibrary(library_uri); | 557 |
| 751 DART_CHECK_VALID(library); | 558 Dart_Handle source = Dart_NewStringFromUTF8(data, num_bytes); |
| 752 result = Dart_LoadSource(library, resolved_script_uri, sourceText, 0, 0); | 559 if (Dart_IsError(source)) { |
| 560 result = DartUtils::NewError("%s is not a valid UTF-8 script", |
| 561 resolved_script_uri); |
| 562 } else { |
| 563 if (tag == Dart_kImportTag) { |
| 564 result = Dart_LoadLibrary(resolved_script_uri, source, 0, 0); |
| 565 } else { |
| 566 ASSERT(tag == Dart_kSourceTag); |
| 567 Dart_Handle library = Dart_LookupLibrary(library_uri); |
| 568 DART_CHECK_VALID(library); |
| 569 result = Dart_LoadSource(library, resolved_script_uri, source, 0, 0); |
| 570 } |
| 571 } |
| 753 } | 572 } |
| 573 |
| 574 if (buffer_copy != NULL) { |
| 575 free(const_cast<uint8_t *>(buffer_copy)); |
| 576 } |
| 577 |
| 754 if (Dart_IsError(result)) { | 578 if (Dart_IsError(result)) { |
| 755 // TODO(hausner): If compilation/loading errors are supposed to | |
| 756 // be observable by the program, we need to mark the bad library | |
| 757 // with the error instead of propagating it. | |
| 758 Dart_PropagateError(result); | 579 Dart_PropagateError(result); |
| 759 } | 580 } |
| 760 } | 581 } |
| 761 | 582 |
| 762 | 583 |
| 763 // Callback function that gets called from dartutils when there are | 584 // Callback function that gets called from dartutils when there are |
| 764 // no more outstanding load requests. | 585 // no more outstanding load requests. |
| 765 void FUNCTION_NAME(Builtin_DoneLoading)(Dart_NativeArguments args) { | 586 void FUNCTION_NAME(Builtin_DoneLoading)(Dart_NativeArguments args) { |
| 766 Dart_Handle res = Dart_FinalizeLoading(true); | 587 Dart_Handle res = Dart_FinalizeLoading(true); |
| 767 if (Dart_IsError(res)) { | 588 if (Dart_IsError(res)) { |
| 768 // TODO(hausner): If compilation/loading errors are supposed to | 589 // TODO(hausner): If compilation/loading errors are supposed to |
| 769 // be observable by the program, we need to mark the bad library | 590 // be observable by the program, we need to mark the bad library |
| 770 // with the error instead of propagating it. | 591 // with the error instead of propagating it. |
| 771 Dart_PropagateError(res); | 592 Dart_PropagateError(res); |
| 772 } | 593 } |
| 773 } | 594 } |
| 774 | 595 |
| 775 | 596 |
| 776 Dart_Handle DartUtils::LoadSource(Dart_Handle library, | 597 Dart_Handle DartUtils::LoadSourceAsync(Dart_Handle library, |
| 777 Dart_Handle url, | 598 Dart_Handle url, |
| 778 Dart_LibraryTag tag, | 599 Dart_LibraryTag tag, |
| 779 const char* url_string) { | 600 Dart_Handle builtin_lib) { |
| 780 bool is_http_scheme_url = DartUtils::IsHttpSchemeURL(url_string); | 601 return LoadDataAsync_Invoke(Dart_NewInteger(tag), url, library, builtin_lib); |
| 781 Dart_Handle source; | |
| 782 if (is_http_scheme_url) { | |
| 783 // Read the file over http. | |
| 784 source = DartUtils::ReadStringFromHttp(url_string); | |
| 785 } else { | |
| 786 // Read the file. | |
| 787 source = DartUtils::ReadStringFromFile(url_string); | |
| 788 } | |
| 789 if (Dart_IsError(source)) { | |
| 790 return source; // source contains the error string. | |
| 791 } | |
| 792 // The tag is either an import or a source tag. | |
| 793 // Load it according to the specified tag. | |
| 794 if (tag == Dart_kImportTag) { | |
| 795 // Return library object or an error string. | |
| 796 return Dart_LoadLibrary(url, source, 0, 0); | |
| 797 } else if (tag == Dart_kSourceTag) { | |
| 798 return Dart_LoadSource(library, url, source, 0, 0); | |
| 799 } | |
| 800 return Dart_NewApiError("wrong tag"); | |
| 801 } | 602 } |
| 802 | 603 |
| 803 | 604 |
| 804 Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root, | 605 Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root, |
| 805 Dart_Handle builtin_lib) { | 606 Dart_Handle builtin_lib) { |
| 806 // First ensure all required libraries are available. | 607 // First ensure all required libraries are available. |
| 807 Dart_Handle url = NewString(kAsyncLibURL); | 608 Dart_Handle url = NewString(kAsyncLibURL); |
| 808 DART_CHECK_VALID(url); | 609 DART_CHECK_VALID(url); |
| 809 Dart_Handle async_lib = Dart_LookupLibrary(url); | 610 Dart_Handle async_lib = Dart_LookupLibrary(url); |
| 810 DART_CHECK_VALID(async_lib); | 611 DART_CHECK_VALID(async_lib); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 new CObjectString(CObject::NewString(os_error->message())); | 983 new CObjectString(CObject::NewString(os_error->message())); |
| 1183 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); | 984 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); |
| 1184 result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError))); | 985 result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError))); |
| 1185 result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code()))); | 986 result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code()))); |
| 1186 result->SetAt(2, error_message); | 987 result->SetAt(2, error_message); |
| 1187 return result; | 988 return result; |
| 1188 } | 989 } |
| 1189 | 990 |
| 1190 } // namespace bin | 991 } // namespace bin |
| 1191 } // namespace dart | 992 } // namespace dart |
| OLD | NEW |