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:
1001
core/iwasm/common/gc/gc_common.c
Normal file
1001
core/iwasm/common/gc/gc_common.c
Normal file
File diff suppressed because it is too large
Load Diff
1071
core/iwasm/common/gc/gc_object.c
Normal file
1071
core/iwasm/common/gc/gc_object.c
Normal file
File diff suppressed because it is too large
Load Diff
378
core/iwasm/common/gc/gc_object.h
Normal file
378
core/iwasm/common/gc/gc_object.h
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _GC_OBJECT_H_
|
||||
#define _GC_OBJECT_H_
|
||||
|
||||
#include "gc_type.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Object header of a WASM object, as the adddress of allocated memory
|
||||
* must be 8-byte aligned, the lowest 3 bits are zero, we use them to
|
||||
* mark the object:
|
||||
* bits[0] is 1: the object is an externref object
|
||||
* bits[1] is 1: the object is an anyref object
|
||||
* bits[2] is 1: the object has extra information
|
||||
* if both bits[0] and bits[1] are 0, then this object header must
|
||||
* be a pointer of a WASMRttType, denotes that the object is a
|
||||
* struct object, or an array object, or a function object
|
||||
*/
|
||||
typedef uintptr_t WASMObjectHeader;
|
||||
|
||||
#define WASM_OBJ_HEADER_MASK (~((uintptr_t)7))
|
||||
|
||||
#define WASM_OBJ_EXTERNREF_OBJ_FLAG (((uintptr_t)1) << 0)
|
||||
|
||||
#define WASM_OBJ_ANYREF_OBJ_FLAG (((uintptr_t)1) << 1)
|
||||
|
||||
#define WASM_OBJ_EXTRA_INFO_FLAG (((uintptr_t)1) << 2)
|
||||
|
||||
/* Representation of WASM objects */
|
||||
typedef struct WASMObject {
|
||||
WASMObjectHeader header;
|
||||
} WASMObject, *WASMObjectRef;
|
||||
|
||||
/* Representation of WASM rtt types */
|
||||
typedef struct WASMRttType {
|
||||
/* type_flag must be WASM_TYPE_FUNC/STRUCT/ARRAY to
|
||||
denote an object of func, struct or array */
|
||||
uint32 type_flag;
|
||||
uint32 inherit_depth;
|
||||
WASMType *defined_type;
|
||||
WASMType *root_type;
|
||||
} WASMRttType, *WASMRttTypeRef;
|
||||
|
||||
/* Representation of WASM externref objects */
|
||||
typedef struct WASMExternrefObject {
|
||||
/* bits[0] must be 1, denotes an externref object */
|
||||
WASMObjectHeader header;
|
||||
/* an object of WASMAnyrefObjectRef which encapsulates the external
|
||||
object passed from host, or other internal objects passed to
|
||||
opcode extern.externalize */
|
||||
WASMObjectRef internal_obj;
|
||||
} WASMExternrefObject, *WASMExternrefObjectRef;
|
||||
|
||||
/* Representation of WASM anyref objects which encapsulate the
|
||||
external object passed from host */
|
||||
typedef struct WASMAnyrefObject {
|
||||
/* bits[1] must be 1, denotes an anyref object */
|
||||
WASMObjectHeader header;
|
||||
const void *host_obj;
|
||||
} WASMAnyrefObject, *WASMAnyrefObjectRef;
|
||||
|
||||
/**
|
||||
* Representation of WASM i31 objects, the lowest bit is 1:
|
||||
* for a pointer of WASMObjectRef, if the lowest bit is 1, then it is an
|
||||
* i31 object and bits[1..31] stores the actual i31 value, otherwise
|
||||
* it is a normal object of rtt/externref/struct/array/func */
|
||||
typedef uintptr_t WASMI31ObjectRef;
|
||||
|
||||
/* Representation of WASM struct objects */
|
||||
typedef struct WASMStructObject {
|
||||
/* Must be pointer of WASMRttObject of struct type */
|
||||
WASMObjectHeader header;
|
||||
uint8 field_data[1];
|
||||
} WASMStructObject, *WASMStructObjectRef;
|
||||
|
||||
/* Representation of WASM array objects */
|
||||
typedef struct WASMArrayObject {
|
||||
/* Must be pointer of WASMRttObject of array type */
|
||||
WASMObjectHeader header;
|
||||
/* (<array length> << 2) | <array element size>,
|
||||
* elem_count = lenght >> 2
|
||||
* elem_size = 2 ^ (length & 0x3)
|
||||
*/
|
||||
uint32 length;
|
||||
uint8 elem_data[1];
|
||||
} WASMArrayObject, *WASMArrayObjectRef;
|
||||
|
||||
#define WASM_ARRAY_LENGTH_SHIFT 2
|
||||
#define WASM_ARRAY_ELEM_SIZE_MASK 3
|
||||
|
||||
/* Representation of WASM function objects */
|
||||
typedef struct WASMFuncObject {
|
||||
/* must be pointer of WASMRttObject of func type */
|
||||
WASMObjectHeader header;
|
||||
uint32 func_idx_bound;
|
||||
} WASMFuncObject, *WASMFuncObjectRef;
|
||||
|
||||
/* Representation of WASM stringref objects */
|
||||
typedef struct WASMStringrefObject {
|
||||
WASMObjectHeader header;
|
||||
const void *str_obj;
|
||||
} WASMStringrefObject, *WASMStringrefObjectRef;
|
||||
|
||||
typedef struct WASMStringviewWTF8Object {
|
||||
WASMObjectHeader header;
|
||||
const void *str_obj;
|
||||
} WASMStringviewWTF8Object, *WASMStringviewWTF8ObjectRef;
|
||||
|
||||
typedef struct WASMStringviewWTF16Object {
|
||||
WASMObjectHeader header;
|
||||
const void *str_obj;
|
||||
} WASMStringviewWTF16Object, *WASMStringviewWTF16ObjectRef;
|
||||
|
||||
typedef struct WASMStringviewIterObject {
|
||||
WASMObjectHeader header;
|
||||
const void *str_obj;
|
||||
int32 pos;
|
||||
} WASMStringviewIterObject, *WASMStringviewIterObjectRef;
|
||||
|
||||
struct WASMExecEnv;
|
||||
|
||||
inline static WASMObjectHeader
|
||||
wasm_object_header(const WASMObjectRef obj)
|
||||
{
|
||||
return (obj->header & WASM_OBJ_HEADER_MASK);
|
||||
}
|
||||
|
||||
WASMRttTypeRef
|
||||
wasm_rtt_type_new(WASMType *defined_type, uint32 defined_type_idx,
|
||||
WASMRttType **rtt_types, uint32 rtt_type_count,
|
||||
korp_mutex *rtt_type_lock);
|
||||
|
||||
inline static WASMType *
|
||||
wasm_rtt_type_get_defined_type(const WASMRttTypeRef rtt_type)
|
||||
{
|
||||
return rtt_type->defined_type;
|
||||
}
|
||||
|
||||
WASMStructObjectRef
|
||||
wasm_struct_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type);
|
||||
|
||||
WASMStructObjectRef
|
||||
wasm_struct_obj_new(struct WASMExecEnv *exec_env, WASMRttTypeRef rtt_type);
|
||||
|
||||
void
|
||||
wasm_struct_obj_set_field(WASMStructObjectRef struct_obj, uint32 field_idx,
|
||||
const WASMValue *value);
|
||||
|
||||
void
|
||||
wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj,
|
||||
uint32 field_idx, bool sign_extend, WASMValue *value);
|
||||
|
||||
WASMArrayObjectRef
|
||||
wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
|
||||
uint32 length, WASMValue *init_value);
|
||||
|
||||
WASMArrayObjectRef
|
||||
wasm_array_obj_new(struct WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
|
||||
uint32 length, WASMValue *init_value);
|
||||
|
||||
void
|
||||
wasm_array_obj_set_elem(WASMArrayObjectRef array_obj, uint32 elem_idx,
|
||||
const WASMValue *value);
|
||||
|
||||
void
|
||||
wasm_array_obj_get_elem(const WASMArrayObjectRef array_obj, uint32 elem_idx,
|
||||
bool sign_extend, WASMValue *value);
|
||||
|
||||
void
|
||||
wasm_array_obj_fill(const WASMArrayObjectRef array_obj, uint32 elem_idx,
|
||||
uint32 len, WASMValue *value);
|
||||
|
||||
void
|
||||
wasm_array_obj_copy(WASMArrayObjectRef dst_obj, uint32 dst_idx,
|
||||
WASMArrayObjectRef src_obj, uint32 src_idx, uint32 len);
|
||||
|
||||
/**
|
||||
* Return the logarithm of the size of array element.
|
||||
*
|
||||
* @param array the WASM array object
|
||||
*
|
||||
* @return log(size of the array element)
|
||||
*/
|
||||
inline static uint32
|
||||
wasm_array_obj_elem_size_log(const WASMArrayObjectRef array_obj)
|
||||
{
|
||||
return (array_obj->length & WASM_ARRAY_ELEM_SIZE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the array.
|
||||
*
|
||||
* @param array_obj the WASM array object
|
||||
*
|
||||
* @return the length of the array
|
||||
*/
|
||||
uint32
|
||||
wasm_array_obj_length(const WASMArrayObjectRef array_obj);
|
||||
|
||||
/**
|
||||
* Return the address of the first element of an array object.
|
||||
*
|
||||
* @param array_obj the WASM array object
|
||||
*
|
||||
* @return the address of the first element of the array object
|
||||
*/
|
||||
void *
|
||||
wasm_array_obj_first_elem_addr(const WASMArrayObjectRef array_obj);
|
||||
|
||||
/**
|
||||
* Return the address of the i-th element of an array object.
|
||||
*
|
||||
* @param array_obj the WASM array object
|
||||
* @param index the index of the element
|
||||
*
|
||||
* @return the address of the i-th element of the array object
|
||||
*/
|
||||
void *
|
||||
wasm_array_obj_elem_addr(const WASMArrayObjectRef array_obj, uint32 elem_idx);
|
||||
|
||||
WASMFuncObjectRef
|
||||
wasm_func_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
|
||||
uint32 func_idx_bound);
|
||||
|
||||
WASMFuncObjectRef
|
||||
wasm_func_obj_new(struct WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
|
||||
uint32 func_idx_bound);
|
||||
|
||||
uint32
|
||||
wasm_func_obj_get_func_idx_bound(const WASMFuncObjectRef func_obj);
|
||||
|
||||
WASMFuncType *
|
||||
wasm_func_obj_get_func_type(const WASMFuncObjectRef func_obj);
|
||||
|
||||
WASMExternrefObjectRef
|
||||
wasm_externref_obj_new(struct WASMExecEnv *exec_env, const void *host_obj);
|
||||
|
||||
WASMAnyrefObjectRef
|
||||
wasm_anyref_obj_new(struct WASMExecEnv *exec_env, const void *host_obj);
|
||||
|
||||
/* Implementation of opcode extern.internalize */
|
||||
WASMObjectRef
|
||||
wasm_externref_obj_to_internal_obj(const WASMExternrefObjectRef externref_obj);
|
||||
|
||||
/* Implementation of opcode extern.externalize */
|
||||
WASMExternrefObjectRef
|
||||
wasm_internal_obj_to_externref_obj(struct WASMExecEnv *exec_env,
|
||||
const WASMObjectRef internal_obj);
|
||||
|
||||
const void *
|
||||
wasm_anyref_obj_get_value(const WASMAnyrefObjectRef anyref_obj);
|
||||
|
||||
const void *
|
||||
wasm_externref_obj_get_value(const WASMExternrefObjectRef externref_obj);
|
||||
|
||||
WASMI31ObjectRef
|
||||
wasm_i31_obj_new(uint32 i31_value);
|
||||
|
||||
uint32
|
||||
wasm_i31_obj_get_value(WASMI31ObjectRef i31_obj, bool sign_extend);
|
||||
|
||||
bool
|
||||
wasm_obj_is_i31_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_externref_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_anyref_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_i31_externref_or_anyref_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_struct_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_array_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_func_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_internal_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_eq_obj(WASMObjectRef obj);
|
||||
|
||||
inline static bool
|
||||
wasm_obj_is_null_obj(WASMObjectRef obj)
|
||||
{
|
||||
return obj == NULL_REF ? true : false;
|
||||
}
|
||||
|
||||
inline static bool
|
||||
wasm_obj_is_created_from_heap(WASMObjectRef obj)
|
||||
{
|
||||
if (obj == NULL || (((uintptr_t)obj) & 1))
|
||||
/* null object or i31 object */
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_obj_is_instance_of(WASMObjectRef obj, uint32 type_idx, WASMType **types,
|
||||
uint32 type_count);
|
||||
|
||||
bool
|
||||
wasm_obj_is_type_of(WASMObjectRef obj, int32 heap_type);
|
||||
|
||||
bool
|
||||
wasm_obj_equal(WASMObjectRef obj1, WASMObjectRef obj2);
|
||||
|
||||
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);
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
WASMStringrefObjectRef
|
||||
wasm_stringref_obj_new(struct WASMExecEnv *exec_env, const void *str_obj);
|
||||
|
||||
WASMStringviewWTF8ObjectRef
|
||||
wasm_stringview_wtf8_obj_new(struct WASMExecEnv *exec_env, const void *str_obj);
|
||||
|
||||
WASMStringviewWTF16ObjectRef
|
||||
wasm_stringview_wtf16_obj_new(struct WASMExecEnv *exec_env,
|
||||
const void *str_obj);
|
||||
|
||||
WASMStringviewIterObjectRef
|
||||
wasm_stringview_iter_obj_new(struct WASMExecEnv *exec_env, const void *str_obj,
|
||||
int32 pos);
|
||||
|
||||
const void *
|
||||
wasm_stringref_obj_get_value(WASMStringrefObjectRef stringref_obj);
|
||||
|
||||
const void *
|
||||
wasm_stringview_wtf8_obj_get_value(
|
||||
WASMStringviewWTF8ObjectRef stringview_wtf8_obj);
|
||||
|
||||
const void *
|
||||
wasm_stringview_wtf16_obj_get_value(
|
||||
WASMStringviewWTF16ObjectRef stringview_wtf16_obj);
|
||||
|
||||
const void *
|
||||
wasm_stringview_iter_obj_get_value(
|
||||
WASMStringviewIterObjectRef stringview_iter_obj);
|
||||
|
||||
int32
|
||||
wasm_stringview_iter_obj_get_pos(
|
||||
WASMStringviewIterObjectRef stringview_iter_obj);
|
||||
|
||||
void
|
||||
wasm_stringview_iter_obj_update_pos(
|
||||
WASMStringviewIterObjectRef stringview_iter_obj, int32 pos);
|
||||
|
||||
bool
|
||||
wasm_obj_is_stringref_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_stringview_wtf8_obj(WASMObjectRef obj);
|
||||
|
||||
bool
|
||||
wasm_obj_is_stringview_wtf16_obj(WASMObjectRef obj);
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _GC_OBJECT_H_ */
|
||||
1253
core/iwasm/common/gc/gc_type.c
Normal file
1253
core/iwasm/common/gc/gc_type.c
Normal file
File diff suppressed because it is too large
Load Diff
378
core/iwasm/common/gc/gc_type.h
Normal file
378
core/iwasm/common/gc/gc_type.h
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _GC_TYPE_H_
|
||||
#define _GC_TYPE_H_
|
||||
|
||||
#include "../interpreter/wasm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_dump_value_type(uint8 type, const WASMRefType *ref_type);
|
||||
|
||||
void
|
||||
wasm_dump_func_type(const WASMFuncType *type);
|
||||
|
||||
void
|
||||
wasm_dump_struct_type(const WASMStructType *type);
|
||||
|
||||
void
|
||||
wasm_dump_array_type(const WASMArrayType *type);
|
||||
|
||||
/* Whether a group of value types is subtype of
|
||||
another group of value types */
|
||||
bool
|
||||
wasm_value_types_is_subtype_of(const uint8 *types1,
|
||||
const WASMRefTypeMap *ref_type_maps1,
|
||||
const uint8 *types2,
|
||||
const WASMRefTypeMap *ref_type_maps2,
|
||||
uint32 value_type_count,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Operations of function type */
|
||||
|
||||
/* Whether two function types are equal */
|
||||
bool
|
||||
wasm_func_type_equal(const WASMFuncType *type1, const WASMFuncType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Whether func type1 is subtype of func type2 */
|
||||
bool
|
||||
wasm_func_type_is_subtype_of(const WASMFuncType *type1,
|
||||
const WASMFuncType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Whether func type1's result types are subtype of
|
||||
func type2's result types */
|
||||
bool
|
||||
wasm_func_type_result_is_subtype_of(const WASMFuncType *type,
|
||||
const WASMFuncType *type2,
|
||||
const WASMTypePtr *types,
|
||||
uint32 type_count);
|
||||
|
||||
/* Operations of struct type */
|
||||
|
||||
/* Whether two struct types are equal */
|
||||
bool
|
||||
wasm_struct_type_equal(const WASMStructType *type1, const WASMStructType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Whether struct type1 is subtype of struct type2 */
|
||||
bool
|
||||
wasm_struct_type_is_subtype_of(const WASMStructType *type1,
|
||||
const WASMStructType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Operations of array type */
|
||||
|
||||
/* Whether two array types are equal */
|
||||
bool
|
||||
wasm_array_type_equal(const WASMArrayType *type1, const WASMArrayType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Whether array type1 is subtype of array type2 */
|
||||
bool
|
||||
wasm_array_type_is_subtype_of(const WASMArrayType *type1,
|
||||
const WASMArrayType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Operations of wasm type */
|
||||
|
||||
/* Whether a wasm type is a function type */
|
||||
inline static bool
|
||||
wasm_type_is_func_type(const WASMType *type)
|
||||
{
|
||||
return type->type_flag == WASM_TYPE_FUNC ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a wasm type is a struct type */
|
||||
inline static bool
|
||||
wasm_type_is_struct_type(const WASMType *type)
|
||||
{
|
||||
return type->type_flag == WASM_TYPE_STRUCT ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a wasm type is an array type */
|
||||
inline static bool
|
||||
wasm_type_is_array_type(const WASMType *type)
|
||||
{
|
||||
return type->type_flag == WASM_TYPE_ARRAY ? true : false;
|
||||
}
|
||||
|
||||
/* Whether two wasm types are equal */
|
||||
bool
|
||||
wasm_type_equal(const WASMType *type1, const WASMType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Whether wasm type1 is subtype of wasm type2 */
|
||||
bool
|
||||
wasm_type_is_subtype_of(const WASMType *type1, const WASMType *type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Operations of reference type */
|
||||
|
||||
/* Whether a value type is a reference type */
|
||||
inline static bool
|
||||
wasm_is_type_reftype(uint8 type)
|
||||
{
|
||||
return ((type >= (uint8)REF_TYPE_ARRAYREF
|
||||
&& type <= (uint8)REF_TYPE_NULLFUNCREF)
|
||||
|| (type >= (uint8)REF_TYPE_HT_NULLABLE
|
||||
&& type <= (uint8)REF_TYPE_HT_NON_NULLABLE)
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|| (type >= (uint8)REF_TYPE_STRINGVIEWWTF8
|
||||
&& type <= (uint8)REF_TYPE_STRINGREF)
|
||||
|| (type >= (uint8)REF_TYPE_STRINGVIEWITER
|
||||
&& type <= (uint8)REF_TYPE_STRINGVIEWWTF16)
|
||||
#endif
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
/* Whether a negative value is a valid heap type */
|
||||
inline static bool
|
||||
wasm_is_valid_heap_type(int32 heap_type)
|
||||
{
|
||||
return ((heap_type <= HEAP_TYPE_NOFUNC && heap_type >= HEAP_TYPE_ARRAY)
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|| heap_type == HEAP_TYPE_STRINGREF
|
||||
|| heap_type == HEAP_TYPE_STRINGVIEWWTF8
|
||||
|| heap_type == HEAP_TYPE_STRINGVIEWWTF16
|
||||
|| heap_type == HEAP_TYPE_STRINGVIEWITER
|
||||
#endif
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
/* Whether a value type is multi-byte type, or, requires ref type map
|
||||
to retrieve extra info */
|
||||
inline static bool
|
||||
wasm_is_type_multi_byte_type(uint8 type)
|
||||
{
|
||||
return (type == (uint8)REF_TYPE_HT_NULLABLE
|
||||
|| type == (uint8)REF_TYPE_HT_NON_NULLABLE)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a funcref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_funcref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_FUNCREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is an externref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_externref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_EXTERNREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is an anyref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_anyref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_ANYREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is an eqref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_eqref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_EQREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a (ref null ht) type */
|
||||
inline static bool
|
||||
wasm_is_reftype_htref_nullable(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_HT_NULLABLE ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a (ref ht) type */
|
||||
inline static bool
|
||||
wasm_is_reftype_htref_non_nullable(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_HT_NON_NULLABLE ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is an i31ref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_i31ref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_I31REF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a structref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_structref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_STRUCTREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is an arrayref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_arrayref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_ARRAYREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a nullref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_nullref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_NULLREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a nullfuncref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_nullfuncref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_NULLFUNCREF ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a reference type is a nullexternref type */
|
||||
inline static bool
|
||||
wasm_is_reftype_nullexternref(uint8 type)
|
||||
{
|
||||
return type == (uint8)REF_TYPE_NULLEXTERNREF ? true : false;
|
||||
}
|
||||
|
||||
/* Return the size of a reference type */
|
||||
uint32
|
||||
wasm_reftype_size(uint8 type);
|
||||
|
||||
/* Return the actual WASMRefType struct size required of a reference type */
|
||||
uint32
|
||||
wasm_reftype_struct_size(const WASMRefType *ref_type);
|
||||
|
||||
/* Operations of ref heap type */
|
||||
|
||||
/* Whether a ref heap type is (type i), i : typeidx, >= 0 */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_typeidx(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type >= 0 ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a ref heap type is a common type: func/any/eq/i31/data,
|
||||
not (type i) or (rtt n i) or (rtt i) */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_common(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ((ref_heap_type->heap_type >= (int32)HEAP_TYPE_ARRAY
|
||||
&& ref_heap_type->heap_type <= (int32)HEAP_TYPE_NONE)
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|| (ref_heap_type->heap_type >= (int32)HEAP_TYPE_STRINGVIEWITER
|
||||
&& ref_heap_type->heap_type <= (int32)HEAP_TYPE_I31)
|
||||
#endif
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
/* Whether a ref heap type is a func type */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_func(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type == (int32)HEAP_TYPE_FUNC ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a ref heap type is an any type */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_any(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type == (int32)HEAP_TYPE_ANY ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a ref heap type is an eq type */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_eq(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type == (int32)HEAP_TYPE_EQ ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a ref heap type is an i31 type */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_i31(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type == (int32)HEAP_TYPE_I31 ? true : false;
|
||||
}
|
||||
|
||||
/* Whether a ref heap type is an array type */
|
||||
inline static bool
|
||||
wasm_is_refheaptype_array(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type == (int32)HEAP_TYPE_ARRAY ? true : false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
inline static bool
|
||||
wasm_is_refheaptype_stringrefs(const RefHeapType_Common *ref_heap_type)
|
||||
{
|
||||
return ref_heap_type->heap_type <= (int32)HEAP_TYPE_STRINGREF
|
||||
&& ref_heap_type->heap_type >= HEAP_TYPE_STRINGVIEWITER
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Whether two ref heap types are equal */
|
||||
bool
|
||||
wasm_refheaptype_equal(const RefHeapType_Common *ref_heap_type1,
|
||||
const RefHeapType_Common *ref_heap_type2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Whether two ref types are equal */
|
||||
bool
|
||||
wasm_reftype_equal(uint8 type1, const WASMRefType *reftype1, uint8 type2,
|
||||
const WASMRefType *reftype2, const WASMTypePtr *types,
|
||||
uint32 type_count);
|
||||
|
||||
/* Whether ref type1 is subtype of ref type2 */
|
||||
bool
|
||||
wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *reftype1,
|
||||
uint8 type2, const WASMRefType *reftype2,
|
||||
const WASMTypePtr *types, uint32 type_count);
|
||||
|
||||
/* Returns a new reference type which is a duplication of ref_type,
|
||||
the caller should use wasm_runtime_free() to free the new ref type */
|
||||
WASMRefType *
|
||||
wasm_reftype_dup(const WASMRefType *ref_type);
|
||||
|
||||
/* Set fields of RefHeapType_TypeIdx */
|
||||
void
|
||||
wasm_set_refheaptype_typeidx(RefHeapType_TypeIdx *ref_ht_typeidx, bool nullable,
|
||||
int32 type_idx);
|
||||
|
||||
/* Set fields of RefHeapType_Common */
|
||||
void
|
||||
wasm_set_refheaptype_common(RefHeapType_Common *ref_ht_common, bool nullable,
|
||||
int32 heap_type);
|
||||
|
||||
/* Find the related reftype in reftype map array with index */
|
||||
WASMRefType *
|
||||
wasm_reftype_map_find(WASMRefTypeMap *ref_type_maps, uint32 ref_type_map_count,
|
||||
uint32 index_to_find);
|
||||
|
||||
/* Create a new hash set of reference type */
|
||||
HashMap *
|
||||
wasm_reftype_set_create(uint32 size);
|
||||
|
||||
/* Insert a reference type into the hash set */
|
||||
WASMRefType *
|
||||
wasm_reftype_set_insert(HashMap *ref_type_set, const WASMRefType *ref_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _GC_TYPE_H_ */
|
||||
36
core/iwasm/common/gc/iwasm_gc.cmake
Normal file
36
core/iwasm/common/gc/iwasm_gc.cmake
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (IWASM_GC_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions (-DWASM_ENABLE_GC=1)
|
||||
|
||||
if (WAMR_TEST_GC EQUAL 1)
|
||||
add_definitions (-DGC_MANUALLY=1 -DGC_IN_EVERY_ALLOCATION=1)
|
||||
endif ()
|
||||
|
||||
include_directories (${IWASM_GC_DIR})
|
||||
|
||||
file (GLOB source_all ${IWASM_GC_DIR}/*.c)
|
||||
|
||||
set (IWASM_GC_SOURCE ${source_all})
|
||||
|
||||
if (WAMR_BUILD_STRINGREF EQUAL 1)
|
||||
set (IWASM_STRINGREF_DIR ${CMAKE_CURRENT_LIST_DIR}/stringref)
|
||||
|
||||
add_definitions (-DWASM_ENABLE_STRINGREF=1)
|
||||
|
||||
include_directories (${IWASM_STRINGREF_DIR})
|
||||
|
||||
if (NOT DEFINED WAMR_STRINGREF_IMPL_SOURCE)
|
||||
message(FATAL_ERROR "stringref feature enabled, but WAMR_STRINGREF_IMPL_SOURCE not set" )
|
||||
else ()
|
||||
if (${WAMR_STRINGREF_IMPL_SOURCE} STREQUAL "STUB")
|
||||
set (IWASM_STRINGREF_SOURCE ${IWASM_STRINGREF_DIR}/stringref_stub.c)
|
||||
else()
|
||||
set (IWASM_STRINGREF_SOURCE ${WAMR_STRINGREF_IMPL_SOURCE})
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
set (IWASM_GC_SOURCE ${IWASM_GC_SOURCE} ${IWASM_STRINGREF_SOURCE})
|
||||
endif ()
|
||||
121
core/iwasm/common/gc/stringref/string_object.h
Normal file
121
core/iwasm/common/gc/stringref/string_object.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _STRING_OBJECT_H_
|
||||
#define _STRING_OBJECT_H_
|
||||
|
||||
#include "wasm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum EncodingFlag {
|
||||
UTF8,
|
||||
WTF8,
|
||||
WTF16,
|
||||
LOSSY_UTF8,
|
||||
} EncodingFlag;
|
||||
|
||||
typedef enum StringViewType {
|
||||
STRING_VIEW_WTF8,
|
||||
STRING_VIEW_WTF16,
|
||||
STRING_VIEW_ITER,
|
||||
} StringViewType;
|
||||
|
||||
typedef enum ErrorCode {
|
||||
Insufficient_Space = -3,
|
||||
Encode_Fail = -2,
|
||||
Isolated_Surrogate = -1,
|
||||
} ErrorCode;
|
||||
|
||||
/******************* gc finalizer *****************/
|
||||
void
|
||||
wasm_string_destroy(WASMString str_obj);
|
||||
|
||||
/******************* opcode functions *****************/
|
||||
|
||||
/* string.const */
|
||||
WASMString
|
||||
wasm_string_new_const(const char *content, uint32 length);
|
||||
|
||||
/* string.new_xx8/new_wtf16 */
|
||||
/* string.new_xx8_array */
|
||||
/* string.new_wtf16_array */
|
||||
WASMString
|
||||
wasm_string_new_with_encoding(void *addr, uint32 count, EncodingFlag flag);
|
||||
|
||||
/* string.measure */
|
||||
int32
|
||||
wasm_string_measure(WASMString str_obj, EncodingFlag flag);
|
||||
|
||||
/* stringview_wtf16.length */
|
||||
int32
|
||||
wasm_string_wtf16_get_length(WASMString str_obj);
|
||||
|
||||
/* string.encode_xx8 */
|
||||
/* string.encode_wtf16 */
|
||||
/* stringview_wtf8.encode_xx */
|
||||
/* stringview_wtf16.encode */
|
||||
/* string.encode_xx8_array */
|
||||
/* string.encode_wtf16_array */
|
||||
int32
|
||||
wasm_string_encode(WASMString str_obj, uint32 pos, uint32 count, void *addr,
|
||||
uint32 *next_pos, EncodingFlag flag);
|
||||
|
||||
/* string.concat */
|
||||
WASMString
|
||||
wasm_string_concat(WASMString str_obj1, WASMString str_obj2);
|
||||
|
||||
/* string.eq */
|
||||
int32
|
||||
wasm_string_eq(WASMString str_obj1, WASMString str_obj2);
|
||||
|
||||
/* string.is_usv_sequence */
|
||||
int32
|
||||
wasm_string_is_usv_sequence(WASMString str_obj);
|
||||
|
||||
/* string.as_wtf8 */
|
||||
/* string.as_wtf16 */
|
||||
/* string.as_iter */
|
||||
WASMString
|
||||
wasm_string_create_view(WASMString str_obj, StringViewType type);
|
||||
|
||||
/* stringview_wtf8.advance */
|
||||
/* stringview_iter.advance */
|
||||
int32
|
||||
wasm_string_advance(WASMString str_obj, uint32 pos, uint32 count,
|
||||
uint32 *target_pos);
|
||||
|
||||
/* stringview_wtf8.slice */
|
||||
/* stringview_wtf16.slice */
|
||||
/* stringview_iter.slice */
|
||||
WASMString
|
||||
wasm_string_slice(WASMString str_obj, uint32 start, uint32 end,
|
||||
StringViewType type);
|
||||
|
||||
/* stringview_wtf16.get_codeunit */
|
||||
int16
|
||||
wasm_string_get_wtf16_codeunit(WASMString str_obj, int32 pos);
|
||||
|
||||
/* stringview_iter.next */
|
||||
uint32
|
||||
wasm_string_next_codepoint(WASMString str_obj, uint32 pos);
|
||||
|
||||
/* stringview_iter.rewind */
|
||||
uint32
|
||||
wasm_string_rewind(WASMString str_obj, uint32 pos, uint32 count,
|
||||
uint32 *target_pos);
|
||||
|
||||
/******************* application functions *****************/
|
||||
|
||||
void
|
||||
wasm_string_dump(WASMString str_obj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _STRING_OBJECT_H_ */
|
||||
136
core/iwasm/common/gc/stringref/stringref_stub.c
Normal file
136
core/iwasm/common/gc/stringref/stringref_stub.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/* This file is the stub for stringref implementation, only used for wamrc
|
||||
* compiler. The runtime embedder SHOULD NOT use this file */
|
||||
|
||||
#include "string_object.h"
|
||||
|
||||
/******************* gc finalizer *****************/
|
||||
void
|
||||
wasm_string_destroy(WASMString str_obj)
|
||||
{}
|
||||
|
||||
/******************* opcode functions *****************/
|
||||
|
||||
/* string.const */
|
||||
WASMString
|
||||
wasm_string_new_const(const char *str, uint32 length)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* string.new_xx8 */
|
||||
/* string.new_wtf16 */
|
||||
/* string.new_xx8_array */
|
||||
/* string.new_wtf16_array */
|
||||
WASMString
|
||||
wasm_string_new_with_encoding(void *addr, uint32 count, EncodingFlag flag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* string.measure */
|
||||
/* stringview_wtf16.length */
|
||||
int32
|
||||
wasm_string_measure(WASMString str_obj, EncodingFlag flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* stringview_wtf16.length */
|
||||
int32
|
||||
wasm_string_wtf16_get_length(WASMString str_obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* string.encode_xx8 */
|
||||
/* string.encode_wtf16 */
|
||||
/* stringview_wtf8.encode_xx */
|
||||
/* stringview_wtf16.encode */
|
||||
/* string.encode_xx8_array */
|
||||
/* string.encode_wtf16_array */
|
||||
int32
|
||||
wasm_string_encode(WASMString str_obj, uint32 pos, uint32 count, void *addr,
|
||||
uint32 *next_pos, EncodingFlag flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* string.concat */
|
||||
WASMString
|
||||
wasm_string_concat(WASMString str_obj1, WASMString str_obj2)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* string.eq */
|
||||
int32
|
||||
wasm_string_eq(WASMString str_obj1, WASMString str_obj2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* string.is_usv_sequence */
|
||||
int32
|
||||
wasm_string_is_usv_sequence(WASMString str_obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* string.as_wtf8 */
|
||||
/* string.as_wtf16 */
|
||||
/* string.as_iter */
|
||||
WASMString
|
||||
wasm_string_create_view(WASMString str_obj, StringViewType type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* stringview_wtf8.advance */
|
||||
/* stringview_iter.advance */
|
||||
int32
|
||||
wasm_string_advance(WASMString str_obj, uint32 pos, uint32 count,
|
||||
uint32 *consumed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* stringview_wtf8.slice */
|
||||
/* stringview_wtf16.slice */
|
||||
/* stringview_iter.slice */
|
||||
WASMString
|
||||
wasm_string_slice(WASMString str_obj, uint32 start, uint32 end,
|
||||
StringViewType type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* stringview_wtf16.get_codeunit */
|
||||
int16
|
||||
wasm_string_get_wtf16_codeunit(WASMString str_obj, int32 pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* stringview_iter.next */
|
||||
uint32
|
||||
wasm_string_next_codepoint(WASMString str_obj, uint32 pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* stringview_iter.rewind */
|
||||
uint32
|
||||
wasm_string_rewind(WASMString str_obj, uint32 pos, uint32 count,
|
||||
uint32 *consumed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_string_dump(WASMString str_obj)
|
||||
{}
|
||||
Reference in New Issue
Block a user