Add support for multi-memory proposal in classic interpreter (#3742)
Implement multi-memory for classic-interpreter. Support core spec (and bulk memory) opcodes now, and will support atomic opcodes, and add multi-memory export APIs in the future. PS: Multi-memory spec test patched a lot for linking test to adapt for multi-module implementation.
This commit is contained in:
@ -62,6 +62,17 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
||||
#define skip_leb_uint32(p, p_end) skip_leb(p)
|
||||
#define skip_leb_int32(p, p_end) skip_leb(p)
|
||||
#define skip_leb_mem_offset(p, p_end) skip_leb(p)
|
||||
#define skip_leb_memidx(p, p_end) skip_leb(p)
|
||||
#if WASM_ENABLE_MULTI_MEMORY == 0
|
||||
#define skip_leb_align(p, p_end) skip_leb(p)
|
||||
#else
|
||||
/* Skip the following memidx if applicable */
|
||||
#define skip_leb_align(p, p_end) \
|
||||
do { \
|
||||
if (*p++ & OPT_MEMIDX_FLAG) \
|
||||
skip_leb_uint32(p, p_end); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static bool
|
||||
is_32bit_type(uint8 type)
|
||||
@ -132,6 +143,35 @@ is_byte_a_type(uint8 type)
|
||||
#else
|
||||
#define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
|
||||
#endif
|
||||
#define read_leb_memidx(p, p_end, res) read_leb_uint32(p, p_end, res)
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
#define check_memidx(module, memidx) \
|
||||
do { \
|
||||
bh_assert(memidx \
|
||||
< module->import_memory_count + module->memory_count); \
|
||||
(void)memidx; \
|
||||
} while (0)
|
||||
/* Bit 6 indicating the optional memidx, and reset bit 6 for
|
||||
* alignment check */
|
||||
#define read_leb_memarg(p, p_end, res) \
|
||||
do { \
|
||||
read_leb_uint32(p, p_end, res); \
|
||||
if (res & OPT_MEMIDX_FLAG) { \
|
||||
res &= ~OPT_MEMIDX_FLAG; \
|
||||
read_leb_uint32(p, p_end, memidx); /* memidx */ \
|
||||
check_memidx(module, memidx); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
/* reserved byte 0x00 */
|
||||
#define check_memidx(module, memidx) \
|
||||
do { \
|
||||
(void)module; \
|
||||
bh_assert(memidx == 0); \
|
||||
(void)memidx; \
|
||||
} while (0)
|
||||
#define read_leb_memarg(p, p_end, res) read_leb_uint32(p, p_end, res)
|
||||
#endif
|
||||
|
||||
static void *
|
||||
loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
|
||||
@ -882,7 +922,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
if (flags & 1)
|
||||
read_leb_uint32(p, p_end, u32);
|
||||
module->import_memory_count++;
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
bh_assert(module->import_memory_count <= 1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_GLOBAL: /* import global */
|
||||
@ -1223,7 +1265,9 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
WASMMemory *memory;
|
||||
|
||||
read_leb_uint32(p, p_end, memory_count);
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
bh_assert(module->import_memory_count + memory_count <= 1);
|
||||
#endif
|
||||
|
||||
if (memory_count) {
|
||||
module->memory_count = memory_count;
|
||||
@ -3585,13 +3629,13 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
||||
case WASM_OP_I64_STORE8:
|
||||
case WASM_OP_I64_STORE16:
|
||||
case WASM_OP_I64_STORE32:
|
||||
skip_leb_uint32(p, p_end); /* align */
|
||||
skip_leb_align(p, p_end); /* align */
|
||||
skip_leb_mem_offset(p, p_end); /* offset */
|
||||
break;
|
||||
|
||||
case WASM_OP_MEMORY_SIZE:
|
||||
case WASM_OP_MEMORY_GROW:
|
||||
skip_leb_uint32(p, p_end); /* 0x00 */
|
||||
skip_leb_memidx(p, p_end); /* memidx */
|
||||
break;
|
||||
|
||||
case WASM_OP_I32_CONST:
|
||||
@ -3758,19 +3802,17 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
case WASM_OP_MEMORY_INIT:
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* skip memory idx */
|
||||
p++;
|
||||
skip_leb_memidx(p, p_end);
|
||||
break;
|
||||
case WASM_OP_DATA_DROP:
|
||||
skip_leb_uint32(p, p_end);
|
||||
break;
|
||||
case WASM_OP_MEMORY_COPY:
|
||||
/* skip two memory idx */
|
||||
p += 2;
|
||||
skip_leb_memidx(p, p_end);
|
||||
skip_leb_memidx(p, p_end);
|
||||
break;
|
||||
case WASM_OP_MEMORY_FILL:
|
||||
/* skip memory idx */
|
||||
p++;
|
||||
skip_leb_memidx(p, p_end);
|
||||
break;
|
||||
#endif
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
@ -5905,7 +5947,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type;
|
||||
BlockType func_block_type;
|
||||
uint16 *local_offsets, local_offset;
|
||||
uint32 count, local_idx, global_idx, u32, align, i;
|
||||
uint32 count, local_idx, global_idx, u32, align, i, memidx;
|
||||
mem_offset_t mem_offset;
|
||||
int32 i32, i32_const = 0;
|
||||
int64 i64_const;
|
||||
@ -7267,7 +7309,7 @@ re_scan:
|
||||
}
|
||||
#endif
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, align); /* align */
|
||||
read_leb_memarg(p, p_end, align); /* align */
|
||||
read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, mem_offset);
|
||||
@ -7329,9 +7371,8 @@ re_scan:
|
||||
|
||||
case WASM_OP_MEMORY_SIZE:
|
||||
CHECK_MEMORY();
|
||||
/* reserved byte 0x00 */
|
||||
bh_assert(*p == 0x00);
|
||||
p++;
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
PUSH_PAGE_COUNT();
|
||||
|
||||
module->possible_memory_grow = true;
|
||||
@ -7342,9 +7383,8 @@ re_scan:
|
||||
|
||||
case WASM_OP_MEMORY_GROW:
|
||||
CHECK_MEMORY();
|
||||
/* reserved byte 0x00 */
|
||||
bh_assert(*p == 0x00);
|
||||
p++;
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
POP_AND_PUSH(mem_offset_type, mem_offset_type);
|
||||
|
||||
module->possible_memory_grow = true;
|
||||
@ -7682,16 +7722,13 @@ re_scan:
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
case WASM_OP_MEMORY_INIT:
|
||||
{
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, segment_index);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, segment_index);
|
||||
#endif
|
||||
bh_assert(module->import_memory_count
|
||||
+ module->memory_count
|
||||
> 0);
|
||||
|
||||
bh_assert(*p == 0x00);
|
||||
p++;
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
|
||||
bh_assert(segment_index < module->data_seg_count);
|
||||
bh_assert(module->data_seg_count1 > 0);
|
||||
@ -7719,14 +7756,13 @@ re_scan:
|
||||
}
|
||||
case WASM_OP_MEMORY_COPY:
|
||||
{
|
||||
CHECK_MEMORY();
|
||||
CHECK_BUF(p, p_end, sizeof(int16));
|
||||
/* both src and dst memory index should be 0 */
|
||||
bh_assert(*(int16 *)p == 0x0000);
|
||||
p += 2;
|
||||
|
||||
bh_assert(module->import_memory_count
|
||||
+ module->memory_count
|
||||
> 0);
|
||||
/* check both src and dst memory index */
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
|
||||
POP_MEM_OFFSET();
|
||||
POP_MEM_OFFSET();
|
||||
@ -7738,12 +7774,9 @@ re_scan:
|
||||
}
|
||||
case WASM_OP_MEMORY_FILL:
|
||||
{
|
||||
bh_assert(*p == 0);
|
||||
p++;
|
||||
|
||||
bh_assert(module->import_memory_count
|
||||
+ module->memory_count
|
||||
> 0);
|
||||
CHECK_MEMORY();
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
|
||||
POP_MEM_OFFSET();
|
||||
POP_I32();
|
||||
|
||||
Reference in New Issue
Block a user