Fix memory/table segment checks in memory.init/table.init (#3081)
According to the wasm core spec, the checks for the table segments in `table.init` opcode are similar to the checks for `memory.init` opcode: - The size of a passive segment is shrunk to zero after `data.drop` (or `elem.drop`) opcode is executed, and the segment can be used to do `memory.init` (or `table.init`) again - The `memory.init` only traps when `s+n > len(data.data)` or `d+n > len(mem.data)` and `table.init` only traps when `s+n > len(elem.elem)` or `d+n > len(tab.elem)` - The active segment can also be used to do `memory.init` (or `table.init`), while it behaves like a dropped passive segment https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md ``` Segments can also be shrunk to size zero by using the following new instructions: - data.drop: discard the data in an data segment - elem.drop: discard the data in an element segment An active segment is equivalent to a passive segment, but with an implicit memory.init followed by a data.drop (or table.init followed by a elem.drop) that is prepended to the module's start function. ``` ps. https://webassembly.github.io/spec/core/bikeshed/#-hrefsyntax-instr-memorymathsfmemoryinitx%E2%91%A0 https://webassembly.github.io/spec/core/bikeshed/#-hrefsyntax-instr-tablemathsftableinitxy%E2%91%A0 https://github.com/bytecodealliance/wasm-micro-runtime/issues/3020
This commit is contained in:
@ -1179,6 +1179,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||
"failed to allocate bitmaps");
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < module->mem_init_data_count; i++) {
|
||||
if (!module->mem_init_data_list[i]->is_passive)
|
||||
bh_bitmap_set_bit(common->data_dropped, i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
@ -1190,6 +1194,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||
"failed to allocate bitmaps");
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < module->table_init_data_count; i++) {
|
||||
if (wasm_elem_is_active(module->table_init_data_list[i]->mode))
|
||||
bh_bitmap_set_bit(common->elem_dropped, i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2621,6 +2629,7 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
||||
{
|
||||
AOTTableInstance *tbl_inst;
|
||||
AOTTableInitData *tbl_seg;
|
||||
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
|
||||
const AOTModule *module = (AOTModule *)module_inst->module;
|
||||
|
||||
tbl_inst = module_inst->tables[tbl_idx];
|
||||
@ -2629,7 +2638,15 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
||||
tbl_seg = module->table_init_data_list[tbl_seg_idx];
|
||||
bh_assert(tbl_seg);
|
||||
|
||||
if (offset_len_out_of_bounds(src_offset, length, tbl_seg->func_index_count)
|
||||
if (!bh_bitmap_get_bit(
|
||||
((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
|
||||
tbl_seg_idx)) {
|
||||
/* table segment isn't dropped */
|
||||
tbl_seg_elems = tbl_seg->func_indexes;
|
||||
tbl_seg_len = tbl_seg->func_index_count;
|
||||
}
|
||||
|
||||
if (offset_len_out_of_bounds(src_offset, length, tbl_seg_len)
|
||||
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
|
||||
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
|
||||
return;
|
||||
@ -2639,22 +2656,10 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
||||
return;
|
||||
}
|
||||
|
||||
if (bh_bitmap_get_bit(
|
||||
((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
|
||||
tbl_seg_idx)) {
|
||||
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wasm_elem_is_passive(tbl_seg->mode)) {
|
||||
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
bh_memcpy_s((uint8 *)tbl_inst + offsetof(AOTTableInstance, elems)
|
||||
+ dst_offset * sizeof(uint32),
|
||||
(tbl_inst->cur_size - dst_offset) * sizeof(uint32),
|
||||
tbl_seg->func_indexes + src_offset, length * sizeof(uint32));
|
||||
tbl_seg_elems + src_offset, length * sizeof(uint32));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user