Implement GC (Garbage Collection) feature for interpreter, AOT and LLVM-JIT (#3125)
Implement the GC (Garbage Collection) feature for interpreter mode, AOT mode and LLVM-JIT mode, and support most features of the latest spec proposal, and also enable the stringref feature. Use `cmake -DWAMR_BUILD_GC=1/0` to enable/disable the feature, and `wamrc --enable-gc` to generate the AOT file with GC supported. And update the AOT file version from 2 to 3 since there are many AOT ABI breaks, including the changes of AOT file format, the changes of AOT module/memory instance layouts, the AOT runtime APIs for the AOT code to invoke and so on.
This commit is contained in:
@ -774,7 +774,7 @@ wasm_valtype_new(wasm_valkind_t kind)
|
||||
wasm_valtype_t *val_type;
|
||||
|
||||
if (kind > WASM_F64 && WASM_FUNCREF != kind
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
&& WASM_ANYREF != kind
|
||||
#endif
|
||||
) {
|
||||
@ -811,7 +811,7 @@ wasm_valtype_kind(const wasm_valtype_t *val_type)
|
||||
}
|
||||
|
||||
static wasm_functype_t *
|
||||
wasm_functype_new_internal(WASMType *type_rt)
|
||||
wasm_functype_new_internal(WASMFuncType *type_rt)
|
||||
{
|
||||
wasm_functype_t *type = NULL;
|
||||
wasm_valtype_t *param_type = NULL, *result_type = NULL;
|
||||
@ -827,7 +827,7 @@ wasm_functype_new_internal(WASMType *type_rt)
|
||||
|
||||
type->extern_kind = WASM_EXTERN_FUNC;
|
||||
|
||||
/* WASMType->types[0 : type_rt->param_count) -> type->params */
|
||||
/* WASMFuncType->types[0 : type_rt->param_count) -> type->params */
|
||||
INIT_VEC(type->params, wasm_valtype_vec_new_uninitialized,
|
||||
type_rt->param_count);
|
||||
for (i = 0; i < type_rt->param_count; ++i) {
|
||||
@ -841,7 +841,7 @@ wasm_functype_new_internal(WASMType *type_rt)
|
||||
}
|
||||
}
|
||||
|
||||
/* WASMType->types[type_rt->param_count : type_rt->result_count) ->
|
||||
/* WASMFuncType->types[type_rt->param_count : type_rt->result_count) ->
|
||||
* type->results */
|
||||
INIT_VEC(type->results, wasm_valtype_vec_new_uninitialized,
|
||||
type_rt->result_count);
|
||||
@ -983,7 +983,7 @@ cmp_val_kind_with_val_type(wasm_valkind_t v_k, uint8 v_t)
|
||||
*/
|
||||
static bool
|
||||
wasm_functype_same_internal(const wasm_functype_t *type,
|
||||
const WASMType *type_intl)
|
||||
const WASMFuncType *type_intl)
|
||||
{
|
||||
uint32 i = 0;
|
||||
|
||||
@ -1132,7 +1132,7 @@ wasm_tabletype_new(own wasm_valtype_t *val_type, const wasm_limits_t *limits)
|
||||
}
|
||||
|
||||
if (wasm_valtype_kind(val_type) != WASM_FUNCREF
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
&& wasm_valtype_kind(val_type) != WASM_ANYREF
|
||||
#endif
|
||||
) {
|
||||
@ -1646,7 +1646,7 @@ rt_val_to_wasm_val(const uint8 *data, uint8 val_type_rt, wasm_val_t *out)
|
||||
out->kind = WASM_F64;
|
||||
out->of.f64 = *((float64 *)data);
|
||||
break;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
out->kind = WASM_ANYREF;
|
||||
if (NULL_REF == *(uint32 *)data) {
|
||||
@ -1687,7 +1687,7 @@ wasm_val_to_rt_val(WASMModuleInstanceCommon *inst_comm_rt, uint8 val_type_rt,
|
||||
bh_assert(WASM_F64 == v->kind);
|
||||
*((float64 *)data) = v->of.f64;
|
||||
break;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
bh_assert(WASM_ANYREF == v->kind);
|
||||
ret =
|
||||
@ -2470,7 +2470,7 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
|
||||
|
||||
if (i < import_func_count) {
|
||||
wasm_functype_t *type = NULL;
|
||||
WASMType *type_rt = NULL;
|
||||
WASMFuncType *type_rt = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if ((*module)->module_type == Wasm_Module_Bytecode) {
|
||||
@ -2715,13 +2715,13 @@ wasm_module_exports(const wasm_module_t *module, wasm_exporttype_vec_t *out)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* WASMExport -> (WASMType, (uint8, bool)) -> (wasm_functype_t,
|
||||
/* WASMExport -> (WASMFuncType, (uint8, bool)) -> (wasm_functype_t,
|
||||
* wasm_globaltype_t) -> wasm_externtype_t*/
|
||||
switch (export->kind) {
|
||||
case EXPORT_KIND_FUNC:
|
||||
{
|
||||
wasm_functype_t *type = NULL;
|
||||
WASMType *type_rt;
|
||||
WASMFuncType *type_rt;
|
||||
|
||||
if (!wasm_runtime_get_export_func_type(*module, export,
|
||||
&type_rt)) {
|
||||
@ -2776,12 +2776,22 @@ wasm_module_exports(const wasm_module_t *module, wasm_exporttype_vec_t *out)
|
||||
{
|
||||
wasm_tabletype_t *type = NULL;
|
||||
uint8 elem_type_rt = 0;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
WASMRefType *elem_ref_type_rt;
|
||||
#endif
|
||||
uint32 min_size = 0, max_size = 0;
|
||||
|
||||
if (!wasm_runtime_get_export_table_type(
|
||||
*module, export, &elem_type_rt, &min_size, &max_size)) {
|
||||
if (!wasm_runtime_get_export_table_type(*module, export,
|
||||
&elem_type_rt,
|
||||
#if WASM_ENABLE_GC != 0
|
||||
&elem_ref_type_rt,
|
||||
#endif
|
||||
&min_size, &max_size)) {
|
||||
goto failed;
|
||||
}
|
||||
#if WASM_ENABLE_GC != 0
|
||||
(void)elem_ref_type_rt; /* TODO */
|
||||
#endif
|
||||
|
||||
if (!(type = wasm_tabletype_new_internal(elem_type_rt, min_size,
|
||||
max_size))) {
|
||||
@ -3032,7 +3042,7 @@ wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt,
|
||||
WASMModuleInstanceCommon *inst_comm_rt)
|
||||
{
|
||||
wasm_func_t *func = NULL;
|
||||
WASMType *type_rt = NULL;
|
||||
WASMFuncType *type_rt = NULL;
|
||||
|
||||
bh_assert(singleton_engine);
|
||||
|
||||
@ -3070,9 +3080,9 @@ wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt,
|
||||
}
|
||||
else {
|
||||
type_rt =
|
||||
module_aot->func_types[module_aot->func_type_indexes
|
||||
[func_idx_rt
|
||||
- module_aot->import_func_count]];
|
||||
(AOTFuncType *)module_aot
|
||||
->types[module_aot->func_type_indexes
|
||||
[func_idx_rt - module_aot->import_func_count]];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3204,8 +3214,7 @@ params_to_argv(const wasm_val_vec_t *params,
|
||||
*(int64 *)argv = param->of.i64;
|
||||
argv += 2;
|
||||
break;
|
||||
break;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case WASM_ANYREF:
|
||||
*(uintptr_t *)argv = (uintptr_t)param->of.ref;
|
||||
argv += sizeof(uintptr_t) / sizeof(uint32);
|
||||
@ -3247,7 +3256,7 @@ argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs,
|
||||
result->of.i64 = *(int64 *)argv;
|
||||
argv += 2;
|
||||
break;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case WASM_ANYREF:
|
||||
result->of.ref = (struct wasm_ref_t *)(*(uintptr_t *)argv);
|
||||
argv += sizeof(uintptr_t) / sizeof(uint32);
|
||||
@ -3830,6 +3839,9 @@ wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt,
|
||||
{
|
||||
wasm_table_t *table = NULL;
|
||||
uint8 val_type_rt = 0;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
WASMRefType *val_ref_type_rt;
|
||||
#endif
|
||||
uint32 init_size = 0, max_size = 0;
|
||||
|
||||
bh_assert(singleton_engine);
|
||||
@ -3845,14 +3857,21 @@ wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt,
|
||||
table->store = store;
|
||||
table->kind = WASM_EXTERN_TABLE;
|
||||
|
||||
if (!wasm_runtime_get_table_inst_elem_type(
|
||||
inst_comm_rt, table_idx_rt, &val_type_rt, &init_size, &max_size)) {
|
||||
if (!wasm_runtime_get_table_inst_elem_type(inst_comm_rt, table_idx_rt,
|
||||
&val_type_rt,
|
||||
#if WASM_ENABLE_GC != 0
|
||||
&val_ref_type_rt,
|
||||
#endif
|
||||
&init_size, &max_size)) {
|
||||
/*
|
||||
* a wrong combination of module filetype and compilation flags
|
||||
* leads to below branch
|
||||
*/
|
||||
goto failed;
|
||||
}
|
||||
#if WASM_ENABLE_GC != 0
|
||||
(void)val_ref_type_rt; /* TODO */
|
||||
#endif
|
||||
|
||||
if (!(table->type =
|
||||
wasm_tabletype_new_internal(val_type_rt, init_size, max_size))) {
|
||||
@ -3922,6 +3941,7 @@ wasm_table_type(const wasm_table_t *table)
|
||||
return wasm_tabletype_copy(table->type);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
own wasm_ref_t *
|
||||
wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
||||
{
|
||||
@ -4010,7 +4030,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
return false;
|
||||
}
|
||||
|
||||
p_ref_idx = table_interp->elems + index;
|
||||
p_ref_idx = (uint32 *)(table_interp->elems + index);
|
||||
function_count =
|
||||
((WASMModuleInstance *)table->inst_comm_rt)->e->function_count;
|
||||
}
|
||||
@ -4026,7 +4046,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
return false;
|
||||
}
|
||||
|
||||
p_ref_idx = table_aot->elems + index;
|
||||
p_ref_idx = (uint32 *)(table_aot->elems + index);
|
||||
function_count = module_aot->func_count;
|
||||
}
|
||||
#endif
|
||||
@ -4062,6 +4082,22 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
|
||||
return true;
|
||||
}
|
||||
#else /* else of WASM_ENABLE_GC == 0 */
|
||||
own wasm_ref_t *
|
||||
wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
||||
{
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
own wasm_ref_t *ref)
|
||||
{
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_GC == 0 */
|
||||
|
||||
wasm_table_size_t
|
||||
wasm_table_size(const wasm_table_t *table)
|
||||
|
||||
Reference in New Issue
Block a user