|
5 | 5 | #include "vm/bootstrap_natives.h"
|
6 | 6 |
|
7 | 7 | #include "lib/invocation_mirror.h"
|
| 8 | +#include "vm/bytecode_reader.h" |
8 | 9 | #include "vm/code_patcher.h"
|
9 | 10 | #include "vm/dart_entry.h"
|
10 | 11 | #include "vm/exceptions.h"
|
@@ -560,6 +561,61 @@ DEFINE_NATIVE_ENTRY(Internal_boundsCheckForPartialInstantiation, 0, 2) {
|
560 | 561 | return Object::null();
|
561 | 562 | }
|
562 | 563 |
|
| 564 | +DEFINE_NATIVE_ENTRY(Internal_loadDynamicModule, 0, 1) { |
| 565 | +#if defined(DART_DYNAMIC_MODULES) |
| 566 | + GET_NON_NULL_NATIVE_ARGUMENT(TypedData, module_bytes, |
| 567 | + arguments->NativeArgAt(0)); |
| 568 | + |
| 569 | + const intptr_t length = module_bytes.LengthInBytes(); |
| 570 | + uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(length)); |
| 571 | + if (data == nullptr) { |
| 572 | + const auto& exception = Instance::Handle( |
| 573 | + zone, thread->isolate_group()->object_store()->out_of_memory()); |
| 574 | + Exceptions::Throw(thread, exception); |
| 575 | + } |
| 576 | + { |
| 577 | + NoSafepointScope no_safepoint; |
| 578 | + // The memory does not overlap. |
| 579 | + memcpy(data, module_bytes.DataAddr(0), length); // NOLINT |
| 580 | + } |
| 581 | + const ExternalTypedData& typed_data = ExternalTypedData::Handle( |
| 582 | + zone, |
| 583 | + ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, length)); |
| 584 | + auto& function = Function::Handle(); |
| 585 | + { |
| 586 | + SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock()); |
| 587 | + bytecode::BytecodeLoader loader(thread, typed_data); |
| 588 | + function = loader.LoadBytecode(); |
| 589 | + } |
| 590 | + |
| 591 | + if (function.IsNull()) { |
| 592 | + return Object::null(); |
| 593 | + } |
| 594 | + ASSERT(function.is_static()); |
| 595 | + ASSERT(function.is_declared_in_bytecode()); |
| 596 | + auto& result = Object::Handle(zone); |
| 597 | + if (function.NumParameters() == 0) { |
| 598 | + result = DartEntry::InvokeFunction(function, Object::empty_array()); |
| 599 | + } else { |
| 600 | + ASSERT(function.NumParameters() == 1); |
| 601 | + // <String>[] |
| 602 | + const auto& arg0 = Array::Handle( |
| 603 | + zone, Array::New(0, Type::Handle(zone, Type::StringType()))); |
| 604 | + const auto& args = Array::Handle(zone, Array::New(1)); |
| 605 | + args.SetAt(0, arg0); |
| 606 | + result = DartEntry::InvokeFunction(function, args); |
| 607 | + } |
| 608 | + if (result.IsError()) { |
| 609 | + Exceptions::PropagateError(Error::Cast(result)); |
| 610 | + } |
| 611 | + return result.ptr(); |
| 612 | +#else |
| 613 | + Exceptions::ThrowUnsupportedError( |
| 614 | + "Loading of dynamic modules is not supported."); |
| 615 | + return Object::null(); |
| 616 | +#endif // defined(DART_DYNAMIC_MODULES) |
| 617 | +} |
| 618 | + |
563 | 619 | DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 0, 2) {
|
564 | 620 | const TypeArguments& type_arguments =
|
565 | 621 | TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
|
|
0 commit comments