Explorar o código

AOT compiler: Implement left of GC opcode compilation (#2487)

Implement the compilation to LLVM IRs for the left GC opcodes (struct/array related):
- WASM_OP_STRUCT_NEW_CANON, WASM_OP_STRUCT_NEW_CANON_DEFAULT
- WASM_OP_STRUCT_GET, WASM_OP_STRUCT_GET_S, WASM_OP_STRUCT_GET_U,
  WASM_OP_STRUCT_SET
- WASM_OP_ARRAY_NEW_CANON, WASM_OP_ARRAY_NEW_CANON_DEFAULT
  WASM_OP_ARRAY_NEW_CANON_FIXED, WASM_OP_ARRAY_NEW_CANON_DATA
- WASM_OP_ARRAY_GET, WASM_OP_ARRAY_GET_S, WASM_OP_ARRAY_GET_U
  WASM_OP_ARRAY_SET, WASM_OP_ARRAY_LEN, WASM_OP_ARRAY_COPY
TianlongLiang %!s(int64=2) %!d(string=hai) anos
pai
achega
760505e607

+ 40 - 0
core/iwasm/aot/aot_runtime.c

@@ -3685,4 +3685,44 @@ aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
     return wasm_obj_is_instance_of(gc_obj, type_index, types, type_count);
 }
 
+WASMRttTypeRef
+aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index)
+{
+    AOTModule *aot_module = (AOTModule *)module_inst->module;
+    AOTType *defined_type = aot_module->types[type_index];
+    WASMRttType **rtt_types = aot_module->rtt_types;
+    uint32 rtt_type_count = aot_module->type_count;
+    korp_mutex *rtt_type_lock = &aot_module->rtt_type_lock;
+
+    return wasm_rtt_type_new(defined_type, type_index, rtt_types,
+                             rtt_type_count, rtt_type_lock);
+}
+
+bool
+aot_array_init_with_data(AOTModuleInstance *module_inst, uint32 seg_index,
+                         uint32 data_seg_offset, WASMArrayObjectRef array_obj,
+                         uint32 elem_size, uint32 array_len)
+{
+    AOTModule *aot_module;
+    uint8 *data = NULL;
+    uint8 *array_elem_base;
+    uint64 seg_len = 0;
+    uint64 total_size = (int64)elem_size * array_len;
+
+    aot_module = (AOTModule *)module_inst->module;
+    seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
+    data = aot_module->mem_init_data_list[seg_index]->bytes;
+
+    if (data_seg_offset >= seg_len || total_size > seg_len - data_seg_offset) {
+        aot_set_exception(module_inst, "out of bounds memory access");
+        return false;
+    }
+
+    array_elem_base = (uint8 *)wasm_array_obj_first_elem_addr(array_obj);
+    bh_memcpy_s(array_elem_base, (uint32)total_size, data + data_seg_offset,
+                (uint32)total_size);
+
+    return true;
+}
+
 #endif /* end of WASM_ENABLE_GC != 0 */

+ 8 - 0
core/iwasm/aot/aot_runtime.h

@@ -682,6 +682,14 @@ bool
 aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
                        uint32 type_index);
 
+WASMRttTypeRef
+aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index);
+
+bool
+aot_array_init_with_data(AOTModuleInstance *module_inst, uint32 seg_index,
+                         uint32 data_seg_offset, WASMArrayObjectRef array_obj,
+                         uint32 elem_size, uint32 array_len);
+
 #endif /* end of WASM_ENABLE_GC != 0 */
 
 #ifdef __cplusplus

+ 94 - 1
core/iwasm/compilation/aot_compiler.c

@@ -599,12 +599,105 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
                     goto unsupport_gc;
                 }
 
