1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#pragma once
#include <memory>
#include <span>
#include <type_traits>
#include <range/v3/view/enumerate.hpp>
#include "vm/Utility.hpp"
#include <lauf/asm/module.h>
#include <lauf/asm/program.h>
#include <lauf/asm/type.h>
namespace OpenVic::Vm {
template<typename T>
concept Arithmetic = std::is_arithmetic_v<T>;
struct ModuleRef : utility::HandleBase<lauf_asm_module> {
using HandleBase::HandleBase;
const char* name() const {
return lauf_asm_module_name(_handle);
}
const char* debug_path() const {
return lauf_asm_module_debug_path(_handle);
}
void debug_path(const char* path) {
lauf_asm_set_module_debug_path(_handle, path);
}
lauf_asm_function* add_function(const char* name, lauf_asm_signature sig) {
return lauf_asm_add_function(_handle, name, sig);
}
const lauf_asm_function* find_function_by_name(const char* name) const {
return lauf_asm_find_function_by_name(_handle, name);
}
lauf_asm_global* add_global(lauf_asm_global_permissions perms) {
return lauf_asm_add_global(_handle, perms);
}
lauf_asm_program create_program(const lauf_asm_function* entry) const {
return lauf_asm_create_program(_handle, entry);
}
void define_data(lauf_asm_global* global, lauf_asm_layout layout, const void* data) {
lauf_asm_define_data_global(_handle, global, layout, data);
}
template<Arithmetic T>
void define_data_type(lauf_asm_global* global, const T* data = nullptr) {
define_data(global, { sizeof(T), alignof(T) }, static_cast<const void*>(data));
}
static std::unique_ptr<const lauf_asm_module* const[]> make_list(std::span<ModuleRef> mods) {
auto result = new const lauf_asm_module*[mods.size()];
auto span = std::span<const lauf_asm_module*> { result, mods.size() };
for (auto [count, element] : span | ranges::views::enumerate) {
element = mods[count].handle();
}
return std::unique_ptr<const lauf_asm_module* const[]>(result);
}
};
struct Module : utility::MoveOnlyHandleDerived<Module, ModuleRef> {
using MoveOnlyHandleDerived::MoveOnlyHandleDerived;
using MoveOnlyHandleDerived::operator=;
Module(const char* module_name) : MoveOnlyHandleDerived(lauf_asm_create_module(module_name)) {}
~Module() {
if (_handle == nullptr) {
return;
}
lauf_asm_destroy_module(_handle);
_handle = nullptr;
}
};
}
|