inline auto __get_mfa__()

in include/photon/common/PMF.h [30:69]


inline auto __get_mfa__(T* obj, MF f)
    -> pmf_map<PF, T>
{
    struct PMF  // Pointer to Member Function
    {
        union { uint64_t func_ptr, offset; };
        uint64_t this_adjustment;
#ifdef __x86_64__
        bool is_virtual() const
        {
            return offset & 1;
        }
        uint64_t get_virtual_function_address(void*& obj) const
        {
            (char*&)obj += this_adjustment;
            auto vtbl_addr = *(uint64_t*)obj;
            return *(uint64_t*)(vtbl_addr + offset - 1);
        }
#elif defined(__aarch64__)
        bool is_virtual() const
        {
            return this_adjustment & 1;
        }
        uint64_t get_virtual_function_address(void*& obj) const
        {
            (char*&)obj += (this_adjustment / 2);
            auto vtbl_addr = *(uint64_t*)obj;
            return *(uint64_t*)(vtbl_addr + offset);
        }
#endif
        uint64_t get_function_address(void*& obj) const
        {
            return is_virtual() ? get_virtual_function_address(obj) : func_ptr;
        }
    };

    auto pmf = (PMF&)f;
    auto addr = pmf.get_function_address((void*&)obj);
    return pmf_map<PF, T>{(PF)addr, obj};
}