|
@@ -42,11 +42,11 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
static bool
|
|
static bool
|
|
|
-skip_leb(const uint8 *buf, const uint8 *buf_end,
|
|
|
|
|
- uint32 *p_offset, uint32 maxbits,
|
|
|
|
|
|
|
+skip_leb(const uint8 **p_buf, const uint8 *buf_end, uint32 maxbits,
|
|
|
char* error_buf, uint32 error_buf_size)
|
|
char* error_buf, uint32 error_buf_size)
|
|
|
{
|
|
{
|
|
|
- uint32 bcnt = 0;
|
|
|
|
|
|
|
+ const uint8 *buf = *p_buf;
|
|
|
|
|
+ uint32 offset = 0, bcnt = 0;
|
|
|
uint64 byte;
|
|
uint64 byte;
|
|
|
|
|
|
|
|
while (true) {
|
|
while (true) {
|
|
@@ -57,51 +57,46 @@ skip_leb(const uint8 *buf, const uint8 *buf_end,
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- CHECK_BUF(buf, buf_end, *p_offset + 1);
|
|
|
|
|
- byte = buf[*p_offset];
|
|
|
|
|
- *p_offset += 1;
|
|
|
|
|
|
|
+ CHECK_BUF(buf, buf_end, offset + 1);
|
|
|
|
|
+ byte = buf[offset];
|
|
|
|
|
+ offset += 1;
|
|
|
bcnt += 1;
|
|
bcnt += 1;
|
|
|
if ((byte & 0x80) == 0) {
|
|
if ((byte & 0x80) == 0) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ *p_buf += offset;
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#define skip_leb_int64(p, p_end) do { \
|
|
#define skip_leb_int64(p, p_end) do { \
|
|
|
- uint32 off = 0; \
|
|
|
|
|
- if (!skip_leb(p, p_end, &off, 64, \
|
|
|
|
|
|
|
+ if (!skip_leb(&p, p_end, 64, \
|
|
|
error_buf, error_buf_size)) \
|
|
error_buf, error_buf_size)) \
|
|
|
return false; \
|
|
return false; \
|
|
|
- p += off; \
|
|
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
#define skip_leb_uint32(p, p_end) do { \
|
|
#define skip_leb_uint32(p, p_end) do { \
|
|
|
- uint32 off = 0; \
|
|
|
|
|
- if (!skip_leb(p, p_end, &off, 32, \
|
|
|
|
|
|
|
+ if (!skip_leb(&p, p_end, 32, \
|
|
|
error_buf, error_buf_size)) \
|
|
error_buf, error_buf_size)) \
|
|
|
return false; \
|
|
return false; \
|
|
|
- p += off; \
|
|
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
#define skip_leb_int32(p, p_end) do { \
|
|
#define skip_leb_int32(p, p_end) do { \
|
|
|
- uint32 off = 0; \
|
|
|
|
|
- if (!skip_leb(p, p_end, &off, 32, \
|
|
|
|
|
|
|
+ if (!skip_leb(&p, p_end, 32, \
|
|
|
error_buf, error_buf_size)) \
|
|
error_buf, error_buf_size)) \
|
|
|
return false; \
|
|
return false; \
|
|
|
- p += off; \
|
|
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
static bool
|
|
static bool
|
|
|
-read_leb(const uint8 *buf, const uint8 *buf_end,
|
|
|
|
|
- uint32 *p_offset, uint32 maxbits,
|
|
|
|
|
- bool sign, uint64 *p_result,
|
|
|
|
|
|
|
+read_leb(uint8 **p_buf, const uint8 *buf_end,
|
|
|
|
|
+ uint32 maxbits, bool sign, uint64 *p_result,
|
|
|
char* error_buf, uint32 error_buf_size)
|
|
char* error_buf, uint32 error_buf_size)
|
|
|
{
|
|
{
|
|
|
|
|
+ const uint8 *buf = *p_buf;
|
|
|
uint64 result = 0;
|
|
uint64 result = 0;
|
|
|
uint32 shift = 0;
|
|
uint32 shift = 0;
|
|
|
- uint32 bcnt = 0;
|
|
|
|
|
|
|
+ uint32 offset = 0, bcnt = 0;
|
|
|
uint64 byte;
|
|
uint64 byte;
|
|
|
|
|
|
|
|
while (true) {
|
|
while (true) {
|
|
@@ -112,9 +107,9 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- CHECK_BUF(buf, buf_end, *p_offset + 1);
|
|
|
|
|
- byte = buf[*p_offset];
|
|
|
|
|
- *p_offset += 1;
|
|
|
|
|
|
|
+ CHECK_BUF(buf, buf_end, offset + 1);
|
|
|
|
|
+ byte = buf[offset];
|
|
|
|
|
+ offset += 1;
|
|
|
result |= ((byte & 0x7f) << shift);
|
|
result |= ((byte & 0x7f) << shift);
|
|
|
shift += 7;
|
|
shift += 7;
|
|
|
bcnt += 1;
|
|
bcnt += 1;
|
|
@@ -160,6 +155,7 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ *p_buf += offset;
|
|
|
*p_result = result;
|
|
*p_result = result;
|
|
|
return true;
|
|
return true;
|
|
|
|
|
|
|
@@ -174,62 +170,26 @@ fail_integer_too_large:
|
|
|
#define read_bool(p) TEMPLATE_READ_VALUE(bool, p)
|
|
#define read_bool(p) TEMPLATE_READ_VALUE(bool, p)
|
|
|
|
|
|
|
|
#define read_leb_int64(p, p_end, res) do { \
|
|
#define read_leb_int64(p, p_end, res) do { \
|
|
|
- if (p < p_end) { \
|
|
|
|
|
- uint8 _val = *p; \
|
|
|
|
|
- if (!(_val & 0x80)) { \
|
|
|
|
|
- res = (int64)_val; \
|
|
|
|
|
- if (_val & 0x40) \
|
|
|
|
|
- /* sign extend */ \
|
|
|
|
|
- res |= 0xFFFFFFFFFFFFFF80LL; \
|
|
|
|
|
- p++; \
|
|
|
|
|
- break; \
|
|
|
|
|
- } \
|
|
|
|
|
- } \
|
|
|
|
|
- uint32 off = 0; \
|
|
|
|
|
uint64 res64; \
|
|
uint64 res64; \
|
|
|
- if (!read_leb(p, p_end, &off, 64, true, &res64, \
|
|
|
|
|
|
|
+ if (!read_leb((uint8**)&p, p_end, 64, true, &res64,\
|
|
|
error_buf, error_buf_size)) \
|
|
error_buf, error_buf_size)) \
|
|
|
return false; \
|
|
return false; \
|
|
|
- p += off; \
|
|
|
|
|
res = (int64)res64; \
|
|
res = (int64)res64; \
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
#define read_leb_uint32(p, p_end, res) do { \
|
|
#define read_leb_uint32(p, p_end, res) do { \
|
|
|
- if (p < p_end) { \
|
|
|
|
|
- uint8 _val = *p; \
|
|
|
|
|
- if (!(_val & 0x80)) { \
|
|
|
|
|
- res = _val; \
|
|
|
|
|
- p++; \
|
|
|
|
|
- break; \
|
|
|
|
|
- } \
|
|
|
|
|
- } \
|
|
|
|
|
- uint32 off = 0; \
|
|
|
|
|
uint64 res64; \
|
|
uint64 res64; \
|
|
|
- if (!read_leb(p, p_end, &off, 32, false, &res64, \
|
|
|
|
|
|
|
+ if (!read_leb((uint8**)&p, p_end, 32, false, &res64,\
|
|
|
error_buf, error_buf_size)) \
|
|
error_buf, error_buf_size)) \
|
|
|
return false; \
|
|
return false; \
|
|
|
- p += off; \
|
|
|
|
|
res = (uint32)res64; \
|
|
res = (uint32)res64; \
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
#define read_leb_int32(p, p_end, res) do { \
|
|
#define read_leb_int32(p, p_end, res) do { \
|
|
|
- if (p < p_end) { \
|
|
|
|
|
- uint8 _val = *p; \
|
|
|
|
|
- if (!(_val & 0x80)) { \
|
|
|
|
|
- res = (int32)_val; \
|
|
|
|
|
- if (_val & 0x40) \
|
|
|
|
|
- /* sign extend */ \
|
|
|
|
|
- res |= 0xFFFFFF80; \
|
|
|
|
|
- p++; \
|
|
|
|
|
- break; \
|
|
|
|
|
- } \
|
|
|
|
|
- } \
|
|
|
|
|
- uint32 off = 0; \
|
|
|
|
|
uint64 res64; \
|
|
uint64 res64; \
|
|
|
- if (!read_leb(p, p_end, &off, 32, true, &res64, \
|
|
|
|
|
|
|
+ if (!read_leb((uint8**)&p, p_end, 32, true, &res64,\
|
|
|
error_buf, error_buf_size)) \
|
|
error_buf, error_buf_size)) \
|
|
|
return false; \
|
|
return false; \
|
|
|
- p += off; \
|
|
|
|
|
res = (int32)res64; \
|
|
res = (int32)res64; \
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
@@ -2094,15 +2054,22 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
|
|
|
{
|
|
{
|
|
|
const uint8 *p = start_addr, *p_end = code_end_addr;
|
|
const uint8 *p = start_addr, *p_end = code_end_addr;
|
|
|
uint8 *else_addr = NULL;
|
|
uint8 *else_addr = NULL;
|
|
|
- uint32 block_nested_depth = 1, count, i;
|
|
|
|
|
|
|
+ uint32 block_nested_depth = 1, count, i, j, t;
|
|
|
uint8 opcode, u8;
|
|
uint8 opcode, u8;
|
|
|
-
|
|
|
|
|
BlockAddr block_stack[16] = { 0 }, *block;
|
|
BlockAddr block_stack[16] = { 0 }, *block;
|
|
|
- uint32 j, t;
|
|
|
|
|
|
|
|
|
|
i = ((uintptr_t)start_addr) % BLOCK_ADDR_CACHE_SIZE;
|
|
i = ((uintptr_t)start_addr) % BLOCK_ADDR_CACHE_SIZE;
|
|
|
block = block_addr_cache + BLOCK_ADDR_CONFLICT_SIZE * i;
|
|
block = block_addr_cache + BLOCK_ADDR_CONFLICT_SIZE * i;
|
|
|
|
|
|
|
|
|
|
+ for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) {
|
|
|
|
|
+ if (block[j].start_addr == start_addr) {
|
|
|
|
|
+ /* Cache hit */
|
|
|
|
|
+ *p_else_addr = block[j].else_addr;
|
|
|
|
|
+ *p_end_addr = block[j].end_addr;
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/* Cache unhit */
|
|
/* Cache unhit */
|
|
|
block_stack[0].start_addr = start_addr;
|
|
block_stack[0].start_addr = start_addr;
|
|
|
|
|
|
|
@@ -2761,6 +2728,20 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type,
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool
|
|
|
|
|
+wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
|
|
|
|
|
+ uint8 type_push, uint8 type_pop,
|
|
|
|
|
+ char *error_buf, uint32 error_buf_size)
|
|
|
|
|
+{
|
|
|
|
|
+ for (int i = 0; i < pop_cnt; i++) {
|
|
|
|
|
+ if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf, error_buf_size))
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size))
|
|
|
|
|
+ return false;
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static bool
|
|
static bool
|
|
|
wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 type,
|
|
wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 type,
|
|
|
uint8 ret_type, uint8* start_addr,
|
|
uint8 ret_type, uint8* start_addr,
|
|
@@ -3253,6 +3234,24 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type,
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool
|
|
|
|
|
+wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
|
|
|
|
|
+ uint8 type_push, uint8 type_pop,
|
|
|
|
|
+ bool disable_emit, int16 operand_offset,
|
|
|
|
|
+ char *error_buf, uint32 error_buf_size)
|
|
|
|
|
+{
|
|
|
|
|
+ for (int i = 0; i < pop_cnt; i++) {
|
|
|
|
|
+ if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf, error_buf_size))
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!wasm_loader_push_frame_offset(ctx, type_push,
|
|
|
|
|
+ disable_emit, operand_offset,
|
|
|
|
|
+ error_buf, error_buf_size))
|
|
|
|
|
+ return false;
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static bool
|
|
static bool
|
|
|
wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
|
|
wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
|
|
|
bool disable_emit, int16 operand_offset,
|
|
bool disable_emit, int16 operand_offset,
|
|
@@ -3279,6 +3278,22 @@ wasm_loader_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool
|
|
|
|
|
+wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
|
|
|
|
|
+ uint8 type_push, uint8 type_pop,
|
|
|
|
|
+ bool disable_emit, int16 operand_offset,
|
|
|
|
|
+ char *error_buf, uint32 error_buf_size)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop,
|
|
|
|
|
+ error_buf, error_buf_size))
|
|
|
|
|
+ return false;
|
|
|
|
|
+ if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop,
|
|
|
|
|
+ disable_emit, operand_offset,
|
|
|
|
|
+ error_buf, error_buf_size))
|
|
|
|
|
+ return false;
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
static bool
|
|
static bool
|
|
|
wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
|
|
wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
|
|
@@ -3432,6 +3447,23 @@ fail:
|
|
|
goto fail; \
|
|
goto fail; \
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
+#define POP_AND_PUSH(type_pop, type_push) do { \
|
|
|
|
|
+ if (!(wasm_loader_push_pop_frame_ref_offset(loader_ctx, 1, \
|
|
|
|
|
+ type_push, type_pop, \
|
|
|
|
|
+ disable_emit, operand_offset, \
|
|
|
|
|
+ error_buf, error_buf_size))) \
|
|
|
|
|
+ goto fail; \
|
|
|
|
|
+ } while (0)
|
|
|
|
|
+
|
|
|
|
|
+/* type of POPs should be the same */
|
|
|
|
|
+#define POP2_AND_PUSH(type_pop, type_push) do { \
|
|
|
|
|
+ if (!(wasm_loader_push_pop_frame_ref_offset(loader_ctx, 2, \
|
|
|
|
|
+ type_push, type_pop, \
|
|
|
|
|
+ disable_emit, operand_offset, \
|
|
|
|
|
+ error_buf, error_buf_size))) \
|
|
|
|
|
+ goto fail; \
|
|
|
|
|
+ } while (0)
|
|
|
|
|
+
|
|
|
#else /* WASM_ENABLE_FAST_INTERP */
|
|
#else /* WASM_ENABLE_FAST_INTERP */
|
|
|
|
|
|
|
|
#define PUSH_I32() do { \
|
|
#define PUSH_I32() do { \
|
|
@@ -3482,8 +3514,85 @@ fail:
|
|
|
goto fail; \
|
|
goto fail; \
|
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
+#define POP_AND_PUSH(type_pop, type_push) do { \
|
|
|
|
|
+ if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 1, \
|
|
|
|
|
+ type_push, type_pop, \
|
|
|
|
|
+ error_buf, error_buf_size))) \
|
|
|
|
|
+ goto fail; \
|
|
|
|
|
+ } while (0)
|
|
|
|
|
+
|
|
|
|
|
+/* type of POPs should be the same */
|
|
|
|
|
+#define POP2_AND_PUSH(type_pop, type_push) do { \
|
|
|
|
|
+ if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 2, \
|
|
|
|
|
+ type_push, type_pop, \
|
|
|
|
|
+ error_buf, error_buf_size))) \
|
|
|
|
|
+ goto fail; \
|
|
|
|
|
+ } while (0)
|
|
|
#endif /* WASM_ENABLE_FAST_INTERP */
|
|
#endif /* WASM_ENABLE_FAST_INTERP */
|
|
|
|
|
|
|
|
|
|
+#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
|
|
+
|
|
|
|
|
+static bool
|
|
|
|
|
+reserve_block_ret(WASMLoaderContext *loader_ctx, uint8 opcode, bool disable_emit,
|
|
|
|
|
+ char *error_buf, uint32 error_buf_size)
|
|
|
|
|
+{
|
|
|
|
|
+ int16 operand_offset = 0;
|
|
|
|
|
+ uint8 block_depth = 0;
|
|
|
|
|
+ if (opcode == WASM_OP_ELSE)
|
|
|
|
|
+ block_depth = 1;
|
|
|
|
|
+ else
|
|
|
|
|
+ block_depth = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ((loader_ctx->frame_csp - block_depth)->return_type != VALUE_TYPE_VOID) {
|
|
|
|
|
+ uint8 return_cells;
|
|
|
|
|
+ if ((loader_ctx->frame_csp - block_depth)->return_type == VALUE_TYPE_I32
|
|
|
|
|
+ || (loader_ctx->frame_csp - block_depth)->return_type == VALUE_TYPE_F32)
|
|
|
|
|
+ return_cells = 1;
|
|
|
|
|
+ else
|
|
|
|
|
+ return_cells = 2;
|
|
|
|
|
+ if ((loader_ctx->frame_csp - block_depth)->dynamic_offset !=
|
|
|
|
|
+ *(loader_ctx->frame_offset - return_cells)) {
|
|
|
|
|
+
|
|
|
|
|
+ /* insert op_copy before else opcode */
|
|
|
|
|
+ if (opcode == WASM_OP_ELSE)
|
|
|
|
|
+ skip_label();
|
|
|
|
|
+
|
|
|
|
|
+ if (return_cells == 1)
|
|
|
|
|
+ emit_label(EXT_OP_COPY_STACK_TOP);
|
|
|
|
|
+ else
|
|
|
|
|
+ emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
|
|
|
|
+ emit_operand(loader_ctx, *(loader_ctx->frame_offset - return_cells));
|
|
|
|
|
+ emit_operand(loader_ctx, (loader_ctx->frame_csp - block_depth)->dynamic_offset);
|
|
|
|
|
+
|
|
|
|
|
+ if (opcode == WASM_OP_ELSE) {
|
|
|
|
|
+ *(loader_ctx->frame_offset - return_cells) =
|
|
|
|
|
+ (loader_ctx->frame_csp - block_depth)->dynamic_offset;
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ loader_ctx->frame_offset -= return_cells;
|
|
|
|
|
+ loader_ctx->dynamic_offset = loader_ctx->frame_csp->dynamic_offset;
|
|
|
|
|
+ PUSH_OFFSET_TYPE((loader_ctx->frame_csp - block_depth)->return_type);
|
|
|
|
|
+ wasm_loader_emit_backspace(loader_ctx, sizeof(int16));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (opcode == WASM_OP_ELSE)
|
|
|
|
|
+ emit_label(opcode);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+
|
|
|
|
|
+fail:
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#endif /* WASM_ENABLE_FAST_INTERP */
|
|
|
|
|
+
|
|
|
|
|
+#define RESERVE_BLOCK_RET() do { \
|
|
|
|
|
+ if (!reserve_block_ret(loader_ctx, opcode, disable_emit, \
|
|
|
|
|
+ error_buf, error_buf_size)) \
|
|
|
|
|
+ goto fail; \
|
|
|
|
|
+ } while (0)
|
|
|
|
|
+
|
|
|
#define PUSH_TYPE(type) do { \
|
|
#define PUSH_TYPE(type) do { \
|
|
|
if (!(wasm_loader_push_frame_ref(loader_ctx, type, \
|
|
if (!(wasm_loader_push_frame_ref(loader_ctx, type, \
|
|
|
error_buf, error_buf_size))) \
|
|
error_buf, error_buf_size))) \
|
|
@@ -3613,12 +3722,10 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
|
|
uint8 *param_types, ret_type, *local_types, local_type, global_type;
|
|
uint8 *param_types, ret_type, *local_types, local_type, global_type;
|
|
|
uint16 *local_offsets, local_offset;
|
|
uint16 *local_offsets, local_offset;
|
|
|
uint32 count, i, local_idx, global_idx, u32, align, mem_offset;
|
|
uint32 count, i, local_idx, global_idx, u32, align, mem_offset;
|
|
|
- uint32 cache_index, item_index;
|
|
|
|
|
int32 i32, i32_const = 0;
|
|
int32 i32, i32_const = 0;
|
|
|
int64 i64;
|
|
int64 i64;
|
|
|
uint8 opcode, u8, block_return_type;
|
|
uint8 opcode, u8, block_return_type;
|
|
|
bool return_value = false, is_i32_const = false;
|
|
bool return_value = false, is_i32_const = false;
|
|
|
- BlockAddr *cache_items;
|
|
|
|
|
WASMLoaderContext *loader_ctx;
|
|
WASMLoaderContext *loader_ctx;
|
|
|
BranchBlock *frame_csp_tmp;
|
|
BranchBlock *frame_csp_tmp;
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
@@ -3723,23 +3830,7 @@ re_scan:
|
|
|
if (!is_i32_const)
|
|
if (!is_i32_const)
|
|
|
(loader_ctx->frame_csp - 1)->is_block_reachable = true;
|
|
(loader_ctx->frame_csp - 1)->is_block_reachable = true;
|
|
|
else {
|
|
else {
|
|
|
- cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr)
|
|
|
|
|
- & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
|
|
|
|
|
- cache_items = block_addr_cache
|
|
|
|
|
- + BLOCK_ADDR_CONFLICT_SIZE * cache_index;
|
|
|
|
|
- for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE;
|
|
|
|
|
- item_index++) {
|
|
|
|
|
- if (cache_items[item_index].start_addr ==
|
|
|
|
|
- (loader_ctx->frame_csp - 1)->start_addr) {
|
|
|
|
|
- (loader_ctx->frame_csp - 1)->else_addr =
|
|
|
|
|
- cache_items[item_index].else_addr;
|
|
|
|
|
- (loader_ctx->frame_csp - 1)->end_addr =
|
|
|
|
|
- cache_items[item_index].end_addr;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (item_index == BLOCK_ADDR_CONFLICT_SIZE
|
|
|
|
|
- && !wasm_loader_find_block_addr(block_addr_cache,
|
|
|
|
|
|
|
+ if (!wasm_loader_find_block_addr(block_addr_cache,
|
|
|
(loader_ctx->frame_csp - 1)->start_addr,
|
|
(loader_ctx->frame_csp - 1)->start_addr,
|
|
|
p_end,
|
|
p_end,
|
|
|
(loader_ctx->frame_csp - 1)->block_type,
|
|
(loader_ctx->frame_csp - 1)->block_type,
|
|
@@ -3796,27 +3887,7 @@ re_scan:
|
|
|
loader_ctx->stack_cell_num;
|
|
loader_ctx->stack_cell_num;
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
/* if the result of if branch is in local or const area, add a copy op */
|
|
/* if the result of if branch is in local or const area, add a copy op */
|
|
|
- if ((loader_ctx->frame_csp - 1)->return_type != VALUE_TYPE_VOID) {
|
|
|
|
|
- uint8 return_cells;
|
|
|
|
|
- if ((loader_ctx->frame_csp - 1)->return_type == VALUE_TYPE_I32
|
|
|
|
|
- || (loader_ctx->frame_csp - 1)->return_type == VALUE_TYPE_F32)
|
|
|
|
|
- return_cells = 1;
|
|
|
|
|
- else
|
|
|
|
|
- return_cells = 2;
|
|
|
|
|
- if ((loader_ctx->frame_csp - 1)->dynamic_offset !=
|
|
|
|
|
- *(loader_ctx->frame_offset - return_cells)) {
|
|
|
|
|
- skip_label();
|
|
|
|
|
- if (return_cells == 1)
|
|
|
|
|
- emit_label(EXT_OP_COPY_STACK_TOP);
|
|
|
|
|
- else
|
|
|
|
|
- emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
|
|
|
|
- emit_operand(loader_ctx, *(loader_ctx->frame_offset - return_cells));
|
|
|
|
|
- emit_operand(loader_ctx, (loader_ctx->frame_csp - 1)->dynamic_offset);
|
|
|
|
|
- *(loader_ctx->frame_offset - return_cells) =
|
|
|
|
|
- (loader_ctx->frame_csp - 1)->dynamic_offset;
|
|
|
|
|
- emit_label(opcode);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ RESERVE_BLOCK_RET();
|
|
|
loader_ctx->frame_offset = loader_ctx->frame_offset_bottom +
|
|
loader_ctx->frame_offset = loader_ctx->frame_offset_bottom +
|
|
|
loader_ctx->stack_cell_num;
|
|
loader_ctx->stack_cell_num;
|
|
|
emit_empty_label_addr_and_frame_ip(PATCH_END);
|
|
emit_empty_label_addr_and_frame_ip(PATCH_END);
|
|
@@ -3830,29 +3901,8 @@ re_scan:
|
|
|
|
|
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
skip_label();
|
|
skip_label();
|
|
|
- // copy the result to the block return address
|
|
|
|
|
- if (loader_ctx->frame_csp->return_type != VALUE_TYPE_VOID) {
|
|
|
|
|
- uint8 return_cells;
|
|
|
|
|
- if (loader_ctx->frame_csp->return_type == VALUE_TYPE_I32
|
|
|
|
|
- || loader_ctx->frame_csp->return_type == VALUE_TYPE_F32)
|
|
|
|
|
- return_cells = 1;
|
|
|
|
|
- else
|
|
|
|
|
- return_cells = 2;
|
|
|
|
|
- if (loader_ctx->frame_csp->dynamic_offset !=
|
|
|
|
|
- *(loader_ctx->frame_offset - return_cells)) {
|
|
|
|
|
- if (return_cells == 1)
|
|
|
|
|
- emit_label(EXT_OP_COPY_STACK_TOP);
|
|
|
|
|
- else
|
|
|
|
|
- emit_label(EXT_OP_COPY_STACK_TOP_I64);
|
|
|
|
|
- emit_operand(loader_ctx, *(loader_ctx->frame_offset - return_cells));
|
|
|
|
|
- emit_operand(loader_ctx, loader_ctx->frame_csp->dynamic_offset);
|
|
|
|
|
- }
|
|
|
|
|
- // the frame_offset stack top should be the return address of the block
|
|
|
|
|
- loader_ctx->frame_offset -= return_cells;
|
|
|
|
|
- loader_ctx->dynamic_offset = loader_ctx->frame_csp->dynamic_offset;
|
|
|
|
|
- PUSH_OFFSET_TYPE(loader_ctx->frame_csp->return_type);
|
|
|
|
|
- wasm_loader_emit_backspace(loader_ctx, sizeof(int16));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /* copy the result to the block return address */
|
|
|
|
|
+ RESERVE_BLOCK_RET();
|
|
|
|
|
|
|
|
apply_label_patch(loader_ctx, 0, PATCH_END);
|
|
apply_label_patch(loader_ctx, 0, PATCH_END);
|
|
|
free_label_patch_list(loader_ctx->frame_csp);
|
|
free_label_patch_list(loader_ctx->frame_csp);
|
|
@@ -3892,24 +3942,13 @@ handle_next_reachable_block:
|
|
|
|
|
|
|
|
block_return_type = (loader_ctx->frame_csp - i)->return_type;
|
|
block_return_type = (loader_ctx->frame_csp - i)->return_type;
|
|
|
|
|
|
|
|
- cache_index = ((uintptr_t)(loader_ctx->frame_csp - i)->start_addr)
|
|
|
|
|
- & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
|
|
|
|
|
- cache_items = block_addr_cache + BLOCK_ADDR_CONFLICT_SIZE * cache_index;
|
|
|
|
|
- for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; item_index++) {
|
|
|
|
|
- if (cache_items[item_index].start_addr == (loader_ctx->frame_csp - i)->start_addr) {
|
|
|
|
|
- (loader_ctx->frame_csp - i)->else_addr = cache_items[item_index].else_addr;
|
|
|
|
|
- (loader_ctx->frame_csp - i)->end_addr = cache_items[item_index].end_addr;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if(item_index == BLOCK_ADDR_CONFLICT_SIZE
|
|
|
|
|
- && !wasm_loader_find_block_addr(block_addr_cache,
|
|
|
|
|
- (loader_ctx->frame_csp - i)->start_addr,
|
|
|
|
|
- p_end,
|
|
|
|
|
- (loader_ctx->frame_csp - i)->block_type,
|
|
|
|
|
- &(loader_ctx->frame_csp - i)->else_addr,
|
|
|
|
|
- &(loader_ctx->frame_csp - i)->end_addr,
|
|
|
|
|
- error_buf, error_buf_size))
|
|
|
|
|
|
|
+ if(!wasm_loader_find_block_addr(block_addr_cache,
|
|
|
|
|
+ (loader_ctx->frame_csp - i)->start_addr,
|
|
|
|
|
+ p_end,
|
|
|
|
|
+ (loader_ctx->frame_csp - i)->block_type,
|
|
|
|
|
+ &(loader_ctx->frame_csp - i)->else_addr,
|
|
|
|
|
+ &(loader_ctx->frame_csp - i)->end_addr,
|
|
|
|
|
+ error_buf, error_buf_size))
|
|
|
goto fail;
|
|
goto fail;
|
|
|
|
|
|
|
|
loader_ctx->stack_cell_num = (loader_ctx->frame_csp - i)->stack_cell_num;
|
|
loader_ctx->stack_cell_num = (loader_ctx->frame_csp - i)->stack_cell_num;
|
|
@@ -4443,8 +4482,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I32_LOAD8_U:
|
|
case WASM_OP_I32_LOAD8_U:
|
|
|
case WASM_OP_I32_LOAD16_S:
|
|
case WASM_OP_I32_LOAD16_S:
|
|
|
case WASM_OP_I32_LOAD16_U:
|
|
case WASM_OP_I32_LOAD16_U:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
case WASM_OP_I64_LOAD:
|
|
case WASM_OP_I64_LOAD:
|
|
|
case WASM_OP_I64_LOAD8_S:
|
|
case WASM_OP_I64_LOAD8_S:
|
|
@@ -4453,16 +4491,13 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I64_LOAD16_U:
|
|
case WASM_OP_I64_LOAD16_U:
|
|
|
case WASM_OP_I64_LOAD32_S:
|
|
case WASM_OP_I64_LOAD32_S:
|
|
|
case WASM_OP_I64_LOAD32_U:
|
|
case WASM_OP_I64_LOAD32_U:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
case WASM_OP_F32_LOAD:
|
|
case WASM_OP_F32_LOAD:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
case WASM_OP_F64_LOAD:
|
|
case WASM_OP_F64_LOAD:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
/* store */
|
|
/* store */
|
|
|
case WASM_OP_I32_STORE:
|
|
case WASM_OP_I32_STORE:
|
|
@@ -4513,8 +4548,7 @@ handle_next_reachable_block:
|
|
|
"zero flag expected");
|
|
"zero flag expected");
|
|
|
goto fail;
|
|
goto fail;
|
|
|
}
|
|
}
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
|
|
|
|
|
func->has_op_memory_grow = true;
|
|
func->has_op_memory_grow = true;
|
|
|
module->possible_memory_grow = true;
|
|
module->possible_memory_grow = true;
|
|
@@ -4566,8 +4600,7 @@ handle_next_reachable_block:
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_EQZ:
|
|
case WASM_OP_I32_EQZ:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_EQ:
|
|
case WASM_OP_I32_EQ:
|
|
@@ -4580,14 +4613,11 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I32_LE_U:
|
|
case WASM_OP_I32_LE_U:
|
|
|
case WASM_OP_I32_GE_S:
|
|
case WASM_OP_I32_GE_S:
|
|
|
case WASM_OP_I32_GE_U:
|
|
case WASM_OP_I32_GE_U:
|
|
|
- POP_I32();
|
|
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_EQZ:
|
|
case WASM_OP_I64_EQZ:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_EQ:
|
|
case WASM_OP_I64_EQ:
|
|
@@ -4600,9 +4630,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I64_LE_U:
|
|
case WASM_OP_I64_LE_U:
|
|
|
case WASM_OP_I64_GE_S:
|
|
case WASM_OP_I64_GE_S:
|
|
|
case WASM_OP_I64_GE_U:
|
|
case WASM_OP_I64_GE_U:
|
|
|
- POP_I64();
|
|
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_EQ:
|
|
case WASM_OP_F32_EQ:
|
|
@@ -4611,9 +4639,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_F32_GT:
|
|
case WASM_OP_F32_GT:
|
|
|
case WASM_OP_F32_LE:
|
|
case WASM_OP_F32_LE:
|
|
|
case WASM_OP_F32_GE:
|
|
case WASM_OP_F32_GE:
|
|
|
- POP_F32();
|
|
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_EQ:
|
|
case WASM_OP_F64_EQ:
|
|
@@ -4622,9 +4648,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_F64_GT:
|
|
case WASM_OP_F64_GT:
|
|
|
case WASM_OP_F64_LE:
|
|
case WASM_OP_F64_LE:
|
|
|
case WASM_OP_F64_GE:
|
|
case WASM_OP_F64_GE:
|
|
|
- POP_F64();
|
|
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
break;
|
|
break;
|
|
@@ -4632,8 +4656,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I32_CLZ:
|
|
case WASM_OP_I32_CLZ:
|
|
|
case WASM_OP_I32_CTZ:
|
|
case WASM_OP_I32_CTZ:
|
|
|
case WASM_OP_I32_POPCNT:
|
|
case WASM_OP_I32_POPCNT:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_ADD:
|
|
case WASM_OP_I32_ADD:
|
|
@@ -4651,16 +4674,13 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I32_SHR_U:
|
|
case WASM_OP_I32_SHR_U:
|
|
|
case WASM_OP_I32_ROTL:
|
|
case WASM_OP_I32_ROTL:
|
|
|
case WASM_OP_I32_ROTR:
|
|
case WASM_OP_I32_ROTR:
|
|
|
- POP_I32();
|
|
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_CLZ:
|
|
case WASM_OP_I64_CLZ:
|
|
|
case WASM_OP_I64_CTZ:
|
|
case WASM_OP_I64_CTZ:
|
|
|
case WASM_OP_I64_POPCNT:
|
|
case WASM_OP_I64_POPCNT:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_ADD:
|
|
case WASM_OP_I64_ADD:
|
|
@@ -4678,9 +4698,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_I64_SHR_U:
|
|
case WASM_OP_I64_SHR_U:
|
|
|
case WASM_OP_I64_ROTL:
|
|
case WASM_OP_I64_ROTL:
|
|
|
case WASM_OP_I64_ROTR:
|
|
case WASM_OP_I64_ROTR:
|
|
|
- POP_I64();
|
|
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_ABS:
|
|
case WASM_OP_F32_ABS:
|
|
@@ -4690,8 +4708,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_F32_TRUNC:
|
|
case WASM_OP_F32_TRUNC:
|
|
|
case WASM_OP_F32_NEAREST:
|
|
case WASM_OP_F32_NEAREST:
|
|
|
case WASM_OP_F32_SQRT:
|
|
case WASM_OP_F32_SQRT:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_ADD:
|
|
case WASM_OP_F32_ADD:
|
|
@@ -4701,9 +4718,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_F32_MIN:
|
|
case WASM_OP_F32_MIN:
|
|
|
case WASM_OP_F32_MAX:
|
|
case WASM_OP_F32_MAX:
|
|
|
case WASM_OP_F32_COPYSIGN:
|
|
case WASM_OP_F32_COPYSIGN:
|
|
|
- POP_F32();
|
|
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_ABS:
|
|
case WASM_OP_F64_ABS:
|
|
@@ -4713,8 +4728,7 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_F64_TRUNC:
|
|
case WASM_OP_F64_TRUNC:
|
|
|
case WASM_OP_F64_NEAREST:
|
|
case WASM_OP_F64_NEAREST:
|
|
|
case WASM_OP_F64_SQRT:
|
|
case WASM_OP_F64_SQRT:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_ADD:
|
|
case WASM_OP_F64_ADD:
|
|
@@ -4724,111 +4738,91 @@ handle_next_reachable_block:
|
|
|
case WASM_OP_F64_MIN:
|
|
case WASM_OP_F64_MIN:
|
|
|
case WASM_OP_F64_MAX:
|
|
case WASM_OP_F64_MAX:
|
|
|
case WASM_OP_F64_COPYSIGN:
|
|
case WASM_OP_F64_COPYSIGN:
|
|
|
- POP_F64();
|
|
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP2_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_WRAP_I64:
|
|
case WASM_OP_I32_WRAP_I64:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_TRUNC_S_F32:
|
|
case WASM_OP_I32_TRUNC_S_F32:
|
|
|
case WASM_OP_I32_TRUNC_U_F32:
|
|
case WASM_OP_I32_TRUNC_U_F32:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_TRUNC_S_F64:
|
|
case WASM_OP_I32_TRUNC_S_F64:
|
|
|
case WASM_OP_I32_TRUNC_U_F64:
|
|
case WASM_OP_I32_TRUNC_U_F64:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_EXTEND_S_I32:
|
|
case WASM_OP_I64_EXTEND_S_I32:
|
|
|
case WASM_OP_I64_EXTEND_U_I32:
|
|
case WASM_OP_I64_EXTEND_U_I32:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_TRUNC_S_F32:
|
|
case WASM_OP_I64_TRUNC_S_F32:
|
|
|
case WASM_OP_I64_TRUNC_U_F32:
|
|
case WASM_OP_I64_TRUNC_U_F32:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_TRUNC_S_F64:
|
|
case WASM_OP_I64_TRUNC_S_F64:
|
|
|
case WASM_OP_I64_TRUNC_U_F64:
|
|
case WASM_OP_I64_TRUNC_U_F64:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_CONVERT_S_I32:
|
|
case WASM_OP_F32_CONVERT_S_I32:
|
|
|
case WASM_OP_F32_CONVERT_U_I32:
|
|
case WASM_OP_F32_CONVERT_U_I32:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_CONVERT_S_I64:
|
|
case WASM_OP_F32_CONVERT_S_I64:
|
|
|
case WASM_OP_F32_CONVERT_U_I64:
|
|
case WASM_OP_F32_CONVERT_U_I64:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_DEMOTE_F64:
|
|
case WASM_OP_F32_DEMOTE_F64:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_CONVERT_S_I32:
|
|
case WASM_OP_F64_CONVERT_S_I32:
|
|
|
case WASM_OP_F64_CONVERT_U_I32:
|
|
case WASM_OP_F64_CONVERT_U_I32:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_CONVERT_S_I64:
|
|
case WASM_OP_F64_CONVERT_S_I64:
|
|
|
case WASM_OP_F64_CONVERT_U_I64:
|
|
case WASM_OP_F64_CONVERT_U_I64:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_PROMOTE_F32:
|
|
case WASM_OP_F64_PROMOTE_F32:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_REINTERPRET_F32:
|
|
case WASM_OP_I32_REINTERPRET_F32:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_REINTERPRET_F64:
|
|
case WASM_OP_I64_REINTERPRET_F64:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F32_REINTERPRET_I32:
|
|
case WASM_OP_F32_REINTERPRET_I32:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_F32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_F32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_F64_REINTERPRET_I64:
|
|
case WASM_OP_F64_REINTERPRET_I64:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_F64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_F64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I32_EXTEND8_S:
|
|
case WASM_OP_I32_EXTEND8_S:
|
|
|
case WASM_OP_I32_EXTEND16_S:
|
|
case WASM_OP_I32_EXTEND16_S:
|
|
|
- POP_I32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_I64_EXTEND8_S:
|
|
case WASM_OP_I64_EXTEND8_S:
|
|
|
case WASM_OP_I64_EXTEND16_S:
|
|
case WASM_OP_I64_EXTEND16_S:
|
|
|
case WASM_OP_I64_EXTEND32_S:
|
|
case WASM_OP_I64_EXTEND32_S:
|
|
|
- POP_I64();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_I64, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WASM_OP_MISC_PREFIX:
|
|
case WASM_OP_MISC_PREFIX:
|
|
@@ -4841,23 +4835,19 @@ handle_next_reachable_block:
|
|
|
{
|
|
{
|
|
|
case WASM_OP_I32_TRUNC_SAT_S_F32:
|
|
case WASM_OP_I32_TRUNC_SAT_S_F32:
|
|
|
case WASM_OP_I32_TRUNC_SAT_U_F32:
|
|
case WASM_OP_I32_TRUNC_SAT_U_F32:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
case WASM_OP_I32_TRUNC_SAT_S_F64:
|
|
case WASM_OP_I32_TRUNC_SAT_S_F64:
|
|
|
case WASM_OP_I32_TRUNC_SAT_U_F64:
|
|
case WASM_OP_I32_TRUNC_SAT_U_F64:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_I32();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I32);
|
|
|
break;
|
|
break;
|
|
|
case WASM_OP_I64_TRUNC_SAT_S_F32:
|
|
case WASM_OP_I64_TRUNC_SAT_S_F32:
|
|
|
case WASM_OP_I64_TRUNC_SAT_U_F32:
|
|
case WASM_OP_I64_TRUNC_SAT_U_F32:
|
|
|
- POP_F32();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F32, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
case WASM_OP_I64_TRUNC_SAT_S_F64:
|
|
case WASM_OP_I64_TRUNC_SAT_S_F64:
|
|
|
case WASM_OP_I64_TRUNC_SAT_U_F64:
|
|
case WASM_OP_I64_TRUNC_SAT_U_F64:
|
|
|
- POP_F64();
|
|
|
|
|
- PUSH_I64();
|
|
|
|
|
|
|
+ POP_AND_PUSH(VALUE_TYPE_F64, VALUE_TYPE_I64);
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
if (error_buf != NULL)
|
|
if (error_buf != NULL)
|