#pragma once #include #include #include "pointer.h" namespace fugg { namespace wasm { using pointer::BasePointer; class Memory { wasm_rt_memory_t** memory; public: constexpr explicit Memory(wasm_rt_memory_t** memory) : memory(memory) { } uintptr_t address_of(uintptr_t offset) const { if(offset != NULL) return reinterpret_cast(&(*memory)->data[offset]); else return NULL; } uintptr_t data() const { return reinterpret_cast((*memory)->data); } uintptr_t size() const { return (*memory)->size; } }; static constexpr auto kRawMemory = &Z_clientZ_memory; static constexpr auto kMemory = Memory { kRawMemory }; } template T& module_ref(uintptr_t address) { return *reinterpret_cast(wasm::kMemory.address_of(address)); } // A pointer that relative to the module's memory. template using ModulePointer = pointer::OffsetPointer; // A pointer allocated INSIDE the module's memory, but passed as global. template using RuntimePointer = pointer::RelativePointer; // A pointer that is globally accessible in the linear memory. template using Pointer = pointer::Pointer; static_assert( sizeof(ModulePointer) == sizeof(void*), "ModulePointer needs a size of sizeof(void*)" ); static_assert( sizeof(RuntimePointer) == sizeof(unsigned char*), "RuntimePointer needs a size of sizeof(unsigned char*)" ); // Modifies the array to let the pointers be accessible from outside the WASM runtime template static T* ptr_array(uintptr_t address, size_t length) { auto src = reinterpret_cast( wasm::kMemory.address_of(address) ); for(unsigned int i = 0; i < length; i++) { src[i] = wasm::kMemory.address_of(src[i]); } return reinterpret_cast(src); } }