#pragma once #include "vm_ptr.h" namespace vm { template struct page_allocator { static inline vm::addr_t alloc(u32 size, u32 align) { return vm::cast(vm::alloc(size, Location, std::max(align, 4096))); } static inline void dealloc(u32 addr, u32 size = 0) noexcept { return vm::dealloc_verbose_nothrow(addr, Location); } }; template struct stack_allocator { static inline vm::addr_t alloc(u32 size, u32 align) { return vm::cast(T::stack_push(size, align)); } static inline void dealloc(u32 addr, u32 size) noexcept { T::stack_pop_verbose(addr, size); } }; // Variable general specialization template class _var_base final : public _ptr_base { using pointer = _ptr_base; public: _var_base() : pointer(A::alloc(SIZE_32(T), ALIGN_32(T))) { } _var_base(const T& right) : _var_base() { std::memcpy(pointer::get_ptr(), &right, sizeof(T)); } _var_base(_var_base&& right) : pointer(right) { reinterpret_cast(static_cast(right)) = 0; } ~_var_base() { if (pointer::addr()) A::dealloc(pointer::addr(), SIZE_32(T)); } }; // Dynamic length array variable template class _var_base final : public _ptr_base { using pointer = _ptr_base; u32 m_size; public: _var_base(u32 count) : pointer(A::alloc(SIZE_32(T) * count, ALIGN_32(T))) , m_size(SIZE_32(T) * count) { } _var_base(_var_base&& right) : pointer(right) , m_size(right.m_size) { reinterpret_cast(static_cast(right)) = 0; } ~_var_base() { if (pointer::addr()) A::dealloc(pointer::addr(), m_size); } // Remove operator -> T* operator ->() const = delete; u32 get_count() const { return m_size / SIZE_32(T); } auto begin() const { return *this + 0; } auto end() const { return *this + get_count(); } }; // LE variable template using varl = _var_base, A>; // BE variable template using varb = _var_base, A>; namespace ps3 { // BE variable template> using var = varb; // Make BE variable initialized from value template> inline auto make_var(const T& value) { return varb(value); } // Make char[] variable initialized from std::string template> static auto make_str(const std::string& str) { var var_(size32(str) + 1); std::memcpy(var_.get_ptr(), str.c_str(), str.size() + 1); return var_; } // Global HLE variable template struct gvar : ptr { }; } namespace psv { // LE variable template> using var = varl; // Make LE variable initialized from value template> inline auto make_var(const T& value) { return var(value); } // Make char[] variable initialized from std::string template> static auto make_str(const std::string& str) { var var_(size32(str) + 1); std::memcpy(var_.get_ptr(), str.c_str(), str.size() + 1); return var_; } // Global HLE variable template struct gvar : ptr { }; } }