libstrat: convert to experimental new (super-accurate) sf allocation semantics

This commit is contained in:
Michael Scire
2021-01-17 07:55:32 -08:00
committed by SciresM
parent 8314d015f3
commit f06de12bea
149 changed files with 2852 additions and 1746 deletions

View File

@@ -15,9 +15,10 @@
*/
#pragma once
#include "../sf_common.hpp"
#include "sf_cmif_domain_api.hpp"
#include "sf_cmif_domain_service_object.hpp"
#include <stratosphere/sf/sf_common.hpp>
#include <stratosphere/sf/cmif/sf_cmif_domain_api.hpp>
#include <stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp>
#include <stratosphere/sf/impl/sf_service_object_impl.hpp>
namespace ams::sf::cmif {
@@ -39,7 +40,7 @@ namespace ams::sf::cmif {
explicit Entry() : owner(nullptr) { /* ... */ }
};
class Domain final : public DomainServiceObject {
class Domain final : public DomainServiceObject, private sf::impl::ServiceObjectImplBase2 {
NON_COPYABLE(Domain);
NON_MOVEABLE(Domain);
private:
@@ -51,7 +52,17 @@ namespace ams::sf::cmif {
explicit Domain(ServerDomainManager *m) : manager(m) { /* ... */ }
~Domain();
void DestroySelf();
void DisposeImpl();
virtual void AddReference() {
ServiceObjectImplBase2::AddReferenceImpl();
}
virtual void Release() {
if (ServiceObjectImplBase2::ReleaseImpl()) {
this->DisposeImpl();
}
}
virtual ServerDomainBase *GetServerDomain() override final {
return static_cast<ServerDomainBase *>(this);
@@ -120,7 +131,7 @@ namespace ams::sf::cmif {
}
public:
static void DestroyDomainServiceObject(DomainServiceObject *obj) {
static_cast<Domain *>(obj)->DestroySelf();
static_cast<Domain *>(obj)->DisposeImpl();
}
};

View File

@@ -84,18 +84,14 @@ namespace ams::sf::cmif {
}
};
template<size_t N, class = std::make_index_sequence<N>>
class ServiceDispatchTableImpl;
template<size_t N, size_t... Is>
class ServiceDispatchTableImpl<N, std::index_sequence<Is...>> : public ServiceDispatchTableBase {
private:
template<size_t>
using EntryType = ServiceCommandMeta;
template<size_t N>
class ServiceDispatchTableImpl : public ServiceDispatchTableBase {
public:
static constexpr size_t NumEntries = N;
private:
const std::array<ServiceCommandMeta, N> entries;
public:
explicit constexpr ServiceDispatchTableImpl(EntryType<Is>... args) : entries { args... } { /* ... */ }
explicit constexpr ServiceDispatchTableImpl(const std::array<ServiceCommandMeta, N> &e) : entries{e} { /* ... */ }
Result ProcessMessage(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) const {
return this->ProcessMessageImpl(ctx, in_raw_data, this->entries.data(), this->entries.size());
@@ -104,20 +100,20 @@ namespace ams::sf::cmif {
Result ProcessMessageForMitm(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) const {
return this->ProcessMessageForMitmImpl(ctx, in_raw_data, this->entries.data(), this->entries.size());
}
constexpr const std::array<ServiceCommandMeta, N> &GetEntries() const {
return this->entries;
}
};
}
template<typename ...Entries>
class ServiceDispatchTable : public impl::ServiceDispatchTableImpl<sizeof...(Entries)> {
template<size_t N>
class ServiceDispatchTable : public impl::ServiceDispatchTableImpl<N> {
public:
explicit constexpr ServiceDispatchTable(Entries... entries) : impl::ServiceDispatchTableImpl<sizeof...(Entries)>(entries...) { /* ... */ }
explicit constexpr ServiceDispatchTable(const std::array<ServiceCommandMeta, N> &e) : impl::ServiceDispatchTableImpl<N>(e) { /* ... */ }
};
#define AMS_SF_CMIF_IMPL_DEFINE_SERVICE_DISPATCH_TABLE \
template<typename ServiceImpl> \
static constexpr inline ::ams::sf::cmif::ServiceDispatchTable s_CmifServiceDispatchTable
struct ServiceDispatchMeta {
const impl::ServiceDispatchTableBase *DispatchTable;
Result (impl::ServiceDispatchTableBase::*ProcessHandler)(ServiceDispatchContext &, const cmif::PointerAndSize &) const;
@@ -140,6 +136,16 @@ namespace ams::sf::cmif {
static constexpr inline ServiceDispatchMeta Meta{&DispatchTable, ProcessHandlerImpl};
};
template<>
struct ServiceDispatchTraits<sf::IServiceObject> {
static constexpr inline auto DispatchTable = ServiceDispatchTable<0>(std::array<ServiceCommandMeta, 0>{});
};
template<>
struct ServiceDispatchTraits<sf::IMitmServiceObject> {
static constexpr inline auto DispatchTable = ServiceDispatchTable<0>(std::array<ServiceCommandMeta, 0>{});
};
template<typename T>
constexpr ALWAYS_INLINE const ServiceDispatchMeta *GetServiceDispatchMeta() {
return &ServiceDispatchTraits<T>::Meta;

View File

@@ -22,7 +22,7 @@ namespace ams::sf::cmif {
class ServiceObjectHolder {
private:
std::shared_ptr<sf::IServiceObject> srv;
SharedPointer<IServiceObject> srv;
const ServiceDispatchMeta *dispatch_meta;
private:
/* Copy constructor. */
@@ -30,7 +30,7 @@ namespace ams::sf::cmif {
ServiceObjectHolder &operator=(const ServiceObjectHolder &o) = delete;
public:
/* Default constructor, null all members. */
ServiceObjectHolder() : srv(nullptr), dispatch_meta(nullptr) { /* ... */ }
ServiceObjectHolder() : srv(nullptr, false), dispatch_meta(nullptr) { /* ... */ }
~ServiceObjectHolder() {
this->dispatch_meta = nullptr;
@@ -38,9 +38,8 @@ namespace ams::sf::cmif {
/* Ensure correct type id at runtime through template constructor. */
template<typename ServiceImpl>
constexpr explicit ServiceObjectHolder(std::shared_ptr<ServiceImpl> &&s) {
this->srv = std::move(s);
this->dispatch_meta = GetServiceDispatchMeta<ServiceImpl>();
constexpr explicit ServiceObjectHolder(SharedPointer<ServiceImpl> &&s) : srv(std::move(s)), dispatch_meta(GetServiceDispatchMeta<ServiceImpl>()) {
/* ... */
}
/* Move constructor, assignment operator. */
@@ -50,13 +49,13 @@ namespace ams::sf::cmif {
ServiceObjectHolder &operator=(ServiceObjectHolder &&o) {
ServiceObjectHolder tmp(std::move(o));
tmp.Swap(*this);
tmp.swap(*this);
return *this;
}
/* State management. */
void Swap(ServiceObjectHolder &o) {
std::swap(this->srv, o.srv);
void swap(ServiceObjectHolder &o) {
this->srv.swap(o.srv);
std::swap(this->dispatch_meta, o.dispatch_meta);
}
@@ -86,21 +85,21 @@ namespace ams::sf::cmif {
return 0;
}
template<typename ServiceImpl>
template<typename Interface>
constexpr inline bool IsServiceObjectValid() const {
return this->GetServiceId() == GetServiceDispatchMeta<ServiceImpl>()->GetServiceId();
return this->GetServiceId() == GetServiceDispatchMeta<Interface>()->GetServiceId();
}
template<typename ServiceImpl>
inline std::shared_ptr<ServiceImpl> GetServiceObject() const {
if (this->GetServiceId() == GetServiceDispatchMeta<ServiceImpl>()->GetServiceId()) {
return std::static_pointer_cast<ServiceImpl>(this->srv);
template<typename Interface>
inline Interface *GetServiceObject() const {
if (this->GetServiceId() == GetServiceDispatchMeta<Interface>()->GetServiceId()) {
return static_cast<Interface *>(this->srv.Get());
}
return nullptr;
}
inline sf::IServiceObject *GetServiceObjectUnsafe() const {
return this->srv.get();
return static_cast<sf::IServiceObject *>(this->srv.Get());
}
/* Processing. */