mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-30 21:02:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1082 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1082 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2019 Intel Corporation. All rights reserved.
 | |
|  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
|  */
 | |
| 
 | |
| #include "gc_object.h"
 | |
| #include "mem_alloc.h"
 | |
| #include "../wasm_runtime_common.h"
 | |
| #if WASM_ENABLE_INTERP != 0
 | |
| #include "../interpreter/wasm_runtime.h"
 | |
| #endif
 | |
| #if WASM_ENABLE_AOT != 0
 | |
| #include "../aot/aot_runtime.h"
 | |
| #endif
 | |
| #if WASM_ENABLE_STRINGREF != 0
 | |
| #include "string_object.h"
 | |
| #endif
 | |
| 
 | |
| WASMRttTypeRef
 | |
| wasm_rtt_type_new(WASMType *defined_type, uint32 defined_type_idx,
 | |
|                   WASMRttType **rtt_types, uint32 rtt_type_count,
 | |
|                   korp_mutex *rtt_type_lock)
 | |
| {
 | |
|     WASMRttType *rtt_type;
 | |
| 
 | |
|     bh_assert(defined_type_idx < rtt_type_count);
 | |
| 
 | |
|     os_mutex_lock(rtt_type_lock);
 | |
| 
 | |
|     if (rtt_types[defined_type_idx]) {
 | |
|         os_mutex_unlock(rtt_type_lock);
 | |
|         return rtt_types[defined_type_idx];
 | |
|     }
 | |
| 
 | |
|     if ((rtt_type = wasm_runtime_malloc(sizeof(WASMRttType)))) {
 | |
|         rtt_type->type_flag = defined_type->type_flag;
 | |
|         rtt_type->inherit_depth = defined_type->inherit_depth;
 | |
|         rtt_type->defined_type = defined_type;
 | |
|         rtt_type->root_type = defined_type->root_type;
 | |
| 
 | |
|         rtt_types[defined_type_idx] = rtt_type;
 | |
|     }
 | |
| 
 | |
|     os_mutex_unlock(rtt_type_lock);
 | |
|     return rtt_type;
 | |
| }
 | |
| 
 | |
| static void *
 | |
| gc_obj_malloc(void *heap_handle, uint64 size)
 | |
| {
 | |
|     void *mem;
 | |
| 
 | |
|     if (size >= UINT32_MAX
 | |
|         || !(mem = mem_allocator_malloc_with_gc(heap_handle, (uint32)size))) {
 | |
|         LOG_WARNING("warning: failed to allocate memory for gc object");
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     memset(mem, 0, (uint32)size);
 | |
|     return mem;
 | |
| }
 | |
| 
 | |
| static void *
 | |
| get_gc_heap_handle(WASMExecEnv *exec_env)
 | |
| {
 | |
|     void *gc_heap_handle = NULL;
 | |
|     WASMModuleInstanceCommon *module_inst = exec_env->module_inst;
 | |
| 
 | |
| #if WASM_ENABLE_INTERP != 0
 | |
|     if (module_inst->module_type == Wasm_Module_Bytecode)
 | |
|         gc_heap_handle =
 | |
|             ((WASMModuleInstance *)module_inst)->e->common.gc_heap_handle;
 | |
| #endif
 | |
| #if WASM_ENABLE_AOT != 0
 | |
|     if (module_inst->module_type == Wasm_Module_AoT)
 | |
|         gc_heap_handle =
 | |
|             ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
 | |
|                 ->common.gc_heap_handle;
 | |
| #endif
 | |
| 
 | |
|     bh_assert(gc_heap_handle);
 | |
|     return gc_heap_handle;
 | |
| }
 | |
| 
 | |
| WASMStructObjectRef
 | |
| wasm_struct_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type)
 | |
| {
 | |
|     WASMStructObjectRef struct_obj;
 | |
|     WASMStructType *struct_type;
 | |
| 
 | |
|     bh_assert(rtt_type->type_flag == WASM_TYPE_STRUCT);
 | |
| 
 | |
|     struct_type = (WASMStructType *)rtt_type->defined_type;
 | |
|     if (!(struct_obj = gc_obj_malloc(heap_handle, struct_type->total_size))) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     struct_obj->header = (WASMObjectHeader)rtt_type;
 | |
| 
 | |
|     return struct_obj;
 | |
| }
 | |
| 
 | |
| WASMStructObjectRef
 | |
| wasm_struct_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     return wasm_struct_obj_new_internal(heap_handle, rtt_type);
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_struct_obj_set_field(WASMStructObjectRef struct_obj, uint32 field_idx,
 | |
|                           const WASMValue *value)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type =
 | |
