Skip to content

Commit

Permalink
Enhance GC subtyping checks (bytecodealliance#3317)
Browse files Browse the repository at this point in the history
Enhance the GC subtyping checks:
- Fix issues in the type equivalence check
- Enable the recursive type subtyping check
- Add a equivalence type flag in defined types of aot file, if there is an
  equivalence type before, just set it true and re-use the previous type
- Normalize the defined types for interpreter and AOT
- Enable spec test case type-equivalence.wast and type-subtyping.wast,
  and enable some commented cases
- Enable set WAMR_BUILD_SANITIZER from cmake variable

Signed-off-by: victoryang00 <victoryang00@ucsc.edu>
  • Loading branch information
wenyongh authored and victoryang00 committed May 2, 2024
1 parent ea8d170 commit c7ff530
Show file tree
Hide file tree
Showing 20 changed files with 583 additions and 475 deletions.
7 changes: 6 additions & 1 deletion build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ endif ()

# Sanitizers

set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
if (NOT DEFINED WAMR_BUILD_SANITIZER)
set(WAMR_BUILD_SANITIZER $ENV{WAMR_BUILD_SANITIZER})
endif ()

if (NOT DEFINED WAMR_BUILD_SANITIZER)
set(WAMR_BUILD_SANITIZER "")
Expand Down Expand Up @@ -558,3 +560,6 @@ else ()
# Disable aot intrinsics for interp, fast-jit and llvm-jit
add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=0)
endif ()
if (NOT WAMR_BUILD_SANITIZER STREQUAL "")
message (" Sanitizer ${WAMR_BUILD_SANITIZER} enabled")
endif ()
94 changes: 66 additions & 28 deletions core/iwasm/aot/aot_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1525,45 +1525,60 @@ load_table_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
return false;
}

static void
destroy_type(AOTType *type)
{
#if WASM_ENABLE_GC != 0
if (type->ref_count > 1) {
/* The type is referenced by other types
of current aot module */
type->ref_count--;
return;
}

if (type->type_flag == WASM_TYPE_FUNC) {
AOTFuncType *func_type = (AOTFuncType *)type;
if (func_type->ref_type_maps != NULL) {
bh_assert(func_type->ref_type_map_count > 0);
wasm_runtime_free(func_type->ref_type_maps);
}
}
else if (type->type_flag == WASM_TYPE_STRUCT) {
AOTStructType *struct_type = (AOTStructType *)type;
if (struct_type->ref_type_maps != NULL) {
bh_assert(struct_type->ref_type_map_count > 0);
wasm_runtime_free(struct_type->ref_type_maps);
}
}
#endif
wasm_runtime_free(type);
}

static void
destroy_types(AOTType **types, uint32 count)
{
uint32 i;
for (i = 0; i < count; i++) {

if (types[i]) {
#if WASM_ENABLE_GC != 0
if (types[i]->type_flag == WASM_TYPE_FUNC) {
AOTFuncType *func_type = (AOTFuncType *)types[i];
if (func_type->ref_type_maps != NULL) {
bh_assert(func_type->ref_type_map_count > 0);
wasm_runtime_free(func_type->ref_type_maps);
}
}
else if (types[i]->type_flag == WASM_TYPE_STRUCT) {
AOTStructType *struct_type = (AOTStructType *)types[i];
if (struct_type->ref_type_maps != NULL) {
bh_assert(struct_type->ref_type_map_count > 0);
wasm_runtime_free(struct_type->ref_type_maps);
}
}
#endif
wasm_runtime_free(types[i]);
destroy_type(types[i]);
}
}
wasm_runtime_free(types);
}

#if WASM_ENABLE_GC != 0
static void
init_base_type(AOTType *base_type, uint16 type_flag, bool is_sub_final,
uint32 parent_type_idx, uint16 rec_count, uint16 rec_idx)
init_base_type(AOTType *base_type, uint32 type_idx, uint16 type_flag,
bool is_sub_final, uint32 parent_type_idx, uint16 rec_count,
uint16 rec_idx)
{
base_type->type_flag = type_flag;
base_type->ref_count = 1;
base_type->is_sub_final = is_sub_final;
base_type->parent_type_idx = parent_type_idx;
base_type->rec_count = rec_count;
base_type->rec_idx = rec_idx;
base_type->rec_begin_type_idx = type_idx - rec_idx;
}

static bool
Expand All @@ -1576,7 +1591,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
uint32 i, j;
uint32 type_flag, param_cell_num, ret_cell_num;
uint16 param_count, result_count, ref_type_map_count, rec_count, rec_idx;
bool is_sub_final;
bool is_equivalence_type, is_sub_final;
uint32 parent_type_idx;
WASMRefType ref_type;

Expand All @@ -1590,12 +1605,31 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,

