feat(libs): implement NpCppWebApi IntrusivePtr construction, copy, release and access
IntrusivePtr<T> is three pointers: object, deleter, LibContext. The default constructors zero them, the copy constructors copy them and take a reference on the object, operator-> and operator* return the object, and the destructors drop a reference and hand the object to the deleter when it was the last one. The last-reference release of a pointer without a deleter needs the object's destructor and the LibContext memory pool and still throws. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8040d09ad0
commit
f2fb7852bb
|
|
@ -170,6 +170,16 @@ if(BUILD_TESTING)
|
|||
add_test(NAME host_thread_local COMMAND host_thread_local_tests)
|
||||
set_tests_properties(host_thread_local PROPERTIES TIMEOUT 15)
|
||||
|
||||
add_test_executable(guest_np_cpp_web_api_intrusive_ptr_tests tests/GuestNpCppWebApiIntrusivePtr.cpp)
|
||||
target_include_directories(guest_np_cpp_web_api_intrusive_ptr_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_np_cpp_web_api_intrusive_ptr_tests PRIVATE libSceNpCppWebApi libc)
|
||||
configure_windows_unwind(guest_np_cpp_web_api_intrusive_ptr_tests)
|
||||
add_test(NAME guest_np_cpp_web_api_intrusive_ptr COMMAND guest_np_cpp_web_api_intrusive_ptr_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_np_cpp_web_api_intrusive_ptr PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceNpCppWebApi>")
|
||||
endif()
|
||||
|
||||
add_test_executable(savedata_core_write_replacement_tests tests/SaveDataWriteReplacement.cpp)
|
||||
target_include_directories(savedata_core_write_replacement_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(savedata_core_write_replacement_tests PRIVATE libSceSaveData)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include "SceTypes.hpp"
|
||||
|
|
@ -267,89 +268,100 @@ int APS5_VABI _ZN3sce2Np9CppWebApi6Common11TransactionINS2_12IntrusivePtrINS1_12
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1ERS7_(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
struct IntrusivePtr {
|
||||
void* object;
|
||||
void (APS5_VABI* deleter)(void*);
|
||||
void* libContext;
|
||||
};
|
||||
static_assert(sizeof(IntrusivePtr) == 0x18);
|
||||
|
||||
static constexpr std::size_t ReferenceCountOffset = 0;
|
||||
static constexpr std::size_t VectorReferenceCountOffset = 0x30;
|
||||
|
||||
static std::atomic_ref<std::int32_t> ReferenceCount(void* object, const std::size_t offset) {
|
||||
return std::atomic_ref<std::int32_t>(*reinterpret_cast<std::int32_t*>(static_cast<std::uint8_t*>(object) + offset));
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
static void CopyIntrusivePtr(IntrusivePtr* self, const IntrusivePtr* source, const std::size_t referenceCountOffset) {
|
||||
*self = *source;
|
||||
if (self->object) ReferenceCount(self->object, referenceCountOffset).fetch_add(1);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
static void ReleaseIntrusivePtr(IntrusivePtr* self, const std::size_t referenceCountOffset, const char* function) {
|
||||
if (!self->object) return;
|
||||
if (ReferenceCount(self->object, referenceCountOffset).fetch_sub(1) != 1) return;
|
||||
if (!self->deleter) NotImplemented_nid_no_patch(function);
|
||||
self->deleter(self->object);
|
||||
self->object = nullptr;
|
||||
self->deleter = nullptr;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1ERS7_(IntrusivePtr* self, const IntrusivePtr* source) {
|
||||
CopyIntrusivePtr(self, source, ReferenceCountOffset);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1ERS7_(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1ERS7_(IntrusivePtr* self, const IntrusivePtr* source) {
|
||||
CopyIntrusivePtr(self, source, ReferenceCountOffset);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEC1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEED1Ev(void* self) {
|
||||
(void)self;
|
||||
return 0;
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEC1Ev(IntrusivePtr* self) {
|
||||
*self = {};
|
||||
}
|
||||
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, ReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEED1Ev(IntrusivePtr* self) {
|
||||
ReleaseIntrusivePtr(self, VectorReferenceCountOffset, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN3sce2Np9CppWebApi6Common13ConstIteratorINS2_12IntrusivePtrINS1_12Leaderboards2V15EntryEEEED2Ev(void* self) {
|
||||
|
|
@ -663,54 +675,44 @@ int APS5_VABI _ZNK3sce2Np9CppWebApi6Common11TransactionINS2_12IntrusivePtrINS1_1
|
|||
return SCE_NP_WEBAPI_ERROR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V15EntryEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V15EntryEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6BinaryEEptEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6BinaryEEptEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEEdeEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEEdeEv(const IntrusivePtr* self) {
|
||||
return self->object;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK3sce2Np9CppWebApi6Common15TransactionBaseINS2_12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEENS4_INS6_9RecordApi26RecordScoreResponseHeadersEEEE18getResponseHeadersERSB_() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,256 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
using Deleter = void (APS5_VABI*)(void*);
|
||||
|
||||
struct IntrusivePtr {
|
||||
void* object;
|
||||
Deleter deleter;
|
||||
void* libContext;
|
||||
};
|
||||
|
||||
using Construct = void (APS5_VABI*)(IntrusivePtr*);
|
||||
using Copy = void (APS5_VABI*)(IntrusivePtr*, const IntrusivePtr*);
|
||||
using Destroy = void (APS5_VABI*)(IntrusivePtr*);
|
||||
using Access = void* (APS5_VABI*)(const IntrusivePtr*);
|
||||
|
||||
extern "C" {
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEC1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEC1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEC1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEC1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEC1Ev(IntrusivePtr*);
|
||||
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1ERS7_(IntrusivePtr*, const IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1ERS7_(IntrusivePtr*, const IntrusivePtr*);
|
||||
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEED1Ev(IntrusivePtr*);
|
||||
void APS5_VABI _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEED1Ev(IntrusivePtr*);
|
||||
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V15EntryEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6BinaryEEptEv(const IntrusivePtr*);
|
||||
void* APS5_VABI _ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEEdeEv(const IntrusivePtr*);
|
||||
}
|
||||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
static constexpr std::size_t ObjectSize = 0x40;
|
||||
static constexpr std::size_t VectorReferenceCountOffset = 0x30;
|
||||
|
||||
struct DestroyCase {
|
||||
Destroy destroy;
|
||||
std::size_t referenceCountOffset;
|
||||
};
|
||||
|
||||
static void* deletedObject = nullptr;
|
||||
static int deleterCalls = 0;
|
||||
|
||||
static void APS5_VABI RecordDelete(void* object) {
|
||||
deletedObject = object;
|
||||
++deleterCalls;
|
||||
}
|
||||
|
||||
static std::int32_t ReadCount(const unsigned char* object, const std::size_t offset) {
|
||||
std::int32_t value;
|
||||
std::memcpy(&value, object + offset, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static void WriteCount(unsigned char* object, const std::size_t offset, const std::int32_t value) {
|
||||
std::memcpy(object + offset, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static bool OnlyCountChanged(const unsigned char* object, const std::size_t offset) {
|
||||
for (std::size_t index = 0; index < ObjectSize; ++index) {
|
||||
if (index >= offset && index < offset + sizeof(std::int32_t)) continue;
|
||||
if (object[index] != 0x5a) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void TestConstruct(const Construct construct) {
|
||||
IntrusivePtr pointer;
|
||||
std::memset(&pointer, 0xa5, sizeof(pointer));
|
||||
construct(&pointer);
|
||||
Require(pointer.object == nullptr);
|
||||
Require(pointer.deleter == nullptr);
|
||||
Require(pointer.libContext == nullptr);
|
||||
}
|
||||
|
||||
static void TestAccess(const Access access) {
|
||||
int object = 0;
|
||||
int context = 0;
|
||||
const IntrusivePtr empty{nullptr, RecordDelete, &context};
|
||||
Require(access(&empty) == nullptr);
|
||||
const IntrusivePtr filled{&object, nullptr, nullptr};
|
||||
Require(access(&filled) == &object);
|
||||
}
|
||||
|
||||
static void TestCopy(const Copy copy) {
|
||||
alignas(8) unsigned char object[ObjectSize];
|
||||
std::memset(object, 0x5a, sizeof(object));
|
||||
WriteCount(object, 0, 1);
|
||||
int context = 0;
|
||||
|
||||
const IntrusivePtr source{object, RecordDelete, &context};
|
||||
IntrusivePtr target;
|
||||
std::memset(&target, 0xa5, sizeof(target));
|
||||
copy(&target, &source);
|
||||
Require(target.object == object);
|
||||
Require(target.deleter == RecordDelete);
|
||||
Require(target.libContext == &context);
|
||||
Require(source.object == object);
|
||||
Require(ReadCount(object, 0) == 2);
|
||||
Require(OnlyCountChanged(object, 0));
|
||||
|
||||
const IntrusivePtr empty{nullptr, RecordDelete, &context};
|
||||
std::memset(&target, 0xa5, sizeof(target));
|
||||
copy(&target, &empty);
|
||||
Require(target.object == nullptr);
|
||||
Require(target.deleter == RecordDelete);
|
||||
Require(target.libContext == &context);
|
||||
}
|
||||
|
||||
static void TestDestroy(const DestroyCase& testCase) {
|
||||
alignas(8) unsigned char object[ObjectSize];
|
||||
std::memset(object, 0x5a, sizeof(object));
|
||||
int context = 0;
|
||||
const std::size_t offset = testCase.referenceCountOffset;
|
||||
|
||||
deleterCalls = 0;
|
||||
deletedObject = nullptr;
|
||||
|
||||
IntrusivePtr empty{nullptr, RecordDelete, &context};
|
||||
testCase.destroy(&empty);
|
||||
Require(empty.object == nullptr);
|
||||
Require(empty.deleter == RecordDelete);
|
||||
Require(empty.libContext == &context);
|
||||
Require(deleterCalls == 0);
|
||||
|
||||
WriteCount(object, offset, 2);
|
||||
IntrusivePtr shared{object, RecordDelete, &context};
|
||||
testCase.destroy(&shared);
|
||||
Require(ReadCount(object, offset) == 1);
|
||||
Require(shared.object == object);
|
||||
Require(shared.deleter == RecordDelete);
|
||||
Require(shared.libContext == &context);
|
||||
Require(deleterCalls == 0);
|
||||
|
||||
IntrusivePtr last{object, RecordDelete, &context};
|
||||
testCase.destroy(&last);
|
||||
Require(ReadCount(object, offset) == 0);
|
||||
Require(OnlyCountChanged(object, offset));
|
||||
Require(deleterCalls == 1);
|
||||
Require(deletedObject == object);
|
||||
Require(last.object == nullptr);
|
||||
Require(last.deleter == nullptr);
|
||||
Require(last.libContext == &context);
|
||||
|
||||
WriteCount(object, offset, 1);
|
||||
IntrusivePtr pooled{object, nullptr, &context};
|
||||
bool thrown = false;
|
||||
try {
|
||||
testCase.destroy(&pooled);
|
||||
} catch (const std::runtime_error&) {
|
||||
thrown = true;
|
||||
}
|
||||
Require(thrown);
|
||||
Require(deleterCalls == 1);
|
||||
}
|
||||
|
||||
static void TestSharedOwnership() {
|
||||
alignas(8) unsigned char object[ObjectSize];
|
||||
std::memset(object, 0x5a, sizeof(object));
|
||||
WriteCount(object, 0, 1);
|
||||
deleterCalls = 0;
|
||||
deletedObject = nullptr;
|
||||
|
||||
IntrusivePtr owner;
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1Ev(&owner);
|
||||
owner.object = object;
|
||||
owner.deleter = RecordDelete;
|
||||
|
||||
IntrusivePtr argument;
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1ERS7_(&argument, &owner);
|
||||
Require(_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEptEv(&argument) == object);
|
||||
Require(ReadCount(object, 0) == 2);
|
||||
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEED1Ev(&argument);
|
||||
Require(ReadCount(object, 0) == 1);
|
||||
Require(deleterCalls == 0);
|
||||
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEED1Ev(&owner);
|
||||
Require(ReadCount(object, 0) == 0);
|
||||
Require(deleterCalls == 1);
|
||||
Require(deletedObject == object);
|
||||
Require(_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEptEv(&owner) == nullptr);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Require(sizeof(IntrusivePtr) == 0x18);
|
||||
|
||||
const Construct constructors[] = {
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1Ev,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEC1Ev,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1Ev,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEC1Ev,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEC1Ev,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEC1Ev,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEC1Ev,
|
||||
};
|
||||
for (const auto construct : constructors) TestConstruct(construct);
|
||||
|
||||
const Access accessors[] = {
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V15EntryEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6BinaryEEptEv,
|
||||
_ZNK3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEEdeEv,
|
||||
};
|
||||
for (const auto access : accessors) TestAccess(access);
|
||||
|
||||
const Copy copies[] = {
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEEC1ERS7_,
|
||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEEC1ERS7_,
|
||||
};
|
||||
for (const auto copy : copies) TestCopy(copy);
|
||||
|
||||
const DestroyCase destructors[] = {
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V121GetRankingRequestBodyEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122GetRankingResponseBodyEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V122RecordScoreRequestBodyEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V123RecordScoreResponseBodyEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V130GetBoardDefinitionResponseBodyEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V14UserEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_12Leaderboards2V19RecordApi26RecordScoreResponseHeadersEED1Ev, 0},
|
||||
{_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS2_6VectorINS3_INS1_12Leaderboards2V15EntryEEEEEED1Ev, VectorReferenceCountOffset},
|
||||
};
|
||||
for (const auto& testCase : destructors) TestDestroy(testCase);
|
||||
|
||||
TestSharedOwnership();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -64,6 +64,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [sceHttpParseResponseHeader](../../core/libs/prx/libSceHttp/Export.cpp) (libSceHttp) - unknown signature
|
||||
- [sceHttp2GetMemoryPoolStats](../../core/libs/prx/libSceHttp2/Export.cpp) (libSceHttp2) - unknown signature
|
||||
- [sceNetGetMemoryPoolStats](../../core/libs/prx/libSceNet/Export.cpp) (libSceNet) - unknown signature
|
||||
- [sce::Np::CppWebApi::Common::IntrusivePtr](../../core/libs/prx/libSceNpCppWebApi/Export.cpp) (libSceNpCppWebApi) - the 0x18-byte layout (object, deleter, `LibContext*`) and the offset of the 32-bit reference count in the pointee (0x00, 0x30 for `Vector`) come from the module bundled with one title (PPSA21564); other SDK versions are not checked. The destructor throws on the last reference of a pointer without a deleter: destroying the object needs its destructor and the `LibContext` allocator, which are not implemented
|
||||
- [sceNpSessionSignalingGetMemoryInfo](../../core/libs/prx/libSceNpSessionSignaling/Export.cpp) (libSceNpSessionSignaling) - unknown signature
|
||||
- [sceNpSessionSignalingGetConnectionStatistics](../../core/libs/prx/libSceNpSessionSignaling/Export.cpp) (libSceNpSessionSignaling) - unknown signature
|
||||
- [sceNpTrophy2UnregisterUnlockCallback](../../core/libs/prx/libSceNpTrophy2/src/Context.cpp) (libSceNpTrophy2) - unknown signature
|
||||
|
|
|
|||
Loading…
Reference in New Issue