mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
Add the tail-call feature support for classic-interp (#401)
* Add the tail-call feature support for classic-interp Signed-off-by: Xiaokang Qin <xiaokang.qxk@antgroup.com> * add CI for tail call and custom name section * add CI for tail call and custom name section * update CI for mac Co-authored-by: Xu Jun <693788454@qq.com>
This commit is contained in:
parent
a3d374eb57
commit
a70daed17d
14
.github/workflows/linux.yml
vendored
14
.github/workflows/linux.yml
vendored
|
@ -70,6 +70,20 @@ jobs:
|
|||
cmake .. -DWAMR_BUILD_MEMORY_PROFILING=1
|
||||
make
|
||||
cd .. && rm -rf build
|
||||
- name: Build iwasm [tail call]
|
||||
run: |
|
||||
cd product-mini/platforms/linux
|
||||
mkdir build && cd build
|
||||
cmake .. -DWAMR_BUILD_TAIL_CALL=1
|
||||
make
|
||||
cd .. && rm -rf build
|
||||
- name: Build iwasm [custom name section]
|
||||
run: |
|
||||
cd product-mini/platforms/linux
|
||||
mkdir build && cd build
|
||||
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
||||
make
|
||||
cd .. && rm -rf build
|
||||
- name: download wasi-sdk
|
||||
run: |
|
||||
cd /opt
|
||||
|
|
14
.github/workflows/mac.yml
vendored
14
.github/workflows/mac.yml
vendored
|
@ -70,6 +70,20 @@ jobs:
|
|||
cmake .. -DWAMR_BUILD_MEMORY_PROFILING=1
|
||||
make
|
||||
cd .. && rm -rf build
|
||||
- name: Build iwasm [tail call]
|
||||
run: |
|
||||
cd product-mini/platforms/darwin
|
||||
mkdir build && cd build
|
||||
cmake .. -DWAMR_BUILD_TAIL_CALL=1
|
||||
make
|
||||
cd .. && rm -rf build
|
||||
- name: Build iwasm [custom name section]
|
||||
run: |
|
||||
cd product-mini/platforms/darwin
|
||||
mkdir build && cd build
|
||||
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
||||
make
|
||||
cd .. && rm -rf build
|
||||
- name: Build Sample [wasm-c-api]
|
||||
run: |
|
||||
cd samples/wasm-c-api
|
||||
|
|
|
@ -173,4 +173,8 @@ if (WAMR_BUILD_CUSTOM_NAME_SECTION EQUAL 1)
|
|||
add_definitions (-DWASM_ENABLE_CUSTOM_NAME_SECTION=1)
|
||||
message (" Custom name section enabled")
|
||||
endif ()
|
||||
if (WAMR_BUILD_TAIL_CALL EQUAL 1)
|
||||
add_definitions (-DWASM_ENABLE_TAIL_CALL=1)
|
||||
message (" Tail call enabled")
|
||||
endif ()
|
||||
|
||||
|
|
|
@ -244,5 +244,9 @@
|
|||
wasm_runtime_set_max_thread_num */
|
||||
#define CLUSTER_MAX_THREAD_NUM 4
|
||||
|
||||
#ifndef WASM_ENABLE_TAIL_CALL
|
||||
#define WASM_ENABLE_TAIL_CALL 0
|
||||
#endif
|
||||
|
||||
#endif /* end of _CONFIG_H_ */
|
||||
|
||||
|
|
|
@ -1285,11 +1285,33 @@ label_pop_csp_n:
|
|||
cur_func = module->functions + fidx;
|
||||
goto call_func_from_interp;
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
read_leb_uint32(frame_ip, frame_ip_end, fidx);
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (fidx >= module->function_count) {
|
||||
wasm_set_exception(module, "unknown function");
|
||||
goto got_exception;
|
||||
}
|
||||
#endif
|
||||
cur_func = module->functions + fidx;
|
||||
|
||||
goto call_func_from_return_call;
|
||||
#endif /* WASM_ENABLE_TAIL_CALL */
|
||||
|
||||
HANDLE_OP (WASM_OP_CALL_INDIRECT):
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
|
||||
#endif
|
||||
{
|
||||
WASMType *cur_type, *cur_func_type;
|
||||
WASMTableInstance *cur_table_inst;
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
opcode = *(frame_ip - 1);
|
||||
#endif
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
|
@ -1352,7 +1374,10 @@ label_pop_csp_n:
|
|||
wasm_set_exception(module, "indirect call type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
|
||||
goto call_func_from_return_call;
|
||||
#endif
|
||||
goto call_func_from_interp;
|
||||
}
|
||||
|
||||
|
@ -3121,8 +3146,10 @@ label_pop_csp_n:
|
|||
HANDLE_OP (WASM_OP_UNUSED_0x08):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x09):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x0a):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x12):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x13):
|
||||
#if WASM_ENABLE_TAIL_CALL == 0
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL):
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
|
||||
#endif
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x14):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x15):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x16):
|
||||
|
@ -3151,6 +3178,15 @@ label_pop_csp_n:
|
|||
FETCH_OPCODE_AND_DISPATCH ();
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
call_func_from_return_call:
|
||||
POP(cur_func->param_cell_num);
|
||||
word_copy(frame->lp, frame_sp, cur_func->param_cell_num);
|
||||
FREE_FRAME(exec_env, frame);
|
||||
wasm_exec_env_set_cur_frame(exec_env,
|
||||
(WASMRuntimeFrame *)prev_frame);
|
||||
goto call_func_from_entry;
|
||||
#endif
|
||||
call_func_from_interp:
|
||||
/* Only do the copy when it's called from interpreter. */
|
||||
{
|
||||
|
|
|
@ -3125,8 +3125,8 @@ recover_br_info:
|
|||
HANDLE_OP (WASM_OP_UNUSED_0x08):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x09):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x0a):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x12):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x13):
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL):
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x14):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x15):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x16):
|
||||
|
|
|
@ -3307,10 +3307,16 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
|
|||
break;
|
||||
|
||||
case WASM_OP_CALL:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL:
|
||||
#endif
|
||||
skip_leb_uint32(p, p_end); /* funcidx */
|
||||
break;
|
||||
|
||||
case WASM_OP_CALL_INDIRECT:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL_INDIRECT:
|
||||
#endif
|
||||
skip_leb_uint32(p, p_end); /* typeidx */
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
u8 = read_uint8(p); /* 0x00 */
|
||||
|
@ -5812,6 +5818,9 @@ handle_op_block_and_loop:
|
|||
}
|
||||
|
||||
case WASM_OP_CALL:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL:
|
||||
#endif
|
||||
{
|
||||
WASMType *func_type;
|
||||
uint32 func_idx;
|
||||
|
@ -5844,22 +5853,53 @@ handle_op_block_and_loop:
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
/* Here we emit each return value's dynamic_offset. But in fact
|
||||
* these offsets are continuous, so interpreter only need to get
|
||||
* the first return value's offset.
|
||||
*/
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
if (opcode == WASM_OP_CALL) {
|
||||
#endif
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
/* Here we emit each return value's dynamic_offset. But in fact
|
||||
* these offsets are continuous, so interpreter only need to get
|
||||
* the first return value's offset.
|
||||
*/
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#endif
|
||||
}
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
}
|
||||
|
||||
else {
|
||||
char *type_str[] = { "f64", "f32", "i64", "i32" };
|
||||
uint8 type;
|
||||
if (func_type->result_count != func->func_type->result_count) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"%s%u%s", "type mismatch: expect ",
|
||||
func->func_type->result_count,
|
||||
" return values but got other");
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
type = func->func_type->types[func->func_type->param_count + i];
|
||||
if (func_type->types[func_type->param_count + i] != type) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"%s%s%s", "type mismatch: expect ",
|
||||
type_str[type - VALUE_TYPE_F64],
|
||||
" but got other");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
RESET_STACK();
|
||||
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
||||
}
|
||||
#endif
|
||||
func->has_op_func_call = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case WASM_OP_CALL_INDIRECT:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL_INDIRECT:
|
||||
#endif
|
||||
{
|
||||
int32 idx;
|
||||
WASMType *func_type;
|
||||
|
@ -5904,13 +5944,40 @@ handle_op_block_and_loop:
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
if (opcode == WASM_OP_CALL_INDIRECT) {
|
||||
#endif
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#endif
|
||||
}
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
}
|
||||
|
||||
else {
|
||||
char *type_str[] = { "f64", "f32", "i64", "i32" };
|
||||
uint8 type;
|
||||
if (func_type->result_count != func->func_type->result_count) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"%s%u%s", "type mismatch: expect ",
|
||||
func->func_type->result_count,
|
||||
" return values but got other");
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
type = func->func_type->types[func->func_type->param_count + i];
|
||||
if (func_type->types[func_type->param_count + i] != type)
|
||||
set_error_buf_v(error_buf, error_buf_size, "%s%s%s",
|
||||
"type mismatch: expect ",
|
||||
type_str[type - VALUE_TYPE_F64],
|
||||
" but got other");
|
||||
goto fail;
|
||||
}
|
||||
RESET_STACK();
|
||||
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
||||
}
|
||||
#endif
|
||||
func->has_op_func_call = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2235,10 +2235,16 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
|
|||
break;
|
||||
|
||||
case WASM_OP_CALL:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL:
|
||||
#endif
|
||||
skip_leb_uint32(p, p_end); /* funcidx */
|
||||
break;
|
||||
|
||||
case WASM_OP_CALL_INDIRECT:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL_INDIRECT:
|
||||
#endif
|
||||
skip_leb_uint32(p, p_end); /* typeidx */
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
u8 = read_uint8(p); /* 0x00 */
|
||||
|
@ -4612,6 +4618,9 @@ handle_op_block_and_loop:
|
|||
}
|
||||
|
||||
case WASM_OP_CALL:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL:
|
||||
#endif
|
||||
{
|
||||
WASMType *func_type;
|
||||
uint32 func_idx;
|
||||
|
@ -4641,22 +4650,37 @@ handle_op_block_and_loop:
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
/* Here we emit each return value's dynamic_offset. But in fact
|
||||
* these offsets are continuous, so interpreter only need to get
|
||||
* the first return value's offset.
|
||||
*/
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
if (opcode == WASM_OP_CALL) {
|
||||
#endif
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
/* Here we emit each return value's dynamic_offset. But in fact
|
||||
* these offsets are continuous, so interpreter only need to get
|
||||
* the first return value's offset.
|
||||
*/
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#endif
|
||||
}
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
}
|
||||
|
||||
else {
|
||||
bh_assert(func_type->result_count == func->func_type->result_count);
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
bh_assert(func_type->types[func_type->param_count + i] ==
|
||||
func->func_type->types[func->func_type->param_count + i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
func->has_op_func_call = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case WASM_OP_CALL_INDIRECT:
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
case WASM_OP_RETURN_CALL_INDIRECT:
|
||||
#endif
|
||||
{
|
||||
int32 idx;
|
||||
WASMType *func_type;
|
||||
|
@ -4690,12 +4714,25 @@ handle_op_block_and_loop:
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
if (opcode == WASM_OP_CALL) {
|
||||
#endif
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
PUSH_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PUSH_OFFSET_TYPE(func_type->types[func_type->param_count + i]);
|
||||
#endif
|
||||
}
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
}
|
||||
else {
|
||||
bh_assert(func_type->result_count == func->func_type->result_count);
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
bh_assert(func_type->types[func_type->param_count + i] ==
|
||||
func->func_type->types[func->func_type->param_count + i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
func->has_op_func_call = true;
|
||||
break;
|
||||
|
|
|
@ -34,9 +34,9 @@ typedef enum WASMOpcode {
|
|||
WASM_OP_RETURN = 0x0f, /* return */
|
||||
WASM_OP_CALL = 0x10, /* call */
|
||||
WASM_OP_CALL_INDIRECT = 0x11, /* call_indirect */
|
||||
WASM_OP_RETURN_CALL = 0x12, /* return_call */
|
||||
WASM_OP_RETURN_CALL_INDIRECT = 0x13, /* return_call_indirect */
|
||||
|
||||
WASM_OP_UNUSED_0x12 = 0x12,
|
||||
WASM_OP_UNUSED_0x13 = 0x13,
|
||||
WASM_OP_UNUSED_0x14 = 0x14,
|
||||
WASM_OP_UNUSED_0x15 = 0x15,
|
||||
WASM_OP_UNUSED_0x16 = 0x16,
|
||||
|
@ -403,8 +403,8 @@ static type _name[WASM_INSTRUCTION_NUM] = { \
|
|||
HANDLE_OPCODE (WASM_OP_RETURN), /* 0x0f */ \
|
||||
HANDLE_OPCODE (WASM_OP_CALL), /* 0x10 */ \
|
||||
HANDLE_OPCODE (WASM_OP_CALL_INDIRECT), /* 0x11 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x12), /* 0x12 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x13), /* 0x13 */ \
|
||||
HANDLE_OPCODE (WASM_OP_RETURN_CALL), /* 0x12 */ \
|
||||
HANDLE_OPCODE (WASM_OP_RETURN_CALL_INDIRECT), /* 0x13 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x14), /* 0x14 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x15), /* 0x15 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x16), /* 0x16 */ \
|
||||
|
|
Loading…
Reference in New Issue
Block a user