#include <cstddef> #include <cstdint> #include <llvm/ExecutionEngine/RuntimeDyld.h> typedef enum { PROTECT_NONE, PROTECT_READ, PROTECT_READ_WRITE, PROTECT_READ_EXECUTE, } mem_protect_t; typedef enum { RESULT_OK, RESULT_ALLOCATE_FAILURE, RESULT_PROTECT_FAILURE, RESULT_DEALLOC_FAILURE, RESULT_OBJECT_LOAD_FAILURE, } result_t; typedef result_t (*alloc_memory_t)(size_t size, mem_protect_t protect, uint8_t** ptr_out, size_t* size_out); typedef result_t (*protect_memory_t)(uint8_t* ptr, size_t size, mem_protect_t protect); typedef result_t (*dealloc_memory_t)(uint8_t* ptr, size_t size); typedef uintptr_t (*lookup_vm_symbol_t)(char* name_ptr); typedef struct { /* Memory management. */ alloc_memory_t alloc_memory; protect_memory_t protect_memory; dealloc_memory_t dealloc_memory; lookup_vm_symbol_t lookup_vm_symbol; } callbacks_t; class WasmModule { public: WasmModule( const uint8_t *object_start, size_t object_size, callbacks_t *callbacks ); void *get_func(llvm::StringRef name) const; private: std::unique_ptr<llvm::RuntimeDyld::MemoryManager> memory_manager; std::unique_ptr<llvm::object::ObjectFile> object_file; std::map<llvm::StringRef, llvm::JITEvaluatedSymbol> symbol_table; }; extern "C" { result_t object_load(const uint8_t* mem_ptr, size_t mem_size, callbacks_t* callbacks, WasmModule** module_out) { *module_out = new WasmModule(mem_ptr, mem_size, callbacks); return RESULT_OK; } void* get_func_symbol(WasmModule* module, const char* name) { return module->get_func(llvm::StringRef(name)); } }