Browse Source

Implement GC export APIs related to func and array (#2184)

And add comments for the GC export APIs
Xu Jun 2 years ago
parent
commit
21e4bcb52b
2 changed files with 260 additions and 30 deletions
  1. 178 22
      core/iwasm/common/gc/gc_common.c
  2. 82 8
      core/iwasm/include/gc_export.h

+ 178 - 22
core/iwasm/common/gc/gc_common.c

@@ -130,8 +130,7 @@ wasm_obj_get_defined_type_idx(WASMModuleCommon *const module,
 bool
 bool
 wasm_defined_type_is_func_type(WASMType *const def_type)
 wasm_defined_type_is_func_type(WASMType *const def_type)
 {
 {
-    /* TODO */
-    return false;
+    return wasm_type_is_func_type(def_type);
 }
 }
 
 
 bool
 bool
@@ -143,37 +142,75 @@ wasm_defined_type_is_struct_type(WASMType *const def_type)
 bool
 bool
 wasm_defined_type_is_array_type(WASMType *const def_type)
 wasm_defined_type_is_array_type(WASMType *const def_type)
 {
 {
-    /* TODO */
-    return false;
+    return wasm_type_is_array_type(def_type);
 }
 }
 
 
 uint32
 uint32
 wasm_func_type_get_param_count(WASMFuncType *const func_type)
 wasm_func_type_get_param_count(WASMFuncType *const func_type)
 {
 {
-    /* TODO */
-    return 0;
+    return func_type->param_count;
 }
 }
 
 
 wasm_ref_type_t
 wasm_ref_type_t
 wasm_func_type_get_param_type(WASMFuncType *const func_type, uint32 param_idx)
 wasm_func_type_get_param_type(WASMFuncType *const func_type, uint32 param_idx)
 {
 {
+    uint32 i;
     wasm_ref_type_t ref_type = { 0 };
     wasm_ref_type_t ref_type = { 0 };
-    /* TODO */
+
+    bh_assert(param_idx < func_type->param_count);
+
+    if (wasm_is_type_multi_byte_type(func_type->types[param_idx])) {
+        for (i = 0; i < func_type->ref_type_map_count; i++) {
+            if (func_type->ref_type_maps[i].index == param_idx) {
+                WASMRefTypeMap ref_type_map = func_type->ref_type_maps[i];
+                RefHeapType_Common ref_ht_common =
+                    ref_type_map.ref_type->ref_ht_common;
+                ref_type.value_type = ref_ht_common.ref_type;
+                ref_type.nullable = ref_ht_common.nullable;
+                ref_type.heap_type = ref_ht_common.heap_type;
+                break;
+            }
+        }
+    }
+    else {
+        ref_type.value_type = func_type->types[param_idx];
+    }
+
     return ref_type;
     return ref_type;
 }
 }
 
 
 uint32
 uint32
 wasm_func_type_get_result_count(WASMFuncType *const func_type)
 wasm_func_type_get_result_count(WASMFuncType *const func_type)
 {
 {
-    /* TODO */
-    return 0;
+    return (uint32)func_type->result_count;
 }
 }
 
 
 wasm_ref_type_t
 wasm_ref_type_t
-wasm_func_type_get_result_type(WASMFuncType *const func_type, uint32 param_idx)
+wasm_func_type_get_result_type(WASMFuncType *const func_type, uint32 result_idx)
 {
 {
     wasm_ref_type_t ref_type = { 0 };
     wasm_ref_type_t ref_type = { 0 };
-    /* TODO */
+    uint32 i, result_idx_with_param;
+
+    result_idx_with_param = func_type->param_count + result_idx;
+    bh_assert(result_idx < func_type->result_count);
+
+    if (wasm_is_type_multi_byte_type(func_type->types[result_idx_with_param])) {
+        for (i = 0; i < func_type->ref_type_map_count; i++) {
+            if (func_type->ref_type_maps[i].index == result_idx_with_param) {
+                WASMRefTypeMap ref_type_map = func_type->ref_type_maps[i];
+                RefHeapType_Common ref_ht_common =
+                    ref_type_map.ref_type->ref_ht_common;
+                ref_type.value_type = ref_ht_common.ref_type;
+                ref_type.nullable = ref_ht_common.nullable;
+                ref_type.heap_type = ref_ht_common.heap_type;
+                break;
+            }
+        }
+    }
+    else {
+        ref_type.value_type = func_type->types[result_idx_with_param];
+    }
+
     return ref_type;
     return ref_type;
 }
 }
 
 
@@ -226,7 +263,22 @@ wasm_array_type_get_elem_type(WASMArrayType *const array_type,
                               bool *p_is_mutable)
                               bool *p_is_mutable)
 {
 {
     wasm_ref_type_t ref_type = { 0 };
     wasm_ref_type_t ref_type = { 0 };
-    /* TODO */
+
+    if (wasm_is_type_multi_byte_type(array_type->elem_type)) {
+        WASMRefType *elem_ref_type = array_type->elem_ref_type;
+        RefHeapType_Common ref_ht_common = elem_ref_type->ref_ht_common;
+        ref_type.value_type = ref_ht_common.ref_type;
+        ref_type.nullable = ref_ht_common.nullable;
+        ref_type.heap_type = ref_ht_common.heap_type;
+    }
+    else {
+        ref_type.value_type = array_type->elem_type;
+    }
+
+    if (p_is_mutable) {
+        *p_is_mutable = array_type->elem_flags & 1;
+    }
+
     return ref_type;
     return ref_type;
 }
 }
 
 
@@ -457,31 +509,135 @@ wasm_struct_obj_new_with_type(WASMExecEnv *exec_env, WASMStructType *type)
 }
 }
 
 
 WASMArrayObjectRef
 WASMArrayObjectRef
