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:
Wenyong Huang
2024-02-06 20:47:11 +08:00
committed by GitHub
parent 5931aaacbe
commit 16a4d71b34
98 changed files with 33469 additions and 3159 deletions

View File

@ -35,9 +35,9 @@ typedef enum WASMOpcode {
WASM_OP_CALL_INDIRECT = 0x11, /* call_indirect */
WASM_OP_RETURN_CALL = 0x12, /* return_call */
WASM_OP_RETURN_CALL_INDIRECT = 0x13, /* return_call_indirect */
WASM_OP_CALL_REF = 0x14, /* call_ref */
WASM_OP_RETURN_CALL_REF = 0x15, /* return_call_ref */
WASM_OP_UNUSED_0x14 = 0x14,
WASM_OP_UNUSED_0x15 = 0x15,
WASM_OP_UNUSED_0x16 = 0x16,
WASM_OP_UNUSED_0x17 = 0x17,
@ -259,27 +259,124 @@ typedef enum WASMOpcode {
WASM_OP_IMPDEP = 0xcf,
WASM_OP_REF_NULL = 0xd0, /* ref.null */
WASM_OP_REF_IS_NULL = 0xd1, /* ref.is_null */
WASM_OP_REF_FUNC = 0xd2, /* ref.func */
WASM_OP_REF_NULL = 0xd0, /* ref.null */
WASM_OP_REF_IS_NULL = 0xd1, /* ref.is_null */
WASM_OP_REF_FUNC = 0xd2, /* ref.func */
WASM_OP_REF_EQ = 0xd3, /* ref.eq */
WASM_OP_REF_AS_NON_NULL = 0xd4, /* ref.as_non_null */
WASM_OP_BR_ON_NULL = 0xd5, /* br_on_null */
WASM_OP_BR_ON_NON_NULL = 0xd6, /* br_on_non_null */
EXT_OP_BLOCK = 0xd3, /* block with blocktype */
EXT_OP_LOOP = 0xd4, /* loop with blocktype */
EXT_OP_IF = 0xd5, /* if with blocktype */
EXT_OP_BR_TABLE_CACHE = 0xd6, /* br_table from cache */
EXT_OP_BLOCK = 0xd7, /* block with blocktype */
EXT_OP_LOOP = 0xd8, /* loop with blocktype */
EXT_OP_IF = 0xd9, /* if with blocktype */
EXT_OP_BR_TABLE_CACHE = 0xda, /* br_table from cache */
EXT_OP_TRY = 0xd7, /* try block with blocktype */
EXT_OP_TRY = 0xdb, /* try block with blocktype */
#if WASM_ENABLE_DEBUG_INTERP != 0
DEBUG_OP_BREAK = 0xd8, /* debug break point */
DEBUG_OP_BREAK = 0xdc, /* debug break point */
#endif
/* Post-MVP extend op prefix */
WASM_OP_GC_PREFIX = 0xfb,
WASM_OP_MISC_PREFIX = 0xfc,
WASM_OP_SIMD_PREFIX = 0xfd,
WASM_OP_ATOMIC_PREFIX = 0xfe,
} WASMOpcode;
typedef enum WASMGCEXTOpcode {
WASM_OP_STRUCT_NEW = 0x00, /* struct.new */
WASM_OP_STRUCT_NEW_DEFAULT = 0x01, /* struct.new_default */
WASM_OP_STRUCT_GET = 0x02, /* struct.get */
WASM_OP_STRUCT_GET_S = 0x03, /* struct.get_s */
WASM_OP_STRUCT_GET_U = 0x04, /* struct.get_u */
WASM_OP_STRUCT_SET = 0x05, /* struct.set */
WASM_OP_ARRAY_NEW = 0x06, /* array.new */
WASM_OP_ARRAY_NEW_DEFAULT = 0x07, /* array.new_default */
WASM_OP_ARRAY_NEW_FIXED = 0x08, /* array.new_fixed */
WASM_OP_ARRAY_NEW_DATA = 0x09, /* array.new_data */
WASM_OP_ARRAY_NEW_ELEM = 0x0A, /* array.new_elem */
WASM_OP_ARRAY_GET = 0x0B, /* array.get */
WASM_OP_ARRAY_GET_S = 0x0C, /* array.get_s */
WASM_OP_ARRAY_GET_U = 0x0D, /* array.get_u */
WASM_OP_ARRAY_SET = 0x0E, /* array.set */
WASM_OP_ARRAY_LEN = 0x0F, /* array.len */
WASM_OP_ARRAY_FILL = 0x10, /* array.fill */
WASM_OP_ARRAY_COPY = 0x11, /* array.copy */
WASM_OP_ARRAY_INIT_DATA = 0x12,
/* array.init_data */ /* TODO */
WASM_OP_ARRAY_INIT_ELEM = 0x13,
/* array.init_elem */ /* TODO */
WASM_OP_REF_TEST = 0x14, /* ref.test */
WASM_OP_REF_TEST_NULLABLE = 0x15, /* ref.test_nullable */
WASM_OP_REF_CAST = 0x16, /* ref.cast */
WASM_OP_REF_CAST_NULLABLE = 0x17, /* ref.cast_nullable */
WASM_OP_BR_ON_CAST = 0x18, /* br_on_cast */
WASM_OP_BR_ON_CAST_FAIL = 0x19, /* br_on_cast_fail */
WASM_OP_ANY_CONVERT_EXTERN = 0x1A, /* any.convert_extern */
WASM_OP_EXTERN_CONVERT_ANY = 0x1B, /* extern.covert_any */
WASM_OP_REF_I31 = 0x1C, /* ref.i31 */
WASM_OP_I31_GET_S = 0x1D, /* i31.get_s */
WASM_OP_I31_GET_U = 0x1E, /* i31.get_u */
/* stringref related opcoded */
WASM_OP_STRING_NEW_UTF8 = 0x80, /* string.new_utf8 */
WASM_OP_STRING_NEW_WTF16 = 0x81, /* string.new_wtf16 */
WASM_OP_STRING_CONST = 0x82, /* string.const */
WASM_OP_STRING_MEASURE_UTF8 = 0x83, /* string.measure_utf8 */
WASM_OP_STRING_MEASURE_WTF8 = 0x84, /* string.measure_wtf8 */
WASM_OP_STRING_MEASURE_WTF16 = 0x85, /* string.measure_wtf16 */
WASM_OP_STRING_ENCODE_UTF8 = 0x86, /* string.encode_utf8 */
WASM_OP_STRING_ENCODE_WTF16 = 0x87, /* string.encode_wtf16 */
WASM_OP_STRING_CONCAT = 0x88, /* string.concat */
WASM_OP_STRING_EQ = 0x89, /* string.eq */
WASM_OP_STRING_IS_USV_SEQUENCE = 0x8a, /* string.is_usv_sequence */
WASM_OP_STRING_NEW_LOSSY_UTF8 = 0x8b, /* string.new_lossy_utf8 */
WASM_OP_STRING_NEW_WTF8 = 0x8c, /* string.new_wtf8 */
WASM_OP_STRING_ENCODE_LOSSY_UTF8 = 0x8d, /* string.encode_lossy_utf8 */
WASM_OP_STRING_ENCODE_WTF8 = 0x8e, /* string.encode_wtf8 */
WASM_OP_STRING_AS_WTF8 = 0x90, /* string.as_wtf8 */
WASM_OP_STRINGVIEW_WTF8_ADVANCE = 0x91, /* stringview_wtf8.advance */
WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8 =
0x92, /* stringview_wtf8.encode_utf8 */
WASM_OP_STRINGVIEW_WTF8_SLICE = 0x93, /* stringview_wtf8.slice */
WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8 =
0x94, /* stringview_wtf8.encode_lossy_utf8 */
WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8 =
0x95, /* stringview_wtf8.encode_wtf8 */
WASM_OP_STRING_AS_WTF16 = 0x98, /* string.as_wtf16 */
WASM_OP_STRINGVIEW_WTF16_LENGTH = 0x99, /* stringview_wtf16.length */
WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT =
0x9a, /* stringview_wtf16.get_codeunit */
WASM_OP_STRINGVIEW_WTF16_ENCODE = 0x9b, /* stringview_wtf16.encode */
WASM_OP_STRINGVIEW_WTF16_SLICE = 0x9c, /* stringview_wtf16.slice */
WASM_OP_STRING_AS_ITER = 0xa0, /* string.as_iter */
WASM_OP_STRINGVIEW_ITER_NEXT = 0xa1, /* stringview_iter.next */
WASM_OP_STRINGVIEW_ITER_ADVANCE = 0xa2, /* stringview_iter.advance */
WASM_OP_STRINGVIEW_ITER_REWIND = 0xa3, /* stringview_iter.rewind */
WASM_OP_STRINGVIEW_ITER_SLICE = 0xa4, /* stringview_iter.slice */
WASM_OP_STRING_NEW_UTF8_ARRAY = 0xb0, /* string.new_utf8_array */
WASM_OP_STRING_NEW_WTF16_ARRAY = 0xb1, /* string.new_wtf16_array */
WASM_OP_STRING_ENCODE_UTF8_ARRAY = 0xb2, /* string.encode_utf8_array */
WASM_OP_STRING_ENCODE_WTF16_ARRAY = 0xb3, /* string.encode_wtf16_array */
WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY =
0xb4, /* string.new_lossy_utf8_array */
WASM_OP_STRING_NEW_WTF8_ARRAY = 0xb5, /* string.new_wtf8_array */
WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY =
0xb6, /* string.encode_lossy_utf8_array */
WASM_OP_STRING_ENCODE_WTF8_ARRAY = 0xb7, /* string.encode_wtf8_array */
} WASMGCEXTOpcode;
typedef enum WASMMiscEXTOpcode {
WASM_OP_I32_TRUNC_SAT_S_F32 = 0x00,
WASM_OP_I32_TRUNC_SAT_U_F32 = 0x01,
@ -678,7 +775,7 @@ typedef enum WASMAtomicEXTOpcode {
#if WASM_ENABLE_DEBUG_INTERP != 0
#define DEF_DEBUG_BREAK_HANDLE() \
[DEBUG_OP_BREAK] = HANDLE_OPCODE(DEBUG_OP_BREAK), /* 0xd7 */
[DEBUG_OP_BREAK] = HANDLE_OPCODE(DEBUG_OP_BREAK), /* 0xdb */
#else
#define DEF_DEBUG_BREAK_HANDLE()
#endif
@ -719,8 +816,8 @@ typedef enum WASMAtomicEXTOpcode {
HANDLE_OPCODE(WASM_OP_CALL_INDIRECT), /* 0x11 */ \
HANDLE_OPCODE(WASM_OP_RETURN_CALL), /* 0x12 */ \
HANDLE_OPCODE(WASM_OP_RETURN_CALL_INDIRECT), /* 0x13 */ \
HANDLE_OPCODE(WASM_OP_UNUSED_0x14), /* 0x14 */ \
HANDLE_OPCODE(WASM_OP_UNUSED_0x15), /* 0x15 */ \
HANDLE_OPCODE(WASM_OP_CALL_REF), /* 0x14 */ \
HANDLE_OPCODE(WASM_OP_RETURN_CALL_REF), /* 0x15 */ \
HANDLE_OPCODE(WASM_OP_UNUSED_0x16), /* 0x16 */ \
HANDLE_OPCODE(WASM_OP_UNUSED_0x17), /* 0x17 */ \
HANDLE_OPCODE(WASM_OP_DELEGATE), /* 0x18 */ \
@ -910,11 +1007,16 @@ typedef enum WASMAtomicEXTOpcode {
HANDLE_OPCODE(WASM_OP_REF_NULL), /* 0xd0 */ \
HANDLE_OPCODE(WASM_OP_REF_IS_NULL), /* 0xd1 */ \
HANDLE_OPCODE(WASM_OP_REF_FUNC), /* 0xd2 */ \
HANDLE_OPCODE(EXT_OP_BLOCK), /* 0xd3 */ \
HANDLE_OPCODE(EXT_OP_LOOP), /* 0xd4 */ \
HANDLE_OPCODE(EXT_OP_IF), /* 0xd5 */ \
HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE), /* 0xd6 */ \
HANDLE_OPCODE(EXT_OP_TRY), /* 0xd7 */ \
HANDLE_OPCODE(WASM_OP_REF_EQ), /* 0xd3 */ \
HANDLE_OPCODE(WASM_OP_REF_AS_NON_NULL), /* 0xd4 */ \
HANDLE_OPCODE(WASM_OP_BR_ON_NULL), /* 0xd5 */ \
HANDLE_OPCODE(WASM_OP_BR_ON_NON_NULL), /* 0xd6 */ \
HANDLE_OPCODE(EXT_OP_BLOCK), /* 0xd7 */ \
HANDLE_OPCODE(EXT_OP_LOOP), /* 0xd8 */ \
HANDLE_OPCODE(EXT_OP_IF), /* 0xd9 */ \
HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE), /* 0xda */ \
HANDLE_OPCODE(EXT_OP_TRY), /* 0xdb */ \
SET_GOTO_TABLE_ELEM(WASM_OP_GC_PREFIX), /* 0xfb */ \
SET_GOTO_TABLE_ELEM(WASM_OP_MISC_PREFIX), /* 0xfc */ \
SET_GOTO_TABLE_SIMD_PREFIX_ELEM() /* 0xfd */ \
SET_GOTO_TABLE_ELEM(WASM_OP_ATOMIC_PREFIX), /* 0xfe */ \