15
15
#include "aot_runtime.h"
16
16
#endif
17
17
18
+ typedef struct __wasi_thread_spawn_result_t {
19
+ uint8 is_error ;
20
+ union {
21
+ uint8 error ;
22
+ uint32 tid ;
23
+ } u ;
24
+ } __wasi_thread_spawn_result_t ;
25
+
26
+ bh_static_assert (sizeof (__wasi_thread_spawn_result_t ) == 8 );
27
+ bh_static_assert (offsetof (__wasi_thread_spawn_result_t , u .error ) == 4 );
28
+ bh_static_assert (offsetof (__wasi_thread_spawn_result_t , u .tid ) == 4 );
29
+
30
+ #define WASI_THREADS_EAGAIN 0
31
+
18
32
static const char * THREAD_START_FUNCTION = "wasi_thread_start" ;
19
33
static korp_mutex thread_id_lock ;
20
34
static TidAllocator tid_allocator ;
@@ -71,8 +85,8 @@ thread_start(void *arg)
71
85
return NULL ;
72
86
}
73
87
74
- static int32
75
- thread_spawn_wrapper (wasm_exec_env_t exec_env , uint32 start_arg )
88
+ static void
89
+ thread_spawn_wrapper (wasm_exec_env_t exec_env , uint32 start_arg , void * retaddr )
76
90
{
77
91
wasm_module_t module = wasm_exec_env_get_module (exec_env );
78
92
wasm_module_inst_t module_inst = get_module_inst (exec_env );
@@ -85,15 +99,18 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
85
99
#if WASM_ENABLE_LIBC_WASI != 0
86
100
WASIContext * wasi_ctx ;
87
101
#endif
102
+ __wasi_thread_spawn_result_t result ;
103
+ memset (& result , 0 , sizeof (result ));
88
104
89
105
bh_assert (module );
90
106
bh_assert (module_inst );
91
107
92
108
stack_size = ((WASMModuleInstance * )module_inst )-> default_wasm_stack_size ;
93
109
94
110
if (!(new_module_inst = wasm_runtime_instantiate_internal (
95
- module , true, stack_size , 0 , NULL , 0 )))
96
- return -1 ;
111
+ module , true, stack_size , 0 , NULL , 0 ))) {
112
+ goto fail ;
113
+ }
97
114
98
115
wasm_runtime_set_custom_data_internal (
99
116
new_module_inst , wasm_runtime_get_custom_data (module_inst ));
@@ -134,7 +151,9 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
134
151
}
135
152
os_mutex_unlock (& exec_env -> wait_lock );
136
153
137
- return thread_id ;
154
+ result .is_error = 0 ;
155
+ result .u .tid = thread_id ;
156
+ goto copyout ;
138
157
139
158
thread_spawn_fail :
140
159
os_mutex_unlock (& exec_env -> wait_lock );
@@ -146,16 +165,28 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
146
165
if (thread_start_arg )
147
166
wasm_runtime_free (thread_start_arg );
148
167
149
- return -1 ;
168
+ fail :
169
+ result .is_error = 1 ;
170
+ result .u .error = WASI_THREADS_EAGAIN ;
171
+
172
+ copyout :
173
+ if (!wasm_runtime_validate_native_addr (module_inst , retaddr ,
174
+ sizeof (result ))) {
175
+ wasm_runtime_set_exception (module_inst , "out of bounds memory access" );
176
+ }
177
+ else {
178
+ memcpy (retaddr , & result , sizeof (result ));
179
+ }
150
180
}
151
181
152
182
/* clang-format off */
153
- #define REG_NATIVE_FUNC (func_name , signature ) \
154
- { #func_name , func_name##_wrapper, signature, NULL }
183
+ #define REG_NATIVE_FUNC (symbol , func_name , signature ) \
184
+ { symbol , func_name##_wrapper, signature, NULL }
155
185
/* clang-format on */
156
186
157
- static NativeSymbol native_symbols_lib_wasi_threads [] = { REG_NATIVE_FUNC (
158
- thread_spawn , "(i)i" ) };
187
+ static NativeSymbol native_symbols_lib_wasi_threads [] = {
188
+ REG_NATIVE_FUNC ("thread-spawn" , thread_spawn , "(i*)" ),
189
+ };
159
190
160
191
uint32
161
192
get_lib_wasi_threads_export_apis (NativeSymbol * * p_lib_wasi_threads_apis )
0 commit comments