Enable WASI feature, enhance security and add SGX sample (#142)

Change emcc to clang
Refine interpreter to improve perforamnce
This commit is contained in:
Weining
2019-11-20 21:16:36 +08:00
committed by wenyongh
parent 29c7c743e9
commit 27f246b5f3
159 changed files with 9543 additions and 3789 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -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 *