Skip to content

Commit 6791ff1

Browse files
authored
feat: wasm system implementation headers (#275)
1 parent c92655e commit 6791ff1

File tree

4 files changed

+435
-8
lines changed

4 files changed

+435
-8
lines changed

BUILD.bazel

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ cc_library(
9696
"ecsact/runtime/serialize.hh",
9797
],
9898
copts = copts,
99-
deps = [":common", ":core"],
99+
deps = [
100+
":common",
101+
":core",
102+
],
100103
)
101104

102105
cc_library(
@@ -106,6 +109,16 @@ cc_library(
106109
deps = [":common"],
107110
)
108111

112+
cc_library(
113+
name = "si_wasm",
114+
hdrs = [
115+
"ecsact/si/wasm.h",
116+
"ecsact/si/wasm.hh",
117+
],
118+
copts = copts,
119+
deps = [":common"],
120+
)
121+
109122
cc_library(
110123
name = "dylib",
111124
hdrs = ["ecsact/runtime/dylib.h"],
@@ -118,11 +131,11 @@ cc_library(
118131
hdrs = ["ecsact/runtime.h"],
119132
copts = copts,
120133
deps = [
134+
":async",
121135
":core",
122136
":dynamic",
123137
":meta",
124138
":serialize",
125139
":static",
126-
":async",
127140
],
128141
)

ecsact/si/wasm.h

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/**
2+
* @file
3+
* @brief Ecsact System Implementation with WebAssembly header
4+
*/
5+
6+
#ifndef ECSACT_SI_WASM_H
7+
#define ECSACT_SI_WASM_H
8+
9+
#include "ecsact/runtime/common.h"
10+
11+
#ifndef ECSACT_SI_WASM_API_FN
12+
# if defined(ECSACT_SI_WASM_API)
13+
# define ECSACT_SI_WASM_API_FN(ret, name) ECSACT_SI_WASM_API ret name
14+
# elif defined(ECSACT_SI_WASM_API_LOAD_AT_RUNTIME)
15+
# if defined(ECSACT_SI_WASM_API_EXPORT)
16+
# define ECSACT_SI_WASM_API_FN(ret, name) \
17+
ECSACT_EXTERN ECSACT_EXPORT(#name) ret(*name)
18+
# else
19+
# define ECSACT_SI_WASM_API_FN(ret, name) \
20+
ECSACT_EXTERN ECSACT_IMPORT("env", #name) ret(*name)
21+
# endif
22+
# elif defined(ECSACT_SI_WASM_API_EXPORT)
23+
# define ECSACT_SI_WASM_API_FN(ret, name) \
24+
ECSACT_EXTERN ECSACT_EXPORT(#name) ret name
25+
# else
26+
# define ECSACT_SI_WASM_API_FN(ret, name) \
27+
ECSACT_EXTERN ECSACT_IMPORT("env", #name) ret name
28+
# endif
29+
#endif // ECSACT_SI_WASM_API_FN
30+
31+
typedef enum ecsact_si_wasm_error {
32+
/**
33+
* No error.
34+
*/
35+
ECSACT_SI_WASM_OK,
36+
37+
/**
38+
* Unable to open WASM file.
39+
*/
40+
ECSACT_SI_WASM_ERR_FILE_OPEN_FAIL,
41+
42+
/**
43+
* Unable to read WASM file.
44+
*/
45+
ECSACT_SI_WASM_ERR_FILE_READ_FAIL,
46+
47+
/**
48+
* Unable to compile WASM file module.
49+
*/
50+
ECSACT_SI_WASM_ERR_COMPILE_FAIL,
51+
52+
/**
53+
* Unable to instantiate WASM file module.
54+
*/
55+
ECSACT_SI_WASM_ERR_INSTANTIATE_FAIL,
56+
57+
/**
58+
* Export name was not found in WASM file.
59+
*/
60+
ECSACT_SI_WASM_ERR_EXPORT_NOT_FOUND,
61+
62+
/**
63+
* Export name was found, but was not a function.
64+
*/
65+
ECSACT_SI_WASM_ERR_EXPORT_INVALID,
66+
67+
/**
68+
* WASM file contains an unknown guest import.
69+
*/
70+
ECSACT_SI_WASM_ERR_GUEST_IMPORT_UNKNOWN,
71+
72+
/**
73+
* WASM file contains correctly named guest import, but was not a function
74+
*/
75+
ECSACT_SI_WASM_ERR_GUEST_IMPORT_INVALID,
76+
77+
/**
78+
* Invoking `_initialize()` resulted in a wasm trap
79+
*/
80+
ECSACT_SI_WASM_ERR_INITIALIZE_FAIL,
81+
82+
/**
83+
* Ecsact dynamic module is 'load at runtime' but
84+
* 'ecsact_set_system_execution_impl' has not been set.
85+
*/
86+
ECSACT_SI_WASM_ERR_NO_SET_SYSTEM_EXECUTION,
87+
} ecsact_si_wasm_error;
88+
89+
ECSACT_SI_WASM_API_FN(void, ecsact_si_wasm_last_error_message)
90+
( //
91+
char* out_message,
92+
int32_t out_message_max_length
93+
);
94+
95+
ECSACT_SI_WASM_API_FN(int32_t, ecsact_si_wasm_last_error_message_length)();
96+
97+
/**
98+
* Load WASM file at path `wasm_file_path` and call
99+
* `ecsact_set_system_execution_impl` for the specified `system_ids` matching
100+
* the `wasm_exports` names.
101+
* @param wasm_file_path path to WASM file
102+
* @param systems_count Length of `system_ids` and `wasm_exports`
103+
* @param system_ids Sequential array of system ids that will have their system
104+
* implementations set to by the wasm exports dicated by `wasm_exports`
105+
* in the same order. Length is determined by `systems_count`.
106+
* @param wasm_exports Sequential array of wasm export names used as system
107+
* implementations in the same order as `system_ids`. Length is
108+
* determined by `systems_count`.
109+
* @return `ECSACT_SI_WASM_OK` if no error. If there is an error for _any_ of
110+
* the systems then **none of the systems are loaded**.
111+
*/
112+
ECSACT_SI_WASM_API_FN(ecsact_si_wasm_error, ecsact_si_wasm_load_file)
113+
( //
114+
const char* wasm_file_path,
115+
int systems_count,
116+
ecsact_system_like_id* system_ids,
117+
const char** wasm_exports
118+
);
119+
120+
ECSACT_SI_WASM_API_FN(ecsact_si_wasm_error, ecsact_si_wasm_load)
121+
( //
122+
char* wasm_data,
123+
int wasm_data_size,
124+
int systems_count,
125+
ecsact_system_like_id* system_ids,
126+
const char** wasm_exports
127+
);
128+
129+
/**
130+
* Unload 1 or more systems. If a system is not already loaded this is a noop.
131+
* @param systems_count number of systems impls to unload
132+
* @param system_ids array of system IDs to unload. Sequential list length of
133+
* @p systems_count.
134+
*/
135+
ECSACT_SI_WASM_API_FN(void, ecsact_si_wasm_unload)
136+
( //
137+
int systems_count,
138+
ecsact_system_like_id* system_ids
139+
);
140+
141+
/**
142+
* Reset state. Effectively called `ecsact_si_wasm_unload` for each system
143+
* implementation and clears the trap handler.
144+
*/
145+
ECSACT_SI_WASM_API_FN(void, ecsact_si_wasm_reset)();
146+
147+
/**
148+
* @param system_id System ID associated with the impl that triggered the trap
149+
* @param trap_message The trap message contents. Null-terminated string.
150+
*/
151+
typedef void (*ecsact_si_wasm_trap_handler)( //
152+
ecsact_system_like_id system_id,
153+
const char* trap_message
154+
);
155+
156+
/**
157+
* Register a function to be called when a system implementation trap occurs. It
158+
* is recommended that a trap handler is set otherwise the trap message will be
159+
* quietly discarded.
160+
* @param handler The handler function that will be called when a system impl
161+
* function trap occurs. Calling this overwrites the last handler. May be
162+
* `NULL` to remove the current handler.
163+
*/
164+
ECSACT_SI_WASM_API_FN(void, ecsact_si_wasm_set_trap_handler)
165+
( //
166+
ecsact_si_wasm_trap_handler handler
167+
);
168+
169+
typedef enum ecsact_si_wasm_log_level {
170+
ECSACT_SI_WASM_LOG_LEVEL_INFO = 0,
171+
ECSACT_SI_WASM_LOG_LEVEL_WARNING = 1,
172+
ECSACT_SI_WASM_LOG_LEVEL_ERROR = 2,
173+
} ecsact_si_wasm_log_level;
174+
175+
typedef void (*ecsact_si_wasm_log_consumer)( //
176+
ecsact_si_wasm_log_level log_level,
177+
const char* message,
178+
int32_t message_length,
179+
void* user_data
180+
);
181+
182+
/**
183+
* Invokes @p consumer for 1 or more lines that have been printed to stdout or
184+
* stderr between the last `ecsact_si_wasm_consume_logs` call until there are no
185+
* more lines left to consume.
186+
*/
187+
ECSACT_SI_WASM_API_FN(void, ecsact_si_wasm_consume_logs)
188+
( //
189+
ecsact_si_wasm_log_consumer consumer,
190+
void* consumer_user_data
191+
);
192+
193+
/**
194+
* Expose a file on the host for read access during initialization.
195+
*/
196+
ECSACT_SI_WASM_API_FN(int32_t, ecsact_si_wasm_allow_file_read_access)
197+
( //
198+
const char* real_file_path,
199+
int32_t real_file_path_length,
200+
const char* virtual_file_path,
201+
int32_t virtual_file_path_length
202+
);
203+
204+
// # BEGIN FOR_EACH_ECSACT_SI_WASM_API_FN
205+
#ifdef ECSACT_MSVC_TRADITIONAL
206+
# define FOR_EACH_ECSACT_SI_WASM_API_FN(fn, ...) \
207+
ECSACT_MSVC_TRADITIONAL_ERROR()
208+
#else
209+
# define FOR_EACH_ECSACT_SI_WASM_API_FN(fn, ...) \
210+
fn(ecsact_si_wasm_last_error_message, __VA_ARGS__); \
211+
fn(ecsact_si_wasm_last_error_message_length, __VA_ARGS__); \
212+
fn(ecsact_si_wasm_load_file, __VA_ARGS__); \
213+
fn(ecsact_si_wasm_load, __VA_ARGS__); \
214+
fn(ecsact_si_wasm_unload, __VA_ARGS__); \
215+
fn(ecsact_si_wasm_reset, __VA_ARGS__); \
216+
fn(ecsact_si_wasm_set_trap_handler, __VA_ARGS__); \
217+
fn(ecsact_si_wasm_consume_logs, __VA_ARGS__); \
218+
fn(ecsact_si_wasm_allow_file_read_access, __VA_ARGS__)
219+
#endif
220+
221+
#endif // ECSACT_SI_WASM_H

0 commit comments

Comments
 (0)