/* Create each type */
for (i = 0; i < module->type_count; i++) {

buf = align_ptr(buf, 4);

/* Read base type info */
read_uint16(buf, buf_end, type_flag);
read_uint16(buf, buf_end, is_sub_final);

read_uint8(buf, buf_end, is_equivalence_type);
/* If there is an equivalence type, re-use it */
if (is_equivalence_type) {
uint8 u8;
/* padding */
read_uint8(buf, buf_end, u8);
(void)u8;

read_uint32(buf, buf_end, j);
if (module->types[j]->ref_count == UINT16_MAX) {
set_error_buf(error_buf, error_buf_size,
"wasm type's ref count too large");
goto fail;
}
module->types[j]->ref_count++;
module->types[i] = module->types[j];
continue;
}

read_uint8(buf, buf_end, is_sub_final);
read_uint32(buf, buf_end, parent_type_idx);
read_uint16(buf, buf_end, rec_count);
read_uint16(buf, buf_end, rec_idx);
Expand All @@ -1620,7 +1654,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,

types[i] = (AOTType *)func_type;

init_base_type((AOTType *)func_type, type_flag, is_sub_final,
init_base_type((AOTType *)func_type, i, type_flag, is_sub_final,
parent_type_idx, rec_count, rec_idx);
func_type->param_count = param_count;
func_type->result_count = result_count;
Expand Down Expand Up @@ -1726,7 +1760,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
offset = (uint32)offsetof(WASMStructObject, field_data);
types[i] = (AOTType *)struct_type;

init_base_type((AOTType *)struct_type, type_flag, is_sub_final,
init_base_type((AOTType *)struct_type, i, type_flag, is_sub_final,
parent_type_idx, rec_count, rec_idx);
struct_type->field_count = field_count;
struct_type->ref_type_map_count = ref_type_map_count;
Expand Down Expand Up @@ -1812,7 +1846,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,

types[i] = (AOTType *)array_type;

init_base_type((AOTType *)array_type, type_flag, is_sub_final,
init_base_type((AOTType *)array_type, i, type_flag, is_sub_final,
parent_type_idx, rec_count, rec_idx);
read_uint16(buf, buf_end, array_type->elem_flags);
read_uint8(buf, buf_end, array_type->elem_type);
Expand Down Expand Up @@ -1841,7 +1875,6 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
if (rec_count == 0) {
bh_assert(rec_idx == 0);
}

for (j = i - rec_idx; j <= i; j++) {
AOTType *cur_type = module->types[j];
parent_type_idx = cur_type->parent_type_idx;
Expand All @@ -1850,6 +1883,11 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,

module->types[j]->parent_type = parent_type;
module->types[j]->root_type = parent_type->root_type;
if (parent_type->inherit_depth == UINT16_MAX) {
set_error_buf(error_buf, error_buf_size,
"parent type's inherit depth too large");
goto fail;
}
module->types[j]->inherit_depth =
parent_type->inherit_depth + 1;
}
Expand All @@ -1867,7 +1905,7 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
AOTType *parent_type = module->types[parent_type_idx];
/* subtyping has been checked during compilation */
bh_assert(wasm_type_is_subtype_of(
module->types[j], parent_type, module->types, i));
module->types[j], parent_type, module->types, i + 1));
(void)parent_type;
}
}
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/aot/aot_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ typedef struct {
REG_SYM(aot_array_init_with_data), \
REG_SYM(aot_create_func_obj), \
REG_SYM(aot_obj_is_instance_of), \
REG_SYM(aot_func_type_is_super_of), \
REG_SYM(aot_rtt_type_new), \
REG_SYM(wasm_array_obj_copy), \
REG_SYM(wasm_array_obj_new), \
Expand Down
22 changes: 20 additions & 2 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,15 +1742,17 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,

bh_assert(table_init_data);

bh_assert(table_init_data->table_index < module_inst->table_count);
table = module_inst->tables[table_init_data->table_index];
bh_assert(table);

table_data = table->elems;
bh_assert(table_data);

wasm_runtime_get_table_inst_elem_type(
(WASMModuleInstanceCommon *)module_inst, i, &tbl_elem_type,
&tbl_elem_ref_type, &tbl_init_size, &tbl_max_size);
(WASMModuleInstanceCommon *)module_inst,
table_init_data->table_index, &tbl_elem_type, &tbl_elem_ref_type,
&tbl_init_size, &tbl_max_size);

if (!wasm_elem_is_declarative(table_init_data->mode)
&& !wasm_reftype_is_subtype_of(
Expand Down Expand Up @@ -4560,6 +4562,22 @@ aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
return wasm_obj_is_instance_of(gc_obj, type_index, types, type_count);
}

bool
aot_func_type_is_super_of(AOTModuleInstance *module_inst, uint32 type_idx1,
uint32 type_idx2)
{
AOTModule *aot_module = (AOTModule *)module_inst->module;
AOTType **types = aot_module->types;

if (type_idx1 == type_idx2)
return true;

bh_assert(types[type_idx1]->type_flag == WASM_TYPE_FUNC);
bh_assert(types[type_idx2]->type_flag == WASM_TYPE_FUNC);
return wasm_func_type_is_super_of((WASMFuncType *)types[type_idx1],
(WASMFuncType *)types[type_idx2]);
}

WASMRttTypeRef
aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index)
{
Expand Down
5 changes: 5 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,11 @@ bool
aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
uint32 type_index);

/* Whether func type1 is one of super types of func type2 */
bool
aot_func_type_is_super_of(AOTModuleInstance *module_inst, uint32 type_idx1,
uint32 type_idx2);

WASMRttTypeRef
aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index);

Expand Down
7 changes: 6 additions & 1 deletion core/iwasm/common/gc/gc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,12 @@ wasm_defined_type_equal(WASMType *const def_type1, WASMType *const def_type2,
}
#endif
#if WASM_ENABLE_AOT != 0
/* TODO */
if (module->module_type == Wasm_Module_AoT) {
AOTModule *aot_module = (AOTModule *)module;

types = aot_module->types;
type_count = aot_module->type_count;
}
#endif

bh_assert(types);
Expand Down
Loading

0 comments on commit c7ff530

Please sign in to comment.