| Index: src/api.cc
 | 
| diff --git a/src/api.cc b/src/api.cc
 | 
| index 4df8e0a61714608ebdc59d3ecf1b218839a36fae..7fc225e3372737c85d9afdc59a50f1b7881b67b9 100644
 | 
| --- a/src/api.cc
 | 
| +++ b/src/api.cc
 | 
| @@ -1892,31 +1892,15 @@ Local<UnboundScript> Script::GetUnboundScript() {
 | 
|  
 | 
|  int Module::GetModuleRequestsLength() const {
 | 
|    i::Handle<i::Module> self = Utils::OpenHandle(this);
 | 
| -  i::Isolate* isolate = self->GetIsolate();
 | 
| -  i::Handle<i::SharedFunctionInfo> shared;
 | 
| -  if (self->code()->IsSharedFunctionInfo()) {
 | 
| -    shared = i::handle(i::SharedFunctionInfo::cast(self->code()), isolate);
 | 
| -  } else {
 | 
| -    shared = i::handle(i::JSFunction::cast(self->code())->shared(), isolate);
 | 
| -  }
 | 
| -  return shared->scope_info()
 | 
| -      ->ModuleDescriptorInfo()
 | 
| -      ->module_requests()
 | 
| -      ->length();
 | 
| +  return self->info()->module_requests()->length();
 | 
|  }
 | 
|  
 | 
|  Local<String> Module::GetModuleRequest(int i) const {
 | 
|    CHECK_GE(i, 0);
 | 
|    i::Handle<i::Module> self = Utils::OpenHandle(this);
 | 
|    i::Isolate* isolate = self->GetIsolate();
 | 
| -  i::Handle<i::SharedFunctionInfo> shared;
 | 
| -  if (self->code()->IsSharedFunctionInfo()) {
 | 
| -    shared = i::handle(i::SharedFunctionInfo::cast(self->code()), isolate);
 | 
| -  } else {
 | 
| -    shared = i::handle(i::JSFunction::cast(self->code())->shared(), isolate);
 | 
| -  }
 | 
| -  i::Handle<i::FixedArray> module_requests(
 | 
| -      shared->scope_info()->ModuleDescriptorInfo()->module_requests(), isolate);
 | 
| +  i::Handle<i::FixedArray> module_requests(self->info()->module_requests(),
 | 
| +                                           isolate);
 | 
|    CHECK_LT(i, module_requests->length());
 | 
|    return ToApiHandle<String>(i::handle(module_requests->get(i), isolate));
 | 
|  }
 | 
| @@ -1950,33 +1934,73 @@ static bool InstantiateModule(Local<Module> v8_module,
 | 
|            shared, handle(context->native_context(), isolate));
 | 
|    module->set_code(*function);
 | 
|  
 | 
| +  i::Handle<i::FixedArray> regular_exports = i::handle(
 | 
| +      shared->scope_info()->ModuleDescriptorInfo()->regular_exports(), isolate);
 | 
| +  i::Handle<i::FixedArray> regular_imports = i::handle(
 | 
| +      shared->scope_info()->ModuleDescriptorInfo()->regular_imports(), isolate);
 | 
| +  i::Handle<i::FixedArray> special_exports = i::handle(
 | 
| +      shared->scope_info()->ModuleDescriptorInfo()->special_exports(), isolate);
 | 
| +
 | 
| +  // Set up local exports.
 | 
| +  for (int i = 0, n = regular_exports->length(); i < n; i += 2) {
 | 
| +    i::Handle<i::FixedArray> export_names(
 | 
| +        i::FixedArray::cast(regular_exports->get(i + 1)), isolate);
 | 
| +    i::Module::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).
 | 
| +  for (int i = 0, n = special_exports->length(); i < n; ++i) {
 | 
| +    i::Handle<i::ModuleInfoEntry> entry(
 | 
| +        i::ModuleInfoEntry::cast(special_exports->get(i)), isolate);
 | 
| +    i::Handle<i::Object> export_name(entry->export_name(), isolate);
 | 
| +    if (export_name->IsUndefined(isolate)) continue;  // Star export.
 | 
| +    i::Module::CreateIndirectExport(
 | 
| +        module, i::Handle<i::String>::cast(export_name), entry);
 | 
| +  }
 | 
| +
 | 
|    for (int i = 0, length = v8_module->GetModuleRequestsLength(); i < length;
 | 
|         ++i) {
 | 
| -    Local<Module> import;
 | 
| +    Local<Module> 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(v8_context, v8_module->GetModuleRequest(i), v8_module,
 | 
|                    callback_data)
 | 
| -             .ToLocal(&import)) {
 | 
| +             .ToLocal(&requested_module)) {
 | 
|        // TODO(adamk): Give this a better error message. But this is a
 | 
|        // misuse of the API anyway.
 | 
|        isolate->ThrowIllegalOperation();
 | 
|        return false;
 | 
|      }
 | 
| -    if (!InstantiateModule(import, v8_context, callback, callback_data)) {
 | 
| +    if (!requested_module->Instantiate(v8_context, callback, callback_data)) {
 | 
|        return false;
 | 
|      }
 | 
| -    module->requested_modules()->set(i, *Utils::OpenHandle(*import));
 | 
| +    module->requested_modules()->set(i, *Utils::OpenHandle(*requested_module));
 | 
|    }
 | 
|  
 | 
| -  // Set up local exports.
 | 
| -  i::Handle<i::FixedArray> regular_exports = i::handle(
 | 
| -      shared->scope_info()->ModuleDescriptorInfo()->regular_exports(), isolate);
 | 
| -  for (int i = 0, n = regular_exports->length(); i < n; i += 2) {
 | 
| -    i::Handle<i::FixedArray> export_names(
 | 
| -        i::FixedArray::cast(regular_exports->get(i + 1)), isolate);
 | 
| -    i::Module::CreateExport(module, export_names);
 | 
| +  // Resolve imports.
 | 
| +  for (int i = 0, n = regular_imports->length(); i < n; ++i) {
 | 
| +    i::Handle<i::ModuleInfoEntry> entry(
 | 
| +        i::ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
 | 
| +    i::Handle<i::String> name(i::String::cast(entry->import_name()), isolate);
 | 
| +    int module_request = i::Smi::cast(entry->module_request())->value();
 | 
| +    if (i::Module::ResolveImport(module, name, module_request).is_null()) {
 | 
| +      return false;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  // Resolve indirect exports.
 | 
| +  for (int i = 0, n = special_exports->length(); i < n; ++i) {
 | 
| +    i::Handle<i::ModuleInfoEntry> entry(
 | 
| +        i::ModuleInfoEntry::cast(special_exports->get(i)), isolate);
 | 
| +    i::Handle<i::String> name(i::String::cast(entry->export_name()), isolate);
 | 
| +    if (i::Module::ResolveExport(module, name).is_null()) {
 | 
| +      return false;
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    return true;
 | 
| 
 |