| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 538e3e9d94de8c1610aaf7908bdb2891d4079380..adcfd89aaacb6740e8bd2942d354e2483b18613f 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -19727,5 +19727,93 @@ MaybeHandle<Cell> Module::ResolveExportUsingStarExports(Handle<Module> module,
|
| return MaybeHandle<Cell>();
|
| }
|
|
|
| +bool Module::Instantiate(Handle<Module> module, v8::Local<v8::Context> context,
|
| + v8::Module::ResolveCallback callback,
|
| + v8::Local<v8::Value> callback_data) {
|
| + // Already instantiated.
|
| + if (module->code()->IsJSFunction()) return true;
|
| +
|
| + Isolate* isolate = module->GetIsolate();
|
| + Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
|
| + isolate);
|
| + Handle<JSFunction> function =
|
| + isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
| + shared,
|
| + handle(Utils::OpenHandle(*context)->native_context(), isolate));
|
| + module->set_code(*function);
|
| +
|
| + Handle<ModuleInfo> module_info(shared->scope_info()->ModuleDescriptorInfo(),
|
| + isolate);
|
| +
|
| + // Set up local exports.
|
| + Handle<FixedArray> regular_exports(module_info->regular_exports(), isolate);
|
| + for (int i = 0, n = regular_exports->length(); i < n; i += 2) {
|
| + Handle<FixedArray> export_names(
|
| + FixedArray::cast(regular_exports->get(i + 1)), isolate);
|
| + CreateExport(module, export_names);
|
| + }
|
| +
|
| + // Partially set up indirect exports.
|
| + // For each indirect export, we create the appropriate slot in the export
|
| + // table and store its ModuleInfoEntry there. When we later find the correct
|
| + // Cell in the module that actually provides the value, we replace the
|
| + // ModuleInfoEntry by that Cell (see ResolveExport).
|
| + Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
|
| + for (int i = 0, n = special_exports->length(); i < n; ++i) {
|
| + Handle<ModuleInfoEntry> entry(
|
| + ModuleInfoEntry::cast(special_exports->get(i)), isolate);
|
| + Handle<Object> export_name(entry->export_name(), isolate);
|
| + if (export_name->IsUndefined(isolate)) continue; // Star export.
|
| + CreateIndirectExport(module, Handle<String>::cast(export_name), entry);
|
| + }
|
| +
|
| + Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
|
| + for (int i = 0, length = module_requests->length(); i < length; ++i) {
|
| + Handle<String> specifier(String::cast(module_requests->get(i)), isolate);
|
| + v8::Local<v8::Module> api_requested_module;
|
| + // TODO(adamk): Revisit these failure cases once d8 knows how to
|
| + // persist a module_map across multiple top-level module loads, as
|
| + // the current module is left in a "half-instantiated" state.
|
| + if (!callback(context, v8::Utils::ToLocal(specifier),
|
| + v8::Utils::ToLocal(module), callback_data)
|
| + .ToLocal(&api_requested_module)) {
|
| + // TODO(adamk): Give this a better error message. But this is a
|
| + // misuse of the API anyway.
|
| + isolate->ThrowIllegalOperation();
|
| + return false;
|
| + }
|
| + Handle<Module> requested_module = Utils::OpenHandle(*api_requested_module);
|
| + module->requested_modules()->set(i, *requested_module);
|
| + if (!Instantiate(requested_module, context, callback, callback_data)) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // Resolve imports.
|
| + Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
|
| + for (int i = 0, n = regular_imports->length(); i < n; ++i) {
|
| + Handle<ModuleInfoEntry> entry(
|
| + ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
|
| + Handle<String> name(String::cast(entry->import_name()), isolate);
|
| + int module_request = Smi::cast(entry->module_request())->value();
|
| + if (ResolveImport(module, name, module_request, true).is_null()) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // Resolve indirect exports.
|
| + for (int i = 0, n = special_exports->length(); i < n; ++i) {
|
| + Handle<ModuleInfoEntry> entry(
|
| + ModuleInfoEntry::cast(special_exports->get(i)), isolate);
|
| + Handle<Object> name(entry->export_name(), isolate);
|
| + if (name->IsUndefined(isolate)) continue; // Star export.
|
| + if (ResolveExport(module, Handle<String>::cast(name), true).is_null()) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|