re-org bh_definition.c && introduce wamr fast interpreter (#189)

Co-authored-by: Xu Jun
This commit is contained in:
Xu Jun
2020-03-07 22:20:38 +08:00
committed by GitHub
parent cfcaca3d35
commit 057c849fc0
44 changed files with 4118 additions and 1066 deletions

View File

@ -1703,7 +1703,7 @@ create_sections(const uint8 *buf, uint32 size,
memset(section, 0, sizeof(AOTSection));
section->section_type = (int32)section_type;
section->section_body = p;
section->section_body = (uint8*)p;
section->section_body_size = section_size;
if (section_type == AOT_SECTION_TYPE_TEXT) {

View File

@ -7,18 +7,13 @@
#define _WASM_NATIVE_H
#include "bh_common.h"
#include "../include/wasm_export.h"
#include "../interpreter/wasm.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct NativeSymbol {
const char *symbol;
void *func_ptr;
const char *signature;
} NativeSymbol;
typedef struct NativeSymbolsNode {
struct NativeSymbolsNode *next;
const char *module_name;

View File

@ -50,6 +50,49 @@ wasm_runtime_destroy()
vm_thread_sys_destroy();
}
bool
wasm_runtime_full_init(RuntimeInitArgs *init_args)
{
if (init_args->mem_alloc_type == Alloc_With_Pool) {
void *heap_buf = init_args->mem_alloc.pool.heap_buf;
uint32 heap_size = init_args->mem_alloc.pool.heap_size;
if (bh_memory_init_with_pool(heap_buf, heap_size) != 0)
return false;
}
else if (init_args->mem_alloc_type == Alloc_With_Allocator) {
void *malloc_func = init_args->mem_alloc.allocator.malloc_func;
void *free_func = init_args->mem_alloc.allocator.free_func;
if (bh_memory_init_with_allocator(malloc_func, free_func) != 0)
return false;
}
else
return false;
if (!wasm_runtime_init())
goto fail1;
if (init_args->n_native_symbols > 0
&& !wasm_runtime_register_natives(init_args->native_module_name,
init_args->native_symbols,
init_args->n_native_symbols))
goto fail2;
return true;
fail2:
wasm_runtime_destroy();
fail1:
bh_memory_destroy();
return false;
}
void
wasm_runtime_full_destroy()
{
wasm_runtime_destroy();
bh_memory_destroy();
}
PackageType
get_package_type(const uint8 *buf, uint32 size)
{
@ -202,7 +245,7 @@ wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
}
WASMFunctionInstanceCommon *
wasm_runtime_lookup_function(const WASMModuleInstanceCommon *module_inst,
wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
const char *name,
const char *signature)
{
@ -339,7 +382,7 @@ wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst)
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode)
return ((WASMModuleInstance*)module_inst)->custom_data;
#endif
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT)
return ((AOTModuleInstance*)module_inst)->custom_data.ptr;
@ -619,7 +662,7 @@ wasm_runtime_set_wasi_args(WASMModuleCommon *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)
char *argv[], int argc)
{
WASIArguments *wasi_args = NULL;
@ -649,7 +692,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *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 *argv[], uint32 argc,
char *error_buf, uint32 error_buf_size)
{
WASIContext *wasi_ctx;

View File

@ -11,6 +11,7 @@
#include "bh_thread.h"
#include "wasm_exec_env.h"
#include "wasm_native.h"
#include "../include/wasm_export.h"
#include "../interpreter/wasm.h"
#if WASM_ENABLE_LIBC_WASI != 0
#include "wasmtime_ssp.h"
@ -24,13 +25,6 @@ extern "C" {
#define wasm_malloc bh_malloc
#define wasm_free bh_free
/* Package Type */
typedef enum {
Wasm_Module_Bytecode = 0,
Wasm_Module_AoT,
Package_Type_Unknown = 0xFFFF
} PackageType;
typedef struct WASMModuleCommon {
/* Module type, for module loaded from WASM bytecode binary,
this field is Wasm_Module_Bytecode, and this structure should
@ -53,19 +47,6 @@ typedef struct WASMModuleInstanceCommon {
uint8 module_inst_data[1];
} WASMModuleInstanceCommon;
typedef void WASMFunctionInstanceCommon;
/* WASM section */
typedef struct WASMSection {
struct WASMSection *next;
/* section type */
int section_type;
/* section body, not include type and size */
const uint8 *section_body;
/* section body size */
uint32 section_body_size;
} WASMSection, AOTSection;
#if WASM_ENABLE_LIBC_WASI != 0
typedef struct WASIContext {
struct fd_table *curfds;
@ -74,6 +55,9 @@ typedef struct WASIContext {
} WASIContext;
#endif
typedef package_type_t PackageType;
typedef wasm_section_t WASMSection, AOTSection;
/* See wasm_export.h for description */
bool
wasm_runtime_init();
@ -82,6 +66,14 @@ wasm_runtime_init();
void
wasm_runtime_destroy();
/* See wasm_export.h for description */
bool
wasm_runtime_full_init(RuntimeInitArgs *init_args);
/* See wasm_export.h for description */
void
wasm_runtime_full_destroy();
/* See wasm_export.h for description */
PackageType
get_package_type(const uint8 *buf, uint32 size);
@ -112,7 +104,7 @@ wasm_runtime_deinstantiate(WASMModuleInstanceCommon *module_inst);
/* See wasm_export.h for description */
WASMFunctionInstanceCommon *
wasm_runtime_lookup_function(const WASMModuleInstanceCommon *module_inst,
wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
const char *name, const char *signature);
/* See wasm_export.h for description */
@ -245,7 +237,7 @@ wasm_runtime_set_wasi_args(WASMModuleCommon *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);
char *argv[], int argc);
/* See wasm_export.h for description */
bool
@ -260,7 +252,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *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 *argv[], uint32 argc,
char *error_buf, uint32 error_buf_size);
void

View File

@ -6,6 +6,8 @@
#ifndef _LIB_EXPORT_H_
#define _LIB_EXPORT_H_
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -31,25 +33,9 @@ typedef struct NativeSymbol {
*
* @return the number of the exported API
*/
int
uint32_t
get_base_lib_export_apis(NativeSymbol **p_base_lib_apis);
/**
* Get the exported APIs of extended lib, this API isn't provided by WASM VM,
* it must be provided by developer to register the extended native APIs,
* for example, developer can register his native APIs to extended_native_symbol_defs,
* array, and include file ext_lib_export.h which implements this API.
* And if developer hasn't any native API to register, he can define an empty
* extended_native_symbol_defs array, and then include file ext_lib_export.h to
* implements this API.
*
* @param p_base_lib_apis return the exported API array of extend lib
*
* @return the number of the exported API
*/
int
get_extend_lib_export_apis(NativeSymbol **p_base_lib_apis);
#ifdef __cplusplus
}
#endif

View File

@ -9,6 +9,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include "lib_export.h"
#include "bh_memory.h"
#ifdef __cplusplus
@ -25,21 +26,19 @@ struct WASMModuleInstanceCommon;
typedef struct WASMModuleInstanceCommon *wasm_module_inst_t;
/* Function instance */
struct WASMFunctionInstanceCommon;
typedef struct WASMFunctionInstanceCommon *wasm_function_inst_t;
typedef void WASMFunctionInstanceCommon;
typedef WASMFunctionInstanceCommon *wasm_function_inst_t;
/* WASM section */
typedef struct wasm_section {
struct wasm_section *next;
typedef struct wasm_section_t {
struct wasm_section_t *next;
/* section type */
int section_type;
/* section body, not include type and size */
uint8_t *section_body;
/* section body size */
uint32_t section_body_size;
} wasm_section_t, *wasm_section_list_t;
typedef wasm_section_t aot_section_t, *aot_section_list_t;
} wasm_section_t, aot_section_t, *wasm_section_list_t, *aot_section_list_t;
/* Execution environment, e.g. stack info */
struct WASMExecEnv;
@ -52,6 +51,31 @@ typedef enum {
Package_Type_Unknown = 0xFFFF
} package_type_t;
/* Memory allocator type */
typedef enum {
Alloc_With_Pool = 0,
Alloc_With_Allocator
} mem_alloc_type_t;
/* WASM runtime initialize arguments */
typedef struct RuntimeInitArgs {
mem_alloc_type_t mem_alloc_type;
union {
struct {
void *heap_buf;
uint32_t heap_size;
} pool;
struct {
void *malloc_func;
void *free_func;
} allocator;
} mem_alloc;
const char *native_module_name;
NativeSymbol *native_symbols;
uint32_t n_native_symbols;
} RuntimeInitArgs;
/**
* Initialize the WASM runtime environment.
*
@ -66,6 +90,25 @@ wasm_runtime_init();
void
wasm_runtime_destroy();
/**
* Initialize the WASM runtime environment, and also initialize
* the memory allocator and register native symbols, which are specified
* with init arguments
*
* @param init_args specifies the init arguments
*
* @return return true if success, false otherwise
*/
bool
wasm_runtime_full_init(RuntimeInitArgs *init_args);
/**
* Destroy the wasm runtime environment, and also destroy
* the memory allocator and registered native symbols
*/
void
wasm_runtime_full_destroy();
/**
* Get the package type of a buffer.
*
@ -167,7 +210,7 @@ wasm_runtime_lookup_wasi_start_function(wasm_module_inst_t module_inst);
* @return the function instance found
*/
wasm_function_inst_t
wasm_runtime_lookup_function(const wasm_module_inst_t module_inst,
wasm_runtime_lookup_function(wasm_module_inst_t const module_inst,
const char *name, const char *signature);
/**

View File

@ -7,7 +7,17 @@ add_definitions (-DWASM_ENABLE_INTERP=1)
include_directories(${IWASM_INTERP_DIR})
file (GLOB_RECURSE source_all ${IWASM_INTERP_DIR}/*.c)
if (WAMR_BUILD_FAST_INTERP EQUAL 1)
set (INTERPRETER "wasm_interp_fast.c")
else ()
set (INTERPRETER "wasm_interp.c")
endif ()
file (GLOB_RECURSE source_all
${IWASM_INTERP_DIR}/wasm_loader.c
${IWASM_INTERP_DIR}/wasm_runtime.c
${IWASM_INTERP_DIR}/${INTERPRETER}
)
set (IWASM_INTERP_SOURCE ${source_all})

View File

@ -189,6 +189,12 @@ typedef struct WASMFunction {
bool has_op_func_call;
uint32 code_size;
uint8 *code;
#if WASM_ENABLE_FAST_INTERP != 0
uint32 code_compiled_size;
uint8 *code_compiled;
uint8 *consts;
uint32 const_cell_num;
#endif
} WASMFunction;
typedef struct WASMGlobal {
@ -231,7 +237,7 @@ typedef struct WASIArguments {
uint32 map_dir_count;
const char **env;
uint32 env_count;
const char **argv;
char **argv;
uint32 argc;
} WASIArguments;
#endif

View File

@ -225,27 +225,24 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
#define CHECK_MEMORY_OVERFLOW() do { \
uint32 offset1 = offset + addr; \
uint64 offset1 = offset + addr; \
/* if (flags != 2) \
LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\
/* The WASM spec doesn't require that the dynamic address operand must be \
unsigned, so we don't check whether integer overflow or not here. */ \
/* if (offset1 < offset) \
goto out_of_bounds; */ \
if (offset1 < memory_data_size) { \
if (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= memory_data_size) { \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->memory_data + offset1; \
if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > memory->end_addr) \
goto out_of_bounds; \
} \
else if (offset1 > heap_base_offset \
&& offset1 < heap_base_offset + heap_data_size) { \
else if (offset1 > DEFAULT_APP_HEAP_BASE_OFFSET \
&& (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= \
DEFAULT_APP_HEAP_BASE_OFFSET + heap_data_size)) { \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->heap_data + offset1 - memory->heap_base_offset; \
if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > memory->heap_data_end) \
goto out_of_bounds; \
} \
else \
goto out_of_bounds; \
@ -795,7 +792,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMMemoryInstance *memory = module->default_memory;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint32 memory_data_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0;
uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
uint8 *global_data = memory ? memory->global_data : NULL;
WASMTableInstance *table = module->default_table;
@ -1080,7 +1076,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_GET_LOCAL_FAST):
HANDLE_OP (EXT_OP_GET_LOCAL_FAST):
{
local_offset = *frame_ip++;
if (local_offset & 0x80)
@ -1111,7 +1107,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_SET_LOCAL_FAST):
HANDLE_OP (EXT_OP_SET_LOCAL_FAST):
{
local_offset = *frame_ip++;
if (local_offset & 0x80)
@ -1143,7 +1139,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_TEE_LOCAL_FAST):
HANDLE_OP (EXT_OP_TEE_LOCAL_FAST):
{
local_offset = *frame_ip++;
if (local_offset & 0x80)
@ -2225,6 +2221,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_UNUSED_0x25):
HANDLE_OP (WASM_OP_UNUSED_0x26):
HANDLE_OP (WASM_OP_UNUSED_0x27):
/* Used by fast interpreter */
HANDLE_OP (EXT_OP_SET_LOCAL_FAST_I64):
HANDLE_OP (EXT_OP_TEE_LOCAL_FAST_I64):
HANDLE_OP (EXT_OP_COPY_STACK_TOP):
HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64):
{
wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
goto got_exception;

View File

@ -26,6 +26,13 @@ typedef struct WASMInterpFrame {
/* Instruction pointer of the bytecode array. */
uint8 *ip;
#if WASM_ENABLE_FAST_INTERP != 0
/* return offset of current frame.
the callee will put return value here */
uint32 ret_offset;
uint32 *lp;
uint32 operand[1];
#else
/* Operand stack top pointer of the current frame. The bottom of
the stack is the next cell after the last local variable. */
uint32 *sp_bottom;
@ -43,6 +50,7 @@ typedef struct WASMInterpFrame {
ref to frame end: data types of local vairables and stack data
*/
uint32 lp[1];
#endif
} WASMInterpFrame;
/**

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -238,13 +238,19 @@ typedef enum WASMOpcode {
WASM_OP_F64_REINTERPRET_I64 = 0xbf, /* f64.reinterpret/i64 */
/* drop/select specified types*/
WASM_OP_DROP_64 = 0xc0,
WASM_OP_SELECT_64 = 0xc1,
WASM_OP_GET_LOCAL_FAST = 0xc2,
WASM_OP_SET_LOCAL_FAST = 0xc3,
WASM_OP_TEE_LOCAL_FAST = 0xc4,
WASM_OP_DROP_64 = 0xc0,
WASM_OP_SELECT_64 = 0xc1,
WASM_OP_IMPDEP = 0xc5
/* extend op code */
EXT_OP_GET_LOCAL_FAST = 0xc2,
EXT_OP_SET_LOCAL_FAST_I64 = 0xc3,
EXT_OP_SET_LOCAL_FAST = 0xc4,
EXT_OP_TEE_LOCAL_FAST = 0xc5,
EXT_OP_TEE_LOCAL_FAST_I64 = 0xc6,
EXT_OP_COPY_STACK_TOP = 0xc7,
EXT_OP_COPY_STACK_TOP_I64 = 0xc8,
WASM_OP_IMPDEP = 0xc9
} WASMOpcode;
#ifdef __cplusplus
@ -450,12 +456,16 @@ static const void *_name[WASM_INSTRUCTION_NUM] = { \
HANDLE_OPCODE (WASM_OP_I64_REINTERPRET_F64), /* 0xbd */ \
HANDLE_OPCODE (WASM_OP_F32_REINTERPRET_I32), /* 0xbe */ \
HANDLE_OPCODE (WASM_OP_F64_REINTERPRET_I64), /* 0xbf */ \
HANDLE_OPCODE (WASM_OP_DROP_64), /* 0xc0 */ \
HANDLE_OPCODE (WASM_OP_SELECT_64), /* 0xc1 */ \
HANDLE_OPCODE (WASM_OP_GET_LOCAL_FAST),/* 0xc2 */ \
HANDLE_OPCODE (WASM_OP_SET_LOCAL_FAST),/* 0xc3 */ \
HANDLE_OPCODE (WASM_OP_TEE_LOCAL_FAST),/* 0xc4 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xc5 */ \
HANDLE_OPCODE (WASM_OP_DROP_64), /* 0xc0 */ \
HANDLE_OPCODE (WASM_OP_SELECT_64), /* 0xc1 */ \
HANDLE_OPCODE (EXT_OP_GET_LOCAL_FAST), /* 0xc2 */ \
HANDLE_OPCODE (EXT_OP_SET_LOCAL_FAST_I64), /* 0xc3 */ \
HANDLE_OPCODE (EXT_OP_SET_LOCAL_FAST), /* 0xc4 */ \
HANDLE_OPCODE (EXT_OP_TEE_LOCAL_FAST), /* 0xc5 */ \
HANDLE_OPCODE (EXT_OP_TEE_LOCAL_FAST_I64), /* 0xc6 */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_TOP), /* 0xc7 */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_TOP_I64), /* 0xc8 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xc9 */ \
}
#endif /* end of _WASM_OPCODE_H */

