Skip to content

Commit a5170aa

Browse files
authored
implement extended const expr (#4318)
1 parent ea5757f commit a5170aa

23 files changed

Lines changed: 1715 additions & 375 deletions

.github/workflows/compilation_on_android_ubuntu.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ env:
6969
GC_TEST_OPTIONS: "-s spec -G -b -P"
7070
MEMORY64_TEST_OPTIONS: "-s spec -W -b -P"
7171
MULTI_MEMORY_TEST_OPTIONS: "-s spec -E -b -P"
72+
EXTENDED_CONST_EXPR_TEST_OPTIONS: "-s spec -N -b -P"
7273

7374
permissions:
7475
contents: read
@@ -164,6 +165,7 @@ jobs:
164165
"-DWAMR_BUILD_MEMORY64=1",
165166
"-DWAMR_BUILD_MULTI_MEMORY=1",
166167
"-DWAMR_BUILD_SHARED=1",
168+
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
167169
]
168170
os: [ubuntu-22.04]
169171
platform: [android, linux]
@@ -609,6 +611,7 @@ jobs:
609611
$GC_TEST_OPTIONS,
610612
$MEMORY64_TEST_OPTIONS,
611613
$MULTI_MEMORY_TEST_OPTIONS,
614+
$EXTENDED_CONST_EXPR_TEST_OPTIONS,
612615
]
613616
include:
614617
- os: ubuntu-22.04

.github/workflows/compilation_on_macos.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ jobs:
142142
"-DWAMR_BUILD_SIMD=1",
143143
"-DWAMR_BUILD_TAIL_CALL=1",
144144
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
145+
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
145146
]
146147
os: [macos-13]
147148
platform: [darwin]

.github/workflows/compilation_on_sgx.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ jobs:
100100
"-DWAMR_BUILD_MULTI_MODULE=1",
101101
"-DWAMR_BUILD_PERF_PROFILING=1",
102102
"-DWAMR_BUILD_REF_TYPES=1",
103+
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
103104
# doesn't support
104105
"-DWAMR_BUILD_SIMD=0",
105106
"-DWAMR_BUILD_TAIL_CALL=1",

.github/workflows/nightly_run.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ env:
4040
DEFAULT_TEST_OPTIONS: "-s spec -P"
4141
MULTI_MODULES_TEST_OPTIONS: "-s spec -M -P"
4242
SIMD_TEST_OPTIONS: "-s spec -S -P"
43+
EXTENDED_CONST_EXPR_TEST_OPTIONS: "-s spec -N -P"
4344
THREADS_TEST_OPTIONS: "-s spec -p -P"
4445
X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P"
4546
WASI_TEST_OPTIONS: "-s wasi_certification -w"
@@ -129,6 +130,7 @@ jobs:
129130
"-DWAMR_BUILD_MEMORY64=1",
130131
"-DWAMR_BUILD_MULTI_MEMORY=1",
131132
"-DWAMR_BUILD_SHARED=1",
133+
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
132134
]
133135
os: [ubuntu-22.04]
134136
platform: [android, linux]
@@ -589,6 +591,7 @@ jobs:
589591
$DEFAULT_TEST_OPTIONS,
590592
$MULTI_MODULES_TEST_OPTIONS,
591593
$SIMD_TEST_OPTIONS,
594+
$EXTENDED_CONST_EXPR_TEST_OPTIONS,
592595
$THREADS_TEST_OPTIONS,
593596
$WASI_TEST_OPTIONS,
594597
]

build-scripts/config_common.cmake

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ if (NOT DEFINED WAMR_BUILD_TAIL_CALL)
211211
set (WAMR_BUILD_TAIL_CALL 0)
212212
endif ()
213213