-wasm_array_obj_new_with_typeidx(WASMExecEnv *exec_env, uint32 type_idx)
+wasm_array_obj_new_with_typeidx(WASMExecEnv *exec_env, uint32 type_idx,
+                                uint32 length, wasm_value_t *init_value)
 {
 {
+    WASMArrayObjectRef array_obj;
+    WASMModuleCommon *module = wasm_exec_env_get_module(exec_env);
+    WASMType *defined_type = wasm_get_defined_type(module, type_idx);
+    WASMRttTypeRef rtt_type = NULL;
+
+    bh_assert(wasm_defined_type_is_array_type(defined_type));
+
+#if WASM_ENABLE_INTERP != 0
+    if (module->module_type == Wasm_Module_Bytecode) {
+        WASMModule *wasm_module = (WASMModule *)module;
+
+        rtt_type = wasm_rtt_type_new(
+            defined_type, type_idx, wasm_module->rtt_types,
+            wasm_module->type_count, &wasm_module->rtt_type_lock);
+    }
+#endif
+#if WASM_ENABLE_AOT != 0
     /* TODO */
     /* TODO */
-    return NULL;
+#endif
+
+    if (!rtt_type) {
+        return NULL;
+    }
+    array_obj = wasm_array_obj_new(exec_env, rtt_type, length, init_value);
+
+    return array_obj;
 }
 }
 
 
 WASMArrayObjectRef
 WASMArrayObjectRef
-wasm_array_obj_new_with_type(WASMExecEnv *exec_env, WASMArrayType *type)
+wasm_array_obj_new_with_type(WASMExecEnv *exec_env, WASMArrayType *type,
+                             uint32 length, wasm_value_t *init_value)
 {
 {
+    WASMArrayObjectRef array_obj;
+    uint32 i, type_count, type_idx = 0;
+    WASMModuleCommon *module = wasm_exec_env_get_module(exec_env);
+
+    bh_assert(type->type_flag == WASM_TYPE_ARRAY);
+
+#if WASM_ENABLE_INTERP != 0
+    if (module->module_type == Wasm_Module_Bytecode) {
+        WASMModule *wasm_module = (WASMModule *)module;
+
+        type_count = wasm_module->type_count;
+        for (i = 0; i < type_count; i++) {
+            if (wasm_module->types[i] == (WASMType *)type) {
+                break;
+            }
+        }
+        bh_assert(i < wasm_module->type_count);
+
+        type_idx = i;
+    }
+#endif
+#if WASM_ENABLE_AOT != 0
     /* TODO */
     /* TODO */
-    return NULL;
+#endif
+
+    array_obj =
+        wasm_array_obj_new_with_typeidx(exec_env, type_idx, length, init_value);
+
+    return array_obj;
 }
 }
 
 
 WASMFuncObjectRef
 WASMFuncObjectRef
