JSModuleNamespaceObject* AbstractModuleRecord::getModuleNamespace(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    // http://www.ecma-international.org/ecma-262/6.0/#sec-getmodulenamespace
    if (m_moduleNamespaceObject)
        return m_moduleNamespaceObject.get();

    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    IdentifierSet exportedNames;
    getExportedNames(exec, this, exportedNames);
    RETURN_IF_EXCEPTION(scope, nullptr);

    Vector<std::pair<Identifier, Resolution>> resolutions;
    for (auto& name : exportedNames) {
        Identifier ident = Identifier::fromUid(exec, name.get());
        const Resolution resolution = resolveExport(exec, ident);
        RETURN_IF_EXCEPTION(scope, nullptr);
        switch (resolution.type) {
        case Resolution::Type::NotFound:
            throwSyntaxError(exec, scope, makeString("Exported binding name '", String(name.get()), "' is not found."));
            return nullptr;

        case Resolution::Type::Error:
            throwSyntaxError(exec, scope, makeString("Exported binding name 'default' cannot be resolved by star export entries."));
            return nullptr;

        case Resolution::Type::Ambiguous:
            break;

        case Resolution::Type::Resolved:
            resolutions.append({ WTFMove(ident), resolution });
            break;
        }
    }

    auto* moduleNamespaceObject = JSModuleNamespaceObject::create(exec, globalObject, globalObject->moduleNamespaceObjectStructure(), this, WTFMove(resolutions));
    RETURN_IF_EXCEPTION(scope, nullptr);
    m_moduleNamespaceObject.set(vm, this, moduleNamespaceObject);
    return moduleNamespaceObject;
}