214+
if (NOT DEFINED WAMR_BUILD_EXTENDED_CONST_EXPR)
215+
set (WAMR_BUILD_EXTENDED_CONST_EXPR 0)
216+
endif ()
217+
214218
########################################
215219
# Compilation options to marco
216220
########################################
@@ -675,7 +679,13 @@ if (WAMR_BUILD_INSTRUCTION_METERING EQUAL 1)
675679
message (" Instruction metering enabled")
676680
add_definitions (-DWASM_ENABLE_INSTRUCTION_METERING=1)
677681
endif ()
678-
682+
if (WAMR_BUILD_EXTENDED_CONST_EXPR EQUAL 1)
683+
message (" Extended constant expression enabled")
684+
add_definitions(-DWASM_ENABLE_EXTENDED_CONST_EXPR=1)
685+
else()
686+
message (" Extended constant expression disabled")
687+
add_definitions(-DWASM_ENABLE_EXTENDED_CONST_EXPR=0)
688+
endif ()
679689
########################################
680690
# Show Phase4 Wasm proposals status.
681691
########################################
@@ -689,6 +699,7 @@ message (
689699
" \"WebAssembly C and C++ API\"\n"
690700
" Configurable. 0 is OFF. 1 is ON:\n"
691701
" \"Bulk Memory Operation\" via WAMR_BUILD_BULK_MEMORY: ${WAMR_BUILD_BULK_MEMORY}\n"
702+
" \"Extended Constant Expressions\" via WAMR_BUILD_EXTENDED_CONST_EXPR: ${WAMR_BUILD_EXTENDED_CONST_EXPR}\n"
692703
" \"Fixed-width SIMD\" via WAMR_BUILD_SIMD: ${WAMR_BUILD_SIMD}\n"
693704
" \"Garbage collection\" via WAMR_BUILD_GC: ${WAMR_BUILD_GC}\n"
694705
" \"Legacy Exception handling\" via WAMR_BUILD_EXCE_HANDLING: ${WAMR_BUILD_EXCE_HANDLING}\n"
@@ -703,7 +714,6 @@ message (
703714
" \"Branch Hinting\"\n"
704715
" \"Custom Annotation Syntax in the Text Format\"\n"
705716
" \"Exception handling\"\n"
706-
" \"Extended Constant Expressions\"\n"
707717
" \"Import/Export of Mutable Globals\"\n"
708718
" \"JS String Builtins\"\n"
709719
" \"Relaxed SIMD\"\n"

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,8 @@ unless used elsewhere */
720720
#define WASM_ENABLE_INSTRUCTION_METERING 0
721721
#endif
722722

723+
#ifndef WASM_ENABLE_EXTENDED_CONST_EXPR
724+
#define WASM_ENABLE_EXTENDED_CONST_EXPR 0
725+
#endif
726+
723727
#endif /* end of _CONFIG_H_ */

core/iwasm/aot/aot_loader.c

Lines changed: 91 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,35 @@ load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
968968
return false;
969969
}
970970

971+
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
972+
static void
973+
destroy_init_expr(InitializerExpression *expr)
974+
{
975+
#if WASM_ENABLE_GC != 0
976+
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
977+
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
978+
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
979+
wasm_runtime_free(expr->u.unary.v.data);
980+
}
981+
#endif
982+
983+
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
984+
// free left expr and right expr for binary oprand
985+
if (!is_expr_binary_op(expr->init_expr_type)) {
986+
return;
987+
}
988+
if (expr->u.binary.l_expr) {
989+
destroy_init_expr_recursive(expr->u.binary.l_expr);
990+
}
991+
if (expr->u.binary.r_expr) {
992+
destroy_init_expr_recursive(expr->u.binary.r_expr);
993+
}
994+
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
995+
#endif
996+
}
997+
#endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0 \
998+
*/
999+
9711000
static void
9721001
destroy_import_memories(AOTImportMemory *import_memories)
9731002
{
@@ -993,6 +1022,10 @@ destroy_mem_init_data_list(AOTModule *module, AOTMemInitData **data_list,
9931022
/* If the module owns the binary data, free the bytes buffer */
9941023
if (module->is_binary_freeable && data_list[i]->bytes)
9951024
wasm_runtime_free(data_list[i]->bytes);
1025+
1026+
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
1027+
destroy_init_expr(&data_list[i]->offset);
1028+
#endif
9961029
/* Free the data segment structure itself */
9971030
wasm_runtime_free(data_list[i]);
9981031
}
@@ -1043,11 +1076,11 @@ load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
10431076
uint32 byte_count;
10441077
uint32 is_passive;
10451078
uint32 memory_index;
1046-
InitializerExpression init_value;
1079+
InitializerExpression offset_expr;
10471080

10481081
read_uint32(buf, buf_end, is_passive);
10491082
read_uint32(buf, buf_end, memory_index);
1050-
if (!load_init_expr(&buf, buf_end, module, &init_value, error_buf,
1083+
if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
10511084
error_buf_size)) {
10521085
return false;
10531086
}
@@ -1062,8 +1095,7 @@ load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
10621095
data_list[i]->is_passive = (bool)is_passive;
10631096
data_list[i]->memory_index = memory_index;
10641097
#endif
1065-
data_list[i]->offset.init_expr_type = init_value.init_expr_type;
1066-
data_list[i]->offset.u = init_value.u;
1098+
data_list[i]->offset = offset_expr;
10671099
data_list[i]->byte_count = byte_count;
10681100
data_list[i]->bytes = NULL;
10691101
/* If the module owns the binary data, clone the bytes buffer */
@@ -1148,18 +1180,6 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
11481180
return false;
11491181
}
11501182