-                uint32 opcode1;
+                uint32 opcode1, field_idx, data_seg_idx, array_len;
 
                 read_leb_uint32(frame_ip, frame_ip_end, opcode1);
                 opcode = (uint8)opcode1;
 
                 switch (opcode) {
+                    case WASM_OP_STRUCT_NEW_CANON:
+                    case WASM_OP_STRUCT_NEW_CANON_DEFAULT:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        if (!aot_compile_op_struct_new(
+                                comp_ctx, func_ctx, type_index,
+                                opcode == WASM_OP_STRUCT_NEW_CANON_DEFAULT))
+                            return false;
+                        break;
+
+                    case WASM_OP_STRUCT_GET:
+                    case WASM_OP_STRUCT_GET_S:
+                    case WASM_OP_STRUCT_GET_U:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        read_leb_uint32(frame_ip, frame_ip_end, field_idx);
+                        if (!aot_compile_op_struct_get(
+                                comp_ctx, func_ctx, type_index, field_idx,
+                                opcode == WASM_OP_STRUCT_GET_S))
+                            return false;
+                        break;
+
+                    case WASM_OP_STRUCT_SET:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        read_leb_uint32(frame_ip, frame_ip_end, field_idx);
+                        if (!aot_compile_op_struct_set(comp_ctx, func_ctx,
+                                                       type_index, field_idx))
+                            return false;
+                        break;
+
+                    case WASM_OP_ARRAY_NEW_CANON:
+                    case WASM_OP_ARRAY_NEW_CANON_DEFAULT:
+                    case WASM_OP_ARRAY_NEW_CANON_FIXED:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        if (opcode == WASM_OP_ARRAY_NEW_CANON_FIXED)
+                            read_leb_uint32(frame_ip, frame_ip_end, array_len);
+                        else
+                            array_len = 0;
+                        if (!aot_compile_op_array_new(
+                                comp_ctx, func_ctx, type_index,
+                                opcode == WASM_OP_ARRAY_NEW_CANON_DEFAULT,
+                                opcode == WASM_OP_ARRAY_NEW_CANON_FIXED,
+                                array_len))
+                            return false;
+                        break;
+
+                    case WASM_OP_ARRAY_NEW_CANON_DATA:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        read_leb_uint32(frame_ip, frame_ip_end, data_seg_idx);
+                        if (!aot_compile_op_array_new_data(
+                                comp_ctx, func_ctx, type_index, data_seg_idx))
+                            return false;
+                        break;
+
+                    case WASM_OP_ARRAY_NEW_CANON_ELEM:
+                        /* TODO */
+                        aot_set_last_error("unsupported opcode");
+                        return false;
+
+                    case WASM_OP_ARRAY_GET:
+                    case WASM_OP_ARRAY_GET_S:
+                    case WASM_OP_ARRAY_GET_U:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        if (!aot_compile_op_array_get(
+                                comp_ctx, func_ctx, type_index,
+                                opcode == WASM_OP_ARRAY_GET_S))
+                            return false;
+                        break;
+
+                    case WASM_OP_ARRAY_SET:
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        if (!aot_compile_op_array_set(comp_ctx, func_ctx,
+                                                      type_index))
+                            return false;
+                        break;
+
+#if WASM_ENABLE_GC_BINARYEN != 0
+                    case WASM_OP_ARRAY_COPY:
+                    {
+                        uint32 src_type_index;
+
+                        read_leb_uint32(frame_ip, frame_ip_end, type_index);
+                        read_leb_uint32(frame_ip, frame_ip_end, src_type_index);
+                        if (!aot_compile_op_array_copy(
+                                comp_ctx, func_ctx, type_index, src_type_index))
+                            return false;
+                        break;
+                    }
+#endif
+
+                    case WASM_OP_ARRAY_LEN:
+                        if (!aot_compile_op_array_len(comp_ctx, func_ctx))
+                            return false;
+                        break;
+
                     case WASM_OP_I31_NEW:
                         if (!aot_compile_op_i31_new(comp_ctx, func_ctx))
                             return false;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1215 - 0
core/iwasm/compilation/aot_emit_gc.c


+ 43 - 0
core/iwasm/compilation/aot_emit_gc.h

@@ -29,10 +29,53 @@ aot_call_wasm_obj_is_type_of(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                              LLVMValueRef gc_obj, LLVMValueRef heap_type,
                              LLVMValueRef *castable);
 
+bool
+aot_call_aot_rtt_type_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                          LLVMValueRef type_index, LLVMValueRef *rtt_type);
+
 bool
 aot_compile_op_ref_as_non_null(AOTCompContext *comp_ctx,
                                AOTFuncContext *func_ctx);
 
