Remove the binding between current thread and module instance and bugs fix (#131)
Remove wasm_export_api.h that may confuse Implement wasm_runtime_validate_app_str_addr() Fix bugs of loader and pass more spec cases Signed-off-by: Weining Lu <weining.x.lu@intel.com>
This commit is contained in:
@ -255,37 +255,23 @@ void
|
||||
wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* Attach the current native thread to a WASM module instance.
|
||||
* A native thread cannot be attached simultaneously to two WASM module
|
||||
* instances. The WASM module instance will be attached to the native
|
||||
* thread which it is instantiated in by default.
|
||||
* Set custom data to WASM module instance.
|
||||
*
|
||||
* @param module_inst the WASM module instance to attach
|
||||
* @param thread_data the thread data that current native thread requires
|
||||
* the WASM module instance to store
|
||||
*
|
||||
* @return true if SUCCESS, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_attach_current_thread(wasm_module_inst_t module_inst,
|
||||
void *thread_data);
|
||||
|
||||
/**
|
||||
* Detach the current native thread from a WASM module instance.
|
||||
*
|
||||
* @param module_inst the WASM module instance to detach
|
||||
* @param module_inst the WASM module instance
|
||||
* @param custom_data the custom data to be set
|
||||
*/
|
||||
void
|
||||
wasm_runtime_detach_current_thread(wasm_module_inst_t module_inst);
|
||||
|
||||
wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
|
||||
void *custom_data);
|
||||
/**
|
||||
* Get the thread data that the current native thread requires the WASM
|
||||
* module instance to store when attaching.
|
||||
* Get the custom data within a WASM module instance.
|
||||
*
|
||||
* @return the thread data stored when attaching
|
||||
* @param module_inst the WASM module instance
|
||||
*
|
||||
* @return the custom data (NULL if not set yet)
|
||||
*/
|
||||
void*
|
||||
wasm_runtime_get_current_thread_data();
|
||||
wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* Allocate memory from the heap of WASM module instance
|
||||
@ -342,6 +328,23 @@ bool
|
||||
wasm_runtime_validate_app_addr(wasm_module_inst_t module_inst,
|
||||
int32_t app_offset, uint32_t size);
|
||||
|
||||
/**
|
||||
* Similar to wasm_runtime_validate_app_addr(), except that the size parameter
|
||||
* is not provided. This function validates the app string address, check whether it
|
||||
* belongs to WASM module instance's address space, or in its heap space or
|
||||
* memory space. Moreover, it checks whether it is the offset of a string that
|
||||
* is end with '\0'.
|
||||
* @param module_inst the WASM module instance
|
||||
* @param app_str_offset the app address of the string to validate, which is a
|
||||
* relative address
|
||||
*
|
||||
* @return true if success, false otherwise. If failed, an exception will
|
||||
* be thrown.
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_validate_app_str_addr(wasm_module_inst_t module_inst,
|
||||
int32_t app_str_offset);
|
||||
|
||||
/**
|
||||
* Validate the native address, check whether it belongs to WASM module
|
||||
* instance's address space, or in its heap space or memory space.
|
||||
|
||||
@ -18,7 +18,8 @@
|
||||
|
||||
void invokeNative(void (*native_code)(), uint32 argv[], uint32 argc)
|
||||
{
|
||||
WASMThread *self;
|
||||
wasm_assert(argc >= sizeof(WASMModuleInstance *)/sizeof(uint32));
|
||||
|
||||
switch(argc) {
|
||||
case 0:
|
||||
native_code();
|
||||
@ -84,9 +85,11 @@ void invokeNative(void (*native_code)(), uint32 argv[], uint32 argc)
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], argv[19]);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
/* FIXME: If this happen, add more cases. */
|
||||
self = wasm_runtime_get_self();
|
||||
wasm_runtime_set_exception(self->module_inst, "the argument number of native function exceeds maximum");
|
||||
WASMModuleInstance *module_inst = *(WASMModuleInstance**)argv;
|
||||
wasm_runtime_set_exception(module_inst, "the argument number of native function exceeds maximum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2178,10 +2178,11 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
}
|
||||
|
||||
void
|
||||
wasm_interp_call_wasm(WASMFunctionInstance *function,
|
||||
wasm_interp_call_wasm(WASMModuleInstance *module_inst,
|
||||
WASMFunctionInstance *function,
|
||||
uint32 argc, uint32 argv[])
|
||||
{
|
||||
WASMThread *self = wasm_runtime_get_self();
|
||||
WASMThread *self = &module_inst->main_tlr;
|
||||
WASMRuntimeFrame *prev_frame = wasm_thread_get_cur_frame(self);
|
||||
WASMInterpFrame *frame, *outs_area;
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct WASMModuleInstance;
|
||||
struct WASMFunctionInstance;
|
||||
|
||||
typedef struct WASMInterpFrame {
|
||||
@ -69,7 +70,8 @@ wasm_interp_interp_frame_size(unsigned all_cell_num)
|
||||
}
|
||||
|
||||
void
|
||||
wasm_interp_call_wasm(struct WASMFunctionInstance *function,
|
||||
wasm_interp_call_wasm(struct WASMModuleInstance *module_inst,
|
||||
struct WASMFunctionInstance *function,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -60,14 +60,14 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
||||
*p_offset += 1;
|
||||
result |= ((byte & 0x7f) << shift);
|
||||
shift += 7;
|
||||
bcnt += 1;
|
||||
if ((byte & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
bcnt += 1;
|
||||
}
|
||||
if (bcnt > (maxbits + 7 - 1) / 7) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"WASM module load failed: unsigned LEB overflow.");
|
||||
"integer representation too long");
|
||||
return false;
|
||||
}
|
||||
if (sign && (shift < maxbits) && (byte & 0x40)) {
|
||||
@ -625,17 +625,19 @@ 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 code_count, code_size, type_index, i, j, k, local_type_index;
|
||||
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;
|
||||
WASMFunction *func;
|
||||
|
||||
read_leb_uint32(p, p_end, func_count);
|
||||
|
||||
read_leb_uint32(p_code, buf_code_end, code_count);
|
||||
if (buf_code)
|
||||
read_leb_uint32(p_code, buf_code_end, code_count);
|
||||
|
||||
if (func_count != code_count) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load function section failed: invalid function count.");
|
||||
"function and code section have inconsistent lengths");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -677,6 +679,11 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
/* Calculate total local count */
|
||||
for (j = 0; j < local_set_count; j++) {
|
||||
read_leb_uint32(p_code, buf_code_end, sub_local_count);
|
||||
if (sub_local_count > UINT32_MAX - local_count) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"too many locals");
|
||||
return false;
|
||||
}
|
||||
read_leb_uint8(p_code, buf_code_end, type);
|
||||
local_count += sub_local_count;
|
||||
}
|
||||
@ -1084,11 +1091,29 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
}
|
||||
|
||||
static bool
|
||||
load_code_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
load_code_section(const uint8 *buf, const uint8 *buf_end,
|
||||
const uint8 *buf_func,
|
||||
const uint8 *buf_func_end,
|
||||
WASMModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
/* code has been loaded in function section, so pass it here */
|
||||
/* TODO: should check if there really have section_size code bytes */
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
const uint8 *p_func = buf_func;
|
||||
uint32 func_count = 0, code_count;
|
||||
|
||||
/* code has been loaded in function section, so pass it here, just check
|
||||
* whether function and code section have inconsistent lengths */
|
||||
read_leb_uint32(p, p_end, code_count);
|
||||
|
||||
if (buf_func)
|
||||
read_leb_uint32(p_func, buf_func_end, func_count);
|
||||
|
||||
if (func_count != code_count) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"function and code section have inconsistent lengths");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("Load code segment section success.\n");
|
||||
return true;
|
||||
}
|
||||
@ -1132,14 +1157,19 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMSection *section = sections;
|
||||
const uint8 *buf, *buf_end, *buf_code = NULL, *buf_code_end = NULL;
|
||||
const uint8 *buf, *buf_end, *buf_code = NULL, *buf_code_end = NULL,
|
||||
*buf_func = NULL, *buf_func_end = NULL;
|
||||
uint32 i;
|
||||
|
||||
/* Find code and function sections if have */
|
||||
while (section) {
|
||||
if (section->section_type == SECTION_TYPE_CODE) {
|
||||
buf_code = section->section_body;
|
||||
buf_code_end = buf_code + section->section_body_size;
|
||||
break;
|
||||
}
|
||||
else if (section->section_type == SECTION_TYPE_FUNC) {
|
||||
buf_func = section->section_body;
|
||||
buf_func_end = buf_func + section->section_body_size;
|
||||
}
|
||||
section = section->next;
|
||||
}
|
||||
@ -1151,6 +1181,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
switch (section->section_type) {
|
||||
case SECTION_TYPE_USER:
|
||||
/* unsupported user section, ignore it. */
|
||||
/* add a check to pass spec test case */
|
||||
CHECK_BUF(buf, buf_end, 1);
|
||||
break;
|
||||
case SECTION_TYPE_TYPE:
|
||||
if (!load_type_section(buf, buf_end, module, error_buf, error_buf_size))
|
||||
@ -1161,11 +1193,6 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
return false;
|
||||
break;
|
||||
case SECTION_TYPE_FUNC:
|
||||
if (!buf_code) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"WASM module load failed: find code section failed.");
|
||||
return false;
|
||||
}
|
||||
if (!load_function_section(buf, buf_end, buf_code, buf_code_end,
|
||||
module, error_buf, error_buf_size))
|
||||
return false;
|
||||
@ -1195,7 +1222,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
return false;
|
||||
break;
|
||||
case SECTION_TYPE_CODE:
|
||||
if (!load_code_section(buf, buf_end, module, error_buf, error_buf_size))
|
||||
if (!load_code_section(buf, buf_end, buf_func, buf_func_end,
|
||||
module, error_buf, error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
case SECTION_TYPE_DATA:
|
||||
@ -1356,7 +1384,7 @@ create_sections(const uint8 *buf, uint32 size,
|
||||
p += section_size;
|
||||
}
|
||||
else {
|
||||
set_error_buf(error_buf, error_buf_size, "invalid section type");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid section id");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2540,7 +2568,14 @@ handle_op_br:
|
||||
}
|
||||
|
||||
read_leb_uint32(p, p_end, type_idx);
|
||||
read_leb_uint8(p, p_end, u8); /* 0x00 */
|
||||
|
||||
/* reserved byte 0x00 */
|
||||
if (*p++ != 0x00) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"zero flag expected");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
POP_I32();
|
||||
|
||||
if (type_idx >= module->type_count) {
|
||||
@ -2752,13 +2787,23 @@ handle_op_br:
|
||||
|
||||
case WASM_OP_MEMORY_SIZE:
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, u32); /* 0x00 */
|
||||
/* reserved byte 0x00 */
|
||||
if (*p++ != 0x00) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"zero flag expected");
|
||||
goto fail;
|
||||
}
|
||||
PUSH_I32();
|
||||
break;
|
||||
|
||||
case WASM_OP_MEMORY_GROW:
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, u32); /* 0x00 */
|
||||
/* reserved byte 0x00 */
|
||||
if (*p++ != 0x00) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"zero flag expected");
|
||||
goto fail;
|
||||
}
|
||||
POP_I32();
|
||||
PUSH_I32();
|
||||
break;
|
||||
|
||||
@ -44,8 +44,6 @@ wasm_runtime_init()
|
||||
if (ws_thread_sys_init() != 0)
|
||||
return false;
|
||||
|
||||
wasm_runtime_set_tlr(NULL);
|
||||
|
||||
wasm_native_init();
|
||||
return true;
|
||||
}
|
||||
@ -53,7 +51,6 @@ wasm_runtime_init()
|
||||
void
|
||||
wasm_runtime_destroy()
|
||||
{
|
||||
wasm_runtime_set_tlr(NULL);
|
||||
ws_thread_sys_destroy();
|
||||
}
|
||||
|
||||
@ -71,7 +68,7 @@ wasm_runtime_call_wasm(WASMModuleInstance *module_inst,
|
||||
unsigned argc, uint32 argv[])
|
||||
{
|
||||
/* Only init stack when no application is running. */
|
||||
if (!wasm_runtime_get_self()->cur_frame) {
|
||||
if (!module_inst->main_tlr.cur_frame) {
|
||||
if (!exec_env) {
|
||||
if (!module_inst->wasm_stack) {
|
||||
if (!(module_inst->wasm_stack =
|
||||
@ -107,7 +104,7 @@ wasm_runtime_call_wasm(WASMModuleInstance *module_inst,
|
||||
}
|
||||
}
|
||||
|
||||
wasm_interp_call_wasm(function, argc, argv);
|
||||
wasm_interp_call_wasm(module_inst, function, argc, argv);
|
||||
return !wasm_runtime_get_exception(module_inst) ? true : false;
|
||||
}
|
||||
|
||||
@ -959,9 +956,7 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
module_inst->wasm_stack_size = stack_size;
|
||||
module_inst->main_tlr.module_inst = module_inst;
|
||||
|
||||
/* Bind thread data with current native thread:
|
||||
set thread local root to current thread. */
|
||||
wasm_runtime_set_tlr(&module_inst->main_tlr);
|
||||
/* The native thread handle may be used in future, e.g multiple threads. */
|
||||
module_inst->main_tlr.handle = ws_self_thread();
|
||||
|
||||
/* Execute __post_instantiate and start function */
|
||||
@ -1133,34 +1128,17 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *env)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_attach_current_thread(WASMModuleInstance *module_inst,
|
||||
void *thread_data)
|
||||
{
|
||||
wasm_runtime_set_tlr(&module_inst->main_tlr);
|
||||
module_inst->main_tlr.handle = ws_self_thread();
|
||||
module_inst->thread_data = thread_data;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_detach_current_thread(WASMModuleInstance *module_inst)
|
||||
wasm_runtime_set_custom_data(WASMModuleInstance *module_inst,
|
||||
void *custom_data)
|
||||
{
|
||||
module_inst->thread_data = NULL;
|
||||
module_inst->custom_data = custom_data;
|
||||
}
|
||||
|
||||
void*
|
||||
wasm_runtime_get_current_thread_data()
|
||||
wasm_runtime_get_custom_data(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMThread *tlr = wasm_runtime_get_self();
|
||||
return (tlr && tlr->module_inst) ? tlr->module_inst->thread_data : NULL;
|
||||
}
|
||||
|
||||
WASMModuleInstance *
|
||||
wasm_runtime_get_current_module_inst()
|
||||
{
|
||||
WASMThread *tlr = wasm_runtime_get_self();
|
||||
return tlr ? tlr->module_inst : NULL;
|
||||
return module_inst->custom_data;
|
||||
}
|
||||
|
||||
int32
|
||||
@ -1247,6 +1225,30 @@ fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_validate_app_str_addr(WASMModuleInstance *module_inst,
|
||||
int32 app_str_offset)
|
||||
{
|
||||
int32 app_end_offset;
|
||||
char *str, *str_end;
|
||||
|
||||
if (!wasm_runtime_get_app_addr_range(module_inst, app_str_offset,
|
||||
NULL, &app_end_offset))
|
||||
goto fail;
|
||||
|
||||
str = wasm_runtime_addr_app_to_native(module_inst, app_str_offset);
|
||||
str_end = str + (app_end_offset - app_str_offset);
|
||||
while (str < str_end && *str != '\0')
|
||||
str++;
|
||||
if (str == str_end)
|
||||
goto fail;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
|
||||
void *native_ptr, uint32 size)
|
||||
|
||||
@ -164,8 +164,9 @@ typedef struct WASMModuleInstance {
|
||||
/* The exception buffer of wasm interpreter for current thread. */
|
||||
char cur_exception[128];
|
||||
|
||||
/* The thread data of the attaching thread */
|
||||
void *thread_data;
|
||||
/* The custom data that can be set/get by
|
||||
* wasm_runtime_set_custom_data/wasm_runtime_get_custom_data */
|
||||
void *custom_data;
|
||||
|
||||
/* Main Thread */
|
||||
WASMThread main_tlr;
|
||||
@ -283,38 +284,57 @@ wasm_runtime_get_exception(WASMModuleInstance *module);
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
WASMModuleInstance *
|
||||
wasm_runtime_get_current_module_inst();
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
int32
|
||||
wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
void
|
||||
wasm_runtime_module_free(WASMModuleInstance *module_inst, int32 ptr);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
bool
|
||||
wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
|
||||
int32 app_offset, uint32 size);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
bool
|
||||
wasm_runtime_validate_app_str_addr(WASMModuleInstance *module_inst,
|
||||
int32 app_offset);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
bool
|
||||
wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
|
||||
void *native_ptr, uint32 size);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
void *
|
||||
wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst,
|
||||
int32 app_offset);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
/* See wasm_export.h for description */
|
||||
int32
|
||||
wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
|
||||
void *native_ptr);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
bool
|
||||
wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst,
|
||||
int32_t app_offset,
|
||||
int32_t *p_app_start_offset,
|
||||
int32_t *p_app_end_offset);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
bool
|
||||
wasm_runtime_get_native_addr_range(WASMModuleInstance *module_inst,
|
||||
uint8_t *native_ptr,
|
||||
uint8_t **p_native_start_addr,
|
||||
uint8_t **p_native_end_addr);
|
||||
|
||||
bool
|
||||
wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
WASMModuleInstance *module_inst,
|
||||
|
||||
Reference in New Issue
Block a user