Enable WASI feature, enhance security and add SGX sample (#142)
Change emcc to clang Refine interpreter to improve perforamnce
This commit is contained in:
@ -217,6 +217,19 @@ typedef struct BlockAddr {
|
||||
#define BLOCK_ADDR_CACHE_SIZE 64
|
||||
#define BLOCK_ADDR_CONFLICT_SIZE 4
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
typedef struct WASIArguments {
|
||||
const char **dir_list;
|
||||
uint32 dir_count;
|
||||
const char **map_dir_list;
|
||||
uint32 map_dir_count;
|
||||
const char **env;
|
||||
uint32 env_count;
|
||||
const char **argv;
|
||||
uint32 argc;
|
||||
} WASIArguments;
|
||||
#endif
|
||||
|
||||
typedef struct WASMModule {
|
||||
uint32 type_count;
|
||||
uint32 import_count;
|
||||
@ -255,16 +268,19 @@ typedef struct WASMModule {
|
||||
#else
|
||||
BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
WASIArguments wasi_args;
|
||||
bool is_wasi_module;
|
||||
#endif
|
||||
} WASMModule;
|
||||
|
||||
typedef struct WASMBranchBlock {
|
||||
uint8 block_type;
|
||||
uint8 return_type;
|
||||
uint8 *start_addr;
|
||||
uint8 *else_addr;
|
||||
uint8 *end_addr;
|
||||
uint32 *frame_sp;
|
||||
uint8 *frame_ref;
|
||||
} WASMBranchBlock;
|
||||
|
||||
typedef struct WASMSection {
|
||||
@ -299,7 +315,7 @@ align_uint (unsigned v, unsigned b)
|
||||
inline static uint32
|
||||
wasm_string_hash(const char *str)
|
||||
{
|
||||
unsigned h = strlen(str);
|
||||
unsigned h = (unsigned)strlen(str);
|
||||
const uint8 *p = (uint8*)str;
|
||||
const uint8 *end = p + h;
|
||||
|
||||
@ -356,11 +372,11 @@ wasm_value_type_cell_num(uint8 value_type)
|
||||
inline static uint16
|
||||
wasm_get_cell_num(const uint8 *types, uint32 type_count)
|
||||
{
|
||||
uint16 cell_num = 0;
|
||||
uint32 cell_num = 0;
|
||||
uint32 i;
|
||||
for (i = 0; i < type_count; i++)
|
||||
cell_num += wasm_value_type_cell_num(types[i]);
|
||||
return cell_num;
|
||||
return (uint16)cell_num;
|
||||
}
|
||||
|
||||
inline static uint16
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_platform_log.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
|
||||
static WASMFunctionInstance*
|
||||
@ -55,17 +56,55 @@ check_main_func_type(const WASMType *type)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
static WASMFunctionInstance *
|
||||
lookup_wasi_start_function(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMFunctionInstance *func = NULL;
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_func_count; i++) {
|
||||
if (!strcmp(module_inst->export_functions[i].name, "_start")) {
|
||||
func = module_inst->export_functions[i].function;
|
||||
if (func->u.func->func_type->param_count != 0
|
||||
|| func->u.func->func_type->result_count != 0) {
|
||||
LOG_ERROR("Lookup wasi _start function failed: "
|
||||
"invalid function type.\n");
|
||||
return NULL;
|
||||
}
|
||||
return func;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_application_execute_main(WASMModuleInstance *module_inst,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
WASMFunctionInstance *func = resolve_main_function(module_inst);
|
||||
WASMFunctionInstance *func;
|
||||
uint32 argc1 = 0, argv1[2] = { 0 };
|
||||
uint32 total_argv_size = 0, total_size;
|
||||
uint32 total_argv_size = 0;
|
||||
uint64 total_size;
|
||||
int32 argv_buf_offset, i;
|
||||
char *argv_buf, *p;
|
||||
char *argv_buf, *p, *p_end;
|
||||
int32 *argv_offsets;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
if (module_inst->module->is_wasi_module) {
|
||||
/* In wasi mode, we should call function named "_start"
|
||||
which initializes the wasi envrionment and then calls
|
||||
the actual main function. Directly call main function
|
||||
may cause exception thrown. */
|
||||
if ((func = lookup_wasi_start_function(module_inst)))
|
||||
return wasm_runtime_call_wasm(module_inst, NULL,
|
||||
func, 0, NULL);
|
||||
/* if no start function is found, we execute
|
||||
the main function as normal */
|
||||
}
|
||||
#endif
|
||||
|
||||
func = resolve_main_function(module_inst);
|
||||
if (!func || func->is_import_func)
|
||||
return false;
|
||||
|
||||
@ -74,25 +113,28 @@ wasm_application_execute_main(WASMModuleInstance *module_inst,
|
||||
|
||||
if (func->u.func->func_type->param_count) {
|
||||
for (i = 0; i < argc; i++)
|
||||
total_argv_size += strlen(argv[i]) + 1;
|
||||
total_argv_size += (uint32)(strlen(argv[i]) + 1);
|
||||
total_argv_size = align_uint(total_argv_size, 4);
|
||||
|
||||
total_size = total_argv_size + sizeof(int32) * argc;
|
||||
total_size = (uint64)total_argv_size + sizeof(int32) * (uint64)argc;
|
||||
|
||||
if (!(argv_buf_offset = wasm_runtime_module_malloc(module_inst, total_size)))
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(argv_buf_offset =
|
||||
wasm_runtime_module_malloc(module_inst, (uint32)total_size)))
|
||||
return false;
|
||||
|
||||
argv_buf = p = wasm_runtime_addr_app_to_native(module_inst, argv_buf_offset);
|
||||
argv_offsets = (int32*)(p + total_argv_size);
|
||||
p_end = p + total_size;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
memcpy(p, argv[i], strlen(argv[i]) + 1);
|
||||
argv_offsets[i] = argv_buf_offset + (p - argv_buf);
|
||||
bh_memcpy_s(p, (uint32)(p_end - p), argv[i], (uint32)(strlen(argv[i]) + 1));
|
||||
argv_offsets[i] = argv_buf_offset + (int32)(p - argv_buf);
|
||||
p += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
argc1 = 2;
|
||||
argv1[0] = argc;
|
||||
argv1[0] = (uint32)argc;
|
||||
argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
|
||||
}
|
||||
|
||||
@ -165,6 +207,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
WASMType *type;
|
||||
uint32 argc1, *argv1;
|
||||
int32 i, p;
|
||||
uint64 total_size;
|
||||
const char *exception;
|
||||
|
||||
wasm_assert(argc >= 0);
|
||||
@ -181,15 +224,16 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
}
|
||||
|
||||
argc1 = func->param_cell_num;
|
||||
argv1 = wasm_malloc(sizeof(uint32) * (argc1 > 2 ? argc1 : 2));
|
||||
if (argv1 == NULL) {
|
||||
total_size = sizeof(uint32) * (uint64)(argc1 > 2 ? argc1 : 2);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| (!(argv1 = wasm_malloc((uint32)total_size)))) {
|
||||
LOG_ERROR("Wasm prepare param failed: malloc failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Parse arguments */
|
||||
for (i = 0, p = 0; i < argc; i++) {
|
||||
char *endptr;
|
||||
char *endptr = NULL;
|
||||
wasm_assert(argv[i] != NULL);
|
||||
if (argv[i][0] == '\0') {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
|
||||
@ -197,7 +241,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
}
|
||||
switch (type->types[i]) {
|
||||
case VALUE_TYPE_I32:
|
||||
argv1[p++] = strtoul(argv[i], &endptr, 0);
|
||||
argv1[p++] = (uint32)strtoul(argv[i], &endptr, 0);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
{
|
||||
@ -217,7 +261,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
if (endptr[0] == ':') {
|
||||
uint32 sig;
|
||||
union ieee754_float u;
|
||||
sig = strtoul(endptr + 1, &endptr, 0);
|
||||
sig = (uint32)strtoul(endptr + 1, &endptr, 0);
|
||||
u.f = f32;
|
||||
if (is_little_endian())
|
||||
u.ieee.ieee_little_endian.mantissa = sig;
|
||||
@ -244,11 +288,11 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
ud.d = u.val;
|
||||
if (is_little_endian()) {
|
||||
ud.ieee.ieee_little_endian.mantissa0 = sig >> 32;
|
||||
ud.ieee.ieee_little_endian.mantissa1 = sig;
|
||||
ud.ieee.ieee_little_endian.mantissa1 = (uint32)sig;
|
||||
}
|
||||
else {
|
||||
ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
|
||||
ud.ieee.ieee_big_endian.mantissa1 = sig;
|
||||
ud.ieee.ieee_big_endian.mantissa1 = (uint32)sig;
|
||||
}
|
||||
u.val = ud.d;
|
||||
}
|
||||
@ -258,7 +302,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endptr != '\0' && *endptr != '_') {
|
||||
if (endptr && *endptr != '\0' && *endptr != '_') {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ typedef float64 CellType_F64;
|
||||
#else /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
|
||||
#define PUT_I64_TO_ADDR(addr, value) do { \
|
||||
union { int64 val; uint32 parts[2]; } u; \
|
||||
u.val = (value); \
|
||||
u.val = (int64)(value); \
|
||||
(addr)[0] = u.parts[0]; \
|
||||
(addr)[1] = u.parts[1]; \
|
||||
} while (0)
|
||||
@ -110,36 +110,36 @@ GET_F64_FROM_ADDR (uint32 *addr)
|
||||
} while (0)
|
||||
|
||||
static inline uint32
|
||||
rotl32(uint32 n, unsigned int c)
|
||||
rotl32(uint32 n, uint32 c)
|
||||
{
|
||||
const unsigned int mask = (31);
|
||||
const uint32 mask = (31);
|
||||
c = c % 32;
|
||||
c &= mask;
|
||||
return (n<<c) | (n>>( (-c)&mask ));
|
||||
}
|
||||
|
||||
static inline uint32
|
||||
rotr32(uint32 n, unsigned int c)
|
||||
rotr32(uint32 n, uint32 c)
|
||||
{
|
||||
const unsigned int mask = (31);
|
||||
const uint32 mask = (31);
|
||||
c = c % 32;
|
||||
c &= mask;
|
||||
return (n>>c) | (n<<( (-c)&mask ));
|
||||
}
|
||||
|
||||
static inline uint64
|
||||
rotl64(uint64 n, unsigned int c)
|
||||
rotl64(uint64 n, uint64 c)
|
||||
{
|
||||
const unsigned int mask = (63);
|
||||
const uint64 mask = (63);
|
||||
c = c % 64;
|
||||
c &= mask;
|
||||
return (n<<c) | (n>>( (-c)&mask ));
|
||||
}
|
||||
|
||||
static inline uint64
|
||||
rotr64(uint64 n, unsigned int c)
|
||||
rotr64(uint64 n, uint64 c)
|
||||
{
|
||||
const unsigned int mask = (63);
|
||||
const uint64 mask = (63);
|
||||
c = c % 64;
|
||||
c &= mask;
|
||||
return (n>>c) | (n<<( (-c)&mask ));
|
||||
@ -237,21 +237,6 @@ popcount64(uint64 u)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline WASMGlobalInstance*
|
||||
get_global(const WASMModuleInstance *module, uint32 global_idx)
|
||||
{
|
||||
if (global_idx >= module->global_count)
|
||||
return NULL;
|
||||
|
||||
return module->globals + global_idx;
|
||||
}
|
||||
|
||||
static inline uint8*
|
||||
get_global_addr(WASMMemoryInstance *memory, WASMGlobalInstance *global)
|
||||
{
|
||||
return memory->global_data + global->data_offset;
|
||||
}
|
||||
|
||||
static uint64
|
||||
read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
{
|
||||
@ -300,7 +285,6 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
frame_csp->block_type = type; \
|
||||
frame_csp->return_type = ret_type; \
|
||||
frame_csp->start_addr = start; \
|
||||
frame_csp->else_addr = else_; \
|
||||
frame_csp->end_addr = end; \
|
||||
frame_csp->frame_sp = frame_sp; \
|
||||
frame_csp++; \
|
||||
@ -315,7 +299,7 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
#define POP_F64() (frame_sp -= 2, GET_F64_FROM_ADDR(frame_sp))
|
||||
|
||||
#define POP_CSP_CHECK_OVERFLOW(n) do { \
|
||||
wasm_assert(frame_csp - n >= frame->csp_bottom); \
|
||||
wasm_assert(frame_csp - n >= frame->csp_bottom); \
|
||||
} while (0)
|
||||
|
||||
#define POP_CSP() do { \
|
||||
@ -355,28 +339,28 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
#define LOCAL_I32(n) (*(int32*)(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_I32(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
*(int32*)(local_off(n)) = (int32)(val); \
|
||||
} while (0)
|
||||
|
||||
#define LOCAL_F32(n) (*(float32*)(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_F32(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
*(float32*)(local_off(n)) = (float32)(val); \
|
||||
} while (0)
|
||||
|
||||
#define LOCAL_I64(n) (GET_I64_FROM_ADDR(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_I64(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
PUT_I64_TO_ADDR(local_off(n), val); \
|
||||
} while (0)
|
||||
|
||||
#define LOCAL_F64(n) (GET_F64_FROM_ADDR(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_F64(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
PUT_F64_TO_ADDR(local_off(n), val); \
|
||||
} while (0)
|
||||
|
||||
@ -428,15 +412,15 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
p += _off; \
|
||||
} while (0)
|
||||
|
||||
#define RECOVER_CONTEXT(new_frame) do { \
|
||||
frame = (new_frame); \
|
||||
cur_func = frame->function; \
|
||||
prev_frame = frame->prev_frame; \
|
||||
frame_ip = frame->ip; \
|
||||
frame_ip_end = wasm_runtime_get_func_code_end(cur_func); \
|
||||
frame_lp = frame->lp; \
|
||||
frame_sp = frame->sp; \
|
||||
frame_csp = frame->csp; \
|
||||
#define RECOVER_CONTEXT(new_frame) do { \
|
||||
frame = (new_frame); \
|
||||
cur_func = frame->function; \
|
||||
prev_frame = frame->prev_frame; \
|
||||
frame_ip = frame->ip; \
|
||||
frame_ip_end = wasm_runtime_get_func_code_end(cur_func); \
|
||||
frame_lp = frame->lp; \
|
||||
frame_sp = frame->sp; \
|
||||
frame_csp = frame->csp; \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
@ -445,56 +429,56 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
#define GET_OPCODE() (void)0
|
||||
#endif
|
||||
|
||||
#define DEF_OP_LOAD(operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
#define DEF_OP_LOAD(operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_STORE(sval_type, sval_op_type, operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
sval_type sval; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
sval = POP_##sval_op_type(); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
#define DEF_OP_STORE(sval_type, sval_op_type, operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
sval_type sval; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
sval = POP_##sval_op_type(); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_I_CONST(ctype, src_op_type) do { \
|
||||
ctype cval; \
|
||||
read_leb_##ctype(frame_ip, frame_ip_end, cval); \
|
||||
PUSH_##src_op_type(cval); \
|
||||
#define DEF_OP_I_CONST(ctype, src_op_type) do { \
|
||||
ctype cval; \
|
||||
read_leb_##ctype(frame_ip, frame_ip_end, cval); \
|
||||
PUSH_##src_op_type(cval); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_EQZ(src_op_type) do { \
|
||||
uint32 val; \
|
||||
val = POP_##src_op_type() == 0; \
|
||||
PUSH_I32(val); \
|
||||
#define DEF_OP_EQZ(src_op_type) do { \
|
||||
int32 val; \
|
||||
val = POP_##src_op_type() == 0; \
|
||||
PUSH_I32(val); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_CMP(src_type, src_op_type, cond) do { \
|
||||
uint32 res; \
|
||||
src_type val1, val2; \
|
||||
val2 = POP_##src_op_type(); \
|
||||
val1 = POP_##src_op_type(); \
|
||||
res = val1 cond val2; \
|
||||
PUSH_I32(res); \
|
||||
#define DEF_OP_CMP(src_type, src_op_type, cond) do { \
|
||||
uint32 res; \
|
||||
src_type val1, val2; \
|
||||
val2 = (src_type)POP_##src_op_type(); \
|
||||
val1 = (src_type)POP_##src_op_type(); \
|
||||
res = val1 cond val2; \
|
||||
PUSH_I32(res); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
|
||||
src_type val1, val2; \
|
||||
val1 = POP_##src_op_type(); \
|
||||
val2 = operation(val1); \
|
||||
PUSH_##src_op_type(val2); \
|
||||
#define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
|
||||
src_type val1, val2; \
|
||||
val1 = (src_type)POP_##src_op_type(); \
|
||||
val2 = (src_type)operation(val1); \
|
||||
PUSH_##src_op_type(val2); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) do { \
|
||||
@ -503,50 +487,48 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
*(src_type2*)(frame_sp); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_MATH(src_type, src_op_type, method) do { \
|
||||
src_type val; \
|
||||
val = POP_##src_op_type(); \
|
||||
PUSH_##src_op_type(method(val)); \
|
||||
#define DEF_OP_MATH(src_type, src_op_type, method) do { \
|
||||
src_type val; \
|
||||
val = POP_##src_op_type(); \
|
||||
PUSH_##src_op_type(method(val)); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_TRUNC(dst_type, dst_op_type, src_type, src_op_type, \
|
||||
min_cond, max_cond) do { \
|
||||
src_type value = POP_##src_op_type(); \
|
||||
if (isnan(value)) { \
|
||||
wasm_runtime_set_exception(module, \
|
||||
"invalid conversion to integer"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
else if (value min_cond || value max_cond) { \
|
||||
wasm_runtime_set_exception(module, "integer overflow"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
PUSH_##dst_op_type(((dst_type)value)); \
|
||||
#define DEF_OP_TRUNC(dst_type, dst_op_type, src_type, src_op_type, \
|
||||
min_cond, max_cond) do { \
|
||||
src_type value = POP_##src_op_type(); \
|
||||
if (isnan(value)) { \
|
||||
wasm_runtime_set_exception(module, \
|
||||
"invalid conversion to integer"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
else if (value min_cond || value max_cond) { \
|
||||
wasm_runtime_set_exception(module, "integer overflow"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
PUSH_##dst_op_type(((dst_type)value)); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_CONVERT(dst_type, dst_op_type, \
|
||||
src_type, src_op_type) do { \
|
||||
dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
|
||||
PUSH_##dst_op_type(value); \
|
||||
#define DEF_OP_CONVERT(dst_type, dst_op_type, \
|
||||
src_type, src_op_type) do { \
|
||||
dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
|
||||
PUSH_##dst_op_type(value); \
|
||||
} while (0)
|
||||
|
||||
#define GET_LOCAL_INDEX_AND_TYPE() do { \
|
||||
param_count = cur_func->u.func->func_type->param_count; \
|
||||
local_count = cur_func->u.func->local_count; \
|
||||
uint32 param_count = cur_func->param_count; \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
|
||||
wasm_assert(local_idx < param_count + local_count); \
|
||||
wasm_assert(local_idx < param_count + cur_func->local_count); \
|
||||
if (local_idx < param_count) \
|
||||
local_type = cur_func->u.func->func_type->types[local_idx]; \
|
||||
local_type = cur_func->param_types[local_idx]; \
|
||||
else \
|
||||
local_type = \
|
||||
cur_func->u.func->local_types[local_idx - param_count]; \
|
||||
local_type = cur_func->local_types[local_idx - param_count]; \
|
||||
} while (0)
|
||||
|
||||
static inline int32
|
||||
sign_ext_8_32(int8 val)
|
||||
{
|
||||
if (val & 0x80)
|
||||
return val | 0xffffff00;
|
||||
return (int32)val | (int32)0xffffff00;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -554,7 +536,7 @@ static inline int32
|
||||
sign_ext_16_32(int16 val)
|
||||
{
|
||||
if (val & 0x8000)
|
||||
return val | 0xffff0000;
|
||||
return (int32)val | (int32)0xffff0000;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -562,7 +544,7 @@ static inline int64
|
||||
sign_ext_8_64(int8 val)
|
||||
{
|
||||
if (val & 0x80)
|
||||
return val | 0xffffffffffffff00;
|
||||
return (int64)val | (int64)0xffffffffffffff00;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -570,15 +552,15 @@ static inline int64
|
||||
sign_ext_16_64(int16 val)
|
||||
{
|
||||
if (val & 0x8000)
|
||||
return val | 0xffffffffffff0000;
|
||||
return (int64)val | (int64)0xffffffffffff0000;
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int64
|
||||
sign_ext_32_64(int32 val)
|
||||
{
|
||||
if (val & 0x80000000)
|
||||
return val | 0xffffffff00000000;
|
||||
if (val & (int32)0x80000000)
|
||||
return (int64)val | (int64)0xffffffff00000000;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -674,10 +656,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
WASMMemoryInstance *memory = module->default_memory;
|
||||
uint32 memory_data_size = memory
|
||||
? NumBytesPerPage * memory->cur_page_count : 0;
|
||||
uint32 heap_base_offset = memory ? memory->heap_base_offset : 0;
|
||||
uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0;
|
||||
uint32 heap_data_size = memory
|
||||
? memory->heap_data_end - memory->heap_data : 0;
|
||||
? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
|
||||
WASMTableInstance *table = module->default_table;
|
||||
WASMGlobalInstance *globals = module->globals;
|
||||
uint8 *global_data = memory ? memory->global_data : NULL;
|
||||
uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
|
||||
WASMInterpFrame *frame = NULL;
|
||||
/* Points to this special opcode so as to jump to the
|
||||
@ -690,10 +674,10 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
uint8 opcode, block_ret_type;
|
||||
uint32 *depths = NULL;
|
||||
uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
|
||||
uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0;
|
||||
uint32 i, depth, cond, count, fidx, tidx, frame_size = 0;
|
||||
uint64 all_cell_num = 0;
|
||||
int32 didx, val;
|
||||
uint8 *else_addr, *end_addr;
|
||||
uint8 *maddr = NULL;
|
||||
uint8 *else_addr, *end_addr, *maddr = NULL;
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||
@ -723,7 +707,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BLOCK):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
|
||||
read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
|
||||
|
||||
if (!wasm_loader_find_block_addr(module->module,
|
||||
frame_ip, frame_ip_end,
|
||||
@ -738,7 +722,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_LOOP):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
|
||||
read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
|
||||
|
||||
if (!wasm_loader_find_block_addr(module->module,
|
||||
frame_ip, frame_ip_end,
|
||||
@ -753,7 +737,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_IF):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
|
||||
read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
|
||||
|
||||
if (!wasm_loader_find_block_addr(module->module,
|
||||
frame_ip, frame_ip_end,
|
||||
@ -764,7 +748,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
|
||||
PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr);
|
||||
|
||||
@ -806,7 +790,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
HANDLE_OP (WASM_OP_BR_IF):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, depth);
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
if (cond)
|
||||
POP_CSP_N(depth);
|
||||
HANDLE_OP_END ();
|
||||
@ -816,7 +800,9 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
if (count <= BR_TABLE_TMP_BUF_LEN)
|
||||
depths = depth_buf;
|
||||
else {
|
||||
if (!(depths = wasm_malloc(sizeof(uint32) * count))) {
|
||||
uint64 total_size = sizeof(uint32) * (uint64)count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(depths = wasm_malloc((uint32)total_size))) {
|
||||
wasm_runtime_set_exception(module,
|
||||
"WASM interp failed: "
|
||||
"allocate memory failed.");
|
||||
@ -916,7 +902,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
HANDLE_OP (WASM_OP_SELECT_32):
|
||||
{
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
frame_sp--;
|
||||
if (!cond)
|
||||
*(frame_sp - 1) = *frame_sp;
|
||||
@ -925,7 +911,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
HANDLE_OP (WASM_OP_SELECT_64):
|
||||
{
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
frame_sp -= 2;
|
||||
if (!cond) {
|
||||
*(frame_sp - 2) = *frame_sp;
|
||||
@ -937,7 +923,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
/* variable instructions */
|
||||
HANDLE_OP (WASM_OP_GET_LOCAL):
|
||||
{
|
||||
uint32 local_idx, param_count, local_count;
|
||||
uint32 local_idx;
|
||||
uint8 local_type;
|
||||
|
||||
GET_LOCAL_INDEX_AND_TYPE();
|
||||
@ -960,13 +946,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
"invalid local type");
|
||||
goto got_exception;
|
||||
}
|
||||
(void)local_count;
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
HANDLE_OP (WASM_OP_SET_LOCAL):
|
||||
{
|
||||
uint32 local_idx, param_count, local_count;
|
||||
uint32 local_idx;
|
||||
uint8 local_type;
|
||||
|
||||
GET_LOCAL_INDEX_AND_TYPE();
|
||||
@ -989,13 +974,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
"invalid local type");
|
||||
goto got_exception;
|
||||
}
|
||||
(void)local_count;
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
HANDLE_OP (WASM_OP_TEE_LOCAL):
|
||||
{
|
||||
uint32 local_idx, param_count, local_count;
|
||||
uint32 local_idx;
|
||||
uint8 local_type;
|
||||
|
||||
GET_LOCAL_INDEX_AND_TYPE();
|
||||
@ -1017,7 +1001,6 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
wasm_runtime_set_exception(module, "invalid local type");
|
||||
goto got_exception;
|
||||
}
|
||||
(void)local_count;
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
@ -1025,24 +1008,26 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
WASMGlobalInstance *global;
|
||||
uint32 global_idx;
|
||||
uint8 *global_addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
|
||||
|
||||
global = get_global(module, global_idx);
|
||||
wasm_assert(global && global_idx < module->global_count);
|
||||
wasm_assert(global_idx < module->global_count);
|
||||
global = globals + global_idx;
|
||||
global_addr = global_data + global->data_offset;
|
||||
|
||||
switch (global->type) {
|
||||
case VALUE_TYPE_I32:
|
||||
PUSH_I32(*(uint32*)get_global_addr(memory, global));
|
||||
PUSH_I32(*(uint32*)global_addr);
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
PUSH_F32(*(float32*)get_global_addr(memory, global));
|
||||
PUSH_F32(*(float32*)global_addr);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
PUSH_I64(*(uint64*)get_global_addr(memory, global));
|
||||
PUSH_I64(GET_I64_FROM_ADDR((uint32*)global_addr));
|
||||
break;
|
||||
case VALUE_TYPE_F64:
|
||||
PUSH_F64(*(float64*)get_global_addr(memory, global));
|
||||
PUSH_F64(GET_F64_FROM_ADDR((uint32*)global_addr));
|
||||
break;
|
||||
default:
|
||||
wasm_runtime_set_exception(module, "invalid global type");
|
||||
@ -1059,13 +1044,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
|
||||
|
||||
global = get_global(module, global_idx);
|
||||
wasm_assert(global && global_idx < module->global_count);
|
||||
wasm_assert(global_idx < module->global_count);
|
||||
global = globals + global_idx;
|
||||
global_addr = global_data + global->data_offset;
|
||||
|
||||
global_addr = get_global_addr(memory, global);
|
||||
switch (global->type) {
|
||||
case VALUE_TYPE_I32:
|
||||
*(uint32*)global_addr = POP_I32();
|
||||
*(int32*)global_addr = POP_I32();
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
*(float32*)global_addr = POP_F32();
|
||||
@ -1103,7 +1088,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
GET_OPCODE();
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
static const void *handle_load_table[] = {
|
||||
@ -1184,7 +1169,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
frame_sp--;
|
||||
addr = POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
*(uint32*)maddr = frame_sp[1];
|
||||
(void)flags;
|
||||
@ -1198,7 +1183,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
frame_sp -= 2;
|
||||
addr = POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
*(uint32*)maddr = frame_sp[1];
|
||||
*((uint32*)maddr + 1) = frame_sp[2];
|
||||
@ -1215,12 +1200,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
GET_OPCODE();
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
sval = POP_I32();
|
||||
addr = POP_I32();
|
||||
sval = (uint32)POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
switch (opcode) {
|
||||
case WASM_OP_I32_STORE:
|
||||
*(int32*)maddr = sval;
|
||||
*(uint32*)maddr = sval;
|
||||
break;
|
||||
case WASM_OP_I32_STORE8:
|
||||
*(uint8*)maddr = (uint8)sval;
|
||||
@ -1243,8 +1228,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
GET_OPCODE();
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
sval = POP_I64();
|
||||
addr = POP_I32();
|
||||
sval = (uint64)POP_I64();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
switch (opcode) {
|
||||
case WASM_OP_I64_STORE:
|
||||
@ -1279,13 +1264,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
uint32 reserved, delta, prev_page_count = memory->cur_page_count;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, reserved);
|
||||
delta = POP_I32();
|
||||
delta = (uint32)POP_I32();
|
||||
|
||||
if (!wasm_runtime_enlarge_memory(module, delta)) {
|
||||
/* fail to memory.grow, return -1 */
|
||||
PUSH_I32(-1);
|
||||
if (wasm_runtime_get_exception(module)) {
|
||||
printf("%s\n", wasm_runtime_get_exception(module));
|
||||
bh_printf("%s\n", wasm_runtime_get_exception(module));
|
||||
wasm_runtime_set_exception(module, NULL);
|
||||
}
|
||||
}
|
||||
@ -1295,6 +1280,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
/* update the memory instance ptr */
|
||||
memory = module->default_memory;
|
||||
memory_data_size = NumBytesPerPage * memory->cur_page_count;
|
||||
global_data = memory->global_data;
|
||||
}
|
||||
|
||||
(void)reserved;
|
||||
@ -1514,8 +1500,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1546,8 +1532,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1584,8 +1570,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
PUSH_I32(rotl32(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -1594,8 +1580,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
PUSH_I32(rotr32(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -1647,8 +1633,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1679,8 +1665,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1717,8 +1703,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
PUSH_I64(rotl64(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -1727,8 +1713,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
PUSH_I64(rotr64(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -2092,14 +2078,23 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
goto got_exception;
|
||||
}
|
||||
else {
|
||||
WASMFunction *cur_wasm_func = cur_func->u.func;
|
||||
WASMType *func_type;
|
||||
uint8 ret_type;
|
||||
|
||||
all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num
|
||||
+ cur_func->u.func->max_stack_cell_num
|
||||
+ cur_func->u.func->max_block_num * sizeof(WASMBranchBlock) / 4;
|
||||
frame_size = wasm_interp_interp_frame_size(all_cell_num);
|
||||
func_type = cur_wasm_func->func_type;
|
||||
|
||||
all_cell_num = (uint64)cur_func->param_cell_num
|
||||
+ (uint64)cur_func->local_cell_num
|
||||
+ (uint64)cur_wasm_func->max_stack_cell_num
|
||||
+ ((uint64)cur_wasm_func->max_block_num) * sizeof(WASMBranchBlock) / 4;
|
||||
if (all_cell_num >= UINT32_MAX) {
|
||||
wasm_runtime_set_exception(self->module_inst,
|
||||
"WASM interp failed: stack overflow.");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num);
|
||||
if (!(frame = ALLOC_FRAME(self, frame_size, prev_frame))) {
|
||||
frame = prev_frame;
|
||||
goto got_exception;
|
||||
@ -2113,19 +2108,18 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
frame_sp = frame->sp_bottom = frame_lp + cur_func->param_cell_num
|
||||
+ cur_func->local_cell_num;
|
||||
frame->sp_boundary = frame->sp_bottom + cur_func->u.func->max_stack_cell_num;
|
||||
frame->sp_boundary = frame->sp_bottom + cur_wasm_func->max_stack_cell_num;
|
||||
|
||||
frame_csp = frame->csp_bottom = (WASMBranchBlock*)frame->sp_boundary;
|
||||
frame->csp_boundary = frame->csp_bottom + cur_func->u.func->max_block_num;
|
||||
frame->csp_boundary = frame->csp_bottom + cur_wasm_func->max_block_num;
|
||||
|
||||
/* Initialize the local varialbes */
|
||||
memset(frame_lp + cur_func->param_cell_num, 0,
|
||||
cur_func->local_cell_num * 4);
|
||||
(uint32)(cur_func->local_cell_num * 4));
|
||||
|
||||
/* Push function block as first block */
|
||||
func_type = cur_func->u.func->func_type;
|
||||
ret_type = func_type->result_count
|
||||
? func_type->types[func_type->param_count]
|
||||
? cur_func->param_types[func_type->param_count]
|
||||
: VALUE_TYPE_VOID;
|
||||
PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type,
|
||||
frame_ip, NULL, frame_ip_end - 1);
|
||||
|
||||
@ -55,7 +55,8 @@ typedef struct WASMInterpFrame {
|
||||
static inline unsigned
|
||||
wasm_interp_interp_frame_size(unsigned all_cell_num)
|
||||
{
|
||||
return align_uint(offsetof(WASMInterpFrame, lp) + all_cell_num * 5, 4);
|
||||
return align_uint((uint32)offsetof(WASMInterpFrame, lp)
|
||||
+ all_cell_num * 5, 4);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_dlfcn.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
/* Read a value of given type from the address pointed to by the given
|
||||
pointer and increase the pointer to the position just after the
|
||||
@ -108,7 +109,7 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
||||
error_buf, error_buf_size)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (uint32)res64; \
|
||||
res = (int32)res64; \
|
||||
} while (0)
|
||||
|
||||
#define read_leb_uint8(p, p_end, res) do { \
|
||||
@ -118,11 +119,11 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
||||
error_buf, error_buf_size)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (uint32)res64; \
|
||||
res = (uint8)res64; \
|
||||
} while (0)
|
||||
|
||||
static char*
|
||||
const_str_set_insert(const uint8 *str, int32 len, WASMModule *module,
|
||||
const_str_set_insert(const uint8 *str, uint32 len, WASMModule *module,
|
||||
char* error_buf, uint32 error_buf_size)
|
||||
{
|
||||
HashMap *set = module->const_str_set;
|
||||
@ -135,7 +136,7 @@ const_str_set_insert(const uint8 *str, int32 len, WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(c_str, str, len);
|
||||
bh_memcpy_s(c_str, len + 1, str, len);
|
||||
c_str[len] = '\0';
|
||||
|
||||
if ((value = wasm_hash_map_find(set, c_str))) {
|
||||
@ -215,6 +216,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end, *p_org;
|
||||
uint32 type_count, param_count, result_count, i, j;
|
||||
uint64 total_size;
|
||||
uint8 flag;
|
||||
WASMType *type;
|
||||
|
||||
@ -222,13 +224,15 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
||||
if (type_count) {
|
||||
module->type_count = type_count;
|
||||
if (!(module->types = wasm_malloc(sizeof(WASMType*) * type_count))) {
|
||||
total_size = sizeof(WASMType*) * (uint64)type_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->types = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load type section failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->types, 0, sizeof(WASMType*) * type_count);
|
||||
memset(module->types, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < type_count; i++) {
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
@ -254,8 +258,10 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
CHECK_BUF(p, p_end, result_count);
|
||||
p = p_org;
|
||||
|
||||
if (!(type = module->types[i] = wasm_malloc(offsetof(WASMType, types) +
|
||||
sizeof(uint8) * (param_count + result_count)))) {
|
||||
total_size = offsetof(WASMType, types) +
|
||||
sizeof(uint8) * (uint64)(param_count + result_count);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(type = module->types[i] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load type section failed: allocate memory failed.");
|
||||
return false;
|
||||
@ -398,6 +404,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end, *p_old;
|
||||
uint32 import_count, name_len, type_index, i, u32, flags;
|
||||
uint64 total_size;
|
||||
WASMImport *import;
|
||||
WASMImport *import_functions = NULL, *import_tables = NULL;
|
||||
WASMImport *import_memories = NULL, *import_globals = NULL;
|
||||
@ -408,13 +415,15 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
||||
if (import_count) {
|
||||
module->import_count = import_count;
|
||||
if (!(module->imports = wasm_malloc(sizeof(WASMImport) * import_count))) {
|
||||
total_size = sizeof(WASMImport) * (uint64)import_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->imports = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load import section failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->imports, 0, sizeof(WASMImport) * import_count);
|
||||
memset(module->imports, 0, (uint32)total_size);
|
||||
|
||||
p_old = p;
|
||||
|
||||
@ -514,6 +523,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
read_leb_uint8(p, p_end, kind);
|
||||
switch (kind) {
|
||||
case IMPORT_KIND_FUNC: /* import function */
|
||||
wasm_assert(import_functions);
|
||||
import = import_functions++;
|
||||
read_leb_uint32(p, p_end, type_index);
|
||||
if (type_index >= module->type_count) {
|
||||
@ -543,6 +553,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_TABLE: /* import table */
|
||||
wasm_assert(import_tables);
|
||||
import = import_tables++;
|
||||
if (!load_table_import(&p, p_end, &import->u.table,
|
||||
error_buf, error_buf_size))
|
||||
@ -554,6 +565,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_MEMORY: /* import memory */
|
||||
wasm_assert(import_memories);
|
||||
import = import_memories++;
|
||||
if (!load_memory_import(&p, p_end, &import->u.memory,
|
||||
error_buf, error_buf_size))
|
||||
@ -565,6 +577,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_GLOBAL: /* import global */
|
||||
wasm_assert(import_globals);
|
||||
import = import_globals++;
|
||||
read_leb_uint8(p, p_end, import->u.global.type);
|
||||
read_leb_uint8(p, p_end, mutable);
|
||||
@ -590,6 +603,16 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
import->u.names.module_name = module_name;
|
||||
import->u.names.field_name = field_name;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
import = module->import_functions;
|
||||
for (i = 0; i < module->import_function_count; i++, import++) {
|
||||
if (!strcmp(import->u.names.module_name, "wasi_unstable")) {
|
||||
module->is_wasi_module = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (p != p_end) {
|
||||
@ -613,7 +636,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
const uint8 *p_code = buf_code, *p_code_end, *p_code_save;
|
||||
uint32 func_count, total_size;
|
||||
uint32 func_count;
|
||||
uint64 total_size;
|
||||
uint32 code_count = 0, code_size, type_index, i, j, k, local_type_index;
|
||||
uint32 local_count, local_set_count, sub_local_count;
|
||||
uint8 type;
|
||||
@ -632,13 +656,15 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
|
||||
if (func_count) {
|
||||
module->function_count = func_count;
|
||||
if (!(module->functions = wasm_malloc(sizeof(WASMFunction*) * func_count))) {
|
||||
total_size = sizeof(WASMFunction*) * (uint64)func_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->functions = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load function section failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->functions, 0, sizeof(WASMFunction*) * func_count);
|
||||
memset(module->functions, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < func_count; i++) {
|
||||
/* Resolve function type */
|
||||
@ -678,10 +704,11 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
}
|
||||
|
||||
/* Alloc memory, layout: function structure + local types */
|
||||
code_size = p_code_end - p_code;
|
||||
total_size = sizeof(WASMFunction) + local_count;
|
||||
code_size = (uint32)(p_code_end - p_code);
|
||||
|
||||
if (!(func = module->functions[i] = wasm_malloc(total_size))) {
|
||||
total_size = sizeof(WASMFunction) + (uint64)local_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(func = module->functions[i] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load function section failed: "
|
||||
"allocate memory failed.");
|
||||
@ -689,7 +716,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
}
|
||||
|
||||
/* Set function type, local count, code size and code body */
|
||||
memset(func, 0, total_size);
|
||||
memset(func, 0, (uint32)total_size);
|
||||
func->func_type = module->types[type_index];
|
||||
func->local_count = local_count;
|
||||
if (local_count > 0)
|
||||
@ -741,6 +768,7 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 table_count, i;
|
||||
uint64 total_size;
|
||||
WASMTable *table;
|
||||
|
||||
read_leb_uint32(p, p_end, table_count);
|
||||
@ -752,14 +780,16 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
return false;
|
||||
}
|
||||
module->table_count = table_count;
|
||||
if (!(module->tables = wasm_malloc(sizeof(WASMTable) * table_count))) {
|
||||
total_size = sizeof(WASMTable) * (uint64)table_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->tables = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load table section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->tables, 0, sizeof(WASMTable) * table_count);
|
||||
memset(module->tables, 0, (uint32)total_size);
|
||||
|
||||
/* load each table */
|
||||
table = module->tables;
|
||||
@ -784,6 +814,7 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 memory_count, i;
|
||||
uint64 total_size;
|
||||
WASMMemory *memory;
|
||||
|
||||
read_leb_uint32(p, p_end, memory_count);
|
||||
@ -795,14 +826,16 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
return false;
|
||||
}
|
||||
module->memory_count = memory_count;
|
||||
if (!(module->memories = wasm_malloc(sizeof(WASMMemory) * memory_count))) {
|
||||
total_size = sizeof(WASMMemory) * (uint64)memory_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->memories = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load memory section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->memories, 0, sizeof(WASMMemory) * memory_count);
|
||||
memset(module->memories, 0, (uint32)total_size);
|
||||
|
||||
/* load each memory */
|
||||
memory = module->memories;
|
||||
@ -827,20 +860,23 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 global_count, i;
|
||||
uint64 total_size;
|
||||
WASMGlobal *global;
|
||||
|
||||
read_leb_uint32(p, p_end, global_count);
|
||||
|
||||
if (global_count) {
|
||||
module->global_count = global_count;
|
||||
if (!(module->globals = wasm_malloc(sizeof(WASMGlobal) * global_count))) {
|
||||
total_size = sizeof(WASMGlobal) * (uint64)global_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->globals = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load global section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->globals, 0, sizeof(WASMGlobal) * global_count);
|
||||
memset(module->globals, 0, (uint32)total_size);
|
||||
|
||||
global = module->globals;
|
||||
|
||||
@ -872,21 +908,24 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 export_count, i, index;
|
||||
uint8 str_len;
|
||||
uint64 total_size;
|
||||
uint32 str_len;
|
||||
WASMExport *export;
|
||||
|
||||
read_leb_uint32(p, p_end, export_count);
|
||||
|
||||
if (export_count) {
|
||||
module->export_count = export_count;
|
||||
if (!(module->exports = wasm_malloc(sizeof(WASMExport) * export_count))) {
|
||||
total_size = sizeof(WASMExport) * (uint64)export_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->exports = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load export section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->exports, 0, sizeof(WASMExport) * export_count);
|
||||
memset(module->exports, 0, (uint32)total_size);
|
||||
|
||||
export = module->exports;
|
||||
for (i = 0; i < export_count; i++, export++) {
|
||||
@ -965,21 +1004,23 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 table_segment_count, i, j, table_index, function_count, function_index;
|
||||
uint64 total_size;
|
||||
WASMTableSeg *table_segment;
|
||||
|
||||
read_leb_uint32(p, p_end, table_segment_count);
|
||||
|
||||
if (table_segment_count) {
|
||||
module->table_seg_count = table_segment_count;
|
||||
if (!(module->table_segments = wasm_malloc
|
||||
(sizeof(WASMTableSeg) * table_segment_count))) {
|
||||
total_size = sizeof(WASMTableSeg) * (uint64)table_segment_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->table_segments = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load table segment section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->table_segments, 0, sizeof(WASMTableSeg) * table_segment_count);
|
||||
memset(module->table_segments, 0, (uint32)total_size);
|
||||
|
||||
table_segment = module->table_segments;
|
||||
for (i = 0; i < table_segment_count; i++, table_segment++) {
|
||||
@ -993,8 +1034,10 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
|
||||
|
||||
read_leb_uint32(p, p_end, function_count);
|
||||
table_segment->function_count = function_count;
|
||||
if (!(table_segment->func_indexes = (uint32 *)
|
||||
wasm_malloc(sizeof(uint32) * function_count))) {
|
||||
total_size = sizeof(uint32) * (uint64)function_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(table_segment->func_indexes = (uint32 *)
|
||||
wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load table segment section failed: "
|
||||
"allocate memory failed.");
|
||||
@ -1025,6 +1068,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 data_seg_count, i, mem_index, data_seg_len;
|
||||
uint64 total_size;
|
||||
WASMDataSeg *dataseg;
|
||||
InitializerExpression init_expr;
|
||||
|
||||
@ -1032,15 +1076,16 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
|
||||
if (data_seg_count) {
|
||||
module->data_seg_count = data_seg_count;
|
||||
if (!(module->data_segments =
|
||||
wasm_malloc(sizeof(WASMDataSeg*) * data_seg_count))) {
|
||||
total_size = sizeof(WASMDataSeg*) * (uint64)data_seg_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->data_segments = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load data segment section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->data_segments, 0, sizeof(WASMDataSeg*) * data_seg_count);
|
||||
memset(module->data_segments, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < data_seg_count; i++) {
|
||||
read_leb_uint32(p, p_end, mem_index);
|
||||
@ -1051,14 +1096,15 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
read_leb_uint32(p, p_end, data_seg_len);
|
||||
|
||||
if (!(dataseg = module->data_segments[i] =
|
||||
wasm_malloc(sizeof(WASMDataSeg)))) {
|
||||
wasm_malloc((uint32)sizeof(WASMDataSeg)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load data segment section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&dataseg->base_offset, &init_expr, sizeof(init_expr));
|
||||
bh_memcpy_s(&dataseg->base_offset, sizeof(InitializerExpression),
|
||||
&init_expr, sizeof(InitializerExpression));
|
||||
|
||||
dataseg->memory_index = mem_index;
|
||||
dataseg->data_length = data_seg_len;
|
||||
@ -1343,6 +1389,8 @@ create_sections(const uint8 *buf, uint32 size,
|
||||
uint8 section_type;
|
||||
uint32 section_size;
|
||||
|
||||
wasm_assert(!*p_section_list);
|
||||
|
||||
p += 8;
|
||||
while (p < p_end) {
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
@ -1548,6 +1596,25 @@ wasm_loader_unload(WASMModule *module)
|
||||
wasm_free(module);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
void
|
||||
wasm_runtime_set_wasi_args(WASMModule *module,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env_list[], uint32 env_count,
|
||||
const char *argv[], uint32 argc)
|
||||
{
|
||||
module->wasi_args.dir_list = dir_list;
|
||||
module->wasi_args.dir_count = dir_count;
|
||||
module->wasi_args.map_dir_list = map_dir_list;
|
||||
module->wasi_args.map_dir_count = map_dir_count;
|
||||
module->wasi_args.env = env_list;
|
||||
module->wasi_args.env_count = env_count;
|
||||
module->wasi_args.argv = argv;
|
||||
module->wasi_args.argc = argc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
|
||||
typedef struct block_addr {
|
||||
uint8 block_type;
|
||||
@ -1568,7 +1635,8 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
{
|
||||
const uint8 *p = start_addr, *p_end = code_end_addr;
|
||||
uint8 *else_addr = NULL;
|
||||
uint32 block_nested_depth = 1, count, i, u32, u64;
|
||||
uint32 block_nested_depth = 1, count, i, u32;
|
||||
uint64 u64;
|
||||
uint8 opcode, u8;
|
||||
|
||||
#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
|
||||
@ -1586,7 +1654,7 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
BlockAddr block_stack[16] = { 0 }, *block;
|
||||
uint32 j, t;
|
||||
|
||||
i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16);
|
||||
i = (uint32)(((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16));
|
||||
i = i % BLOCK_ADDR_CACHE_SIZE;
|
||||
block = module->block_addr_cache[i];
|
||||
for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) {
|
||||
@ -1613,7 +1681,7 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
case WASM_OP_BLOCK:
|
||||
case WASM_OP_LOOP:
|
||||
case WASM_OP_IF:
|
||||
read_leb_uint32(p, p_end, u32); /* blocktype */
|
||||
read_leb_uint8(p, p_end, u8); /* blocktype */
|
||||
#if WASM_ENABLE_HASH_BLOCK_ADDR == 0
|
||||
if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) {
|
||||
block_stack[block_nested_depth].start_addr = p;
|
||||
@ -1658,7 +1726,7 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
for (t = 0; t < sizeof(block_stack)/sizeof(BlockAddr); t++) {
|
||||
start_addr = block_stack[t].start_addr;
|
||||
if (start_addr) {
|
||||
i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16);
|
||||
i = (uint32)(((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16));
|
||||
i = i % BLOCK_ADDR_CACHE_SIZE;
|
||||
block = module->block_addr_cache[i];
|
||||
for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++)
|
||||
@ -1937,7 +2005,7 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new)
|
||||
uint8 *mem_new;
|
||||
wasm_assert(size_new > size_old);
|
||||
if ((mem_new = wasm_malloc(size_new))) {
|
||||
memcpy(mem_new, mem_old, size_old);
|
||||
bh_memcpy_s(mem_new, size_new, mem_old, size_old);
|
||||
memset(mem_new + size_old, 0, size_new - size_old);
|
||||
wasm_free(mem_old);
|
||||
}
|
||||
@ -2171,8 +2239,9 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
|
||||
#define CHECK_CSP_PUSH() do { \
|
||||
if (frame_csp >= frame_csp_boundary) { \
|
||||
MEM_REALLOC(frame_csp_bottom, frame_csp_size, \
|
||||
frame_csp_size + 8 * sizeof(BranchBlock));\
|
||||
frame_csp_size += 8 * sizeof(BranchBlock); \
|
||||
(uint32)(frame_csp_size \
|
||||
+ 8 * sizeof(BranchBlock))); \
|
||||
frame_csp_size += (uint32)(8 * sizeof(BranchBlock)); \
|
||||
frame_csp_boundary = frame_csp_bottom + \
|
||||
frame_csp_size / sizeof(BranchBlock); \
|
||||
frame_csp = frame_csp_bottom + csp_num; \
|
||||
@ -2281,10 +2350,10 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
uint32 stack_cell_num = 0, csp_num = 0;
|
||||
uint32 frame_ref_size, frame_csp_size;
|
||||
uint8 *param_types, ret_type, *local_types, local_type, global_type;
|
||||
uint32 count, i, local_idx, global_idx, block_return_type, depth, u32;
|
||||
uint32 count, i, local_idx, global_idx, depth, u32;
|
||||
int32 i32, i32_const = 0;
|
||||
int64 i64;
|
||||
uint8 opcode, u8;
|
||||
uint8 opcode, u8, block_return_type;
|
||||
bool return_value = false, is_i32_const = false;
|
||||
|
||||
global_count = module->import_global_count + module->global_count;
|
||||
@ -2332,18 +2401,18 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
break;
|
||||
|
||||
case WASM_OP_BLOCK:
|
||||
read_leb_uint32(p, p_end, block_return_type);
|
||||
read_leb_uint8(p, p_end, block_return_type);
|
||||
PUSH_CSP(BLOCK_TYPE_BLOCK, block_return_type, p);
|
||||
break;
|
||||
|
||||
case WASM_OP_LOOP:
|
||||
read_leb_uint32(p, p_end, block_return_type);
|
||||
read_leb_uint8(p, p_end, block_return_type);
|
||||
PUSH_CSP(BLOCK_TYPE_LOOP, block_return_type, p);
|
||||
break;
|
||||
|
||||
case WASM_OP_IF:
|
||||
POP_I32();
|
||||
read_leb_uint32(p, p_end, block_return_type);
|
||||
read_leb_uint8(p, p_end, block_return_type);
|
||||
PUSH_CSP(BLOCK_TYPE_IF, block_return_type, p);
|
||||
if (!is_i32_const)
|
||||
(frame_csp - 1)->jumped_by_br = true;
|
||||
@ -2535,8 +2604,10 @@ handle_op_br:
|
||||
func_type =
|
||||
module->functions[func_idx - module->import_function_count]->func_type;
|
||||
|
||||
for (idx = func_type->param_count - 1; idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
if (func_type->param_count > 0) {
|
||||
for (idx = (int32)(func_type->param_count - 1); idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
}
|
||||
|
||||
if (func_type->result_count)
|
||||
PUSH_TYPE(func_type->types[func_type->param_count]);
|
||||
@ -2575,8 +2646,10 @@ handle_op_br:
|
||||
|
||||
func_type = module->types[type_idx];
|
||||
|
||||
for (idx = func_type->param_count - 1; idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
if (func_type->param_count > 0) {
|
||||
for (idx = (int32)(func_type->param_count - 1); idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
}
|
||||
|
||||
PUSH_TYPE(func_type->types[func_type->param_count]);
|
||||
break;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "wasm_platform_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "mem_alloc.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
|
||||
static void
|
||||
@ -77,9 +78,9 @@ wasm_runtime_call_wasm(WASMModuleInstance *module_inst,
|
||||
uint32 stack_size;
|
||||
|
||||
/* Set to 8 bytes align */
|
||||
stack = (stack + 7) & ~7;
|
||||
stack_size = exec_env->stack_size
|
||||
- (stack - (uintptr_t)exec_env->stack);
|
||||
stack = (stack + 7) & (uintptr_t)~7;
|
||||
stack_size = (uint32)(exec_env->stack_size
|
||||
- (stack - (uintptr_t)exec_env->stack));
|
||||
|
||||
if (!exec_env->stack || exec_env->stack_size <= 0
|
||||
|| exec_env->stack_size < stack - (uintptr_t)exec_env->stack) {
|
||||
@ -171,18 +172,19 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMMemoryInstance *memory;
|
||||
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
NumBytesPerPage * init_page_count +
|
||||
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
NumBytesPerPage * (uint64)init_page_count +
|
||||
addr_data_size + global_data_size;
|
||||
|
||||
/* Allocate memory space, addr data and global data */
|
||||
if (!(memory = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(memory = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(memory, 0, total_size);
|
||||
memset(memory, 0, (uint32)total_size);
|
||||
memory->cur_page_count = init_page_count;
|
||||
memory->max_page_count = max_page_count;
|
||||
|
||||
@ -238,23 +240,23 @@ memories_instantiate(const WASMModule *module, uint32 addr_data_size,
|
||||
WASMImport *import;
|
||||
uint32 mem_index = 0, i, memory_count =
|
||||
module->import_memory_count + module->memory_count;
|
||||
uint32 total_size;
|
||||
uint64 total_size;
|
||||
WASMMemoryInstance **memories, *memory;
|
||||
|
||||
if (memory_count == 0 && global_data_size > 0)
|
||||
memory_count = 1;
|
||||
|
||||
total_size = sizeof(WASMMemoryInstance*) * memory_count;
|
||||
memories = wasm_malloc(total_size);
|
||||
total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count;
|
||||
|
||||
if (!memories) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(memories = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(memories, 0, total_size);
|
||||
memset(memories, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate memories from import section */
|
||||
import = module->import_memories;
|
||||
@ -329,24 +331,26 @@ tables_instantiate(const WASMModule *module,
|
||||
WASMImport *import;
|
||||
uint32 table_index = 0, i, table_count =
|
||||
module->import_table_count + module->table_count;
|
||||
uint32 total_size = sizeof(WASMTableInstance*) * table_count;
|
||||
WASMTableInstance **tables = wasm_malloc(total_size), *table;
|
||||
uint64 total_size = sizeof(WASMTableInstance*) * (uint64)table_count;
|
||||
WASMTableInstance **tables, *table;
|
||||
|
||||
if (!tables) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(tables = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate table failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(tables, 0, total_size);
|
||||
memset(tables, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate tables from import section */
|
||||
import = module->import_tables;
|
||||
for (i = 0; i < module->import_table_count; i++, import++) {
|
||||
total_size = offsetof(WASMTableInstance, base_addr) +
|
||||
sizeof(uint32) * import->u.table.init_size;
|
||||
if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
|
||||
sizeof(uint32) * (uint64)import->u.table.init_size;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(table = tables[table_index++] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate table failed: "
|
||||
"allocate memory failed.");
|
||||
@ -354,7 +358,7 @@ tables_instantiate(const WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(table, 0, total_size);
|
||||
memset(table, 0, (uint32)total_size);
|
||||
table->cur_size = import->u.table.init_size;
|
||||
table->max_size = import->u.table.max_size;
|
||||
}
|
||||
@ -362,8 +366,9 @@ tables_instantiate(const WASMModule *module,
|
||||
/* instantiate tables from table section */
|
||||
for (i = 0; i < module->table_count; i++) {
|
||||
total_size = offsetof(WASMTableInstance, base_addr) +
|
||||
sizeof(uint32) * module->tables[i].init_size;
|
||||
if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
|
||||
sizeof(uint32) * (uint64)module->tables[i].init_size;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(table = tables[table_index++] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate table failed: "
|
||||
"allocate memory failed.");
|
||||
@ -371,7 +376,7 @@ tables_instantiate(const WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(table, 0, total_size);
|
||||
memset(table, 0, (uint32)total_size);
|
||||
table->cur_size = module->tables[i].init_size;
|
||||
table->max_size = module->tables[i].max_size;
|
||||
}
|
||||
@ -399,24 +404,26 @@ functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
|
||||
static bool
|
||||
function_init_local_offsets(WASMFunctionInstance *func)
|
||||
{
|
||||
uint16 local_offset = 0;
|
||||
uint32 local_offset = 0;
|
||||
WASMType *param_type = func->u.func->func_type;
|
||||
uint32 param_count = param_type->param_count;
|
||||
uint8 *param_types = param_type->types;
|
||||
uint32 local_count = func->u.func->local_count;
|
||||
uint8 *local_types = func->u.func->local_types;
|
||||
uint32 i, total_size = (param_count + local_count) * sizeof(uint16);
|
||||
uint32 i;
|
||||
uint64 total_size = sizeof(uint16) * (uint64)(param_count + local_count);
|
||||
|
||||
if (!(func->local_offsets = wasm_malloc(total_size)))
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(func->local_offsets = wasm_malloc((uint32)total_size)))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < param_count; i++) {
|
||||
func->local_offsets[i] = local_offset;
|
||||
func->local_offsets[i] = (uint16)local_offset;
|
||||
local_offset += wasm_value_type_cell_num(param_types[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < local_count; i++) {
|
||||
func->local_offsets[param_count + i] = local_offset;
|
||||
func->local_offsets[param_count + i] = (uint16)local_offset;
|
||||
local_offset += wasm_value_type_cell_num(local_types[i]);
|
||||
}
|
||||
|
||||
@ -434,17 +441,18 @@ functions_instantiate(const WASMModule *module,
|
||||
WASMImport *import;
|
||||
uint32 i, function_count =
|
||||
module->import_function_count + module->function_count;
|
||||
uint32 total_size = sizeof(WASMFunctionInstance) * function_count;
|
||||
WASMFunctionInstance *functions = wasm_malloc(total_size), *function;
|
||||
uint64 total_size = sizeof(WASMFunctionInstance) * (uint64)function_count;
|
||||
WASMFunctionInstance *functions, *function;
|
||||
|
||||
if (!functions) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(functions = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate function failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(functions, 0, total_size);
|
||||
memset(functions, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate functions from import section */
|
||||
function = functions;
|
||||
@ -459,6 +467,12 @@ functions_instantiate(const WASMModule *module,
|
||||
wasm_type_return_cell_num(import->u.function.func_type);
|
||||
function->local_cell_num = 0;
|
||||
|
||||
function->param_count =
|
||||
(uint16)function->u.func_import->func_type->param_count;
|
||||
function->local_count = 0;
|
||||
function->param_types = function->u.func_import->func_type->types;
|
||||
function->local_types = NULL;
|
||||
|
||||
function++;
|
||||
}
|
||||
|
||||
@ -475,6 +489,11 @@ functions_instantiate(const WASMModule *module,
|
||||
wasm_get_cell_num(function->u.func->local_types,
|
||||
function->u.func->local_count);
|
||||
|
||||
function->param_count = (uint16)function->u.func->func_type->param_count;
|
||||
function->local_count = (uint16)function->u.func->local_count;
|
||||
function->param_types = function->u.func->func_type->types;
|
||||
function->local_types = function->u.func->local_types;
|
||||
|
||||
if (!function_init_local_offsets(function)) {
|
||||
functions_deinstantiate(functions, function_count);
|
||||
return NULL;
|
||||
@ -510,17 +529,18 @@ globals_instantiate(const WASMModule *module,
|
||||
uint32 addr_data_offset = 0, global_data_offset = 0;
|
||||
uint32 i, global_count =
|
||||
module->import_global_count + module->global_count;
|
||||
uint32 total_size = sizeof(WASMGlobalInstance) * global_count;
|
||||
WASMGlobalInstance *globals = wasm_malloc(total_size), *global;
|
||||
uint64 total_size = sizeof(WASMGlobalInstance) * (uint64)global_count;
|
||||
WASMGlobalInstance *globals, *global;
|
||||
|
||||
if (!globals) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(globals = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate global failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(globals, 0, total_size);
|
||||
memset(globals, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate globals from import section */
|
||||
global = globals;
|
||||
@ -535,7 +555,7 @@ globals_instantiate(const WASMModule *module,
|
||||
global_data_offset += wasm_value_type_size(global->type);
|
||||
|
||||
if (global->is_addr)
|
||||
addr_data_offset += sizeof(uint32);
|
||||
addr_data_offset += (uint32)sizeof(uint32);
|
||||
|
||||
global++;
|
||||
}
|
||||
@ -550,7 +570,7 @@ globals_instantiate(const WASMModule *module,
|
||||
global_data_offset += wasm_value_type_size(global->type);
|
||||
|
||||
if (global->is_addr)
|
||||
addr_data_offset += sizeof(uint32);
|
||||
addr_data_offset += (uint32)sizeof(uint32);
|
||||
|
||||
global++;
|
||||
}
|
||||
@ -583,7 +603,7 @@ globals_instantiate_fix(WASMGlobalInstance *globals,
|
||||
}
|
||||
else if (!strcmp(import->u.names.field_name, "DYNAMICTOP_PTR")) {
|
||||
global->initial_value.i32 =
|
||||
NumBytesPerPage * module_inst->default_memory->cur_page_count;
|
||||
(int32)(NumBytesPerPage * module_inst->default_memory->cur_page_count);
|
||||
module_inst->DYNAMICTOP_PTR_offset = global->data_offset;
|
||||
}
|
||||
else if (!strcmp(import->u.names.field_name, "STACKTOP")) {
|
||||
@ -604,7 +624,8 @@ globals_instantiate_fix(WASMGlobalInstance *globals,
|
||||
global->initial_value = globals[init_expr->u.global_index].initial_value;
|
||||
}
|
||||
else {
|
||||
memcpy(&global->initial_value, &init_expr->u, sizeof(int64));
|
||||
bh_memcpy_s(&global->initial_value, sizeof(WASMValue),
|
||||
&init_expr->u, sizeof(init_expr->u));
|
||||
}
|
||||
global++;
|
||||
}
|
||||
@ -647,16 +668,18 @@ export_functions_instantiate(const WASMModule *module,
|
||||
{
|
||||
WASMExportFuncInstance *export_funcs, *export_func;
|
||||
WASMExport *export = module->exports;
|
||||
uint32 i, total_size = sizeof(WASMExportFuncInstance) * export_func_count;
|
||||
uint32 i;
|
||||
uint64 total_size = sizeof(WASMExportFuncInstance) * (uint64)export_func_count;
|
||||
|
||||
if (!(export_func = export_funcs = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(export_func = export_funcs = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate export function failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(export_funcs, 0, total_size);
|
||||
memset(export_funcs, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < module->export_count; i++, export++)
|
||||
if (export->kind == EXPORT_KIND_FUNC) {
|
||||
@ -710,11 +733,209 @@ execute_start_function(WASMModuleInstance *module_inst)
|
||||
return true;
|
||||
|
||||
wasm_assert(!func->is_import_func && func->param_cell_num == 0
|
||||
&& func->ret_cell_num == 0);
|
||||
&& func->ret_cell_num == 0);
|
||||
|
||||
return wasm_runtime_call_wasm(module_inst, NULL, func, 0, NULL);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
static bool
|
||||
wasm_runtime_init_wasi(WASMModuleInstance *module_inst,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env[], uint32 env_count,
|
||||
const char *argv[], uint32 argc,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
size_t *argv_offsets = NULL;
|
||||
char *argv_buf = NULL;
|
||||
size_t *env_offsets = NULL;
|
||||
char *env_buf = NULL;
|
||||
uint64 argv_buf_len = 0, env_buf_len = 0;
|
||||
uint32 argv_buf_offset = 0, env_buf_offset = 0;
|
||||
struct fd_table *curfds;
|
||||
struct fd_prestats *prestats;
|
||||
struct argv_environ_values *argv_environ;
|
||||
int32 offset_argv_offsets = 0, offset_env_offsets = 0;
|
||||
int32 offset_argv_buf = 0, offset_env_buf = 0;
|
||||
int32 offset_curfds = 0;
|
||||
int32 offset_prestats = 0;
|
||||
int32 offset_argv_environ = 0;
|
||||
__wasi_fd_t wasm_fd = 3;
|
||||
int32 raw_fd;
|
||||
char *path, resolved_path[PATH_MAX];
|
||||
uint64 total_size;
|
||||
uint32 i;
|
||||
|
||||
if (!module_inst->default_memory) {
|
||||
argv_environ = module_inst->wasi_ctx.argv_environ = NULL;
|
||||
prestats = module_inst->wasi_ctx.prestats = NULL;
|
||||
curfds = module_inst->wasi_ctx.curfds = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* process argv[0], trip the path and suffix, only keep the program name */
|
||||
for (i = 0; i < argc; i++)
|
||||
argv_buf_len += strlen(argv[i]) + 1;
|
||||
|
||||
total_size = sizeof(size_t) * (uint64)argc;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(offset_argv_offsets = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)total_size))
|
||||
|| argv_buf_len >= UINT32_MAX
|
||||
|| !(offset_argv_buf = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)argv_buf_len))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
argv_offsets = (size_t*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_argv_offsets);
|
||||
argv_buf = (char*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_argv_buf);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv_offsets[i] = argv_buf_offset;
|
||||
bh_strcpy_s(argv_buf + argv_buf_offset,
|
||||
(uint32)argv_buf_len - argv_buf_offset, argv[i]);
|
||||
argv_buf_offset += (uint32)(strlen(argv[i]) + 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < env_count; i++)
|
||||
env_buf_len += strlen(env[i]) + 1;
|
||||
|
||||
total_size = sizeof(size_t) * (uint64)argc;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(offset_env_offsets = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)total_size))
|
||||
|| env_buf_len >= UINT32_MAX
|
||||
|| !(offset_env_buf = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)env_buf_len))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
env_offsets = (size_t*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_env_offsets);
|
||||
env_buf = (char*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_env_buf);
|
||||
|
||||
for (i = 0; i < env_count; i++) {
|
||||
env_offsets[i] = env_buf_offset;
|
||||
bh_strcpy_s(env_buf + env_buf_offset,
|
||||
(uint32)env_buf_len - env_buf_offset, env[i]);
|
||||
env_buf_offset += (uint32)(strlen(env[i]) + 1);
|
||||
}
|
||||
|
||||
if (!(offset_curfds = wasm_runtime_module_malloc
|
||||
(module_inst, sizeof(struct fd_table)))
|
||||
|| !(offset_prestats = wasm_runtime_module_malloc
|
||||
(module_inst, sizeof(struct fd_prestats)))
|
||||
|| !(offset_argv_environ = wasm_runtime_module_malloc
|
||||
(module_inst, sizeof(struct argv_environ_values)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
curfds = module_inst->wasi_ctx.curfds = (struct fd_table*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_curfds);
|
||||
prestats = module_inst->wasi_ctx.prestats = (struct fd_prestats*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_prestats);
|
||||
argv_environ = module_inst->wasi_ctx.argv_environ =
|
||||
(struct argv_environ_values*)wasm_runtime_addr_app_to_native
|
||||
(module_inst, offset_argv_environ);
|
||||
|
||||
fd_table_init(curfds);
|
||||
fd_prestats_init(prestats);
|
||||
|
||||
if (!argv_environ_init(argv_environ,
|
||||
argv_offsets, argc,
|
||||
argv_buf, argv_buf_len,
|
||||
env_offsets, env_count,
|
||||
env_buf, env_buf_len)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: "
|
||||
"init argument environment failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
|
||||
if (!fd_table_insert_existing(curfds, 0, 0)
|
||||
|| !fd_table_insert_existing(curfds, 1, 1)
|
||||
|| !fd_table_insert_existing(curfds, 2, 2)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: init fd table failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wasm_fd = 3;
|
||||
for (i = 0; i < dir_count; i++, wasm_fd++) {
|
||||
path = realpath(dir_list[i], resolved_path);
|
||||
if (!path) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening directory %s: %d\n",
|
||||
dir_list[i], errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
|
||||
if (raw_fd == -1) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening directory %s: %d\n",
|
||||
dir_list[i], errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fd_table_insert_existing(curfds, wasm_fd, raw_fd);
|
||||
fd_prestats_insert(prestats, dir_list[i], wasm_fd);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (offset_curfds != 0)
|
||||
wasm_runtime_module_free(module_inst, offset_curfds);
|
||||
if (offset_prestats != 0)
|
||||
wasm_runtime_module_free(module_inst, offset_prestats);
|
||||
if (offset_argv_environ != 0)
|
||||
wasm_runtime_module_free(module_inst, offset_argv_environ);
|
||||
if (offset_argv_buf)
|
||||
wasm_runtime_module_free(module_inst, offset_argv_buf);
|
||||
if (offset_argv_offsets)
|
||||
wasm_runtime_module_free(module_inst, offset_argv_offsets);
|
||||
if (offset_env_buf)
|
||||
wasm_runtime_module_free(module_inst, offset_env_buf);
|
||||
if (offset_env_offsets)
|
||||
wasm_runtime_module_free(module_inst, offset_env_offsets);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
wasm_runtime_destroy_wasi(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASIContext *wasi_ctx = &module_inst->wasi_ctx;
|
||||
|
||||
if (wasi_ctx->argv_environ)
|
||||
argv_environ_destroy(wasi_ctx->argv_environ);
|
||||
if (wasi_ctx->curfds)
|
||||
fd_table_destroy(wasi_ctx->curfds);
|
||||
if (wasi_ctx->prestats)
|
||||
fd_prestats_destroy(wasi_ctx->prestats);
|
||||
}
|
||||
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstance *module_inst)
|
||||
{
|
||||
return &module_inst->wasi_ctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Instantiate module
|
||||
*/
|
||||
@ -754,14 +975,14 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
return NULL;
|
||||
|
||||
/* Allocate the memory */
|
||||
if (!(module_inst = wasm_malloc(sizeof(WASMModuleInstance)))) {
|
||||
if (!(module_inst = wasm_malloc((uint32)sizeof(WASMModuleInstance)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate module failed: allocate memory failed.");
|
||||
globals_deinstantiate(globals);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(module_inst, 0, sizeof(WASMModuleInstance));
|
||||
memset(module_inst, 0, (uint32)sizeof(WASMModuleInstance));
|
||||
module_inst->global_count = global_count;
|
||||
module_inst->globals = globals;
|
||||
|
||||
@ -818,7 +1039,7 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
else {
|
||||
*(int32*)addr_data = global->initial_value.i32;
|
||||
/* Store the offset to memory data for global of addr */
|
||||
*(int32*)global_data = addr_data - memory_data;
|
||||
*(int32*)global_data = (int32)(addr_data - memory_data);
|
||||
addr_data += sizeof(int32);
|
||||
}
|
||||
global_data += sizeof(int32);
|
||||
@ -826,7 +1047,8 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
case VALUE_TYPE_I64:
|
||||
case VALUE_TYPE_F64:
|
||||
wasm_assert(!global->is_addr);
|
||||
memcpy(global_data, &global->initial_value.i64, sizeof(int64));
|
||||
bh_memcpy_s(global_data, (uint32)(global_data_end - global_data),
|
||||
&global->initial_value.i64, sizeof(int64));
|
||||
global_data += sizeof(int64);
|
||||
break;
|
||||
default:
|
||||
@ -880,7 +1102,8 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(memory_data + base_offset, data_seg->data, length);
|
||||
bh_memcpy_s(memory_data + base_offset, memory_size - base_offset,
|
||||
data_seg->data, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -909,10 +1132,10 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
if ((uint32)table_seg->base_offset.u.i32 <
|
||||
module_inst->default_table->cur_size) {
|
||||
length = table_seg->function_count;
|
||||
if (table_seg->base_offset.u.i32 + length >
|
||||
if ((uint32)table_seg->base_offset.u.i32 + length >
|
||||
module_inst->default_table->cur_size)
|
||||
length = module_inst->default_table->cur_size
|
||||
- table_seg->base_offset.u.i32;
|
||||
- (uint32)table_seg->base_offset.u.i32;
|
||||
/* Check function index */
|
||||
for (j = 0; j < length; j++) {
|
||||
if (table_seg->func_indexes[j] >= module_inst->function_count) {
|
||||
@ -922,12 +1145,31 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
memcpy(table_data + table_seg->base_offset.u.i32,
|
||||
table_seg->func_indexes, length * sizeof(uint32));
|
||||
bh_memcpy_s(table_data + table_seg->base_offset.u.i32,
|
||||
(uint32)((module_inst->default_table->cur_size
|
||||
- (uint32)table_seg->base_offset.u.i32)
|
||||
* sizeof(uint32)),
|
||||
table_seg->func_indexes, (uint32)(length * sizeof(uint32)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
if (!wasm_runtime_init_wasi(module_inst,
|
||||
module->wasi_args.dir_list,
|
||||
module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list,
|
||||
module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env,
|
||||
module->wasi_args.env_count,
|
||||
module->wasi_args.argv,
|
||||
module->wasi_args.argc,
|
||||
error_buf, error_buf_size)) {
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (module->start_function != (uint32)-1) {
|
||||
wasm_assert(module->start_function >= module->import_function_count);
|
||||
module_inst->start_function =
|
||||
@ -968,6 +1210,10 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst)
|
||||
if (!module_inst)
|
||||
return;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_runtime_destroy_wasi(module_inst);
|
||||
#endif
|
||||
|
||||
if (module_inst->memory_count > 0)
|
||||
memories_deinstantiate(module_inst->memories, module_inst->memory_count);
|
||||
else if (module_inst->memories != NULL && module_inst->global_count > 0)
|
||||
@ -1018,15 +1264,15 @@ wasm_runtime_set_ext_memory(WASMModuleInstance *module_inst,
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
{
|
||||
#if WASM_ENABLE_MEMORY_GROW != 0
|
||||
WASMMemoryInstance *memory = module->default_memory;
|
||||
WASMMemoryInstance *new_memory;
|
||||
uint32 total_page_count = inc_page_count + memory->cur_page_count;
|
||||
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
memory->addr_data_size +
|
||||
NumBytesPerPage * total_page_count +
|
||||
NumBytesPerPage * (uint64)total_page_count +
|
||||
memory->global_data_size;
|
||||
|
||||
if (inc_page_count <= 0)
|
||||
@ -1039,7 +1285,8 @@ wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(new_memory = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(new_memory = wasm_malloc((uint32)total_size))) {
|
||||
wasm_runtime_set_exception(module, "fail to enlarge memory.");
|
||||
return false;
|
||||
}
|
||||
@ -1059,11 +1306,13 @@ wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
new_memory->end_addr = new_memory->global_data + memory->global_data_size;
|
||||
|
||||
/* Copy addr data and memory data */
|
||||
memcpy(new_memory->addr_data, memory->addr_data,
|
||||
memory->global_data - memory->addr_data);
|
||||
bh_memcpy_s(new_memory->addr_data,
|
||||
(uint32)(memory->global_data - memory->addr_data),
|
||||
memory->addr_data,
|
||||
(uint32)(memory->global_data - memory->addr_data));
|
||||
/* Copy global data */
|
||||
memcpy(new_memory->global_data, memory->global_data,
|
||||
memory->global_data_size);
|
||||
bh_memcpy_s(new_memory->global_data, new_memory->global_data_size,
|
||||
memory->global_data, memory->global_data_size);
|
||||
/* Init free space of new memory */
|
||||
memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count,
|
||||
0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
|
||||
@ -1097,7 +1346,7 @@ get_package_type(const uint8 *buf, uint32 size)
|
||||
WASMExecEnv*
|
||||
wasm_runtime_create_exec_env(uint32 stack_size)
|
||||
{
|
||||
WASMExecEnv *exec_env = wasm_malloc(sizeof(WASMExecEnv));
|
||||
WASMExecEnv *exec_env = wasm_malloc((uint32)sizeof(WASMExecEnv));
|
||||
if (exec_env) {
|
||||
if (!(exec_env->stack = wasm_malloc(stack_size))) {
|
||||
wasm_free(exec_env);
|
||||
@ -1139,7 +1388,7 @@ wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size)
|
||||
wasm_runtime_set_exception(module_inst, "out of memory");
|
||||
return 0;
|
||||
}
|
||||
return memory->heap_base_offset + (addr - memory->heap_data);
|
||||
return memory->heap_base_offset + (int32)(addr - memory->heap_data);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1161,7 +1410,7 @@ wasm_runtime_module_dup_data(WASMModuleInstance *module_inst,
|
||||
if (buffer_offset != 0) {
|
||||
char *buffer;
|
||||
buffer = wasm_runtime_addr_app_to_native(module_inst, buffer_offset);
|
||||
memcpy(buffer, src, size);
|
||||
bh_memcpy_s(buffer, size, src, size);
|
||||
}
|
||||
return buffer_offset;
|
||||
}
|
||||
@ -1174,7 +1423,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
|
||||
uint8 *addr;
|
||||
|
||||
/* integer overflow check */
|
||||
if(app_offset + size < app_offset) {
|
||||
if(app_offset + (int32)size < app_offset) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1294,11 +1543,11 @@ wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
if (memory->base_addr <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < memory->end_addr)
|
||||
return (uint8*)native_ptr - memory->memory_data;
|
||||
return (int32)((uint8*)native_ptr - memory->memory_data);
|
||||
else if (memory->heap_data <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < memory->heap_data_end)
|
||||
return memory->heap_base_offset
|
||||
+ ((uint8*)native_ptr - memory->heap_data);
|
||||
+ (int32)((uint8*)native_ptr - memory->heap_data);
|
||||
#if WASM_ENABLE_EXT_MEMORY_SPACE != 0
|
||||
else if (module_inst->ext_mem_data
|
||||
&& module_inst->ext_mem_data <= (uint8*)native_ptr
|
||||
@ -1321,14 +1570,14 @@ wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst,
|
||||
|
||||
if (0 <= app_offset && app_offset < memory->heap_base_offset) {
|
||||
app_start_offset = 0;
|
||||
app_end_offset = NumBytesPerPage * memory->cur_page_count;
|
||||
app_end_offset = (int32)(NumBytesPerPage * memory->cur_page_count);
|
||||
}
|
||||
else if (memory->heap_base_offset < app_offset
|
||||
&& app_offset < memory->heap_base_offset
|
||||
+ (memory->heap_data_end - memory->heap_data)) {
|
||||
app_start_offset = memory->heap_base_offset;
|
||||
app_end_offset = memory->heap_base_offset
|
||||
+ (memory->heap_data_end - memory->heap_data);
|
||||
+ (int32)(memory->heap_data_end - memory->heap_data);
|
||||
}
|
||||
#if WASM_ENABLE_EXT_MEMORY_SPACE != 0
|
||||
else if (module_inst->ext_mem_data
|
||||
@ -1479,7 +1728,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
#endif
|
||||
|
||||
if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
|
||||
size = ((uint64)sizeof(uint32)) * argc1;
|
||||
size = sizeof(uint32) * (uint64)argc1;
|
||||
if (size >= UINT_MAX
|
||||
|| !(argv1 = wasm_malloc((uint32)size))) {
|
||||
wasm_runtime_set_exception(module_inst, "allocate memory failed.");
|
||||
@ -1524,7 +1773,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
else {
|
||||
switch (func_type->types[func_type->param_count]) {
|
||||
case VALUE_TYPE_I32:
|
||||
ret[0] = invokeNative_Int32(func_ptr, argv1, argc1);
|
||||
ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, argc1));
|
||||
@ -1587,9 +1836,9 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
|
||||
argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2;
|
||||
if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
|
||||
size = sizeof(uint64) * argc1;
|
||||
size = sizeof(uint64) * (uint64)argc1;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(argv1 = wasm_malloc(size))) {
|
||||
|| !(argv1 = wasm_malloc((uint32)size))) {
|
||||
wasm_runtime_set_exception(module_inst, "allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
@ -1641,7 +1890,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
else {
|
||||
switch (func_type->types[func_type->param_count]) {
|
||||
case VALUE_TYPE_I32:
|
||||
ret[0] = invokeNative_Int32(func_ptr, argv1, n_stacks);
|
||||
ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, n_stacks));
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
#include "wasm.h"
|
||||
#include "wasm_thread.h"
|
||||
#include "wasm_hashmap.h"
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
#include "wasmtime_ssp.h"
|
||||
#include "posix.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -81,6 +85,10 @@ typedef struct WASMGlobalInstance {
|
||||
typedef struct WASMFunctionInstance {
|
||||
/* whether it is import function or WASM function */
|
||||
bool is_import_func;
|
||||
/* parameter count */
|
||||
uint16 param_count;
|
||||
/* local variable count, 0 for import function */
|
||||
uint16 local_count;
|
||||
/* cell num of parameters */
|
||||
uint16 param_cell_num;
|
||||
/* cell num of return type */
|
||||
@ -88,6 +96,10 @@ typedef struct WASMFunctionInstance {
|
||||
/* cell num of local variables, 0 for import function */
|
||||
uint16 local_cell_num;
|
||||
uint16 *local_offsets;
|
||||
/* parameter types */
|
||||
uint8 *param_types;
|
||||
/* local types, NULL for import function */
|
||||
uint8 *local_types;
|
||||
union {
|
||||
WASMFunctionImport *func_import;
|
||||
WASMFunction *func;
|
||||
@ -106,6 +118,14 @@ typedef enum {
|
||||
Package_Type_Unknown = 0xFFFF
|
||||
} PackageType;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
typedef struct WASIContext {
|
||||
struct fd_table *curfds;
|
||||
struct fd_prestats *prestats;
|
||||
struct argv_environ_values *argv_environ;
|
||||
} WASIContext;
|
||||
#endif
|
||||
|
||||
typedef struct WASMModuleInstance {
|
||||
/* Module instance type, for module instance loaded from
|
||||
WASM bytecode binary, this field is Wasm_Module_Bytecode;
|
||||
@ -133,6 +153,10 @@ typedef struct WASMModuleInstance {
|
||||
|
||||
WASMModule *module;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
WASIContext wasi_ctx;
|
||||
#endif
|
||||
|
||||
uint32 DYNAMICTOP_PTR_offset;
|
||||
uint32 temp_ret;
|
||||
uint32 llvm_stack;
|
||||
@ -271,7 +295,7 @@ wasm_runtime_get_exception(WASMModuleInstance *module);
|
||||
* @return return true if enlarge successfully, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count);
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASMModuleInstance *
|
||||
|
||||
Reference in New Issue
Block a user