1151-
#if WASM_ENABLE_GC != 0
1152-
static void
1153-
destroy_init_expr(InitializerExpression *expr)
1154-
{
1155-
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
1156-
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
1157-
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
1158-
wasm_runtime_free(expr->u.data);
1159-
}
1160-
}
1161-
#endif /* end of WASM_ENABLE_GC != 0 */
1162-
11631183
static void
11641184
destroy_import_tables(AOTImportTable *import_tables)
11651185
{
@@ -1183,6 +1203,9 @@ destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
11831203
for (j = 0; j < data_list[i]->value_count; j++) {
11841204
destroy_init_expr(&data_list[i]->init_values[j]);
11851205
}
1206+
#endif
1207+
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
1208+
destroy_init_expr(&data_list[i]->offset);
11861209
#endif
11871210
wasm_runtime_free(data_list[i]);
11881211
}
@@ -1208,34 +1231,34 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
12081231
break;
12091232
case INIT_EXPR_TYPE_I32_CONST:
12101233
case INIT_EXPR_TYPE_F32_CONST:
1211-
read_uint32(buf, buf_end, expr->u.i32);
1234+
read_uint32(buf, buf_end, expr->u.unary.v.i32);
12121235
break;
12131236
case INIT_EXPR_TYPE_I64_CONST:
12141237
case INIT_EXPR_TYPE_F64_CONST:
1215-
read_uint64(buf, buf_end, expr->u.i64);
1238+
read_uint64(buf, buf_end, expr->u.unary.v.i64);
12161239
break;
12171240
case INIT_EXPR_TYPE_V128_CONST:
1218-
i64x2 = (uint64 *)expr->u.v128.i64x2;
1241+
i64x2 = (uint64 *)expr->u.unary.v.v128.i64x2;
12191242
CHECK_BUF(buf, buf_end, sizeof(uint64) * 2);
12201243
wasm_runtime_read_v128(buf, &i64x2[0], &i64x2[1]);
12211244
buf += sizeof(uint64) * 2;
12221245
break;
12231246
case INIT_EXPR_TYPE_GET_GLOBAL:
1224-
read_uint32(buf, buf_end, expr->u.global_index);
1247+
read_uint32(buf, buf_end, expr->u.unary.v.global_index);
12251248
break;
12261249
/* INIT_EXPR_TYPE_FUNCREF_CONST can be used when
12271250
both reference types and GC are disabled */
12281251
case INIT_EXPR_TYPE_FUNCREF_CONST:
1229-
read_uint32(buf, buf_end, expr->u.ref_index);
1252+
read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
12301253
break;
12311254
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0
12321255
case INIT_EXPR_TYPE_REFNULL_CONST:
1233-
read_uint32(buf, buf_end, expr->u.ref_index);
1256+
read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
12341257
break;
12351258
#endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0 */
12361259
#if WASM_ENABLE_GC != 0
12371260
case INIT_EXPR_TYPE_I31_NEW:
1238-
read_uint32(buf, buf_end, expr->u.i32);
1261+
read_uint32(buf, buf_end, expr->u.unary.v.i32);
12391262
break;
12401263
case INIT_EXPR_TYPE_STRUCT_NEW:
12411264
{
@@ -1256,7 +1279,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
12561279
free_if_fail = true;
12571280
init_values->count = field_count;
12581281
init_values->type_idx = type_idx;
1259-
expr->u.data = init_values;
1282+
expr->u.unary.v.data = init_values;
12601283

12611284
if (type_idx >= module->type_count) {
12621285
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,
12941317
break;
12951318
}
12961319
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
1297-
read_uint32(buf, buf_end, expr->u.type_index);
1320+
read_uint32(buf, buf_end, expr->u.unary.v.type_index);
12981321
break;
12991322
case INIT_EXPR_TYPE_ARRAY_NEW:
13001323
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
@@ -1310,8 +1333,8 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
13101333
read_uint32(buf, buf_end, length);
13111334

13121335
if (init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
1313-
expr->u.array_new_default.type_index = type_idx;
1314-
expr->u.array_new_default.length = length;
1336+
expr->u.unary.v.array_new_default.type_index = type_idx;
1337+
expr->u.unary.v.array_new_default.length = length;
13151338
}
13161339
else {
13171340
uint32 i, elem_size, elem_data_count;
@@ -1322,7 +1345,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
13221345
return false;
13231346
}
13241347
free_if_fail = true;
1325-
expr->u.data = init_values;
1348+
expr->u.unary.v.data = init_values;
13261349

13271350
init_values->type_idx = type_idx;
13281351
init_values->length = length;
@@ -1350,6 +1373,34 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
13501373
break;
13511374
}
13521375
#endif /* end of WASM_ENABLE_GC != 0 */
1376+
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
1377+
case INIT_EXPR_TYPE_I32_ADD:
1378+
case INIT_EXPR_TYPE_I32_SUB:
1379+
case INIT_EXPR_TYPE_I32_MUL:
1380+
case INIT_EXPR_TYPE_I64_ADD:
1381+
case INIT_EXPR_TYPE_I64_SUB:
1382+
case INIT_EXPR_TYPE_I64_MUL:
1383+
{
1384+
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
1385+
if (!(expr->u.binary.l_expr =
1386+
loader_malloc(sizeof(InitializerExpression), error_buf,
1387+
error_buf_size))) {
1388+
goto fail;
1389+
}
1390+
if (!load_init_expr(&buf, buf_end, module, expr->u.binary.l_expr,
1391+
error_buf, error_buf_size))
1392+
goto fail;
1393+
if (!(expr->u.binary.r_expr =
1394+
loader_malloc(sizeof(InitializerExpression), error_buf,
1395+
error_buf_size))) {
1396+
goto fail;
1397+
}
1398+
if (!load_init_expr(&buf, buf_end, module, expr->u.binary.r_expr,
1399+
error_buf, error_buf_size))
1400+
goto fail;
1401+
break;
1402+
}
1403+
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
13531404
default:
13541405
set_error_buf(error_buf, error_buf_size, "invalid init expr type.");
13551406
return false;
@@ -1362,10 +1413,13 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
13621413
fail:
13631414
#if WASM_ENABLE_GC != 0
13641415
if (free_if_fail) {
1365-
wasm_runtime_free(expr->u.data);
1416+
wasm_runtime_free(expr->u.unary.v.data);
13661417
}
13671418
#else
13681419
(void)free_if_fail;
1420+
#endif
1421+
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
1422+
destroy_init_expr(expr);
13691423
#endif
13701424
return false;
13711425
}
@@ -1528,14 +1582,16 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
15281582
/* Create each table data segment */
15291583
for (i = 0; i < module->table_init_data_count; i++) {
15301584
uint32 mode, elem_type;
1531-
uint32 table_index, init_expr_type, value_count;
1532-
uint64 init_expr_value, size1;
1585+
uint32 table_index, value_count;
1586+
uint64 size1;
1587+
InitializerExpression offset_expr;
15331588

15341589
read_uint32(buf, buf_end, mode);
15351590
read_uint32(buf, buf_end, elem_type);
15361591
read_uint32(buf, buf_end, table_index);
1537-
read_uint32(buf, buf_end, init_expr_type);
1538-
read_uint64(buf, buf_end, init_expr_value);
1592+
if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
1593+
error_buf_size))
1594+
return false;
15391595
#if WASM_ENABLE_GC != 0
15401596
if (wasm_is_type_multi_byte_type(elem_type)) {
15411597
uint16 ref_type, nullable;
@@ -1581,8 +1637,7 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
15811637
}
15821638
}
15831639
#endif
1584-
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
1585-
data_list[i]->offset.u.i64 = (int64)init_expr_value;
1640+
data_list[i]->offset = offset_expr;
15861641
data_list[i]->value_count = value_count;
15871642
for (j = 0; j < data_list[i]->value_count; j++) {
15881643
if (!load_init_expr(&buf, buf_end, module,
@@ -4473,7 +4528,7 @@ aot_unload(AOTModule *module)
44734528
destroy_import_globals(module->import_globals);
44744529

44754530
if (module->globals) {
4476-
#if WASM_ENABLE_GC != 0
4531+
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
44774532
uint32 i;
44784533
for (i = 0; i < module->global_count; i++) {
44794534
destroy_init_expr(&module->globals[i].init_expr);

0 commit comments

Comments
 (0)