Skip to content

Commit 8f6c798

Browse files
Wodannbaszalmstra
andauthored
refactor: link type information at runtime (#377)
Co-authored-by: Bas Zalmstra <zalmstra.bas@gmail.com>
1 parent 98bbeb7 commit 8f6c798

File tree

207 files changed

+7001
-4796
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

207 files changed

+7001
-4796
lines changed

.clang-format

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
BasedOnStyle: Google
22
IndentWidth: 4
3+
IndentAccessModifiers: false
4+
AccessModifierOffset: -4
35
ColumnLimit: 100

c/include/mun/abi.h

Lines changed: 93 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,66 @@ typedef struct MunGuid {
4242
uint8_t _0[16];
4343
} MunGuid;
4444

45+
/**
46+
* Represents a unique identifier for types. The runtime can use this to lookup the corresponding [`TypeInfo`].
47+
*/
48+
typedef struct MunTypeId {
49+
/**
50+
* The GUID of the type
51+
*/
52+
struct MunGuid guid;
53+
} MunTypeId;
54+
55+
/**
56+
* Represents a function signature.
57+
*/
58+
typedef struct MunFunctionSignature {
59+
/**
60+
* Argument types
61+
*/
62+
const struct MunTypeId *arg_types;
63+
/**
64+
* Optional return type
65+
*/
66+
struct MunTypeId return_type;
67+
/**
68+
* Number of argument types
69+
*/
70+
uint16_t num_arg_types;
71+
} MunFunctionSignature;
72+
73+
/**
74+
* Represents a function prototype. A function prototype contains the name, type signature, but
75+
* not an implementation.
76+
*/
77+
typedef struct MunFunctionPrototype {
78+
/**
79+
* Function name
80+
*/
81+
const char *name;
82+
/**
83+
* The type signature of the function
84+
*/
85+
struct MunFunctionSignature signature;
86+
} MunFunctionPrototype;
87+
88+
/**
89+
* Represents a function definition. A function definition contains the name, type signature, and
90+
* a pointer to the implementation.
91+
*
92+
* `fn_ptr` can be used to call the declared function.
93+
*/
94+
typedef struct MunFunctionDefinition {
95+
/**
96+
* Function prototype
97+
*/
98+
struct MunFunctionPrototype prototype;
99+
/**
100+
* Function pointer
101+
*/
102+
const void *fn_ptr;
103+
} MunFunctionDefinition;
104+
45105
/**
46106
* Represents a struct declaration.
47107
*/
@@ -53,7 +113,7 @@ typedef struct MunStructInfo {
53113
/**
54114
* Struct fields' information
55115
*/
56-
const struct MunTypeInfo *const *field_types;
116+
const struct MunTypeId *field_types;
57117
/**
58118
* Struct fields' offsets
59119
*/
@@ -105,9 +165,9 @@ typedef union MunTypeInfoData {
105165
*/
106166
typedef struct MunTypeInfo {
107167
/**
108-
* Type GUID
168+
* Type ID
109169
*/
110-
struct MunGuid guid;
170+
struct MunTypeId id;
111171
/**
112172
* Type name
113173
*/
@@ -126,56 +186,6 @@ typedef struct MunTypeInfo {
126186
union MunTypeInfoData data;
127187
} MunTypeInfo;
128188

129-
/**
130-
* Represents a function signature.
131-
*/
132-
typedef struct MunFunctionSignature {
133-
/**
134-
* Argument types
135-
*/
136-
const struct MunTypeInfo *const *arg_types;
137-
/**
138-
* Optional return type
139-
*/
140-
const struct MunTypeInfo *return_type;
141-
/**
142-
* Number of argument types
143-
*/
144-
uint16_t num_arg_types;
145-
} MunFunctionSignature;
146-
147-
/**
148-
* Represents a function prototype. A function prototype contains the name, type signature, but
149-
* not an implementation.
150-
*/
151-
typedef struct MunFunctionPrototype {
152-
/**
153-
* Function name
154-
*/
155-
const char *name;
156-
/**
157-
* The type signature of the function
158-
*/
159-
struct MunFunctionSignature signature;
160-
} MunFunctionPrototype;
161-
162-
/**
163-
* Represents a function definition. A function definition contains the name, type signature, and
164-
* a pointer to the implementation.
165-
*
166-
* `fn_ptr` can be used to call the declared function.
167-
*/
168-
typedef struct MunFunctionDefinition {
169-
/**
170-
* Function prototype
171-
*/
172-
struct MunFunctionPrototype prototype;
173-
/**
174-
* Function pointer
175-
*/
176-
const void *fn_ptr;
177-
} MunFunctionDefinition;
178-
179189
/**
180190
* Represents a module declaration.
181191
*/
@@ -191,7 +201,7 @@ typedef struct MunModuleInfo {
191201
/**
192202
* Module types
193203
*/
194-
const struct MunTypeInfo *const *types;
204+
const struct MunTypeInfo *types;
195205
/**
196206
* Number of module functions
197207
*/
@@ -222,6 +232,30 @@ typedef struct MunDispatchTable {
222232
uint32_t num_entries;
223233
} MunDispatchTable;
224234

235+
/**
236+
* Represents a lookup table for type information. This is used for runtime linking.
237+
*
238+
* Type IDs and handles are stored separately for cache efficiency.
239+
*/
240+
typedef struct MunTypeLut {
241+
/**
242+
* Type IDs
243+
*/
244+
const struct MunTypeId *type_ids;
245+
/**
246+
* Type information handles
247+
*/
248+
const void **type_handles;
249+
/**
250+
* Debug names
251+
*/
252+
const char *const *type_names;
253+
/**
254+
* Number of types
255+
*/
256+
uint32_t num_entries;
257+
} MunTypeLut;
258+
225259
/**
226260
* Represents an assembly declaration.
227261
*/
@@ -231,9 +265,13 @@ typedef struct MunAssemblyInfo {
231265
*/
232266
struct MunModuleInfo symbols;
233267
/**
234-
* Dispatch table
268+
* Function dispatch table
235269
*/
236270
struct MunDispatchTable dispatch_table;
271+
/**
272+
* Type lookup table
273+
*/
274+
struct MunTypeLut type_lut;
237275
/**
238276
* Paths to assembly dependencies
239277
*/

cpp/include/mun/error.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ namespace mun {
99
* Frees the corresponding error object on destruction, if it exists.
1010
*/
1111
class Error {
12-
public:
12+
public:
1313
/** Default constructs an error. */
14-
Error() noexcept : m_handle{0} {}
14+
Error() noexcept : m_handle{nullptr} {}
1515

1616
/** Constructs an error from a `MunErrorHandle`.
1717
*
@@ -23,31 +23,31 @@ class Error {
2323
*
2424
* \param other an rvalue reference to an error
2525
*/
26-
Error(Error&& other) noexcept : m_handle(other.m_handle) { other.m_handle._0 = 0; }
26+
Error(Error&& other) noexcept : m_handle(other.m_handle) { other.m_handle._0 = nullptr; }
2727

2828
/** Move assigns an error.
2929
*
3030
* \param other an rvalue reference to an error
3131
*/
3232
Error& operator=(Error&& other) noexcept {
3333
m_handle = other.m_handle;
34-
other.m_handle._0 = 0;
34+
other.m_handle._0 = nullptr;
3535
return *this;
3636
}
3737

3838
/** Destructs the error. */
3939
~Error() noexcept { mun_error_destroy(m_handle); }
4040

41-
/** Retrieves the error message, if it exists, otherwise returns a nullptr.
41+
/** Returns the error message, if it exists, otherwise returns a nullptr.
4242
*
4343
* The message is UTF-8 encoded.
4444
*/
45-
const char* message() noexcept { return mun_error_message(m_handle); }
45+
const char* message() noexcept { return m_handle._0; }
4646

47-
/** Retrieves whether an error exists */
48-
operator bool() const noexcept { return m_handle._0 != 0; }
47+
/** Retrieves whether an error occurred */
48+
operator bool() const noexcept { return m_handle._0 != nullptr; }
4949

50-
private:
50+
private:
5151
MunErrorHandle m_handle;
5252
};
5353
} // namespace mun

cpp/include/mun/field_info.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#ifndef MUN_FIELD_INFO_H_
2+
#define MUN_FIELD_INFO_H_
3+
4+
#include <cassert>
5+
6+
#include "mun/runtime_capi.h"
7+
#include "mun/type_info.h"
8+
9+
namespace mun {
10+
/**
11+
* @brief A wrapper around a Mun field information handle.
12+
*/
13+
class FieldInfo {
14+
public:
15+
/**
16+
* @brief Constructs field information from an instantiated `MunFieldInfoHandle`.
17+
*/
18+
FieldInfo(MunFieldInfoHandle handle) noexcept : m_handle(handle) {}
19+
20+
/**
21+
* @brief Retrieves the field's name.
22+
*/
23+
std::string_view name() const noexcept {
24+
const auto ptr = mun_field_info_name(m_handle);
25+
assert(ptr);
26+
return ptr;
27+
}
28+
29+
/**
30+
* @brief Retrieves the field's type.
31+
*/
32+
TypeInfo type() const noexcept {
33+
const auto type_handle = mun_field_info_type(m_handle);
34+
assert(type_handle._0);
35+
return TypeInfo(type_handle);
36+
}
37+
38+
/**
39+
* @brief Retrieves the field's offset.
40+
*/
41+
uint16_t offset() const noexcept {
42+
uint16_t offset;
43+
const auto error_handle = mun_field_info_offset(m_handle, &offset);
44+
assert(error_handle._0 == nullptr);
45+
return offset;
46+
}
47+
48+
private:
49+
MunFieldInfoHandle m_handle;
50+
};
51+
52+
/**
53+
* @brief A wrapper around a span of Mun field informations, which are owned by the Mun runtime.
54+
*/
55+
class FieldInfoSpan {
56+
public:
57+
/**
58+
* @brief Constructs a field information span from an instantiated `MunFieldInfoSpan`.
59+
*/
60+
FieldInfoSpan(MunFieldInfoSpan span) noexcept : m_span(span) {}
61+
62+
FieldInfoSpan(FieldInfoSpan&&) = default;
63+
FieldInfoSpan(const FieldInfoSpan&) = delete;
64+
65+
~FieldInfoSpan() noexcept { mun_field_info_span_destroy(m_span); }
66+
67+
/**
68+
* @brief Returns an iterator to the beginning.
69+
*/
70+
const MunFieldInfoHandle* begin() const noexcept { return data(); }
71+
72+
/**
73+
* @brief Returns an iterator to the end.
74+
*/
75+
const MunFieldInfoHandle* end() const noexcept { return data() + size() + 1; }
76+
77+
/**
78+
* @brief Returns a pointer to the beginning of the sequence of elements.
79+
*/
80+
const MunFieldInfoHandle* data() const noexcept { return m_span.data; }
81+
82+
/**
83+
* @brief Returns the number of elements in the sequence.
84+
*/
85+
size_t size() const noexcept { return m_span.len; }
86+
87+
private:
88+
MunFieldInfoSpan m_span;
89+
};
90+
} // namespace mun
91+
92+
#endif // MUN_FIELD_INFO_H_

0 commit comments

Comments
 (0)