-wasm_func_obj_new_with_typeidx(WASMExecEnv *exec_env, uint32 type_idx)
+wasm_func_obj_new_with_typeidx(WASMExecEnv *exec_env, uint32 type_idx,
+                               uint32 func_idx_bound)
 {
 {
+    WASMFuncObjectRef func_obj;
+    WASMRttTypeRef rtt_type = NULL;
+    WASMModuleCommon *module = wasm_exec_env_get_module(exec_env);
+    WASMType *defined_type = wasm_get_defined_type(module, type_idx);
+
+#if WASM_ENABLE_INTERP != 0
+    if (module->module_type == Wasm_Module_Bytecode) {
+        WASMModule *wasm_module = (WASMModule *)module;
+
+        rtt_type = wasm_rtt_type_new(
+            defined_type, type_idx, wasm_module->rtt_types,
+            wasm_module->type_count, &wasm_module->rtt_type_lock);
+    }
+#endif
+#if WASM_ENABLE_AOT != 0
     /* TODO */
     /* TODO */
-    return NULL;
+#endif
+
+    if (!rtt_type) {
+        return NULL;
+    }
+    func_obj = wasm_func_obj_new(exec_env, rtt_type, func_idx_bound);
+
+    return func_obj;
 }
 }
 
 
 WASMFuncObjectRef
 WASMFuncObjectRef
-wasm_func_obj_new_with_type(WASMExecEnv *exec_env, WASMFuncType *type)
+wasm_func_obj_new_with_type(WASMExecEnv *exec_env, WASMFuncType *type,
+                            uint32 func_idx_bound)
 {
 {
+    WASMFuncObjectRef func_obj;
+    uint32 i, type_count, type_idx = 0;
+    WASMModuleCommon *module = wasm_exec_env_get_module(exec_env);
+
+    bh_assert(type->type_flag == WASM_TYPE_FUNC);
+
+#if WASM_ENABLE_INTERP != 0
+    if (module->module_type == Wasm_Module_Bytecode) {
+        WASMModule *wasm_module = (WASMModule *)module;
+
+        type_count = wasm_module->type_count;
+        for (i = 0; i < type_count; i++) {
+            if (wasm_module->types[i] == (WASMType *)type) {
+                break;
+            }
+        }
+        bh_assert(i < wasm_module->type_count);
+
+        type_idx = i;
+    }
+#endif
+#if WASM_ENABLE_AOT != 0
     /* TODO */
     /* TODO */
-    return NULL;
+#endif
+
+    func_obj =
+        wasm_func_obj_new_with_typeidx(exec_env, type_idx, func_idx_bound);
+
+    return func_obj;
 }
 }
 
 
 bool
 bool
@@ -588,8 +744,8 @@ bool
 wasm_obj_is_instance_of_ref_type(const WASMObjectRef obj,
 wasm_obj_is_instance_of_ref_type(const WASMObjectRef obj,
                                  const wasm_ref_type_t *ref_type)
                                  const wasm_ref_type_t *ref_type)
 {
 {
-    /* TODO */
-    return false;
+    int32 heap_type = ref_type->heap_type;
+    return wasm_obj_is_type_of(obj, heap_type);
 }
 }
 
 
 void
 void

+ 82 - 8
core/iwasm/include/gc_export.h

