mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-10-27 11:21:18 +00:00
feat: add instruction metering support with execution limit
This commit is contained in:
parent
c30e65ba5d
commit
ca78c6644e
|
|
@ -710,4 +710,8 @@
|
|||
#define WASM_ENABLE_AOT_VALIDATOR 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_INSTRUCTION_METERING
|
||||
#define WASM_INSTRUCTION_METERING 1
|
||||
#endif
|
||||
|
||||
#endif /* end of _CONFIG_H_ */
|
||||
|
|
|
|||
|
|
@ -166,6 +166,11 @@ typedef struct WASMExecEnv {
|
|||
/* The WASM stack. */
|
||||
uint8 bottom[1];
|
||||
} wasm_stack_u;
|
||||
|
||||
#if WASM_INSTRUCTION_METERING != 0
|
||||
/* instructions to execute */
|
||||
int instructions_to_execute;
|
||||
#endif
|
||||
} WASMExecEnv;
|
||||
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
|
|
|
|||
|
|
@ -2285,6 +2285,14 @@ wasm_runtime_access_exce_check_guard_page()
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef WASM_INSTRUCTION_METERING
|
||||
void wasm_runtime_set_instructions_to_execute(WASMExecEnv *exec_env,
|
||||
int instructions_to_execute)
|
||||
{
|
||||
exec_env->instructions_to_execute = instructions_to_execute;
|
||||
}
|
||||
#endif
|
||||
|
||||
WASMFuncType *
|
||||
wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
|
||||
uint32 module_type)
|
||||
|
|
|
|||
|
|
@ -672,6 +672,13 @@ WASM_RUNTIME_API_EXTERN void
|
|||
wasm_runtime_set_native_stack_boundary(WASMExecEnv *exec_env,
|
||||
uint8 *native_stack_boundary);
|
||||
|
||||
#if WASM_INSTRUCTION_METERING != 0
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_exception_with_id(WASMModuleInstanceCommon *module,
|
||||
uint32 exception_id);
|
||||
#endif
|
||||
|
||||
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
|
|
|
|||
|
|
@ -1821,6 +1821,21 @@ WASM_RUNTIME_API_EXTERN void
|
|||
wasm_runtime_set_native_stack_boundary(wasm_exec_env_t exec_env,
|
||||
uint8_t *native_stack_boundary);
|
||||
|
||||
/**
|
||||
* Set the instruction count limit to the execution environment.
|
||||
* By default the instruction count limit is -1, which means no limit.
|
||||
* However, if the instruction count limit is set to a positive value,
|
||||
* the execution will be terminated when the instruction count reaches
|
||||
* the limit.
|
||||
*
|
||||
* @param exec_env the execution environment
|
||||
* @param instruction_count the instruction count limit
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_instruction_count_limit(wasm_exec_env_t exec_env,
|
||||
int instruction_count);
|
||||
|
||||
|
||||
/**
|
||||
* Dump runtime memory consumption, including:
|
||||
* Exec env memory consumption
|
||||
|
|
|
|||
|
|
@ -1516,10 +1516,13 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
|||
} \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
} \
|
||||
CHECK_INSTRUCTION_LIMIT(); \ \
|
||||
goto *handle_table[*frame_ip++]; \
|
||||
} while (0)
|
||||
#else
|
||||
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
|
||||
#define HANDLE_OP_END() \
|
||||
CHECK_INSTRUCTION_LIMIT(); \
|
||||
FETCH_OPCODE_AND_DISPATCH()
|
||||
#endif
|
||||
|
||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
|
|
@ -1542,9 +1545,12 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
|||
} \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
} \
|
||||
CHECK_INSTRUCTION_LIMIT(); \
|
||||
continue;
|
||||
#else
|
||||
#define HANDLE_OP_END() continue
|
||||
#define HANDLE_OP_END()
|
||||
CHECK_INSTRUCTION_LIMIT(); \
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
|
|
@ -1562,6 +1568,16 @@ get_global_addr(uint8 *global_data, WASMGlobalInstance *global)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if WASM_INSTRUCTION_METERING != 0
|
||||
#define CHECK_INSTRUCTION_LIMIT() \
|
||||
if (instructions_left == 0) { \
|
||||
goto return_func; \
|
||||
} \
|
||||
instructions_left--;
|
||||
#else
|
||||
#define CHECK_INSTRUCTION_LIMIT() (void)0
|
||||
#endif
|
||||
|
||||
static void
|
||||
wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
WASMExecEnv *exec_env,
|
||||
|
|
@ -1605,6 +1621,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
uint32 local_idx, local_offset, global_idx;
|
||||
uint8 local_type, *global_addr;
|
||||
uint32 cache_index, type_index, param_cell_num, cell_num;
|
||||
|
||||
#if WASM_INSTRUCTION_METERING != 0
|
||||
int instructions_left = exec_env->instructions_to_execute;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||
int32_t exception_tag_index;
|
||||
#endif
|
||||
|
|
@ -2434,7 +2455,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
else
|
||||
cur_func_type = cur_func->u.func->func_type;
|
||||
|
||||
/* clang-format off */
|
||||
/* clang-format off */
|
||||
#if WASM_ENABLE_GC == 0
|
||||
if (cur_type != cur_func_type) {
|
||||
wasm_set_exception(module, "indirect call type mismatch");
|
||||
|
|
|
|||
|
|
@ -101,6 +101,16 @@ typedef float64 CellType_F64;
|
|||
goto unaligned_atomic; \
|
||||
} while (0)
|
||||
|
||||
#if WASM_INSTRUCTION_METERING != 0
|
||||
#define CHECK_INSTRUCTION_LIMIT() \
|
||||
if (instructions_left == 0) { \
|
||||
goto return_func; \
|
||||
} \
|
||||
instructions_left--;
|
||||
#else
|
||||
#define CHECK_INSTRUCTION_LIMIT() (void)0
|
||||
#endif
|
||||
|
||||
static inline uint32
|
||||
rotl32(uint32 n, uint32 c)
|
||||
{
|
||||
|
|
@ -1412,6 +1422,7 @@ wasm_interp_dump_op_count()
|
|||
do { \
|
||||
const void *p_label_addr = *(void **)frame_ip; \
|
||||
frame_ip += sizeof(void *); \
|
||||
CHECK_INSTRUCTION_LIMIT(); \
|
||||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#else
|
||||
|
|
@ -1423,6 +1434,7 @@ wasm_interp_dump_op_count()
|
|||
/* int32 relative offset was emitted in 64-bit target */ \
|
||||
p_label_addr = label_base + (int32)LOAD_U32_WITH_2U16S(frame_ip); \
|
||||
frame_ip += sizeof(int32); \
|
||||
CHECK_INSTRUCTION_LIMIT(); \
|
||||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#else
|
||||
|
|
@ -1433,6 +1445,7 @@ wasm_interp_dump_op_count()
|
|||
/* uint32 label address was emitted in 32-bit target */ \
|
||||
p_label_addr = (void *)(uintptr_t)LOAD_U32_WITH_2U16S(frame_ip); \
|
||||
frame_ip += sizeof(int32); \
|
||||
CHECK_INSTRUCTION_LIMIT(); \
|
||||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
|
@ -1509,6 +1522,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
uint8 *maddr = NULL;
|
||||
uint32 local_idx, local_offset, global_idx;
|
||||
uint8 opcode = 0, local_type, *global_addr;
|
||||
|
||||
#if WASM_INSTRUCTION_METERING != 0
|
||||
int instructions_left = exec_env->instructions_to_execute;
|
||||
#endif
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
|
||||
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user