View File

@ -355,6 +355,10 @@ functions_instantiate(const WASMModule *module,
function->local_offsets = function->u.func->local_offsets;
#if WASM_ENABLE_FAST_INTERP != 0
function->const_cell_num = function->u.func->const_cell_num;
#endif
function++;
}

View File

@ -87,6 +87,10 @@ typedef struct WASMFunctionInstance {
uint16 ret_cell_num;
/* cell num of local variables, 0 for import function */
uint16 local_cell_num;
#if WASM_ENABLE_FAST_INTERP != 0
/* cell num of consts */
uint16 const_cell_num;
#endif
uint16 *local_offsets;
/* parameter types */
uint8 *param_types;
@ -165,7 +169,11 @@ typedef struct WASMInterpFrame WASMRuntimeFrame;
static inline uint8*
wasm_get_func_code(WASMFunctionInstance *func)
{
#if WASM_ENABLE_FAST_INTERP == 0
return func->is_import_func ? NULL : func->u.func->code;
#else
return func->is_import_func ? NULL : func->u.func->code_compiled;
#endif
}
/**
@ -178,8 +186,13 @@ wasm_get_func_code(WASMFunctionInstance *func)
static inline uint8*
wasm_get_func_code_end(WASMFunctionInstance *func)
{
#if WASM_ENABLE_FAST_INTERP == 0
return func->is_import_func
? NULL : func->u.func->code + func->u.func->code_size;
#else
return func->is_import_func
? NULL : func->u.func->code_compiled + func->u.func->code_compiled_size;
#endif
}
WASMModule *