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
9 changed files with 213 additions and 37 deletions

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,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;
}