|         (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
 | |
|     WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
 | |
|     WASMStructFieldType *field;
 | |
|     uint8 field_size, *field_data;
 | |
| 
 | |
|     bh_assert(field_idx < struct_type->field_count);
 | |
| 
 | |
|     field = struct_type->fields + field_idx;
 | |
|     field_data = (uint8 *)struct_obj + field->field_offset;
 | |
|     field_size = field->field_size;
 | |
| 
 | |
|     if (field_size == 4) {
 | |
|         *(int32 *)field_data = value->i32;
 | |
|     }
 | |
|     else if (field_size == 8) {
 | |
| #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
 | |
|     || defined(BUILD_TARGET_X86_32)
 | |
|         *(int64 *)field_data = value->i64;
 | |
| #else
 | |
|         PUT_I64_TO_ADDR((uint32 *)field_data, value->i64);
 | |
| #endif
 | |
|     }
 | |
|     else if (field_size == 1) {
 | |
|         *(int8 *)field_data = (int8)value->i32;
 | |
|     }
 | |
|     else if (field_size == 2) {
 | |
|         *(int16 *)field_data = (int16)value->i32;
 | |
|     }
 | |
|     else {
 | |
|         bh_assert(0);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj,
 | |
|                           uint32 field_idx, bool sign_extend, WASMValue *value)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type =
 | |
|         (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
 | |
|     WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
 | |
|     WASMStructFieldType *field;
 | |
|     uint8 *field_data, field_size;
 | |
| 
 | |
|     bh_assert(field_idx < struct_type->field_count);
 | |
| 
 | |
|     field = struct_type->fields + field_idx;
 | |
|     field_data = (uint8 *)struct_obj + field->field_offset;
 | |
|     field_size = field->field_size;
 | |
| 
 | |
|     if (field_size == 4) {
 | |
|         value->i32 = *(int32 *)field_data;
 | |
|     }
 | |
|     else if (field_size == 8) {
 | |
| #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
 | |
|     || defined(BUILD_TARGET_X86_32)
 | |
|         value->i64 = *(int64 *)field_data;
 | |
| #else
 | |
|         value->i64 = GET_I64_FROM_ADDR((uint32 *)field_data);
 | |
| #endif
 | |
|     }
 | |
|     else if (field_size == 1) {
 | |
|         if (sign_extend)
 | |
|             value->i32 = (int32)(*(int8 *)field_data);
 | |
|         else
 | |
|             value->u32 = (uint32)(*(uint8 *)field_data);
 | |
|     }
 | |
|     else if (field_size == 2) {
 | |
|         if (sign_extend)
 | |
|             value->i32 = (int32)(*(int16 *)field_data);
 | |
|         else
 | |
|             value->u32 = (uint32)(*(uint16 *)field_data);
 | |
|     }
 | |
|     else {
 | |
|         bh_assert(0);
 | |
|     }
 | |
| }
 | |
| 
 | |
| uint32
 | |
| wasm_struct_obj_get_field_count(const WASMStructObjectRef struct_obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type =
 | |
|         (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
 | |
|     WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
 | |
| 
 | |
|     return struct_type->field_count;
 | |
| }
 | |
| 
 | |
| WASMArrayObjectRef
 | |
| wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
 | |
|                             uint32 length, WASMValue *init_value)
 | |
| {
 | |
|     WASMArrayObjectRef array_obj;
 | |
|     WASMArrayType *array_type;
 | |
|     uint64 total_size;
 | |
|     uint32 elem_size, elem_size_log, i;
 | |
| 
 | |
|     bh_assert(rtt_type->type_flag == WASM_TYPE_ARRAY);
 | |
| 
 | |
|     if (length >= (1 << 29))
 | |
|         return NULL;
 | |
| 
 | |
|     array_type = (WASMArrayType *)rtt_type->defined_type;
 | |
|     if (array_type->elem_type == PACKED_TYPE_I8) {
 | |
|         elem_size = 1;
 | |
|         elem_size_log = 0;
 | |
|     }
 | |
|     else if (array_type->elem_type == PACKED_TYPE_I16) {
 | |
|         elem_size = 2;
 | |
|         elem_size_log = 1;
 | |
|     }
 | |
|     else {
 | |
|         elem_size = wasm_value_type_size(array_type->elem_type);
 | |
|         elem_size_log = (elem_size == 4) ? 2 : 3;
 | |
|     }
 | |
| 
 | |
|     total_size =
 | |
|         offsetof(WASMArrayObject, elem_data) + (uint64)elem_size * length;
 | |
|     if (!(array_obj = gc_obj_malloc(heap_handle, total_size))) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     array_obj->header = (WASMObjectHeader)rtt_type;
 | |
|     array_obj->length = (length << 2) | elem_size_log;
 | |
| 
 | |
|     if (init_value != NULL) {
 | |
|         for (i = 0; i < length; i++) {
 | |
|             if (wasm_is_type_reftype(array_type->elem_type)) {
 | |
|                 uint32 *elem_addr =
 | |
|                     (uint32 *)array_obj->elem_data + REF_CELL_NUM * i;
 | |
|                 PUT_REF_TO_ADDR(elem_addr, init_value->gc_obj);
 | |
|             }
 | |
|             else if (array_type->elem_type == VALUE_TYPE_I32
 | |
|                      || array_type->elem_type == VALUE_TYPE_F32) {
 | |
|                 ((int32 *)array_obj->elem_data)[i] = init_value->i32;
 | |
|             }
 | |
|             else if (array_type->elem_type == PACKED_TYPE_I8) {
 | |
|                 ((int8 *)array_obj->elem_data)[i] = (int8)init_value->i32;
 | |
|             }
 | |
|             else if (array_type->elem_type == PACKED_TYPE_I16) {
 | |
|                 ((int16 *)array_obj->elem_data)[i] = (int16)init_value->i32;
 | |
|             }
 | |
|             else {
 | |
|                 uint32 *elem_addr = (uint32 *)array_obj->elem_data + 2 * i;
 | |
|                 PUT_I64_TO_ADDR(elem_addr, init_value->i64);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return array_obj;
 | |
| }
 | |
| 
 | |
| WASMArrayObjectRef
 | |
| wasm_array_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
 | |
|                    uint32 length, WASMValue *init_value)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     return wasm_array_obj_new_internal(heap_handle, rtt_type, length,
 | |
|                                        init_value);
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_array_obj_set_elem(WASMArrayObjectRef array_obj, uint32 elem_idx,
 | |
|                         const WASMValue *value)
 | |
| {
 | |
|     uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
 | |
|     uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
 | |
| 
 | |
|     switch (elem_size) {
 | |
|         case 1:
 | |
|             *(int8 *)elem_data = (int8)value->i32;
 | |
|             break;
 | |
|         case 2:
 | |
|             *(int16 *)elem_data = (int16)value->i32;
 | |
|             break;
 | |
|         case 4:
 | |
|             *(int32 *)elem_data = value->i32;
 | |
|             break;
 | |
|         case 8:
 | |
|             PUT_I64_TO_ADDR((uint32 *)elem_data, value->i64);
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_array_obj_get_elem(const WASMArrayObjectRef array_obj, uint32 elem_idx,
 | |
|                         bool sign_extend, WASMValue *value)
 | |
| {
 | |
|     uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
 | |
|     uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
 | |
| 
 | |
|     switch (elem_size) {
 | |
|         case 1:
 | |
|             value->i32 = sign_extend ? (int32)(*(int8 *)elem_data)
 | |
|                                      : (int32)(uint32)(*(uint8 *)elem_data);
 | |
|             break;
 | |
|         case 2:
 | |
|             value->i32 = sign_extend ? (int32)(*(int16 *)elem_data)
 | |
|                                      : (int32)(uint32)(*(uint16 *)elem_data);
 | |
|             break;
 | |
|         case 4:
 | |
|             value->i32 = *(int32 *)elem_data;
 | |
|             break;
 | |
|         case 8:
 | |
|             value->i64 = GET_I64_FROM_ADDR((uint32 *)elem_data);
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_array_obj_fill(const WASMArrayObjectRef array_obj, uint32 elem_idx,
 | |
|                     uint32 len, WASMValue *value)
 | |
| {
 | |
|     uint32 i;
 | |
|     uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
 | |
|     uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
 | |
| 
 | |
|     if (elem_size == 1) {
 | |
|         memset(elem_data, (int8)value->i32, len);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     for (i = 0; i < len; i++) {
 | |
|         switch (elem_size) {
 | |
|             case 2:
 | |
|                 *(int16 *)elem_data = (int16)value->i32;
 | |
|                 break;
 | |
|             case 4:
 | |
|                 *(int32 *)elem_data = value->i32;
 | |
|                 break;
 | |
|             case 8:
 | |
|                 PUT_I64_TO_ADDR((uint32 *)elem_data, value->i64);
 | |
|                 break;
 | |
|         }
 | |
|         elem_data += elem_size;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_array_obj_copy(WASMArrayObjectRef dst_obj, uint32 dst_idx,
 | |
|                     WASMArrayObjectRef src_obj, uint32 src_idx, uint32 len)
 | |
| {
 | |
|     uint8 *dst_data = wasm_array_obj_elem_addr(dst_obj, dst_idx);
 | |
|     uint8 *src_data = wasm_array_obj_elem_addr(src_obj, src_idx);
 | |
|     uint32 elem_size = 1 << wasm_array_obj_elem_size_log(dst_obj);
 | |
| 
 | |
|     bh_memmove_s(dst_data, elem_size * len, src_data, elem_size * len);
 | |
| }
 | |
| 
 | |
| uint32
 | |
| wasm_array_obj_length(const WASMArrayObjectRef array_obj)
 | |
| {
 | |
|     return array_obj->length >> WASM_ARRAY_LENGTH_SHIFT;
 | |
| }
 | |
| 
 | |
| void *
 | |
| wasm_array_obj_first_elem_addr(const WASMArrayObjectRef array_obj)
 | |
| {
 | |
|     return array_obj->elem_data;
 | |
| }
 | |
| 
 | |
| void *
 | |
| wasm_array_obj_elem_addr(const WASMArrayObjectRef array_obj, uint32 elem_idx)
 | |
| {
 | |
|     return array_obj->elem_data
 | |
|            + (elem_idx << wasm_array_obj_elem_size_log(array_obj));
 | |
| }
 | |
| 
 | |
| WASMFuncObjectRef
 | |
| wasm_func_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
 | |
|                            uint32 func_idx_bound)
 | |
| {
 | |
|     WASMFuncObjectRef func_obj;
 | |
|     uint64 total_size;
 | |
| 
 | |
|     bh_assert(rtt_type->type_flag == WASM_TYPE_FUNC);
 | |
| 
 | |
|     total_size = sizeof(WASMFuncObject);
 | |
|     if (!(func_obj = gc_obj_malloc(heap_handle, total_size))) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     func_obj->header = (WASMObjectHeader)rtt_type;
 | |
|     func_obj->func_idx_bound = func_idx_bound;
 | |
| 
 | |
|     return func_obj;
 | |
| }
 | |
| 
 | |
| WASMFuncObjectRef
 | |
| wasm_func_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
 | |
|                   uint32 func_idx_bound)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     return wasm_func_obj_new_internal(heap_handle, rtt_type, func_idx_bound);
 | |
| }
 | |
| 
 | |
| uint32
 | |
| wasm_func_obj_get_func_idx_bound(const WASMFuncObjectRef func_obj)
 | |
| {
 | |
|     return func_obj->func_idx_bound;
 | |
| }
 | |
| 
 | |
| WASMFuncType *
 | |
| wasm_func_obj_get_func_type(const WASMFuncObjectRef func_obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type =
 | |
|         (WASMRttTypeRef)wasm_object_header((WASMObjectRef)func_obj);
 | |
|     bh_assert(rtt_type->type_flag == WASM_TYPE_FUNC);
 | |
|     return (WASMFuncType *)rtt_type->defined_type;
 | |
| }
 | |
| 
 | |
| WASMExternrefObjectRef
 | |
| wasm_externref_obj_new(WASMExecEnv *exec_env, const void *host_obj)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     WASMAnyrefObjectRef anyref_obj;
 | |
|     WASMExternrefObjectRef externref_obj;
 | |
|     WASMLocalObjectRef local_ref;
 | |
| 
 | |
|     if (!(anyref_obj = gc_obj_malloc(heap_handle, sizeof(WASMAnyrefObject)))) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     anyref_obj->header = WASM_OBJ_ANYREF_OBJ_FLAG;
 | |
|     anyref_obj->host_obj = host_obj;
 | |
| 
 | |
|     /* Lock anyref_obj in case it is reclaimed when allocating memory below */
 | |
|     wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
 | |
|     local_ref.val = (WASMObjectRef)anyref_obj;
 | |
| 
 | |
|     if (!(externref_obj =
 | |
|               gc_obj_malloc(heap_handle, sizeof(WASMExternrefObject)))) {
 | |
|         wasm_runtime_pop_local_obj_ref(exec_env);
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     externref_obj->header = WASM_OBJ_EXTERNREF_OBJ_FLAG;
 | |
|     externref_obj->internal_obj = (WASMObjectRef)anyref_obj;
 | |
| 
 | |
|     wasm_runtime_pop_local_obj_ref(exec_env);
 | |
|     return externref_obj;
 | |
| }
 | |
| 
 | |
| WASMAnyrefObjectRef
 | |
| wasm_anyref_obj_new(WASMExecEnv *exec_env, const void *host_obj)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     WASMAnyrefObjectRef anyref_obj;
 | |
| 
 | |
|     if (!(anyref_obj = gc_obj_malloc(heap_handle, sizeof(WASMAnyrefObject)))) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     anyref_obj->header = WASM_OBJ_ANYREF_OBJ_FLAG;
 | |
|     anyref_obj->host_obj = host_obj;
 | |
| 
 | |
|     return anyref_obj;
 | |
| }
 | |
| 
 | |
| WASMObjectRef
 | |
| wasm_externref_obj_to_internal_obj(WASMExternrefObjectRef externref_obj)
 | |
| {
 | |
|     return externref_obj->internal_obj;
 | |
| }
 | |
| 
 | |
| WASMExternrefObjectRef
 | |
| wasm_internal_obj_to_externref_obj(WASMExecEnv *exec_env,
 | |
|                                    WASMObjectRef internal_obj)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     WASMExternrefObjectRef externref_obj;
 | |
| 
 | |
|     if (!(externref_obj =
 | |
|               gc_obj_malloc(heap_handle, sizeof(WASMExternrefObject)))) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     externref_obj->header = WASM_OBJ_EXTERNREF_OBJ_FLAG;
 | |
|     externref_obj->internal_obj = internal_obj;
 | |
| 
 | |
|     return externref_obj;
 | |
| }
 | |
| 
 | |
| const void *
 | |
| wasm_anyref_obj_get_value(WASMAnyrefObjectRef anyref_obj)
 | |
| {
 | |
|     return anyref_obj->host_obj;
 | |
| }
 | |
| 
 | |
| const void *
 | |
| wasm_externref_obj_get_value(const WASMExternrefObjectRef externref_obj)
 | |
| {
 | |
|     if (wasm_obj_is_anyref_obj(externref_obj->internal_obj))
 | |
|         return ((WASMAnyrefObjectRef)externref_obj->internal_obj)->host_obj;
 | |
|     else
 | |
|         return externref_obj->internal_obj;
 | |
| }
 | |
| 
 | |
| WASMI31ObjectRef
 | |
| wasm_i31_obj_new(uint32 i31_value)
 | |
| {
 | |
|     return (WASMI31ObjectRef)((i31_value << 1) | 1);
 | |
| }
 | |
| 
 | |
| uint32
 | |
| wasm_i31_obj_get_value(WASMI31ObjectRef i31_obj, bool sign_extend)
 | |
| {
 | |
|     uint32 i31_value = (uint32)(((uintptr_t)i31_obj) >> 1);
 | |
|     if (sign_extend && (i31_value & 0x40000000)) /* bit 30 is 1 */
 | |
|         /* set bit 31 to 1 */
 | |
|         i31_value |= 0x80000000;
 | |
|     return i31_value;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_i31_obj(WASMObjectRef obj)
 | |
| {
 | |
|     bh_assert(obj);
 | |
|     return (((uintptr_t)obj) & 1) ? true : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_externref_obj(WASMObjectRef obj)
 | |
| {
 | |
|     bh_assert(obj);
 | |
|     return (!wasm_obj_is_i31_obj(obj)
 | |
|             && (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG))
 | |
|                ? true
 | |
|                : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_anyref_obj(WASMObjectRef obj)
 | |
| {
 | |
|     bh_assert(obj);
 | |
|     return (!wasm_obj_is_i31_obj(obj)
 | |
|             && (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG))
 | |
|                ? true
 | |
|                : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_i31_externref_or_anyref_obj(WASMObjectRef obj)
 | |
| {
 | |
|     bh_assert(obj);
 | |
|     return (wasm_obj_is_i31_obj(obj)
 | |
|             || (obj->header
 | |
|                 & (WASM_OBJ_EXTERNREF_OBJ_FLAG | WASM_OBJ_ANYREF_OBJ_FLAG)))
 | |
|                ? true
 | |
|                : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_struct_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type;
 | |
| 
 | |
|     bh_assert(obj);
 | |
| 
 | |
|     if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
 | |
|         return false;
 | |
| 
 | |
|     rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
 | |
|     return rtt_type->type_flag == WASM_TYPE_STRUCT ? true : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_array_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type;
 | |
| 
 | |
|     bh_assert(obj);
 | |
| 
 | |
|     if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
 | |
|         return false;
 | |
| 
 | |
|     rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
 | |
|     return rtt_type->type_flag == WASM_TYPE_ARRAY ? true : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_func_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type;
 | |
| 
 | |
|     bh_assert(obj);
 | |
| 
 | |
|     if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
 | |
|         return false;
 | |
| 
 | |
|     rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
 | |
|     return rtt_type->type_flag == WASM_TYPE_FUNC ? true : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_internal_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type;
 | |
| 
 | |
|     bh_assert(obj);
 | |
| 
 | |
|     if (wasm_obj_is_i31_obj(obj))
 | |
|         return true;
 | |
|     else if (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG)
 | |
|         return true;
 | |
|     else if (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG)
 | |
|         return false;
 | |
|     else {
 | |
|         rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
 | |
|         return (rtt_type->type_flag == WASM_TYPE_STRUCT
 | |
|                 || rtt_type->type_flag == WASM_TYPE_ARRAY)
 | |
|                    ? true
 | |
|                    : false;
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_eq_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type;
 | |
| 
 | |
|     bh_assert(obj);
 | |
| 
 | |
|     if (wasm_obj_is_i31_obj(obj))
 | |
|         return true;
 | |
|     else if ((obj->header & WASM_OBJ_ANYREF_OBJ_FLAG)
 | |
|              || (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG))
 | |
|         return false;
 | |
|     else {
 | |
|         rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
 | |
|         return (rtt_type->type_flag == WASM_TYPE_STRUCT
 | |
|                 || rtt_type->type_flag == WASM_TYPE_ARRAY)
 | |
|                    ? true
 | |
|                    : false;
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_instance_of(WASMObjectRef obj, uint32 type_idx, WASMType **types,
 | |
|                         uint32 type_count)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type_sub;
 | |
|     WASMType *type_sub, *type_parent;
 | |
|     uint32 distance, i;
 | |
| 
 | |
|     bh_assert(obj);
 | |
|     bh_assert(type_idx < type_count);
 | |
| 
 | |
|     if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
 | |
|         return false;
 | |
| 
 | |
|     rtt_type_sub = (WASMRttTypeRef)wasm_object_header(obj);
 | |
|     type_parent = types[type_idx];
 | |
| 
 | |
|     if (!(rtt_type_sub->root_type == type_parent->root_type
 | |
|           && rtt_type_sub->inherit_depth >= type_parent->inherit_depth))
 | |
|         return false;
 | |
| 
 | |
|     type_sub = rtt_type_sub->defined_type;
 | |
|     distance = type_sub->inherit_depth - type_parent->inherit_depth;
 | |
| 
 | |
|     for (i = 0; i < distance; i++) {
 | |
|         type_sub = type_sub->parent_type;
 | |
|     }
 | |
| 
 | |
|     return (type_sub == type_parent) ? true : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_type_of(WASMObjectRef obj, int32 heap_type)
 | |
| {
 | |
|     bh_assert(obj);
 | |
| 
 | |
|     switch (heap_type) {
 | |
|         case HEAP_TYPE_FUNC:
 | |
|             return wasm_obj_is_func_obj(obj);
 | |
|         case HEAP_TYPE_EXTERN:
 | |
|             return wasm_obj_is_externref_obj(obj);
 | |
|         case HEAP_TYPE_ANY:
 | |
|             return wasm_obj_is_internal_obj(obj);
 | |
|         case HEAP_TYPE_EQ:
 | |
|             return wasm_obj_is_eq_obj(obj);
 | |
|         case HEAP_TYPE_I31:
 | |
|             return wasm_obj_is_i31_obj(obj);
 | |
|         case HEAP_TYPE_STRUCT:
 | |
|             return wasm_obj_is_struct_obj(obj);
 | |
|         case HEAP_TYPE_ARRAY:
 | |
|             return wasm_obj_is_array_obj(obj);
 | |
| #if WASM_ENABLE_STRINGREF != 0
 | |
|         case HEAP_TYPE_STRINGREF:
 | |
|             return wasm_obj_is_stringref_obj(obj);
 | |
|         case HEAP_TYPE_STRINGVIEWWTF8:
 | |
|             return wasm_obj_is_stringview_wtf8_obj(obj);
 | |
|         case HEAP_TYPE_STRINGVIEWWTF16:
 | |
|             return wasm_obj_is_stringview_wtf16_obj(obj);
 | |
| #endif
 | |
|         case HEAP_TYPE_NONE:
 | |
|         case HEAP_TYPE_NOFUNC:
 | |
|         case HEAP_TYPE_NOEXTERN:
 | |
|             return false;
 | |
|         default:
 | |
|             bh_assert(0);
 | |
|             break;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_equal(WASMObjectRef obj1, WASMObjectRef obj2)
 | |
| {
 | |
|     /* TODO: do we need to compare the internal details of the objects */
 | |
|     return obj1 == obj2 ? true : false;
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
 | |
|                          uint32 *p_ref_num, uint16 **p_ref_list,
 | |
|                          uint32 *p_ref_start_offset)
 | |
| {
 | |
|     WASMRttTypeRef rtt_type;
 | |
| 
 | |
|     bh_assert(wasm_obj_is_created_from_heap(obj));
 | |
| 
 | |
|     rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
 | |
| 
 | |
|     if (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG) {
 | |
|         /* externref object */
 | |
|         static uint16 externref_obj_ref_list[] = { (uint16)offsetof(
 | |
|             WASMExternrefObject, internal_obj) };
 | |
|         *p_is_compact_mode = false;
 | |
|         *p_ref_num = 1;
 | |
|         *p_ref_list = externref_obj_ref_list;
 | |
|         return true;
 | |
|     }
 | |
|     else if (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG) {
 | |
|         /* anyref object */
 | |
|         *p_is_compact_mode = false;
 | |
|         *p_ref_num = 0;
 | |
|         *p_ref_list = NULL;
 | |
|         return true;
 | |
|     }
 | |
| #if WASM_ENABLE_STRINGREF != 0
 | |
|     else if (rtt_type->type_flag == WASM_TYPE_STRINGREF
 | |
|              || rtt_type->type_flag == WASM_TYPE_STRINGVIEWWTF8
 | |
|              || rtt_type->type_flag == WASM_TYPE_STRINGVIEWWTF16
 | |
|              || rtt_type->type_flag == WASM_TYPE_STRINGVIEWITER) {
 | |
|         /* stringref/stringview_wtf8/stringview_wtf16/stringview_iter object */
 | |
|         *p_is_compact_mode = false;
 | |
|         *p_ref_num = 0;
 | |
|         *p_ref_list = NULL;
 | |
|         return true;
 | |
|     }
 | |
| #endif /* end of WASM_ENABLE_STRINGREF != 0 */
 | |
|     else if (rtt_type->defined_type->type_flag == WASM_TYPE_FUNC) {
 | |
|         /* function object */
 | |
|         *p_is_compact_mode = false;
 | |
|         *p_ref_num = 0;
 | |
|         *p_ref_list = NULL;
 | |
|         return true;
 | |
|     }
 | |
|     else if (rtt_type->defined_type->type_flag == WASM_TYPE_STRUCT) {
 | |
|         /* struct object */
 | |
|         WASMStructType *type = (WASMStructType *)rtt_type->defined_type;
 | |
|         *p_is_compact_mode = false;
 | |
|         *p_ref_num = *type->reference_table;
 | |
|         *p_ref_list = type->reference_table + 1;
 | |
|         return true;
 | |
|     }
 | |
|     else if (rtt_type->defined_type->type_flag == WASM_TYPE_ARRAY) {
 | |
|         /* array object */
 | |
|         WASMArrayType *type = (WASMArrayType *)rtt_type->defined_type;
 | |
|         if (wasm_is_type_reftype(type->elem_type)) {
 | |
|             *p_is_compact_mode = true;
 | |
|             *p_ref_num = wasm_array_obj_length((WASMArrayObjectRef)obj);
 | |
|             *p_ref_start_offset = (uint16)offsetof(WASMArrayObject, elem_data);
 | |
|         }
 | |
|         else {
 | |
|             *p_is_compact_mode = false;
 | |
|             *p_ref_num = 0;
 | |
|             *p_ref_list = NULL;
 | |
|         }
 | |
| 
 | |
|         return true;
 | |
|     }
 | |
|     else {
 | |
|         bh_assert(0);
 | |
|         return false;
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_set_gc_finalizer(wasm_exec_env_t exec_env, const wasm_obj_t obj,
 | |
|                           wasm_obj_finalizer_t cb, void *data)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     return mem_allocator_set_gc_finalizer(heap_handle, obj, (gc_finalizer_t)cb,
 | |
|                                           data);
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_obj_unset_gc_finalizer(wasm_exec_env_t exec_env, void *obj)
 | |
| {
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     mem_allocator_unset_gc_finalizer(heap_handle, obj);
 | |
| }
 | |
| 
 | |
| #if WASM_ENABLE_STRINGREF != 0
 | |
| WASMRttTypeRef
 | |
| wasm_stringref_rtt_type_new(uint16 type_flag, WASMRttType **rtt_types,
 | |
|                             korp_mutex *rtt_type_lock)
 | |
| {
 | |
|     WASMRttType *rtt_type;
 | |
|     uint32 index;
 | |
| 
 | |
|     bh_assert(type_flag >= WASM_TYPE_STRINGREF
 | |
|               && type_flag <= WASM_TYPE_STRINGVIEWITER);
 | |
| 
 | |
|     index = type_flag - WASM_TYPE_STRINGREF;
 | |
| 
 | |
|     os_mutex_lock(rtt_type_lock);
 | |
| 
 | |
|     if (rtt_types[index]) {
 | |
|         os_mutex_unlock(rtt_type_lock);
 | |
|         return rtt_types[index];
 | |
|     }
 | |
| 
 | |
|     if ((rtt_type = wasm_runtime_malloc(sizeof(WASMRttType)))) {
 | |
|         memset(rtt_type, 0, sizeof(WASMRttType));
 | |
|         rtt_type->type_flag = type_flag;
 | |
| 
 | |
|         rtt_types[index] = rtt_type;
 | |
|     }
 | |
| 
 | |
|     os_mutex_unlock(rtt_type_lock);
 | |
|     return rtt_type;
 | |
| }
 | |
| 
 | |
| static void
 | |
| wasm_stringref_obj_finalizer(WASMStringrefObjectRef stringref_obj, void *data)
 | |
| {
 | |
|     wasm_string_destroy(
 | |
|         (WASMString)wasm_stringref_obj_get_value(stringref_obj));
 | |
| }
 | |
| 
 | |
| static void
 | |
| wasm_stringview_wtf8_obj_finalizer(WASMStringviewWTF8ObjectRef stringref_obj,
 | |
|                                    void *data)
 | |
| {
 | |
|     wasm_string_destroy(
 | |
|         (WASMString)wasm_stringview_wtf8_obj_get_value(stringref_obj));
 | |
| }
 | |
| 
 | |
| static void
 | |
| wasm_stringview_wtf16_obj_finalizer(WASMStringviewWTF16ObjectRef stringref_obj,
 | |
|                                     void *data)
 | |
| {
 | |
|     wasm_string_destroy(
 | |
|         (WASMString)wasm_stringview_wtf16_obj_get_value(stringref_obj));
 | |
| }
 | |
| 
 | |
| static void
 | |
| wasm_stringview_iter_obj_finalizer(WASMStringviewIterObjectRef stringref_obj,
 | |
|                                    void *data)
 | |
| {
 | |
|     wasm_string_destroy(
 | |
|         (WASMString)wasm_stringview_iter_obj_get_value(stringref_obj));
 | |
| }
 | |
| 
 | |
| static WASMObjectRef
 | |
| stringref_obj_new(WASMExecEnv *exec_env, uint32 type, const void *str_obj,
 | |
|                   int32 pos)
 | |
| {
 | |
|     WASMObjectRef stringref_obj = NULL;
 | |
|     void *heap_handle = get_gc_heap_handle(exec_env);
 | |
|     WASMModuleInstanceCommon *module_inst =
 | |
|         wasm_runtime_get_module_inst(exec_env);
 | |
|     WASMRttTypeRef rtt_type = NULL;
 | |
| 
 | |
| #if WASM_ENABLE_INTERP != 0
 | |
|     if (module_inst->module_type == Wasm_Module_Bytecode) {
 | |
|         WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
 | |
|         rtt_type = wasm_stringref_rtt_type_new(type, module->stringref_rtts,
 | |
|                                                &module->rtt_type_lock);
 | |
|     }
 | |
| #endif
 | |
| #if WASM_ENABLE_AOT != 0
 | |
|     if (module_inst->module_type == Wasm_Module_AoT) {
 | |
|         AOTModule *module =
 | |
|             (AOTModule *)((AOTModuleInstance *)module_inst)->module;
 | |
|         rtt_type = wasm_stringref_rtt_type_new(type, module->stringref_rtts,
 | |
|                                                &module->rtt_type_lock);
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     if (!rtt_type) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     if (type == WASM_TYPE_STRINGREF) {
 | |
|         if (!(stringref_obj =
 | |
|                   gc_obj_malloc(heap_handle, sizeof(WASMStringrefObject)))) {
 | |
|             return NULL;
 | |
|         }
 | |
|         ((WASMStringrefObjectRef)stringref_obj)->header =
 | |
|             (WASMObjectHeader)rtt_type;
 | |
|         ((WASMStringrefObjectRef)stringref_obj)->str_obj = str_obj;
 | |
|         wasm_obj_set_gc_finalizer(
 | |
|             exec_env, (wasm_obj_t)stringref_obj,
 | |
|             (wasm_obj_finalizer_t)wasm_stringref_obj_finalizer, NULL);
 | |
|     }
 | |
|     else if (type == WASM_TYPE_STRINGVIEWWTF8) {
 | |
|         if (!(stringref_obj = gc_obj_malloc(
 | |
|                   heap_handle, sizeof(WASMStringviewWTF8Object)))) {
 | |
|             return NULL;
 | |
|         }
 | |
|         ((WASMStringviewWTF8ObjectRef)stringref_obj)->header =
 | |
|             (WASMObjectHeader)rtt_type;
 | |
|         ((WASMStringviewWTF8ObjectRef)stringref_obj)->str_obj = str_obj;
 | |
|         wasm_obj_set_gc_finalizer(
 | |
|             exec_env, (wasm_obj_t)stringref_obj,
 | |
|             (wasm_obj_finalizer_t)wasm_stringview_wtf8_obj_finalizer, NULL);
 | |
|     }
 | |
|     else if (type == WASM_TYPE_STRINGVIEWWTF16) {
 | |
|         if (!(stringref_obj = gc_obj_malloc(
 | |
|                   heap_handle, sizeof(WASMStringviewWTF16Object)))) {
 | |
|             return NULL;
 | |
|         }
 | |
|         ((WASMStringviewWTF16ObjectRef)stringref_obj)->header =
 | |
|             (WASMObjectHeader)rtt_type;
 | |
|         ((WASMStringviewWTF16ObjectRef)stringref_obj)->str_obj = str_obj;
 | |
|         wasm_obj_set_gc_finalizer(
 | |
|             exec_env, (wasm_obj_t)stringref_obj,
 | |
|             (wasm_obj_finalizer_t)wasm_stringview_wtf16_obj_finalizer, NULL);
 | |
|     }
 | |
|     else if (type == WASM_TYPE_STRINGVIEWITER) {
 | |
|         if (!(stringref_obj = gc_obj_malloc(
 | |
|                   heap_handle, sizeof(WASMStringviewIterObject)))) {
 | |
|             return NULL;
 | |
|         }
 | |
|         ((WASMStringviewIterObjectRef)stringref_obj)->header =
 | |
|             (WASMObjectHeader)rtt_type;
 | |
|         ((WASMStringviewIterObjectRef)stringref_obj)->str_obj = str_obj;
 | |
|         ((WASMStringviewIterObjectRef)stringref_obj)->pos = pos;
 | |
|         wasm_obj_set_gc_finalizer(
 | |
|             exec_env, (wasm_obj_t)stringref_obj,
 | |
|             (wasm_obj_finalizer_t)wasm_stringview_iter_obj_finalizer, NULL);
 | |
|     }
 | |
| 
 | |
|     return stringref_obj;
 | |
| }
 | |
| 
 | |
| WASMStringrefObjectRef
 | |
| wasm_stringref_obj_new(WASMExecEnv *exec_env, const void *str_obj)
 | |
| {
 | |
|     WASMStringrefObjectRef stringref_obj;
 | |
| 
 | |
|     stringref_obj = (WASMStringrefObjectRef)stringref_obj_new(
 | |
|         exec_env, WASM_TYPE_STRINGREF, str_obj, 0);
 | |
| 
 | |
|     return stringref_obj;
 | |
| }
 | |
| 
 | |
| WASMStringviewWTF8ObjectRef
 | |
| wasm_stringview_wtf8_obj_new(WASMExecEnv *exec_env, const void *str_obj)
 | |
| {
 | |
|     WASMStringviewWTF8ObjectRef stringview_wtf8_obj;
 | |
| 
 | |
|     stringview_wtf8_obj = (WASMStringviewWTF8ObjectRef)stringref_obj_new(
 | |
|         exec_env, WASM_TYPE_STRINGVIEWWTF8, str_obj, 0);
 | |
| 
 | |
|     return stringview_wtf8_obj;
 | |
| }
 | |
| 
 | |
| WASMStringviewWTF16ObjectRef
 | |
| wasm_stringview_wtf16_obj_new(WASMExecEnv *exec_env, const void *str_obj)
 | |
| {
 | |
|     WASMStringviewWTF16ObjectRef stringview_wtf16_obj;
 | |
| 
 | |
|     stringview_wtf16_obj = (WASMStringviewWTF16ObjectRef)stringref_obj_new(
 | |
|         exec_env, WASM_TYPE_STRINGVIEWWTF16, str_obj, 0);
 | |
| 
 | |
|     return stringview_wtf16_obj;
 | |
| }
 | |
| 
 | |
| WASMStringviewIterObjectRef
 | |
| wasm_stringview_iter_obj_new(WASMExecEnv *exec_env, const void *str_obj,
 | |
|                              int32 pos)
 | |
| {
 | |
|     WASMStringviewIterObjectRef stringview_iter_obj;
 | |
| 
 | |
|     stringview_iter_obj = (WASMStringviewIterObjectRef)stringref_obj_new(
 | |
|         exec_env, WASM_TYPE_STRINGVIEWITER, str_obj, pos);
 | |
| 
 | |
|     return stringview_iter_obj;
 | |
| }
 | |
| 
 | |
| const void *
 | |
| wasm_stringref_obj_get_value(WASMStringrefObjectRef stringref_obj)
 | |
| {
 | |
|     return stringref_obj->str_obj;
 | |
| }
 | |
| 
 | |
| const void *
 | |
| wasm_stringview_wtf8_obj_get_value(
 | |
|     WASMStringviewWTF8ObjectRef stringview_wtf8_obj)
 | |
| {
 | |
|     return stringview_wtf8_obj->str_obj;
 | |
| }
 | |
| 
 | |
| const void *
 | |
| wasm_stringview_wtf16_obj_get_value(
 | |
|     WASMStringviewWTF16ObjectRef stringview_wtf16_obj)
 | |
| {
 | |
|     return stringview_wtf16_obj->str_obj;
 | |
| }
 | |
| 
 | |
| const void *
 | |
| wasm_stringview_iter_obj_get_value(
 | |
|     WASMStringviewIterObjectRef stringview_iter_obj)
 | |
| {
 | |
|     return stringview_iter_obj->str_obj;
 | |
| }
 | |
| 
 | |
| int32
 | |
| wasm_stringview_iter_obj_get_pos(
 | |
|     WASMStringviewIterObjectRef stringview_iter_obj)
 | |
| {
 | |
|     return stringview_iter_obj->pos;
 | |
| }
 | |
| 
 | |
| void
 | |
| wasm_stringview_iter_obj_update_pos(
 | |
|     WASMStringviewIterObjectRef stringview_iter_obj, int32 pos)
 | |
| {
 | |
|     stringview_iter_obj->pos = pos;
 | |
| }
 | |
| 
 | |
| #define WASM_OBJ_IS_STRINGREF_IMPL(flag)                \
 | |
|     WASMRttTypeRef rtt_type;                            \
 | |
|                                                         \
 | |
|     bh_assert(obj);                                     \
 | |
|                                                         \
 | |
|     if (wasm_obj_is_i31_externref_or_anyref_obj(obj))   \
 | |
|         return false;                                   \
 | |
|                                                         \
 | |
|     rtt_type = (WASMRttTypeRef)wasm_object_header(obj); \
 | |
|     return rtt_type->type_flag == flag ? true : false
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_stringref_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASM_OBJ_IS_STRINGREF_IMPL(WASM_TYPE_STRINGREF);
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_stringview_wtf8_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASM_OBJ_IS_STRINGREF_IMPL(WASM_TYPE_STRINGVIEWWTF8);
 | |
| }
 | |
| 
 | |
| bool
 | |
| wasm_obj_is_stringview_wtf16_obj(WASMObjectRef obj)
 | |
| {
 | |
|     WASM_OBJ_IS_STRINGREF_IMPL(WASM_TYPE_STRINGVIEWWTF16);
 | |
| }
 | |
| #undef WASM_OBJ_IS_STRINGREF_IMPL
 | |
| 
 | |
| #endif /* end of WASM_ENABLE_STRINGREF != 0 */
 | 
