mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 13:16:26 +00:00
Enable lock for Vector to protect wasm-c-api read/write/extend operations (#1010)
This commit is contained in:
parent
e7079eeb17
commit
86b79cfb93
|
@ -3025,7 +3025,8 @@ aot_dump_call_stack(WASMExecEnv *exec_env)
|
||||||
|
|
||||||
/* release previous stack frames and create new ones */
|
/* release previous stack frames and create new ones */
|
||||||
if (!bh_vector_destroy(module_inst->frames.ptr)
|
if (!bh_vector_destroy(module_inst->frames.ptr)
|
||||||
|| !bh_vector_init(module_inst->frames.ptr, n, sizeof(WASMCApiFrame))) {
|
|| !bh_vector_init(module_inst->frames.ptr, n, sizeof(WASMCApiFrame),
|
||||||
|
false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,8 @@ failed: \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t))) { \
|
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t), \
|
||||||
|
true)) { \
|
||||||
LOG_DEBUG("bh_vector_init failed"); \
|
LOG_DEBUG("bh_vector_init failed"); \
|
||||||
goto failed; \
|
goto failed; \
|
||||||
} \
|
} \
|
||||||
|
@ -166,7 +167,8 @@ failed: \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t *))) { \
|
if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t *), \
|
||||||
|
true)) { \
|
||||||
LOG_DEBUG("bh_vector_init failed"); \
|
LOG_DEBUG("bh_vector_init failed"); \
|
||||||
goto failed; \
|
goto failed; \
|
||||||
} \
|
} \
|
||||||
|
@ -191,7 +193,7 @@ failed: \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (!bh_vector_init((Vector *)out, src->size, \
|
if (!bh_vector_init((Vector *)out, src->size, \
|
||||||
sizeof(wasm_##name##_t *))) { \
|
sizeof(wasm_##name##_t *), true)) { \
|
||||||
LOG_DEBUG("bh_vector_init failed"); \
|
LOG_DEBUG("bh_vector_init failed"); \
|
||||||
goto failed; \
|
goto failed; \
|
||||||
} \
|
} \
|
||||||
|
@ -377,7 +379,7 @@ wasm_store_new(wasm_engine_t *engine)
|
||||||
DEFAULT_VECTOR_INIT_LENGTH);
|
DEFAULT_VECTOR_INIT_LENGTH);
|
||||||
|
|
||||||
if (!(store->foreigns = malloc_internal(sizeof(Vector)))
|
if (!(store->foreigns = malloc_internal(sizeof(Vector)))
|
||||||
|| !(bh_vector_init(store->foreigns, 24, sizeof(Vector *)))) {
|
|| !(bh_vector_init(store->foreigns, 24, sizeof(Vector *), true))) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ typedef double float64_t;
|
||||||
wasm_##name##_t ptr_or_none* data; \
|
wasm_##name##_t ptr_or_none* data; \
|
||||||
size_t num_elems; \
|
size_t num_elems; \
|
||||||
size_t size_of_elem; \
|
size_t size_of_elem; \
|
||||||
|
void *lock; \
|
||||||
} wasm_##name##_vec_t; \
|
} wasm_##name##_vec_t; \
|
||||||
\
|
\
|
||||||
WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \
|
WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \
|
||||||
|
@ -589,8 +590,8 @@ WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_exte
|
||||||
|
|
||||||
// Vectors
|
// Vectors
|
||||||
|
|
||||||
#define WASM_EMPTY_VEC {0, NULL, 0, 0}
|
#define WASM_EMPTY_VEC {0, NULL, 0, 0, NULL}
|
||||||
#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array, sizeof(array)/sizeof(*(array)), sizeof(*(array))}
|
#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array, sizeof(array)/sizeof(*(array)), sizeof(*(array)), NULL}
|
||||||
|
|
||||||
|
|
||||||
// Value Type construction short-hands
|
// Value Type construction short-hands
|
||||||
|
|
|
@ -2504,7 +2504,8 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||||
|
|
||||||
/* release previous stack frames and create new ones */
|
/* release previous stack frames and create new ones */
|
||||||
if (!bh_vector_destroy(module_inst->frames)
|
if (!bh_vector_destroy(module_inst->frames)
|
||||||
|| !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame))) {
|
|| !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame),
|
||||||
|
false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,15 +38,21 @@ extend_vector(Vector *vector, size_t length)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_lock(vector->lock);
|
||||||
memcpy(data, vector->data, vector->size_elem * vector->max_elems);
|
memcpy(data, vector->data, vector->size_elem * vector->max_elems);
|
||||||
BH_FREE(vector->data);
|
BH_FREE(vector->data);
|
||||||
|
|
||||||
vector->data = data;
|
vector->data = data;
|
||||||
vector->max_elems = length;
|
vector->max_elems = length;
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_unlock(vector->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem)
|
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem,
|
||||||
|
bool use_lock)
|
||||||
{
|
{
|
||||||
if (!vector) {
|
if (!vector) {
|
||||||
LOG_ERROR("Init vector failed: vector is NULL.\n");
|
LOG_ERROR("Init vector failed: vector is NULL.\n");
|
||||||
|
@ -65,6 +71,26 @@ bh_vector_init(Vector *vector, size_t init_length, size_t size_elem)
|
||||||
vector->size_elem = size_elem;
|
vector->size_elem = size_elem;
|
||||||
vector->max_elems = init_length;
|
vector->max_elems = init_length;
|
||||||
vector->num_elems = 0;
|
vector->num_elems = 0;
|
||||||
|
vector->lock = NULL;
|
||||||
|
|
||||||
|
if (use_lock) {
|
||||||
|
if (!(vector->lock = wasm_runtime_malloc(sizeof(korp_mutex)))) {
|
||||||
|
LOG_ERROR("Init vector failed: alloc locker failed.\n");
|
||||||
|
bh_vector_destroy(vector);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BHT_OK != os_mutex_init(vector->lock)) {
|
||||||
|
LOG_ERROR("Init vector failed: init locker failed.\n");
|
||||||
|
|
||||||
|
wasm_runtime_free(vector->lock);
|
||||||
|
vector->lock = NULL;
|
||||||
|
|
||||||
|
bh_vector_destroy(vector);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,13 +107,17 @@ bh_vector_set(Vector *vector, uint32 index, const void *elem_buf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_lock(vector->lock);
|
||||||
memcpy(vector->data + vector->size_elem * index, elem_buf,
|
memcpy(vector->data + vector->size_elem * index, elem_buf,
|
||||||
vector->size_elem);
|
vector->size_elem);
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_unlock(vector->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
bh_vector_get(const Vector *vector, uint32 index, void *elem_buf)
|
bh_vector_get(Vector *vector, uint32 index, void *elem_buf)
|
||||||
{
|
{
|
||||||
if (!vector || !elem_buf) {
|
if (!vector || !elem_buf) {
|
||||||
LOG_ERROR("Get vector elem failed: vector or elem buf is NULL.\n");
|
LOG_ERROR("Get vector elem failed: vector or elem buf is NULL.\n");
|
||||||
|
@ -99,8 +129,12 @@ bh_vector_get(const Vector *vector, uint32 index, void *elem_buf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_lock(vector->lock);
|
||||||
memcpy(elem_buf, vector->data + vector->size_elem * index,
|
memcpy(elem_buf, vector->data + vector->size_elem * index,
|
||||||
vector->size_elem);
|
vector->size_elem);
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_unlock(vector->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +159,8 @@ bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_lock(vector->lock);
|
||||||
p = vector->data + vector->size_elem * vector->num_elems;
|
p = vector->data + vector->size_elem * vector->num_elems;
|
||||||
for (i = vector->num_elems - 1; i > index; i--) {
|
for (i = vector->num_elems - 1; i > index; i--) {
|
||||||
memcpy(p, p - vector->size_elem, vector->size_elem);
|
memcpy(p, p - vector->size_elem, vector->size_elem);
|
||||||
|
@ -133,6 +169,8 @@ bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
|
||||||
|
|
||||||
memcpy(p, elem_buf, vector->size_elem);
|
memcpy(p, elem_buf, vector->size_elem);
|
||||||
vector->num_elems++;
|
vector->num_elems++;
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_unlock(vector->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,9 +187,13 @@ bh_vector_append(Vector *vector, const void *elem_buf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_lock(vector->lock);
|
||||||
memcpy(vector->data + vector->size_elem * vector->num_elems, elem_buf,
|
memcpy(vector->data + vector->size_elem * vector->num_elems, elem_buf,
|
||||||
vector->size_elem);
|
vector->size_elem);
|
||||||
vector->num_elems++;
|
vector->num_elems++;
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_unlock(vector->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +213,8 @@ bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_lock(vector->lock);
|
||||||
p = vector->data + vector->size_elem * index;
|
p = vector->data + vector->size_elem * index;
|
||||||
|
|
||||||
if (old_elem_buf) {
|
if (old_elem_buf) {
|
||||||
|
@ -183,6 +227,8 @@ bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
vector->num_elems--;
|
vector->num_elems--;
|
||||||
|
if (vector->lock)
|
||||||
|
os_mutex_unlock(vector->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +248,12 @@ bh_vector_destroy(Vector *vector)
|
||||||
|
|
||||||
if (vector->data)
|
if (vector->data)
|
||||||
BH_FREE(vector->data);
|
BH_FREE(vector->data);
|
||||||
|
|
||||||
|
if (vector->lock) {
|
||||||
|
os_mutex_destroy(vector->lock);
|
||||||
|
wasm_runtime_free(vector->lock);
|
||||||
|
}
|
||||||
|
|
||||||
memset(vector, 0, sizeof(Vector));
|
memset(vector, 0, sizeof(Vector));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ typedef struct Vector {
|
||||||
size_t num_elems;
|
size_t num_elems;
|
||||||
/* size of each element */
|
/* size of each element */
|
||||||
size_t size_elem;
|
size_t size_elem;
|
||||||
|
void *lock;
|
||||||
} Vector;
|
} Vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +36,8 @@ typedef struct Vector {
|
||||||
* @return true if success, false otherwise
|
* @return true if success, false otherwise
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem);
|
bh_vector_init(Vector *vector, size_t init_length, size_t size_elem,
|
||||||
|
bool use_lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set element of vector
|
* Set element of vector
|
||||||
|
@ -60,7 +62,7 @@ bh_vector_set(Vector *vector, uint32 index, const void *elem_buf);
|
||||||
* @return true if success, false otherwise
|
* @return true if success, false otherwise
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
bh_vector_get(const Vector *vector, uint32 index, void *elem_buf);
|
bh_vector_get(Vector *vector, uint32 index, void *elem_buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert element of vector
|
* Insert element of vector
|
||||||
|
|
|
@ -3,24 +3,42 @@
|
||||||
All samples come from the commit 340fd9528cc3b26d22fe30ee1628c8c3f2b8c53b
|
All samples come from the commit 340fd9528cc3b26d22fe30ee1628c8c3f2b8c53b
|
||||||
of [wasm-c-api](https://github.com/WebAssembly/wasm-c-api).
|
of [wasm-c-api](https://github.com/WebAssembly/wasm-c-api).
|
||||||
|
|
||||||
Developer can learn these *APIs* from
|
Developer can learn these _APIs_ from
|
||||||
[wasm.h](https://github.com/WebAssembly/wasm-c-api/blob/master/include/wasm.h).
|
[wasm.h](https://github.com/WebAssembly/wasm-c-api/blob/master/include/wasm.h).
|
||||||
|
|
||||||
And here are [examples](https://github.com/WebAssembly/wasm-c-api/tree/master/example) which
|
And here are [examples](https://github.com/WebAssembly/wasm-c-api/tree/master/example) which
|
||||||
are helpful.
|
are helpful.
|
||||||
|
|
||||||
|
## FYI
|
||||||
|
|
||||||
|
- The thread model of _wasm_c_api_ is
|
||||||
|
|
||||||
|
- An `wasm_engine_t` instance may only be created once per process
|
||||||
|
- Every `wasm_store_t` and its objects may only be accessed in a single thread
|
||||||
|
|
||||||
|
- `wasm_engine_new`, `wasm_engine_new_with_config`, `wasm_engine_new_with_args`,
|
||||||
|
`wasm_engine_delete`should be called in a thread-safe environment. Such
|
||||||
|
behaviors are not recommended, and please make sure an appropriate calling
|
||||||
|
sequence if it has to be.
|
||||||
|
|
||||||
|
- call `wasm_engine_new` and `wasm_engine_delete` in different threads
|
||||||
|
- call `wasm_engine_new` or `wasm_engine_delete` multiple times in
|
||||||
|
different threads
|
||||||
|
|
||||||
|
## unspported list
|
||||||
|
|
||||||
Currently WAMR supports most of the APIs, the unsupported APIs are listed as below:
|
Currently WAMR supports most of the APIs, the unsupported APIs are listed as below:
|
||||||
|
|
||||||
- References
|
- References
|
||||||
|
|
||||||
``` c
|
```c
|
||||||
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*);
|
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*);
|
||||||
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
|
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
|
||||||
```
|
```
|
||||||
|
|
||||||
- Several Module APIs
|
- Several Module APIs
|
||||||
|
|
||||||
``` c
|
```c
|
||||||
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
||||||
WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
|
WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
|
||||||
```
|
```
|
||||||
|
@ -30,12 +48,12 @@ by host-side function callings.
|
||||||
|
|
||||||
- Table Grow APIs
|
- Table Grow APIs
|
||||||
|
|
||||||
``` c
|
```c
|
||||||
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
|
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
|
||||||
```
|
```
|
||||||
|
|
||||||
- Memory Grow APIs
|
- Memory Grow APIs
|
||||||
|
|
||||||
``` c
|
```c
|
||||||
WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
|
WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
|
||||||
```
|
```
|
||||||
|
|
|
@ -34,7 +34,7 @@ void check(bool success) {
|
||||||
|
|
||||||
void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) {
|
void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) {
|
||||||
wasm_val_t r[] = {WASM_INIT_VAL};
|
wasm_val_t r[] = {WASM_INIT_VAL};
|
||||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL};
|
||||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||||
if (wasm_func_call(func, &args_, &results) || r[0].of.i32 != expected) {
|
if (wasm_func_call(func, &args_, &results) || r[0].of.i32 != expected) {
|
||||||
printf("> Error on result\n");
|
printf("> Error on result\n");
|
||||||
|
@ -57,7 +57,7 @@ void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) {
|
void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL};
|
||||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
||||||
if (wasm_func_call(func, &args_, &results)) {
|
if (wasm_func_call(func, &args_, &results)) {
|
||||||
printf("> Error on result, expected empty\n");
|
printf("> Error on result, expected empty\n");
|
||||||
|
@ -72,7 +72,7 @@ void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
||||||
|
|
||||||
void check_trap(wasm_func_t* func, int i, wasm_val_t args[]) {
|
void check_trap(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||||
wasm_val_t r[] = {WASM_INIT_VAL};
|
wasm_val_t r[] = {WASM_INIT_VAL};
|
||||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t), NULL};
|
||||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||||
own wasm_trap_t* trap = wasm_func_call(func, &args_, &results);
|
own wasm_trap_t* trap = wasm_func_call(func, &args_, &results);
|
||||||
if (! trap) {
|
if (! trap) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user