@@ -171,6 +171,10 @@ wasm_obj_get_defined_type_idx(const wasm_module_t module, const wasm_obj_t obj);
 
 
 /**
 /**
  * Check whether a defined type is a function type
  * Check whether a defined type is a function type
+ *
+ * @param def_type the defined type to be checked
+ *
+ * @return true if the defined type is function type, false otherwise
  */
  */
 WASM_RUNTIME_API_EXTERN bool
 WASM_RUNTIME_API_EXTERN bool
 wasm_defined_type_is_func_type(const wasm_defined_type_t def_type);
 wasm_defined_type_is_func_type(const wasm_defined_type_t def_type);
@@ -183,18 +187,32 @@ wasm_defined_type_is_struct_type(const wasm_defined_type_t def_type);
 
 
 /**
 /**
  * Check whether a defined type is an array type
  * Check whether a defined type is an array type
+ *
+ * @param def_type the defined type to be checked
+ *
+ * @return true if the defined type is array type, false otherwise
  */
  */
 WASM_RUNTIME_API_EXTERN bool
 WASM_RUNTIME_API_EXTERN bool
 wasm_defined_type_is_array_type(const wasm_defined_type_t def_type);
 wasm_defined_type_is_array_type(const wasm_defined_type_t def_type);
 
 
 /**
 /**
  * Get parameter count of a function type
  * Get parameter count of a function type
+ *
+ * @param func_type the specified function type
+ *
+ * @return the param count of the specified function type
  */
  */
 WASM_RUNTIME_API_EXTERN uint32_t
 WASM_RUNTIME_API_EXTERN uint32_t
 wasm_func_type_get_param_count(const wasm_func_type_t func_type);
 wasm_func_type_get_param_count(const wasm_func_type_t func_type);
 
 
 /**
 /**
  * Get type of a specified parameter of a function type
  * Get type of a specified parameter of a function type
+ *
+ * @param func_type the specified function type
+ * @param param_idx the specified param index
+ *
+ * @return the param type at the specified param index of the specified func
+ * type
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_ref_type_t
 WASM_RUNTIME_API_EXTERN wasm_ref_type_t
 wasm_func_type_get_param_type(const wasm_func_type_t func_type,
 wasm_func_type_get_param_type(const wasm_func_type_t func_type,
@@ -202,12 +220,22 @@ wasm_func_type_get_param_type(const wasm_func_type_t func_type,
 
 
 /**
 /**
  * Get result count of a function type
  * Get result count of a function type
+ *
+ * @param func_type the specified function type
+ *
+ * @return the result count of the specified function type
  */
  */
 WASM_RUNTIME_API_EXTERN uint32_t
 WASM_RUNTIME_API_EXTERN uint32_t
 wasm_func_type_get_result_count(const wasm_func_type_t func_type);
 wasm_func_type_get_result_count(const wasm_func_type_t func_type);
 
 
 /**
 /**
  * Get type of a specified result of a function type
  * Get type of a specified result of a function type
+ *
+ * @param func_type the specified function type
+ * @param param_idx the specified result index
+ *
+ * @return the result type at the specified result index of the specified func
+ * type
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_ref_type_t
 WASM_RUNTIME_API_EXTERN wasm_ref_type_t
 wasm_func_type_get_result_type(const wasm_func_type_t func_type,
 wasm_func_type_get_result_type(const wasm_func_type_t func_type,
@@ -228,6 +256,12 @@ wasm_struct_type_get_field_type(const wasm_struct_type_t struct_type,
 
 
 /**
 /**
  * Get element type of an array type
  * Get element type of an array type
+ *
+ * @param array_type the specified array type
+ * @param p_is_mutable the pointer passed by invoker, record if the elem is
+ * mutable
+ *
+ * @return the ref type of array's elem type
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_ref_type_t
 WASM_RUNTIME_API_EXTERN wasm_ref_type_t
 wasm_array_type_get_elem_type(const wasm_array_type_t array_type,
 wasm_array_type_get_elem_type(const wasm_array_type_t array_type,
@@ -243,6 +277,13 @@ wasm_defined_type_equal(const wasm_defined_type_t def_type1,
 
 
 /**
 /**
  * Check whether def_type1 is subtype of def_type2
  * Check whether def_type1 is subtype of def_type2
+ *
+ * @param def_type1 the specified defined type1
+ * @param def_type2 the specified defined type2
+ * @param module current wasm module
+ *
+ * @return true if the defined type1 is subtype of the defined type2,
+ * false otherwise
  */
  */
 WASM_RUNTIME_API_EXTERN bool
 WASM_RUNTIME_API_EXTERN bool
 wasm_defined_type_is_subtype_of(const wasm_defined_type_t def_type1,
 wasm_defined_type_is_subtype_of(const wasm_defined_type_t def_type1,
@@ -311,17 +352,35 @@ wasm_struct_obj_get_field(const wasm_struct_obj_t obj, uint32_t field_idx,
                           bool sign_extend, wasm_value_t *value);
                           bool sign_extend, wasm_value_t *value);
 
 
 /**
 /**
- * Create an array object with the index of defined type
+ * Create an array object with the index of defined type, the obj's length is
+ * length, init value is init_value
+ *
+ * @param exec_env the execution environment
+ * @param type_idx the index of the specified type
+ * @param length the array's length
+ * @param init_value the array's init value
+ *
+ * @return the created array object
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_array_obj_t
 WASM_RUNTIME_API_EXTERN wasm_array_obj_t
-wasm_array_obj_new_with_typeidx(wasm_exec_env_t exec_env, uint32_t type_idx);
+wasm_array_obj_new_with_typeidx(wasm_exec_env_t exec_env, uint32_t type_idx,
+                                uint32_t length, wasm_value_t *init_value);
 
 
 /**
 /**
- * Create an array object with the array type
+ * Create an array object with the array type, the obj's length is length, init
+ * value is init_value
+ *
+ * @param exec_env the execution environment
+ * @param type the array's specified type
+ * @param length the array's length
+ * @param init_value the array's init value
+ *
+ * @return the created array object
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_array_obj_t
 WASM_RUNTIME_API_EXTERN wasm_array_obj_t
 wasm_array_obj_new_with_type(wasm_exec_env_t exec_env,
 wasm_array_obj_new_with_type(wasm_exec_env_t exec_env,
-                             const wasm_array_type_t type);
+                             const wasm_array_type_t type, uint32_t length,
+                             wasm_value_t *init_value);
 
 
 /**
 /**
  * Set the specified element's value of an array object
  * Set the specified element's value of an array object
@@ -364,16 +423,31 @@ WASM_RUNTIME_API_EXTERN void *
 wasm_array_obj_elem_addr(const wasm_array_obj_t array_obj, uint32_t elem_idx);
 wasm_array_obj_elem_addr(const wasm_array_obj_t array_obj, uint32_t elem_idx);
 
 
 /**
 /**
- * Create a function object with the index of defined type
+ * Create a function object with the index of defined type and the index of the
+ * function
+ *
+ * @param exec_env the execution environment
+ * @param type_idx the index of the specified type
+ * @param func_idx_bound the index of the function
+ *
+ * @return the created function object
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_func_obj_t
 WASM_RUNTIME_API_EXTERN wasm_func_obj_t
-wasm_func_obj_new_with_typeidx(wasm_exec_env_t exec_env, uint32_t type_idx);
+wasm_func_obj_new_with_typeidx(wasm_exec_env_t exec_env, uint32_t type_idx,
+                               uint32_t func_idx_bound);
 
 
 /**
 /**
- * Create a function object with the function type
+ * Create a function object with the function type and the index of the function
+ *
+ * @param exec_env the execution environment
+ * @param type the specified type
+ * @param func_idx_bound the index of the function
+ *
+ * @return the created function object
  */
  */
 WASM_RUNTIME_API_EXTERN wasm_func_obj_t
 WASM_RUNTIME_API_EXTERN wasm_func_obj_t
-wasm_func_obj_new_with_type(wasm_exec_env_t exec_env, wasm_func_type_t type);
+wasm_func_obj_new_with_type(wasm_exec_env_t exec_env, wasm_func_type_t type,
+                            uint32_t func_idx_bound);
 
 
 /**
 /**
  * Get the function index bound of a function object
  * Get the function index bound of a function object