Support extended constant expressions (#4432)
* implement extended const expr (#4318) * add a toggle to enable extended const on wamrc (#4412)
This commit is contained in:
@ -968,6 +968,35 @@ fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
static void
|
||||
destroy_init_expr(InitializerExpression *expr)
|
||||
{
|
||||
#if WASM_ENABLE_GC != 0
|
||||
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|
||||
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|
||||
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
||||
wasm_runtime_free(expr->u.unary.v.data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
// free left expr and right expr for binary oprand
|
||||
if (!is_expr_binary_op(expr->init_expr_type)) {
|
||||
return;
|
||||
}
|
||||
if (expr->u.binary.l_expr) {
|
||||
destroy_init_expr_recursive(expr->u.binary.l_expr);
|
||||
}
|
||||
if (expr->u.binary.r_expr) {
|
||||
destroy_init_expr_recursive(expr->u.binary.r_expr);
|
||||
}
|
||||
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0 \
|
||||
*/
|
||||
|
||||
static void
|
||||
destroy_import_memories(AOTImportMemory *import_memories)
|
||||
{
|
||||
@ -993,6 +1022,10 @@ destroy_mem_init_data_list(AOTModule *module, AOTMemInitData **data_list,
|
||||
/* If the module owns the binary data, free the bytes buffer */
|
||||
if (module->is_binary_freeable && data_list[i]->bytes)
|
||||
wasm_runtime_free(data_list[i]->bytes);
|
||||
|
||||
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
destroy_init_expr(&data_list[i]->offset);
|
||||
#endif
|
||||
/* Free the data segment structure itself */
|
||||
wasm_runtime_free(data_list[i]);
|
||||
}
|
||||
@ -1043,11 +1076,11 @@ load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
|
||||
uint32 byte_count;
|
||||
uint32 is_passive;
|
||||
uint32 memory_index;
|
||||
InitializerExpression init_value;
|
||||
InitializerExpression offset_expr;
|
||||
|
||||
read_uint32(buf, buf_end, is_passive);
|
||||
read_uint32(buf, buf_end, memory_index);
|
||||
if (!load_init_expr(&buf, buf_end, module, &init_value, error_buf,
|
||||
if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
|
||||
error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
@ -1062,8 +1095,7 @@ load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
|
||||
data_list[i]->is_passive = (bool)is_passive;
|
||||
data_list[i]->memory_index = memory_index;
|
||||
#endif
|
||||
data_list[i]->offset.init_expr_type = init_value.init_expr_type;
|
||||
data_list[i]->offset.u = init_value.u;
|
||||
data_list[i]->offset = offset_expr;
|
||||
data_list[i]->byte_count = byte_count;
|
||||
data_list[i]->bytes = NULL;
|
||||
/* If the module owns the binary data, clone the bytes buffer */
|
||||
@ -1148,18 +1180,6 @@ fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
static void
|
||||
destroy_init_expr(InitializerExpression *expr)
|
||||
{
|
||||
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|
||||
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|
||||
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
|
||||
wasm_runtime_free(expr->u.data);
|
||||
}
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
|
||||
static void
|
||||
destroy_import_tables(AOTImportTable *import_tables)
|
||||
{
|
||||
@ -1183,6 +1203,9 @@ destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
|
||||
for (j = 0; j < data_list[i]->value_count; j++) {
|
||||
destroy_init_expr(&data_list[i]->init_values[j]);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
destroy_init_expr(&data_list[i]->offset);
|
||||
#endif
|
||||
wasm_runtime_free(data_list[i]);
|
||||
}
|
||||
@ -1208,34 +1231,34 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
break;
|
||||
case INIT_EXPR_TYPE_I32_CONST:
|
||||
case INIT_EXPR_TYPE_F32_CONST:
|
||||
read_uint32(buf, buf_end, expr->u.i32);
|
||||
read_uint32(buf, buf_end, expr->u.unary.v.i32);
|
||||
break;
|
||||
case INIT_EXPR_TYPE_I64_CONST:
|
||||
case INIT_EXPR_TYPE_F64_CONST:
|
||||
read_uint64(buf, buf_end, expr->u.i64);
|
||||
read_uint64(buf, buf_end, expr->u.unary.v.i64);
|
||||
break;
|
||||
case INIT_EXPR_TYPE_V128_CONST:
|
||||
i64x2 = (uint64 *)expr->u.v128.i64x2;
|
||||
i64x2 = (uint64 *)expr->u.unary.v.v128.i64x2;
|
||||
CHECK_BUF(buf, buf_end, sizeof(uint64) * 2);
|
||||
wasm_runtime_read_v128(buf, &i64x2[0], &i64x2[1]);
|
||||
buf += sizeof(uint64) * 2;
|
||||
break;
|
||||
case INIT_EXPR_TYPE_GET_GLOBAL:
|
||||
read_uint32(buf, buf_end, expr->u.global_index);
|
||||
read_uint32(buf, buf_end, expr->u.unary.v.global_index);
|
||||
break;
|
||||
/* INIT_EXPR_TYPE_FUNCREF_CONST can be used when
|
||||
both reference types and GC are disabled */
|
||||
case INIT_EXPR_TYPE_FUNCREF_CONST:
|
||||
read_uint32(buf, buf_end, expr->u.ref_index);
|
||||
read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
|
||||
break;
|
||||
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0
|
||||
case INIT_EXPR_TYPE_REFNULL_CONST:
|
||||
read_uint32(buf, buf_end, expr->u.ref_index);
|
||||
read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
|
||||
break;
|
||||
#endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0 */
|
||||
#if WASM_ENABLE_GC != 0
|
||||
case INIT_EXPR_TYPE_I31_NEW:
|
||||
read_uint32(buf, buf_end, expr->u.i32);
|
||||
read_uint32(buf, buf_end, expr->u.unary.v.i32);
|
||||
break;
|
||||
case INIT_EXPR_TYPE_STRUCT_NEW:
|
||||
{
|
||||
@ -1256,7 +1279,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
free_if_fail = true;
|
||||
init_values->count = field_count;
|
||||
init_values->type_idx = type_idx;
|
||||
expr->u.data = init_values;
|
||||
expr->u.unary.v.data = init_values;
|
||||
|
||||
if (type_idx >= module->type_count) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
@ -1294,7 +1317,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
break;
|
||||
}
|
||||
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
|
||||
read_uint32(buf, buf_end, expr->u.type_index);
|
||||
read_uint32(buf, buf_end, expr->u.unary.v.type_index);
|
||||
break;
|
||||
case INIT_EXPR_TYPE_ARRAY_NEW:
|
||||
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
|
||||
@ -1317,8 +1340,8 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
}
|
||||
|
||||
if (init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
|
||||
expr->u.array_new_default.type_index = type_idx;
|
||||
expr->u.array_new_default.length = length;
|
||||
expr->u.unary.v.array_new_default.type_index = type_idx;
|
||||
expr->u.unary.v.array_new_default.length = length;
|
||||
}
|
||||
else {
|
||||
uint32 i, elem_size, elem_data_count;
|
||||
@ -1329,7 +1352,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
return false;
|
||||
}
|
||||
free_if_fail = true;
|
||||
expr->u.data = init_values;
|
||||
expr->u.unary.v.data = init_values;
|
||||
|
||||
init_values->type_idx = type_idx;
|
||||
init_values->length = length;
|
||||
@ -1357,6 +1380,34 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
break;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
case INIT_EXPR_TYPE_I32_ADD:
|
||||
case INIT_EXPR_TYPE_I32_SUB:
|
||||
case INIT_EXPR_TYPE_I32_MUL:
|
||||
case INIT_EXPR_TYPE_I64_ADD:
|
||||
case INIT_EXPR_TYPE_I64_SUB:
|
||||
case INIT_EXPR_TYPE_I64_MUL:
|
||||
{
|
||||
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
|
||||
if (!(expr->u.binary.l_expr =
|
||||
loader_malloc(sizeof(InitializerExpression), error_buf,
|
||||
error_buf_size))) {
|
||||
goto fail;
|
||||
}
|
||||
if (!load_init_expr(&buf, buf_end, module, expr->u.binary.l_expr,
|
||||
error_buf, error_buf_size))
|
||||
goto fail;
|
||||
if (!(expr->u.binary.r_expr =
|
||||
loader_malloc(sizeof(InitializerExpression), error_buf,
|
||||
error_buf_size))) {
|
||||
goto fail;
|
||||
}
|
||||
if (!load_init_expr(&buf, buf_end, module, expr->u.binary.r_expr,
|
||||
error_buf, error_buf_size))
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
|
||||
default:
|
||||
set_error_buf(error_buf, error_buf_size, "invalid init expr type.");
|
||||
return false;
|
||||
@ -1369,10 +1420,13 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
fail:
|
||||
#if WASM_ENABLE_GC != 0
|
||||
if (free_if_fail) {
|
||||
wasm_runtime_free(expr->u.data);
|
||||
wasm_runtime_free(expr->u.unary.v.data);
|
||||
}
|
||||
#else
|
||||
(void)free_if_fail;
|
||||
#endif
|
||||
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
destroy_init_expr(expr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -1535,14 +1589,16 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
|
||||
/* Create each table data segment */
|
||||
for (i = 0; i < module->table_init_data_count; i++) {
|
||||
uint32 mode, elem_type;
|
||||
uint32 table_index, init_expr_type, value_count;
|
||||
uint64 init_expr_value, size1;
|
||||
uint32 table_index, value_count;
|
||||
uint64 size1;
|
||||
InitializerExpression offset_expr;
|
||||
|
||||
read_uint32(buf, buf_end, mode);
|
||||
read_uint32(buf, buf_end, elem_type);
|
||||
read_uint32(buf, buf_end, table_index);
|
||||
read_uint32(buf, buf_end, init_expr_type);
|
||||
read_uint64(buf, buf_end, init_expr_value);
|
||||
if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
if (wasm_is_type_multi_byte_type(elem_type)) {
|
||||
uint16 ref_type, nullable;
|
||||
@ -1588,8 +1644,7 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
|
||||
data_list[i]->offset.u.i64 = (int64)init_expr_value;
|
||||
data_list[i]->offset = offset_expr;
|
||||
data_list[i]->value_count = value_count;
|
||||
for (j = 0; j < data_list[i]->value_count; j++) {
|
||||
if (!load_init_expr(&buf, buf_end, module,
|
||||
@ -4500,7 +4555,7 @@ aot_unload(AOTModule *module)
|
||||
destroy_import_globals(module->import_globals);
|
||||
|
||||
if (module->globals) {
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
|
||||
uint32 i;
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
destroy_init_expr(&module->globals[i].init_expr);
|
||||
|
||||
Reference in New Issue
Block a user