You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.0 KiB
107 lines
3.0 KiB
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <vec.h>
|
|
|
|
/* https://webassembly.github.io/spec/core/syntax/modules.html#globals */
|
|
|
|
/* This only supports i32 and i64 because this is all that aWsm currently supports */
|
|
enum wasm_global_type
|
|
{
|
|
WASM_GLOBAL_TYPE_UNUSED,
|
|
WASM_GLOBAL_TYPE_I32,
|
|
WASM_GLOBAL_TYPE_I64,
|
|
// WASM_GLOBAL_TYPE_F32,
|
|
// WASM_GLOBAL_TYPE_F64,
|
|
// WASM_GLOBAL_TYPE_V128,
|
|
// WASM_GLOBAL_TYPE_FUNCREF,
|
|
// WASM_GLOBAL_TYPE_EXTERNREF,
|
|
};
|
|
|
|
|
|
union wasm_global_value {
|
|
int32_t i32;
|
|
int64_t i64;
|
|
// float f32;
|
|
// double f64;
|
|
};
|
|
|
|
typedef struct wasm_global {
|
|
enum wasm_global_type type;
|
|
bool mut;
|
|
union wasm_global_value value;
|
|
} wasm_global_t;
|
|
|
|
VEC(wasm_global_t)
|
|
|
|
static inline void
|
|
wasm_globals_deinit(struct vec_wasm_global_t *globals)
|
|
{
|
|
vec_wasm_global_t_deinit(globals);
|
|
}
|
|
|
|
static inline int
|
|
wasm_globals_init(struct vec_wasm_global_t *globals, uint32_t capacity)
|
|
{
|
|
return vec_wasm_global_t_init(globals, capacity);
|
|
}
|
|
|
|
static inline void
|
|
wasm_globals_update_if_used(struct vec_wasm_global_t *globals, uint32_t idx, uint64_t *dest)
|
|
{
|
|
wasm_global_t *global = vec_wasm_global_t_get(globals, idx);
|
|
if (likely(global->type != WASM_GLOBAL_TYPE_UNUSED)) *dest = (uint64_t)global->value.i64;
|
|
}
|
|
|
|
static inline int
|
|
wasm_globals_get_i32(struct vec_wasm_global_t *globals, uint32_t idx, int32_t *return_val)
|
|
{
|
|
wasm_global_t *global = vec_wasm_global_t_get(globals, idx);
|
|
|
|
if (unlikely(global == NULL)) return -1;
|
|
if (unlikely(global->type != WASM_GLOBAL_TYPE_I32)) return -2;
|
|
|
|
*return_val = global->value.i32;
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
wasm_globals_get_i64(struct vec_wasm_global_t *globals, uint32_t idx, int64_t *return_val)
|
|
{
|
|
wasm_global_t *global = vec_wasm_global_t_get(globals, idx);
|
|
|
|
if (unlikely(global == NULL)) return -1;
|
|
if (unlikely(global->type != WASM_GLOBAL_TYPE_I64)) return -2;
|
|
|
|
*return_val = global->value.i64;
|
|
return 0;
|
|
}
|
|
|
|
// 0 on success, -1 on out of bounds, -2 on mismatched type
|
|
static inline int
|
|
wasm_globals_set_i32(struct vec_wasm_global_t *globals, uint32_t idx, int32_t value, bool is_mutable)
|
|
{
|
|
wasm_global_t *current = vec_wasm_global_t_get(globals, idx);
|
|
if (unlikely(current->type != WASM_GLOBAL_TYPE_UNUSED && current->mut == false)) return -2;
|
|
|
|
int rc = vec_wasm_global_t_insert(globals, idx,
|
|
(wasm_global_t){
|
|
.mut = is_mutable, .type = WASM_GLOBAL_TYPE_I32, .value = value });
|
|
return rc;
|
|
}
|
|
|
|
// 0 on success, -1 on out of bounds, -2 on mismatched type
|
|
static inline int
|
|
wasm_globals_set_i64(struct vec_wasm_global_t *globals, uint32_t idx, int64_t value, bool is_mutable)
|
|
{
|
|
wasm_global_t *current = vec_wasm_global_t_get(globals, idx);
|
|
if (unlikely(current->type != WASM_GLOBAL_TYPE_UNUSED && current->mut == false)) return -2;
|
|
|
|
// Returns -1 if idx > capacity
|
|
int rc = vec_wasm_global_t_insert(globals, idx,
|
|
(wasm_global_t){
|
|
.mut = is_mutable, .type = WASM_GLOBAL_TYPE_I64, .value = value });
|
|
return rc;
|
|
}
|