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:
Xiaokang Qin 2020-09-24 12:38:54 +08:00 committed by GitHub
parent a3d374eb57
commit a70daed17d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 213 additions and 37 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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. */
{

View File

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

View File

@ -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,6 +5853,9 @@ handle_op_block_and_loop:
}
}
#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
@ -5854,12 +5866,40 @@ handle_op_block_and_loop:
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:
}
}
#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;
}

View File

@ -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,6 +4650,9 @@ handle_op_block_and_loop:
}
}
#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
@ -4651,12 +4663,24 @@ handle_op_block_and_loop:
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:
}
}
#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;

View File

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