+bool
+aot_compile_op_struct_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                          uint32 type_index, bool init_with_default);
+
+bool
+aot_compile_op_struct_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                          uint32 type_index, uint32 field_idx, bool sign);
+
+bool
+aot_compile_op_struct_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                          uint32 type_index, uint32 field_idx);
+
+bool
+aot_compile_op_array_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                         uint32 type_index, bool init_with_default,
+                         bool fixed_size, uint32 array_len);
+
+bool
+aot_compile_op_array_new_data(AOTCompContext *comp_ctx,
+                              AOTFuncContext *func_ctx, uint32 type_index,
+                              uint32 data_seg_index);
+
+bool
+aot_compile_op_array_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                         uint32 type_index, bool sign);
+
+bool
+aot_compile_op_array_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                         uint32 type_index);
+
+#if WASM_ENABLE_GC_BINARYEN != 0
+bool
+aot_compile_op_array_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                          uint32 type_index, uint32 src_type_index);
+#endif
+
+bool
+aot_compile_op_array_len(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
+
 bool
 aot_compile_op_i31_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
 

+ 38 - 0
core/iwasm/interpreter/wasm_runtime.c

@@ -3693,6 +3693,44 @@ llvm_jit_obj_is_instance_of(WASMModuleInstance *module_inst,
     return wasm_obj_is_instance_of(gc_obj, type_index, types, type_count);
 }
 
+WASMRttTypeRef
+llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index)
+{
+    WASMModule *module = module_inst->module;
+    WASMType *defined_type = module->types[type_index];
+    WASMRttType **rtt_types = module->rtt_types;
+    uint32 rtt_type_count = module->type_count;
+    korp_mutex *rtt_type_lock = &module->rtt_type_lock;
+
+    return wasm_rtt_type_new(defined_type, type_index, rtt_types,
+                             rtt_type_count, rtt_type_lock);
+}
+
+bool
+llvm_array_init_with_data(WASMModuleInstance *module_inst, uint32 seg_index,
+                          uint32 data_seg_offset, WASMArrayObjectRef array_obj,
+                          uint32 elem_size, uint32 array_len)
+{
+    WASMModule *wasm_module = module_inst->module;
+    WASMDataSeg *data_seg;
+    uint8 *array_elem_base;
+    uint64 total_size;
+
+    data_seg = wasm_module->data_segments[seg_index];
+    total_size = (int64)elem_size * array_len;
+
+    if (data_seg_offset >= data_seg->data_length
+        || total_size > data_seg->data_length - data_seg_offset) {
+        wasm_set_exception(module_inst, "out of bounds memory access");
+        return false;
+    }
+
+    array_elem_base = (uint8 *)wasm_array_obj_first_elem_addr(array_obj);
+    bh_memcpy_s(array_elem_base, (uint32)total_size,
+                data_seg->data + data_seg_offset, (uint32)total_size);
+
+    return true;
+}
 #endif /* end of WASM_ENABLE_GC != 0  */
 
 #endif /* end of WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 */

+ 9 - 0
core/iwasm/interpreter/wasm_runtime.h

@@ -70,6 +70,7 @@ typedef enum WASMExceptionID {
     EXCE_ALREADY_THROWN,
     EXCE_NULL_GC_REF,
     EXCE_TYPE_NONCASTABLE,
+    EXCE_ARRAY_OOB,
     EXCE_NUM,
 } WASMExceptionID;
 
@@ -714,6 +715,14 @@ llvm_jit_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
 bool
 llvm_jit_obj_is_instance_of(WASMModuleInstance *module_inst,
                             WASMObjectRef gc_obj, uint32 type_index);
+
+WASMRttTypeRef
+llvm_jit_rtt_type_new(WASMModuleInstance *module_inst, uint32 type_index);
+
+bool
+llvm_array_init_with_data(WASMModuleInstance *module_inst, uint32 seg_index,
+                          uint32 data_seg_offset, WASMArrayObjectRef array_obj,
+                          uint32 elem_size, uint32 array_len);
 #endif
 #endif /* end of WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 */
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio