mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-07-16 17:28:31 +00:00
Support stringref proposal (#2651)
This PR implements the WebAssembly stringref proposal: https://github.com/WebAssembly/stringref It adds cmake variable `WAMR_BUILD_STRINGREF` to build the feature, which will enable GC automatically. The stringref contains two parts: - `part 1`: add new ref types in WasmGC, add opcode processing in loader and interpreter - `part 2`: add a library for string representation/encoding/decoding and so on To reduce the code size introduced to WAMR, this PR only includes `part 1`, `part 2` can be provided by embedder, they may use their own implementation, e.g., Wasmnizer-ts uses JSString from QuickJS to implement stringref: https://github.com/intel/Wasmnizer-ts/blob/main/runtime-library/stringref/stringref_qjs.c We will submit another PR of `part 2` and make it as a sample rather than WAMR core part. Signed-off-by: Su Yihan <yihan.su@intel.com> Co-authored-by: Xu Jun <jun1.xu@intel.com>
This commit is contained in:
parent
06d46b0fb6
commit
2f45f12cd7
|
@ -335,6 +335,14 @@ if (WAMR_BUILD_GC_BINARYEN EQUAL 1)
|
|||
add_definitions (-DWASM_ENABLE_GC_BINARYEN=1)
|
||||
message (" GC binaryen compatible mode on")
|
||||
endif ()
|
||||
if (WAMR_BUILD_STRINGREF EQUAL 1)
|
||||
message (" Stringref enabled")
|
||||
if (NOT DEFINED WAMR_STRINGREF_IMPL_SOURCE)
|
||||
message (" Using WAMR builtin implementation for stringref")
|
||||
else ()
|
||||
message (" Using custom implementation for stringref")
|
||||
endif()
|
||||
endif ()
|
||||
if (WAMR_BUILD_PERF_PROFILING EQUAL 1 OR
|
||||
WAMR_BUILD_DUMP_CALL_STACK EQUAL 1 OR
|
||||
WAMR_BUILD_GC EQUAL 1 OR WAMR_BUILD_GC_BINARYEN EQUAL 1)
|
||||
|
|
|
@ -78,6 +78,10 @@ if (WAMR_BUILD_AOT EQUAL 1)
|
|||
include (${IWASM_DIR}/aot/iwasm_aot.cmake)
|
||||
endif ()
|
||||
|
||||
if (WAMR_BUILD_STRINGREF EQUAL 1)
|
||||
set (WAMR_BUILD_GC 1)
|
||||
endif ()
|
||||
|
||||
if (WAMR_BUILD_GC_BINARYEN EQUAL 1)
|
||||
set (WAMR_BUILD_GC 1)
|
||||
endif ()
|
||||
|
|
|
@ -467,6 +467,10 @@
|
|||
#define WASM_ENABLE_GC_BINARYEN 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_STRINGREF
|
||||
#define WASM_ENABLE_STRINGREF 0
|
||||
#endif
|
||||
|
||||
#ifndef GC_REFTYPE_MAP_SIZE_DEFAULT
|
||||
#define GC_REFTYPE_MAP_SIZE_DEFAULT 64
|
||||
#endif
|
||||
|
|
|
@ -19,14 +19,25 @@ wasm_ref_type_normalize(wasm_ref_type_t *ref_type)
|
|||
int32 heap_type = ref_type->heap_type;
|
||||
|
||||
if (!((value_type >= VALUE_TYPE_I16 && value_type <= VALUE_TYPE_I32)
|
||||
|| (value_type >= VALUE_TYPE_NULLREF
|
||||
|| (
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
value_type >= VALUE_TYPE_STRINGVIEWITER
|
||||
#else
|
||||
value_type >= VALUE_TYPE_NULLREF
|
||||
#endif
|
||||
&& value_type <= VALUE_TYPE_FUNCREF))) {
|
||||
return false;
|
||||
}
|
||||
if (value_type == VALUE_TYPE_HT_NULLABLE_REF
|
||||
|| value_type == VALUE_TYPE_HT_NON_NULLABLE_REF) {
|
||||
if (heap_type < 0
|
||||
&& (heap_type < HEAP_TYPE_NONE || heap_type > HEAP_TYPE_FUNC)) {
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
&& (heap_type < HEAP_TYPE_STRINGVIEWITER
|
||||
|| heap_type > HEAP_TYPE_FUNC)
|
||||
#else
|
||||
&& (heap_type < HEAP_TYPE_NONE || heap_type > HEAP_TYPE_FUNC)
|
||||
#endif
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +46,20 @@ wasm_ref_type_normalize(wasm_ref_type_t *ref_type)
|
|||
ref_type->nullable = false;
|
||||
}
|
||||
else {
|
||||
if (heap_type >= HEAP_TYPE_NONE && heap_type <= HEAP_TYPE_FUNC) {
|
||||
if (
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
heap_type >= HEAP_TYPE_STRINGVIEWITER && heap_type <= HEAP_TYPE_FUNC
|
||||
#else
|
||||
heap_type >= HEAP_TYPE_NONE && heap_type <= HEAP_TYPE_FUNC
|
||||
#endif
|
||||
) {
|
||||
ref_type->value_type =
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
(uint8)(REF_TYPE_STRINGVIEWITER + heap_type
|
||||
- HEAP_TYPE_STRINGVIEWITER);
|
||||
#else
|
||||
(uint8)(REF_TYPE_NULLREF + heap_type - HEAP_TYPE_NONE);
|
||||
#endif
|
||||
ref_type->nullable = false;
|
||||
ref_type->heap_type = 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#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,
|
||||
|
@ -653,6 +656,14 @@ wasm_obj_is_type_of(WASMObjectRef obj, int32 heap_type)
|
|||
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:
|
||||
|
@ -698,6 +709,18 @@ wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
|
|||
*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;
|
||||
|
@ -750,3 +773,270 @@ 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;
|
||||
/* TODO: implement stringref for AoT */
|
||||
/*
|
||||
rtt_type = aot_stringref_rtt_type_new(WASM_TYPE_STRINGREF,
|
||||
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 */
|
||||
|
|
|
@ -102,6 +102,28 @@ typedef struct WASMFuncObject {
|
|||
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
|
||||
|
@ -284,6 +306,54 @@ 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
|
||||
|
|
|
@ -616,7 +616,12 @@ wasm_reftype_size(uint8 type)
|
|||
return 4;
|
||||
else if (type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)
|
||||
return 8;
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
else if (type >= (uint8)REF_TYPE_STRINGVIEWITER
|
||||
&& type <= (uint8)REF_TYPE_FUNCREF)
|
||||
#else
|
||||
else if (type >= (uint8)REF_TYPE_NULLREF && type <= (uint8)REF_TYPE_FUNCREF)
|
||||
#endif
|
||||
return sizeof(uintptr_t);
|
||||
else if (type == PACKED_TYPE_I8)
|
||||
return 1;
|
||||
|
@ -745,13 +750,26 @@ wasm_is_reftype_supers_of_extern(uint8 type)
|
|||
return (type == REF_TYPE_EXTERNREF) ? true : false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
inline static bool
|
||||
wasm_is_reftype_supers_of_string(uint8 type)
|
||||
{
|
||||
return (type == REF_TYPE_STRINGREF || type == REF_TYPE_ANYREF) ? true
|
||||
: false;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline static bool
|
||||
wasm_is_reftype_supers_of_none(uint8 type, const WASMRefType *ref_type,
|
||||
const WASMTypePtr *types, uint32 type_count)
|
||||
{
|
||||
if (type == REF_TYPE_NULLREF || type == REF_TYPE_I31REF
|
||||
|| type == REF_TYPE_STRUCTREF || type == REF_TYPE_ARRAYREF
|
||||
|| wasm_is_reftype_supers_of_eq(type))
|
||||
|| wasm_is_reftype_supers_of_eq(type)
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|| type == REF_TYPE_STRINGREF
|
||||
#endif
|
||||
)
|
||||
return true;
|
||||
|
||||
if (type == REF_TYPE_HT_NULLABLE && ref_type != NULL
|
||||
|
@ -875,6 +893,20 @@ wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
|
|||
else if (type1 == REF_TYPE_NULLEXTERNREF) {
|
||||
return wasm_is_reftype_supers_of_noextern(type2);
|
||||
}
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
else if (type1 == REF_TYPE_STRINGREF) {
|
||||
return wasm_is_reftype_supers_of_string(type2);
|
||||
}
|
||||
else if (type1 == REF_TYPE_STRINGVIEWWTF8) {
|
||||
return type2 == REF_TYPE_STRINGVIEWWTF8 ? true : false;
|
||||
}
|
||||
else if (type1 == REF_TYPE_STRINGVIEWWTF16) {
|
||||
return type2 == REF_TYPE_STRINGVIEWWTF16 ? true : false;
|
||||
}
|
||||
else if (type1 == REF_TYPE_STRINGVIEWITER) {
|
||||
return type2 == REF_TYPE_STRINGVIEWITER ? true : false;
|
||||
}
|
||||
#endif
|
||||
else if (type1 == REF_TYPE_HT_NULLABLE) {
|
||||
if (wasm_is_refheaptype_typeidx(&ref_type1->ref_ht_common)) {
|
||||
/* reftype1 is (ref null $t) */
|
||||
|
@ -895,6 +927,23 @@ wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
|
|||
else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
|
||||
== WASM_TYPE_FUNC)
|
||||
return wasm_is_reftype_supers_of_func(type2);
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
|
||||
== WASM_TYPE_STRINGREF)
|
||||
return wasm_is_reftype_supers_of_string(type2);
|
||||
else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
|
||||
== WASM_TYPE_STRINGVIEWWTF8) {
|
||||
return type2 == REF_TYPE_STRINGVIEWWTF8 ? true : false;
|
||||
}
|
||||
else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
|
||||
== WASM_TYPE_STRINGVIEWWTF16) {
|
||||
return type2 == REF_TYPE_STRINGVIEWWTF16 ? true : false;
|
||||
}
|
||||
else if (types[ref_type1->ref_ht_typeidx.type_idx]->type_flag
|
||||
== WASM_TYPE_STRINGVIEWITER) {
|
||||
return type2 == REF_TYPE_STRINGVIEWITER ? true : false;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -1019,6 +1068,20 @@ wasm_reftype_is_subtype_of(uint8 type1, const WASMRefType *ref_type1,
|
|||
/* (ref func) <: [funcref] */
|
||||
return wasm_is_reftype_supers_of_func(type2);
|
||||
}
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
else if (heap_type == HEAP_TYPE_STRINGREF) {
|
||||
return wasm_is_reftype_supers_of_string(type2);
|
||||
}
|
||||
else if (heap_type == HEAP_TYPE_STRINGVIEWWTF8) {
|
||||
return type2 == REF_TYPE_STRINGVIEWWTF8 ? true : false;
|
||||
}
|
||||
else if (heap_type == HEAP_TYPE_STRINGVIEWWTF16) {
|
||||
return type2 == REF_TYPE_STRINGVIEWWTF16 ? true : false;
|
||||
}
|
||||
else if (heap_type == HEAP_TYPE_STRINGVIEWITER) {
|
||||
return type2 == REF_TYPE_STRINGVIEWITER ? true : false;
|
||||
}
|
||||
#endif
|
||||
else if (heap_type == HEAP_TYPE_NONE) {
|
||||
/* (ref none) */
|
||||
/* TODO */
|
||||
|
|
|
@ -120,7 +120,13 @@ wasm_type_is_subtype_of(const WASMType *type1, const WASMType *type2,
|
|||
inline static bool
|
||||
wasm_is_type_reftype(uint8 type)
|
||||
{
|
||||
return (type >= (uint8)REF_TYPE_NULLREF && type <= (uint8)REF_TYPE_FUNCREF)
|
||||
return (
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
type >= (uint8)REF_TYPE_STRINGVIEWITER
|
||||
#else
|
||||
type >= (uint8)REF_TYPE_NULLREF
|
||||
#endif
|
||||
&& type <= (uint8)REF_TYPE_FUNCREF)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
@ -244,8 +250,14 @@ wasm_is_refheaptype_common(const RefHeapType_Common *ref_heap_type)
|
|||
{
|
||||
return ((ref_heap_type->heap_type >= (int32)HEAP_TYPE_EQ
|
||||
&& ref_heap_type->heap_type <= (int32)HEAP_TYPE_FUNC)
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|| (ref_heap_type->heap_type >= (int32)HEAP_TYPE_STRINGVIEWITER
|
||||
&& ref_heap_type->heap_type <= (int32)HEAP_TYPE_I31)
|
||||
#else
|
||||
|| (ref_heap_type->heap_type >= (int32)HEAP_TYPE_NONE
|
||||
&& ref_heap_type->heap_type <= (int32)HEAP_TYPE_I31))
|
||||
&& ref_heap_type->heap_type <= (int32)HEAP_TYPE_I31)
|
||||
#endif
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
@ -285,6 +297,17 @@ 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,
|
||||
|
|
|
@ -11,7 +11,22 @@ endif ()
|
|||
|
||||
include_directories (${IWASM_GC_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${IWASM_GC_DIR}/*.c)
|
||||
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 ()
|
||||
set (IWASM_STRINGREF_SOURCE ${WAMR_STRINGREF_IMPL_SOURCE})
|
||||
endif ()
|
||||
|
||||
set (IWASM_GC_SOURCE ${IWASM_GC_SOURCE} ${IWASM_STRINGREF_SOURCE})
|
||||
endif ()
|
||||
|
|
113
core/iwasm/common/gc/stringref/string_object.h
Normal file
113
core/iwasm/common/gc/stringref/string_object.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
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 *str);
|
||||
|
||||
/* 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);
|
||||
|
||||
#endif /* end of _STRING_OBJECT_H_ */
|
|
@ -15,6 +15,9 @@
|
|||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#include "gc/gc_object.h"
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
#include "string_object.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void
|
||||
|
@ -718,6 +721,18 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
|||
}
|
||||
else if (wasm_obj_is_func_obj(gc_obj))
|
||||
os_printf("ref.func");
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
else if (wasm_obj_is_stringref_obj(gc_obj)
|
||||
|| wasm_obj_is_stringview_wtf8_obj(gc_obj)) {
|
||||
wasm_string_dump(
|
||||
(WASMString)wasm_stringref_obj_get_value(gc_obj));
|
||||
}
|
||||
else if (wasm_obj_is_stringview_wtf16_obj(gc_obj)) {
|
||||
wasm_string_dump(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
gc_obj));
|
||||
}
|
||||
#endif
|
||||
else if (wasm_obj_is_externref_obj(gc_obj)) {
|
||||
WASMObjectRef obj = wasm_externref_obj_to_internal_obj(
|
||||
(WASMExternrefObjectRef)gc_obj);
|
||||
|
|
|
@ -96,7 +96,11 @@ compare_type_with_signautre(uint8 type, const char signature)
|
|||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
if ('r' == signature
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
&& (type >= REF_TYPE_STRINGVIEWITER && type <= REF_TYPE_FUNCREF)
|
||||
#else
|
||||
&& (type >= REF_TYPE_NULLREF && type <= REF_TYPE_FUNCREF)
|
||||
#endif
|
||||
#else
|
||||
&& type == VALUE_TYPE_EXTERNREF
|
||||
#endif
|
||||
|
|
|
@ -3569,6 +3569,12 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
{
|
||||
bh_memcpy_s(argv_dst, sizeof(uintptr_t), argv_src,
|
||||
sizeof(uintptr_t));
|
||||
|
@ -3632,6 +3638,12 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
{
|
||||
bh_memcpy_s(argv_ret, sizeof(uintptr_t), argv1,
|
||||
sizeof(uintptr_t));
|
||||
|
@ -3734,6 +3746,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
|
@ -3892,6 +3910,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
|
@ -4111,6 +4135,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
|
@ -4257,6 +4287,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
|
@ -4357,6 +4393,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
|
@ -4616,6 +4658,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
if (n_ints < MAX_REG_INTS)
|
||||
ints[n_ints++] = *(uint64 *)argv_src;
|
||||
|
@ -4719,6 +4767,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|||
case REF_TYPE_STRUCTREF:
|
||||
case REF_TYPE_ARRAYREF:
|
||||
case REF_TYPE_NULLREF:
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case REF_TYPE_STRINGREF:
|
||||
case REF_TYPE_STRINGVIEWWTF8:
|
||||
case REF_TYPE_STRINGVIEWWTF16:
|
||||
case REF_TYPE_STRINGVIEWITER:
|
||||
#endif
|
||||
#endif
|
||||
PUT_I64_TO_ADDR(argv_ret,
|
||||
invokeNative_Int64(func_ptr, argv1, n_stacks));
|
||||
|
|
|
@ -34,6 +34,10 @@ typedef enum wasm_value_type_enum {
|
|||
VALUE_TYPE_STRUCTREF = 0x67,
|
||||
VALUE_TYPE_ARRAYREF = 0x66,
|
||||
VALUE_TYPE_NULLREF = 0x65,
|
||||
VALUE_TYPE_STRINGREF = 0X64,
|
||||
VALUE_TYPE_STRINGVIEWWTF8 = 0x63,
|
||||
VALUE_TYPE_STRINGVIEWWTF16 = 0x62,
|
||||
VALUE_TYPE_STRINGVIEWITER = 0x61
|
||||
} wasm_value_type_enum;
|
||||
|
||||
typedef int32_t wasm_heap_type_t;
|
||||
|
@ -133,6 +137,7 @@ typedef struct WASMAnyrefObject *wasm_anyref_obj_t;
|
|||
typedef struct WASMStructObject *wasm_struct_obj_t;
|
||||
typedef struct WASMArrayObject *wasm_array_obj_t;
|
||||
typedef struct WASMFuncObject *wasm_func_obj_t;
|
||||
typedef struct WASMStringrefObject *wasm_stringref_obj_t;
|
||||
typedef uintptr_t wasm_i31_obj_t;
|
||||
|
||||
typedef void (*wasm_obj_finalizer_t)(const wasm_obj_t obj, void *data);
|
||||
|
|
|
@ -44,6 +44,10 @@ extern "C" {
|
|||
#define REF_TYPE_STRUCTREF 0x67
|
||||
#define REF_TYPE_ARRAYREF 0x66
|
||||
#define REF_TYPE_NULLREF 0x65
|
||||
#define REF_TYPE_STRINGREF VALUE_TYPE_STRINGREF
|
||||
#define REF_TYPE_STRINGVIEWWTF8 VALUE_TYPE_STRINGVIEWWTF8
|
||||
#define REF_TYPE_STRINGVIEWWTF16 VALUE_TYPE_STRINGVIEWWTF16
|
||||
#define REF_TYPE_STRINGVIEWITER VALUE_TYPE_STRINGVIEWITER
|
||||
|
||||
/* Heap Types */
|
||||
#define HEAP_TYPE_FUNC (-0x10)
|
||||
|
@ -56,6 +60,10 @@ extern "C" {
|
|||
#define HEAP_TYPE_STRUCT (-0x19)
|
||||
#define HEAP_TYPE_ARRAY (-0x1A)
|
||||
#define HEAP_TYPE_NONE (-0x1B)
|
||||
#define HEAP_TYPE_STRINGREF (-0x1C)
|
||||
#define HEAP_TYPE_STRINGVIEWWTF8 (-0x1D)
|
||||
#define HEAP_TYPE_STRINGVIEWWTF16 (-0x1E)
|
||||
#define HEAP_TYPE_STRINGVIEWITER (-0x1F)
|
||||
|
||||
/* Defined Types */
|
||||
#define DEFINED_TYPE_FUNC 0x60
|
||||
|
@ -71,7 +79,7 @@ extern "C" {
|
|||
* Used by loader to represent any type of i32/i64/f32/f64/v128
|
||||
* and ref types, including funcref, externref, anyref, eqref,
|
||||
* (ref null $ht), (ref $ht), i31ref, structref, arrayref,
|
||||
* nullfuncref, nullexternref and nullref
|
||||
* nullfuncref, nullexternref, nullref and stringref
|
||||
*/
|
||||
#define VALUE_TYPE_ANY 0x42
|
||||
/**
|
||||
|
@ -132,6 +140,9 @@ typedef void *table_elem_type_t;
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
#define SECTION_TYPE_DATACOUNT 12
|
||||
#endif
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
#define SECTION_TYPE_STRINGREF 14
|
||||
#endif
|
||||
|
||||
#define SUB_SECTION_TYPE_MODULE 0
|
||||
#define SUB_SECTION_TYPE_FUNC 1
|
||||
|
@ -156,6 +167,13 @@ typedef void *table_elem_type_t;
|
|||
#define WASM_TYPE_STRUCT 1
|
||||
#define WASM_TYPE_ARRAY 2
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
#define WASM_TYPE_STRINGREF 3
|
||||
#define WASM_TYPE_STRINGVIEWWTF8 4
|
||||
#define WASM_TYPE_STRINGVIEWWTF16 5
|
||||
#define WASM_TYPE_STRINGVIEWITER 6
|
||||
#endif
|
||||
|
||||
typedef struct WASMModule WASMModule;
|
||||
typedef struct WASMFunction WASMFunction;
|
||||
typedef struct WASMGlobal WASMGlobal;
|
||||
|
@ -353,6 +371,36 @@ typedef struct WASMArrayType {
|
|||
described with one byte */
|
||||
WASMRefType *elem_ref_type;
|
||||
} WASMArrayType;
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
/* stringref representation, we define it as a void * pointer here, the
|
||||
* stringref implementation can use any structure */
|
||||
/*
|
||||
WasmGC heap
|
||||
+-----------------------+
|
||||
| |
|
||||
| stringref |
|
||||
| +----------+ | external string representation
|
||||
| | host_ptr |--------o------+----->+------------+
|
||||
| +----------+ | | | |
|
||||
| | | +------------+
|
||||
| stringview_wtf8/16 | |
|
||||
| +----------+ | |
|
||||
| | host_ptr |--------o------+
|
||||
| +----------+ | |
|
||||
| | |
|
||||
| stringview_iter | |
|
||||
| +----------+ | |
|
||||
| | host_ptr |--------o------+
|
||||
| +----------+ |
|
||||
| | pos | |
|
||||
| +----------+ |
|
||||
| |
|
||||
+-----------------------+
|
||||
*/
|
||||
typedef void *WASMString;
|
||||
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
|
||||
typedef struct WASMTable {
|
||||
|
@ -680,6 +728,12 @@ struct WASMModule {
|
|||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
/* data count read from datacount section */
|
||||
uint32 data_seg_count1;
|
||||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
uint32 stringref_count;
|
||||
char **string_consts;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint32 import_function_count;
|
||||
|
@ -760,6 +814,15 @@ struct WASMModule {
|
|||
HashMap *ref_type_set;
|
||||
struct WASMRttType **rtt_types;
|
||||
korp_mutex rtt_type_lock;
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
/* special rtts for stringref types
|
||||
- stringref
|
||||
- stringview_wtf8
|
||||
- stringview_wtf16
|
||||
- stringview_iter
|
||||
*/
|
||||
struct WASMRttType *stringref_rtts[4];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_DEBUG_AOT != 0
|
||||
|
@ -970,7 +1033,12 @@ wasm_value_type_size_ex(uint8 value_type, bool gc_enabled)
|
|||
else if (value_type == VALUE_TYPE_V128)
|
||||
return sizeof(int64) * 2;
|
||||
#endif
|
||||
else if (value_type >= (uint8)REF_TYPE_NULLREF /* 0x65 */
|
||||
else if (
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
value_type >= (uint8)REF_TYPE_STRINGVIEWITER /* 0x61 */
|
||||
#else
|
||||
value_type >= (uint8)REF_TYPE_NULLREF /* 0x65 */
|
||||
#endif
|
||||
&& value_type <= (uint8)REF_TYPE_FUNCREF /* 0x70 */ && gc_enabled)
|
||||
return sizeof(uintptr_t);
|
||||
else if (value_type == VALUE_TYPE_FUNCREF
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#if WASM_ENABLE_GC != 0
|
||||
#include "../common/gc/gc_object.h"
|
||||
#include "mem_alloc.h"
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
#include "string_object.h"
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
#include "../common/wasm_shared_memory.h"
|
||||
|
@ -1391,6 +1394,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
WASMFuncObjectRef func_obj;
|
||||
WASMI31ObjectRef i31_obj;
|
||||
WASMExternrefObjectRef externref_obj;
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
WASMString str_obj = NULL;
|
||||
WASMStringrefObjectRef stringref_obj;
|
||||
WASMStringviewWTF8ObjectRef stringview_wtf8_obj;
|
||||
WASMStringviewWTF16ObjectRef stringview_wtf16_obj;
|
||||
WASMStringviewIterObjectRef stringview_iter_obj;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
|
@ -2672,6 +2682,727 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP_END();
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case WASM_OP_STRING_NEW_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF16:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF8:
|
||||
{
|
||||
uint32 mem_idx, addr, bytes_length, offset = 0;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
|
||||
bytes_length = POP_I32();
|
||||
addr = POP_I32();
|
||||
|
||||
CHECK_MEMORY_OVERFLOW(bytes_length);
|
||||
|
||||
if (opcode == WASM_OP_STRING_NEW_WTF16) {
|
||||
flag = WTF16;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_LOSSY_UTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_WTF8) {
|
||||
flag = WTF8;
|
||||
}
|
||||
|
||||
str_obj = wasm_string_new_with_encoding(
|
||||
maddr, bytes_length, flag);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
|
||||
(void)mem_idx;
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_CONST:
|
||||
{
|
||||
WASMModule *wasm_module = module->module;
|
||||
uint32 contents;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, contents);
|
||||
|
||||
str_obj = wasm_string_new_const(
|
||||
wasm_module->string_consts[contents]);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_MEASURE_UTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF16:
|
||||
{
|
||||
int32 target_bytes_length;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
if (opcode == WASM_OP_STRING_MEASURE_WTF16) {
|
||||
flag = WTF16;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_MEASURE_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_MEASURE_WTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
target_bytes_length = wasm_string_measure(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
flag);
|
||||
|
||||
PUSH_I32(target_bytes_length);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_ENCODE_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF16:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF8:
|
||||
{
|
||||
uint32 mem_idx, addr;
|
||||
int32 target_bytes_length;
|
||||
WASMMemoryInstance *memory_inst;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
|
||||
addr = POP_I32();
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = (WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj);
|
||||
|
||||
memory_inst = module->memories[mem_idx];
|
||||
maddr = memory_inst->memory_data + addr;
|
||||
|
||||
if (opcode == WASM_OP_STRING_ENCODE_WTF16) {
|
||||
flag = WTF16;
|
||||
count = wasm_string_measure(str_obj, flag);
|
||||
target_bytes_length = wasm_string_encode(
|
||||
str_obj, 0, count, maddr, NULL, flag);
|
||||
}
|
||||
else {
|
||||
if (opcode == WASM_OP_STRING_ENCODE_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRING_ENCODE_LOSSY_UTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_ENCODE_WTF8) {
|
||||
flag = WTF8;
|
||||
}
|
||||
count = wasm_string_measure(str_obj, flag);
|
||||
target_bytes_length = wasm_string_encode(
|
||||
str_obj, 0, count, maddr, NULL, flag);
|
||||
|
||||
if (target_bytes_length == -1) {
|
||||
wasm_set_exception(
|
||||
module, "isolated surrogate is seen");
|
||||
goto got_exception;
|
||||
}
|
||||
}
|
||||
if (target_bytes_length < 0) {
|
||||
wasm_set_exception(module,
|
||||
"stringref encode failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(target_bytes_length);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_CONCAT:
|
||||
{
|
||||
WASMStringrefObjectRef stringref_obj1, stringref_obj2;
|
||||
|
||||
stringref_obj2 = POP_REF();
|
||||
stringref_obj1 = POP_REF();
|
||||
|
||||
str_obj = wasm_string_concat(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj1),
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj2));
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_EQ:
|
||||
{
|
||||
WASMStringrefObjectRef stringref_obj1, stringref_obj2;
|
||||
int32 is_eq;
|
||||
|
||||
stringref_obj2 = POP_REF();
|
||||
stringref_obj1 = POP_REF();
|
||||
|
||||
is_eq = wasm_string_eq(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj1),
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj2));
|
||||
|
||||
PUSH_I32(is_eq);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_IS_USV_SEQUENCE:
|
||||
{
|
||||
int32 is_usv_sequence;
|
||||
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
is_usv_sequence = wasm_string_is_usv_sequence(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj));
|
||||
|
||||
PUSH_I32(is_usv_sequence);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_AS_WTF8:
|
||||
{
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_create_view(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
STRING_VIEW_WTF8);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringview_wtf8_obj =
|
||||
wasm_stringview_wtf8_obj_new(exec_env, str_obj);
|
||||
if (!stringview_wtf8_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringview wtf8 failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringview_wtf8_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_ADVANCE:
|
||||
{
|
||||
uint32 next_pos, bytes, pos;
|
||||
|
||||
bytes = POP_I32();
|
||||
pos = POP_I32();
|
||||
stringview_wtf8_obj = POP_REF();
|
||||
|
||||
next_pos = wasm_string_advance(
|
||||
(WASMString)wasm_stringview_wtf8_obj_get_value(
|
||||
stringview_wtf8_obj),
|
||||
pos, bytes, NULL);
|
||||
|
||||
PUSH_I32(next_pos);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8:
|
||||
{
|
||||
uint32 mem_idx, addr, pos, bytes, next_pos;
|
||||
int32 bytes_written;
|
||||
WASMMemoryInstance *memory_inst;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
if (opcode == WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8) {
|
||||
flag = WTF8;
|
||||
}
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
|
||||
bytes = POP_I32();
|
||||
pos = POP_I32();
|
||||
addr = POP_I32();
|
||||
stringview_wtf8_obj = POP_REF();
|
||||
|
||||
memory_inst = module->memories[mem_idx];
|
||||
maddr = memory_inst->memory_data + addr;
|
||||
|
||||
bytes_written = wasm_string_encode(
|
||||
(WASMString)wasm_stringview_wtf8_obj_get_value(
|
||||
stringview_wtf8_obj),
|
||||
pos, bytes, maddr, &next_pos, flag);
|
||||
|
||||
if (bytes_written < 0) {
|
||||
if (bytes_written == Isolated_Surrogate) {
|
||||
wasm_set_exception(
|
||||
module, "isolated surrogate is seen");
|
||||
}
|
||||
else {
|
||||
wasm_set_exception(module, "encode failed");
|
||||
}
|
||||
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(next_pos);
|
||||
PUSH_I32(bytes_written);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_SLICE:
|
||||
{
|
||||
uint32 start, end;
|
||||
|
||||
end = POP_I32();
|
||||
start = POP_I32();
|
||||
stringview_wtf8_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_slice(
|
||||
(WASMString)wasm_stringview_wtf8_obj_get_value(
|
||||
stringview_wtf8_obj),
|
||||
start, end, STRING_VIEW_WTF8);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_AS_WTF16:
|
||||
{
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_create_view(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
STRING_VIEW_WTF16);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringview_wtf16_obj =
|
||||
wasm_stringview_wtf16_obj_new(exec_env, str_obj);
|
||||
if (!stringview_wtf16_obj) {
|
||||
wasm_set_exception(
|
||||
module, "create stringview wtf16 failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringview_wtf16_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_LENGTH:
|
||||
{
|
||||
int32 code_units_length;
|
||||
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
code_units_length = wasm_string_wtf16_get_length(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj));
|
||||
|
||||
PUSH_I32(code_units_length);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT:
|
||||
{
|
||||
int32 pos;
|
||||
uint32 code_unit;
|
||||
|
||||
pos = POP_I32();
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
code_unit = (uint32)wasm_string_get_wtf16_codeunit(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj),
|
||||
pos);
|
||||
|
||||
PUSH_I32(code_unit);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_ENCODE:
|
||||
{
|
||||
uint32 mem_idx, addr, pos, len, offset = 0;
|
||||
int32 written_code_units = 0;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
|
||||
len = POP_I32();
|
||||
pos = POP_I32();
|
||||
addr = POP_I32();
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
CHECK_MEMORY_OVERFLOW(len * sizeof(uint16));
|
||||
|
||||
/* check 2-byte alignment */
|
||||
if (((uintptr_t)maddr & (((uintptr_t)1 << 2) - 1))
|
||||
!= 0) {
|
||||
wasm_set_exception(module,
|
||||
"unaligned memory access");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
written_code_units = wasm_string_encode(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj),
|
||||
pos, len, maddr, NULL, WTF16);
|
||||
if (written_code_units < 0) {
|
||||
wasm_set_exception(module, "encode failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(written_code_units);
|
||||
(void)mem_idx;
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_SLICE:
|
||||
{
|
||||
uint32 start, end;
|
||||
|
||||
end = POP_I32();
|
||||
start = POP_I32();
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_slice(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj),
|
||||
start, end, STRING_VIEW_WTF16);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_AS_ITER:
|
||||
{
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_create_view(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
STRING_VIEW_ITER);
|
||||
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringview_iter_obj =
|
||||
wasm_stringview_iter_obj_new(exec_env, str_obj, 0);
|
||||
if (!stringview_iter_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringview iter failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringview_iter_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_NEXT:
|
||||
{
|
||||
uint32 code_point;
|
||||
|
||||
stringview_iter_obj = POP_REF();
|
||||
|
||||
code_point = wasm_string_next_codepoint(
|
||||
(WASMString)wasm_stringview_iter_obj_get_value(
|
||||
stringview_iter_obj),
|
||||
wasm_stringview_iter_obj_get_pos(
|
||||
stringview_iter_obj));
|
||||
|
||||
PUSH_I32(code_point);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_ADVANCE:
|
||||
case WASM_OP_STRINGVIEW_ITER_REWIND:
|
||||
{
|
||||
uint32 code_points_count, code_points_consumed = 0,
|
||||
cur_pos, next_pos = 0;
|
||||
|
||||
code_points_count = POP_I32();
|
||||
stringview_iter_obj = POP_REF();
|
||||
|
||||
str_obj =
|
||||
(WASMString)wasm_stringview_iter_obj_get_value(
|
||||
stringview_iter_obj);
|
||||
cur_pos = wasm_stringview_iter_obj_get_pos(
|
||||
stringview_iter_obj);
|
||||
|
||||
if (opcode == WASM_OP_STRINGVIEW_ITER_ADVANCE) {
|
||||
next_pos = wasm_string_advance(
|
||||
str_obj, cur_pos, code_points_count,
|
||||
&code_points_consumed);
|
||||
}
|
||||
else if (opcode == WASM_OP_STRINGVIEW_ITER_REWIND) {
|
||||
next_pos = wasm_string_rewind(
|
||||
str_obj, cur_pos, code_points_count,
|
||||
&code_points_consumed);
|
||||
}
|
||||
|
||||
wasm_stringview_iter_obj_update_pos(stringview_iter_obj,
|
||||
next_pos);
|
||||
|
||||
PUSH_I32(code_points_consumed);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_SLICE:
|
||||
{
|
||||
uint32 code_points_count, cur_pos;
|
||||
|
||||
code_points_count = POP_I32();
|
||||
stringview_iter_obj = POP_REF();
|
||||
|
||||
cur_pos = wasm_stringview_iter_obj_get_pos(
|
||||
stringview_iter_obj);
|
||||
|
||||
str_obj = wasm_string_slice(
|
||||
(WASMString)wasm_stringview_iter_obj_get_value(
|
||||
stringview_iter_obj),
|
||||
cur_pos, code_points_count, STRING_VIEW_ITER);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_NEW_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF8_ARRAY:
|
||||
{
|
||||
uint32 start, end, array_len;
|
||||
EncodingFlag flag = WTF8;
|
||||
WASMArrayType *array_type;
|
||||
void *arr_start_addr;
|
||||
|
||||
end = POP_I32();
|
||||
start = POP_I32();
|
||||
array_obj = POP_REF();
|
||||
|
||||
array_type = (WASMArrayType *)wasm_obj_get_defined_type(
|
||||
(WASMObjectRef)array_obj);
|
||||
arr_start_addr =
|
||||
wasm_array_obj_elem_addr(array_obj, start);
|
||||
array_len = wasm_array_obj_length(array_obj);
|
||||
|
||||
if (start > end || end > array_len) {
|
||||
wasm_set_exception(module,
|
||||
"array index out of bounds");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
if (opcode == WASM_OP_STRING_NEW_WTF16_ARRAY) {
|
||||
if (array_type->elem_type != VALUE_TYPE_I16) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
flag = WTF16;
|
||||
}
|
||||
else {
|
||||
if (array_type->elem_type != VALUE_TYPE_I8) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
if (opcode == WASM_OP_STRING_NEW_UTF8_ARRAY) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_WTF8_ARRAY) {
|
||||
flag = WTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
str_obj = wasm_string_new_with_encoding(
|
||||
arr_start_addr, (end - start), flag);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_ENCODE_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF8_ARRAY:
|
||||
{
|
||||
uint32 start, array_len;
|
||||
int32 bytes_written;
|
||||
EncodingFlag flag = WTF8;
|
||||
WASMArrayType *array_type;
|
||||
void *arr_start_addr;
|
||||
|
||||
start = POP_I32();
|
||||
array_obj = POP_REF();
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = (WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj);
|
||||
|
||||
array_type = (WASMArrayType *)wasm_obj_get_defined_type(
|
||||
(WASMObjectRef)array_obj);
|
||||
arr_start_addr =
|
||||
wasm_array_obj_elem_addr(array_obj, start);
|
||||
array_len = wasm_array_obj_length(array_obj);
|
||||
|
||||
if (start > array_len) {
|
||||
wasm_set_exception(module,
|
||||
"array index out of bounds");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
if (opcode == WASM_OP_STRING_ENCODE_WTF16_ARRAY) {
|
||||
if (array_type->elem_type != VALUE_TYPE_I16) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
flag = WTF16;
|
||||
}
|
||||
else {
|
||||
if (array_type->elem_type != VALUE_TYPE_I8) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
if (opcode == WASM_OP_STRING_ENCODE_UTF8_ARRAY) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRING_ENCODE_WTF8_ARRAY) {
|
||||
flag = WTF8;
|
||||
}
|
||||
else if (
|
||||
opcode
|
||||
== WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
bytes_written =
|
||||
wasm_string_encode(str_obj, start, array_len,
|
||||
arr_start_addr, NULL, flag);
|
||||
|
||||
if (bytes_written < 0) {
|
||||
if (bytes_written == Isolated_Surrogate) {
|
||||
wasm_set_exception(
|
||||
module, "isolated surrogate is seen");
|
||||
}
|
||||
else if (bytes_written == Insufficient_Space) {
|
||||
wasm_set_exception(
|
||||
module, "array space is insufficient");
|
||||
}
|
||||
else {
|
||||
wasm_set_exception(module, "encode failed");
|
||||
}
|
||||
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(bytes_written);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
default:
|
||||
{
|
||||
wasm_set_exception(module, "unsupported opcode");
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#if WASM_ENABLE_GC != 0
|
||||
#include "../common/gc/gc_object.h"
|
||||
#include "mem_alloc.h"
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
#include "string_object.h"
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
#include "../common/wasm_shared_memory.h"
|
||||
|
@ -1477,6 +1480,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
WASMI31ObjectRef i31_obj;
|
||||
WASMExternrefObjectRef externref_obj;
|
||||
uint32 type_idx;
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
WASMString str_obj;
|
||||
WASMStringrefObjectRef stringref_obj;
|
||||
WASMStringviewWTF8ObjectRef stringview_wtf8_obj;
|
||||
WASMStringviewWTF16ObjectRef stringview_wtf16_obj;
|
||||
WASMStringviewIterObjectRef stringview_iter_obj;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
|
@ -2608,6 +2618,722 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
HANDLE_OP_END();
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case WASM_OP_STRING_NEW_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF16:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF8:
|
||||
{
|
||||
uint32 mem_idx, addr, bytes_length, offset = 0;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
mem_idx = (uint32)read_uint32(frame_ip);
|
||||
bytes_length = POP_I32();
|
||||
addr = POP_I32();
|
||||
|
||||
CHECK_MEMORY_OVERFLOW(bytes_length);
|
||||
|
||||
if (opcode == WASM_OP_STRING_NEW_WTF16) {
|
||||
flag = WTF16;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_LOSSY_UTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_WTF8) {
|
||||
flag = WTF8;
|
||||
}
|
||||
|
||||
str_obj = wasm_string_new_with_encoding(
|
||||
maddr, bytes_length, flag);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
|
||||
(void)mem_idx;
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_CONST:
|
||||
{
|
||||
WASMModule *wasm_module = module->module;
|
||||
uint32 contents;
|
||||
|
||||
contents = (uint32)read_uint32(frame_ip);
|
||||
|
||||
str_obj = wasm_string_new_const(
|
||||
wasm_module->string_consts[contents]);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_MEASURE_UTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF16:
|
||||
{
|
||||
int32 target_bytes_length;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
if (opcode == WASM_OP_STRING_MEASURE_WTF16) {
|
||||
flag = WTF16;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_MEASURE_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_MEASURE_WTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
target_bytes_length = wasm_string_measure(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
flag);
|
||||
|
||||
PUSH_I32(target_bytes_length);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_ENCODE_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF16:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF8:
|
||||
{
|
||||
uint32 mem_idx, addr;
|
||||
int32 target_bytes_length;
|
||||
WASMMemoryInstance *memory_inst;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
mem_idx = (uint32)read_uint32(frame_ip);
|
||||
addr = POP_I32();
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = (WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj);
|
||||
|
||||
memory_inst = module->memories[mem_idx];
|
||||
maddr = memory_inst->memory_data + addr;
|
||||
|
||||
if (opcode == WASM_OP_STRING_ENCODE_WTF16) {
|
||||
flag = WTF16;
|
||||
count = wasm_string_measure(str_obj, flag);
|
||||
target_bytes_length = wasm_string_encode(
|
||||
str_obj, 0, count, maddr, NULL, flag);
|
||||
}
|
||||
else {
|
||||
if (opcode == WASM_OP_STRING_ENCODE_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRING_ENCODE_LOSSY_UTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_ENCODE_WTF8) {
|
||||
flag = WTF8;
|
||||
}
|
||||
count = wasm_string_measure(str_obj, flag);
|
||||
target_bytes_length = wasm_string_encode(
|
||||
str_obj, 0, count, maddr, NULL, flag);
|
||||
|
||||
if (target_bytes_length == -1) {
|
||||
wasm_set_exception(
|
||||
module, "isolated surrogate is seen");
|
||||
goto got_exception;
|
||||
}
|
||||
}
|
||||
if (target_bytes_length < 0) {
|
||||
wasm_set_exception(module,
|
||||
"stringref encode failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(target_bytes_length);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_CONCAT:
|
||||
{
|
||||
WASMStringrefObjectRef stringref_obj1, stringref_obj2;
|
||||
|
||||
stringref_obj2 = POP_REF();
|
||||
stringref_obj1 = POP_REF();
|
||||
|
||||
str_obj = wasm_string_concat(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj1),
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj2));
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_EQ:
|
||||
{
|
||||
WASMStringrefObjectRef stringref_obj1, stringref_obj2;
|
||||
int32 is_eq;
|
||||
|
||||
stringref_obj2 = POP_REF();
|
||||
stringref_obj1 = POP_REF();
|
||||
|
||||
is_eq = wasm_string_eq(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj1),
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj2));
|
||||
|
||||
PUSH_I32(is_eq);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_IS_USV_SEQUENCE:
|
||||
{
|
||||
int32 is_usv_sequence;
|
||||
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
is_usv_sequence = wasm_string_is_usv_sequence(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj));
|
||||
|
||||
PUSH_I32(is_usv_sequence);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_AS_WTF8:
|
||||
{
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_create_view(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
STRING_VIEW_WTF8);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringview_wtf8_obj =
|
||||
wasm_stringview_wtf8_obj_new(exec_env, str_obj);
|
||||
if (!stringview_wtf8_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringview wtf8 failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringview_wtf8_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_ADVANCE:
|
||||
{
|
||||
uint32 next_pos, bytes, pos;
|
||||
|
||||
bytes = POP_I32();
|
||||
pos = POP_I32();
|
||||
stringview_wtf8_obj = POP_REF();
|
||||
|
||||
next_pos = wasm_string_advance(
|
||||
(WASMString)wasm_stringview_wtf8_obj_get_value(
|
||||
stringview_wtf8_obj),
|
||||
pos, bytes, NULL);
|
||||
|
||||
PUSH_I32(next_pos);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8:
|
||||
{
|
||||
uint32 mem_idx, addr, pos, bytes, next_pos;
|
||||
int32 bytes_written;
|
||||
WASMMemoryInstance *memory_inst;
|
||||
EncodingFlag flag = WTF8;
|
||||
|
||||
if (opcode == WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8) {
|
||||
flag = WTF8;
|
||||
}
|
||||
|
||||
mem_idx = (uint32)read_uint32(frame_ip);
|
||||
bytes = POP_I32();
|
||||
pos = POP_I32();
|
||||
addr = POP_I32();
|
||||
stringview_wtf8_obj = POP_REF();
|
||||
|
||||
memory_inst = module->memories[mem_idx];
|
||||
maddr = memory_inst->memory_data + addr;
|
||||
|
||||
bytes_written = wasm_string_encode(
|
||||
(WASMString)wasm_stringview_wtf8_obj_get_value(
|
||||
stringview_wtf8_obj),
|
||||
pos, bytes, maddr, &next_pos, flag);
|
||||
|
||||
if (bytes_written < 0) {
|
||||
if (bytes_written == Isolated_Surrogate) {
|
||||
wasm_set_exception(
|
||||
module, "isolated surrogate is seen");
|
||||
}
|
||||
else {
|
||||
wasm_set_exception(module, "encode failed");
|
||||
}
|
||||
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(next_pos);
|
||||
PUSH_I32(bytes_written);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_SLICE:
|
||||
{
|
||||
uint32 start, end;
|
||||
|
||||
end = POP_I32();
|
||||
start = POP_I32();
|
||||
stringview_wtf8_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_slice(
|
||||
(WASMString)wasm_stringview_wtf8_obj_get_value(
|
||||
stringview_wtf8_obj),
|
||||
start, end, STRING_VIEW_WTF8);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_AS_WTF16:
|
||||
{
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_create_view(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
STRING_VIEW_WTF16);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringview_wtf16_obj =
|
||||
wasm_stringview_wtf16_obj_new(exec_env, str_obj);
|
||||
if (!stringview_wtf16_obj) {
|
||||
wasm_set_exception(
|
||||
module, "create stringview wtf16 failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringview_wtf16_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_LENGTH:
|
||||
{
|
||||
int32 code_units_length;
|
||||
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
code_units_length = wasm_string_wtf16_get_length(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj));
|
||||
|
||||
PUSH_I32(code_units_length);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT:
|
||||
{
|
||||
int32 pos;
|
||||
uint32 code_unit;
|
||||
|
||||
pos = POP_I32();
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
code_unit = (uint32)wasm_string_get_wtf16_codeunit(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj),
|
||||
pos);
|
||||
|
||||
PUSH_I32(code_unit);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_ENCODE:
|
||||
{
|
||||
uint32 mem_idx, addr, pos, len, offset = 0;
|
||||
int32 written_code_units = 0;
|
||||
|
||||
mem_idx = (uint32)read_uint32(frame_ip);
|
||||
len = POP_I32();
|
||||
pos = POP_I32();
|
||||
addr = POP_I32();
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
CHECK_MEMORY_OVERFLOW(len * sizeof(uint16));
|
||||
|
||||
/* check 2-byte alignment */
|
||||
if (((uintptr_t)maddr & (((uintptr_t)1 << 2) - 1))
|
||||
!= 0) {
|
||||
wasm_set_exception(module,
|
||||
"unaligned memory access");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
written_code_units = wasm_string_encode(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj),
|
||||
pos, len, maddr, NULL, WTF16);
|
||||
|
||||
PUSH_I32(written_code_units);
|
||||
(void)mem_idx;
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_SLICE:
|
||||
{
|
||||
uint32 start, end;
|
||||
|
||||
end = POP_I32();
|
||||
start = POP_I32();
|
||||
stringview_wtf16_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_slice(
|
||||
(WASMString)wasm_stringview_wtf16_obj_get_value(
|
||||
stringview_wtf16_obj),
|
||||
start, end, STRING_VIEW_WTF16);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_AS_ITER:
|
||||
{
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = wasm_string_create_view(
|
||||
(WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj),
|
||||
STRING_VIEW_ITER);
|
||||
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringview_iter_obj =
|
||||
wasm_stringview_iter_obj_new(exec_env, str_obj, 0);
|
||||
if (!stringview_iter_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringview iter failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringview_iter_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_NEXT:
|
||||
{
|
||||
uint32 code_point;
|
||||
|
||||
stringview_iter_obj = POP_REF();
|
||||
|
||||
code_point = wasm_string_next_codepoint(
|
||||
(WASMString)wasm_stringview_iter_obj_get_value(
|
||||
stringview_iter_obj),
|
||||
wasm_stringview_iter_obj_get_pos(
|
||||
stringview_iter_obj));
|
||||
|
||||
PUSH_I32(code_point);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_ADVANCE:
|
||||
case WASM_OP_STRINGVIEW_ITER_REWIND:
|
||||
{
|
||||
uint32 code_points_count, code_points_consumed = 0,
|
||||
cur_pos, next_pos = 0;
|
||||
|
||||
code_points_count = POP_I32();
|
||||
stringview_iter_obj = POP_REF();
|
||||
|
||||
str_obj =
|
||||
(WASMString)wasm_stringview_iter_obj_get_value(
|
||||
stringview_iter_obj);
|
||||
cur_pos = wasm_stringview_iter_obj_get_pos(
|
||||
stringview_iter_obj);
|
||||
|
||||
if (opcode == WASM_OP_STRINGVIEW_ITER_ADVANCE) {
|
||||
next_pos = wasm_string_advance(
|
||||
str_obj, cur_pos, code_points_count,
|
||||
&code_points_consumed);
|
||||
}
|
||||
else if (opcode == WASM_OP_STRINGVIEW_ITER_REWIND) {
|
||||
next_pos = wasm_string_rewind(
|
||||
str_obj, cur_pos, code_points_count,
|
||||
&code_points_consumed);
|
||||
}
|
||||
|
||||
wasm_stringview_iter_obj_update_pos(stringview_iter_obj,
|
||||
next_pos);
|
||||
|
||||
PUSH_I32(code_points_consumed);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_SLICE:
|
||||
{
|
||||
uint32 code_points_count, cur_pos;
|
||||
|
||||
code_points_count = POP_I32();
|
||||
stringview_iter_obj = POP_REF();
|
||||
|
||||
cur_pos = wasm_stringview_iter_obj_get_pos(
|
||||
stringview_iter_obj);
|
||||
|
||||
str_obj = wasm_string_slice(
|
||||
(WASMString)wasm_stringview_iter_obj_get_value(
|
||||
stringview_iter_obj),
|
||||
cur_pos, code_points_count, STRING_VIEW_ITER);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_NEW_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF8_ARRAY:
|
||||
{
|
||||
uint32 start, end, array_len;
|
||||
EncodingFlag flag = WTF8;
|
||||
WASMArrayType *array_type;
|
||||
void *arr_start_addr;
|
||||
|
||||
end = POP_I32();
|
||||
start = POP_I32();
|
||||
array_obj = POP_REF();
|
||||
|
||||
array_type = (WASMArrayType *)wasm_obj_get_defined_type(
|
||||
(WASMObjectRef)array_obj);
|
||||
arr_start_addr =
|
||||
wasm_array_obj_elem_addr(array_obj, start);
|
||||
array_len = wasm_array_obj_length(array_obj);
|
||||
|
||||
if (start > end || end > array_len) {
|
||||
wasm_set_exception(module,
|
||||
"array index out of bounds");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
if (opcode == WASM_OP_STRING_NEW_WTF16_ARRAY) {
|
||||
if (array_type->elem_type != VALUE_TYPE_I16) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
flag = WTF16;
|
||||
}
|
||||
else {
|
||||
if (array_type->elem_type != VALUE_TYPE_I8) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
if (opcode == WASM_OP_STRING_NEW_UTF8_ARRAY) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode == WASM_OP_STRING_NEW_WTF8_ARRAY) {
|
||||
flag = WTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
str_obj = wasm_string_new_with_encoding(
|
||||
arr_start_addr, (end - start), flag);
|
||||
if (!str_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create string object failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
SYNC_ALL_TO_FRAME();
|
||||
stringref_obj =
|
||||
wasm_stringref_obj_new(exec_env, str_obj);
|
||||
if (!stringref_obj) {
|
||||
wasm_set_exception(module,
|
||||
"create stringref failed");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_REF(stringref_obj);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
case WASM_OP_STRING_ENCODE_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF8_ARRAY:
|
||||
{
|
||||
uint32 start, array_len;
|
||||
int32 bytes_written;
|
||||
EncodingFlag flag = WTF8;
|
||||
WASMArrayType *array_type;
|
||||
void *arr_start_addr;
|
||||
|
||||
start = POP_I32();
|
||||
array_obj = POP_REF();
|
||||
stringref_obj = POP_REF();
|
||||
|
||||
str_obj = (WASMString)wasm_stringref_obj_get_value(
|
||||
stringref_obj);
|
||||
|
||||
array_type = (WASMArrayType *)wasm_obj_get_defined_type(
|
||||
(WASMObjectRef)array_obj);
|
||||
arr_start_addr =
|
||||
wasm_array_obj_elem_addr(array_obj, start);
|
||||
array_len = wasm_array_obj_length(array_obj);
|
||||
|
||||
if (start > array_len) {
|
||||
wasm_set_exception(module,
|
||||
"array index out of bounds");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
if (opcode == WASM_OP_STRING_ENCODE_WTF16_ARRAY) {
|
||||
if (array_type->elem_type != VALUE_TYPE_I16) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
flag = WTF16;
|
||||
}
|
||||
else {
|
||||
if (array_type->elem_type != VALUE_TYPE_I8) {
|
||||
wasm_set_exception(module,
|
||||
"array type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
if (opcode == WASM_OP_STRING_ENCODE_UTF8_ARRAY) {
|
||||
flag = UTF8;
|
||||
}
|
||||
else if (opcode
|
||||
== WASM_OP_STRING_ENCODE_WTF8_ARRAY) {
|
||||
flag = WTF8;
|
||||
}
|
||||
else if (
|
||||
opcode
|
||||
== WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY) {
|
||||
flag = LOSSY_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
bytes_written = wasm_string_encode(
|
||||
str_obj, 0, array_len, arr_start_addr, NULL, flag);
|
||||
if (bytes_written < 0) {
|
||||
if (bytes_written == Isolated_Surrogate) {
|
||||
wasm_set_exception(
|
||||
module, "isolated surrogate is seen");
|
||||
}
|
||||
else if (bytes_written == Insufficient_Space) {
|
||||
wasm_set_exception(
|
||||
module, "array space is insufficient");
|
||||
}
|
||||
else {
|
||||
wasm_set_exception(module, "encode failed");
|
||||
}
|
||||
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
PUSH_I32(bytes_written);
|
||||
HANDLE_OP_END();
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
|
||||
default:
|
||||
{
|
||||
wasm_set_exception(module, "unsupported opcode");
|
||||
|
|
|
@ -925,6 +925,14 @@ resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
|
|||
error_buf, error_buf_size))
|
||||
return false;
|
||||
*p_need_ref_type_map = true;
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
/* covert (ref string) to stringref */
|
||||
if (wasm_is_refheaptype_stringrefs(&ref_type->ref_ht_common)) {
|
||||
ref_type->ref_type =
|
||||
(uint8)((int32)0x80 + ref_type->ref_ht_common.heap_type);
|
||||
*p_need_ref_type_map = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* type which can be represented by one byte */
|
||||
|
@ -3702,6 +3710,60 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
static bool
|
||||
load_stringref_section(const uint8 *buf, const uint8 *buf_end,
|
||||
WASMModule *module, bool is_load_from_file_buf,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
int32 deferred_count, immediate_count, string_length, i;
|
||||
uint64 total_size;
|
||||
|
||||
read_leb_uint32(p, p_end, deferred_count);
|
||||
read_leb_uint32(p, p_end, immediate_count);
|
||||
|
||||
/* proposal set deferred_count for future extension */
|
||||
if (deferred_count != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (immediate_count > 0) {
|
||||
total_size = sizeof(char *) * (uint64)immediate_count;
|
||||
if (!(module->string_consts =
|
||||
loader_malloc(total_size, error_buf, error_buf_size))) {
|
||||
goto fail;
|
||||
}
|
||||
module->stringref_count = immediate_count;
|
||||
|
||||
for (i = 0; i < immediate_count; i++) {
|
||||
read_leb_uint32(p, p_end, string_length);
|
||||
|
||||
CHECK_BUF(p, p_end, string_length);
|
||||
if (!(module->string_consts[i] = const_str_list_insert(
|
||||
p, string_length, module, is_load_from_file_buf,
|
||||
error_buf, error_buf_size))) {
|
||||
goto fail;
|
||||
}
|
||||
p += string_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != p_end) {
|
||||
set_error_buf(error_buf, error_buf_size, "section size mismatch");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("Load stringref section success.\n");
|
||||
return true;
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
static bool
|
||||
handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
@ -4469,6 +4531,16 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case SECTION_TYPE_STRINGREF:
|
||||
if (!load_stringref_section(buf, buf_end, module,
|
||||
is_load_from_file_buf, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
set_error_buf(error_buf, error_buf_size, "invalid section id");
|
||||
|
@ -4927,6 +4999,11 @@ static uint8 section_ids[] = {
|
|||
SECTION_TYPE_FUNC,
|
||||
SECTION_TYPE_TABLE,
|
||||
SECTION_TYPE_MEMORY,
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
SECTION_TYPE_STRINGREF,
|
||||
#endif
|
||||
#endif
|
||||
SECTION_TYPE_GLOBAL,
|
||||
SECTION_TYPE_EXPORT,
|
||||
SECTION_TYPE_START,
|
||||
|
@ -5374,6 +5451,14 @@ wasm_loader_unload(WASMModule *module)
|
|||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
if (module->string_consts) {
|
||||
wasm_runtime_free(module->string_consts);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
if (module->br_table_cache_list) {
|
||||
BrTableCache *node = bh_list_first_elem(module->br_table_cache_list);
|
||||
|
@ -5451,6 +5536,12 @@ wasm_loader_unload(WASMModule *module)
|
|||
}
|
||||
wasm_runtime_free(module->rtt_types);
|
||||
}
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
for (i = 0; i < WASM_TYPE_STRINGVIEWITER - WASM_TYPE_STRINGREF + 1; i++) {
|
||||
if (module->stringref_rtts[i])
|
||||
wasm_runtime_free(module->stringref_rtts[i]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
wasm_runtime_free(module);
|
||||
|
@ -5954,6 +6045,61 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case WASM_OP_EXTERN_EXTERNALIZE:
|
||||
break;
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case WASM_OP_STRING_NEW_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF16:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF8:
|
||||
skip_leb_uint32(p, p_end); /* memory index 0x00 */
|
||||
break;
|
||||
case WASM_OP_STRING_CONST:
|
||||
skip_leb_int32(p, p_end); /* contents */
|
||||
break;
|
||||
case WASM_OP_STRING_MEASURE_UTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF16:
|
||||
break;
|
||||
case WASM_OP_STRING_ENCODE_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF16:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF8:
|
||||
skip_leb_uint32(p, p_end); /* memory index 0x00 */
|
||||
break;
|
||||
case WASM_OP_STRING_CONCAT:
|
||||
case WASM_OP_STRING_EQ:
|
||||
case WASM_OP_STRING_IS_USV_SEQUENCE:
|
||||
case WASM_OP_STRING_AS_WTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ADVANCE:
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8:
|
||||
skip_leb_uint32(p, p_end); /* memory index 0x00 */
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_WTF8_SLICE:
|
||||
case WASM_OP_STRING_AS_WTF16:
|
||||
case WASM_OP_STRINGVIEW_WTF16_LENGTH:
|
||||
case WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT:
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_WTF16_ENCODE:
|
||||
skip_leb_uint32(p, p_end); /* memory index 0x00 */
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_WTF16_SLICE:
|
||||
case WASM_OP_STRING_AS_ITER:
|
||||
case WASM_OP_STRINGVIEW_ITER_NEXT:
|
||||
case WASM_OP_STRINGVIEW_ITER_ADVANCE:
|
||||
case WASM_OP_STRINGVIEW_ITER_REWIND:
|
||||
case WASM_OP_STRINGVIEW_ITER_SLICE:
|
||||
case WASM_OP_STRING_NEW_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF8_ARRAY:
|
||||
break;
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -8042,6 +8188,7 @@ fail:
|
|||
#define POP_V128() TEMPLATE_POP(V128)
|
||||
#define POP_FUNCREF() TEMPLATE_POP(FUNCREF)
|
||||
#define POP_EXTERNREF() TEMPLATE_POP(EXTERNREF)
|
||||
#define POP_STRINGREF() TEMPLATE_POP(STRINGREF)
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
|
||||
|
@ -8277,7 +8424,7 @@ fail:
|
|||
wasm_reftype_struct_size(_ref_type)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif /* end of WASM_ENABLE_GC == 0 */
|
||||
|
||||
#define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \
|
||||
do { \
|
||||
|
@ -11756,7 +11903,12 @@ re_scan:
|
|||
}
|
||||
else {
|
||||
if (heap_type > HEAP_TYPE_FUNC
|
||||
|| heap_type < HEAP_TYPE_NONE) {
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|| heap_type < HEAP_TYPE_STRINGVIEWITER
|
||||
#else
|
||||
|| heap_type < HEAP_TYPE_NONE
|
||||
#endif
|
||||
) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"unknown type");
|
||||
goto fail;
|
||||
|
@ -11774,11 +11926,16 @@ re_scan:
|
|||
bool nullable =
|
||||
(opcode1 == WASM_OP_REF_CAST_NULLABLE) ? true
|
||||
: false;
|
||||
if (heap_type >= 0 || !nullable) {
|
||||
wasm_set_refheaptype_typeidx(
|
||||
&wasm_ref_type.ref_ht_typeidx, nullable,
|
||||
heap_type);
|
||||
PUSH_REF(wasm_ref_type.ref_type);
|
||||
}
|
||||
else {
|
||||
PUSH_REF((uint8)((int32)0x80 + heap_type));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -11998,6 +12155,215 @@ re_scan:
|
|||
break;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
case WASM_OP_STRING_NEW_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF16:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_NEW_WTF8:
|
||||
{
|
||||
uint32 memidx;
|
||||
|
||||
read_leb_uint32(p, p_end, memidx);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, (uint32)memidx);
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
(void)memidx;
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_CONST:
|
||||
{
|
||||
uint32 contents;
|
||||
|
||||
read_leb_uint32(p, p_end, contents);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, (uint32)contents);
|
||||
#endif
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
(void)contents;
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_MEASURE_UTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF8:
|
||||
case WASM_OP_STRING_MEASURE_WTF16:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_ENCODE_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF16:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRING_ENCODE_WTF8:
|
||||
{
|
||||
uint32 memidx;
|
||||
|
||||
read_leb_uint32(p, p_end, memidx);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, (uint32)memidx);
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_STRINGREF();
|
||||
PUSH_I32();
|
||||
(void)memidx;
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_CONCAT:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
POP_STRINGREF();
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_EQ:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
POP_STRINGREF();
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_IS_USV_SEQUENCE:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_AS_WTF8:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
PUSH_REF(REF_TYPE_STRINGVIEWWTF8);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_ADVANCE:
|
||||
{
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF8);
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8:
|
||||
case WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8:
|
||||
{
|
||||
uint32 memidx;
|
||||
|
||||
read_leb_uint32(p, p_end, memidx);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, (uint32)memidx);
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF8);
|
||||
PUSH_I32();
|
||||
PUSH_I32();
|
||||
(void)memidx;
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_SLICE:
|
||||
{
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF8);
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_AS_WTF16:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
PUSH_REF(REF_TYPE_STRINGVIEWWTF16);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_LENGTH:
|
||||
{
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF16);
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT:
|
||||
{
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF16);
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_ENCODE:
|
||||
{
|
||||
uint32 memidx;
|
||||
|
||||
read_leb_uint32(p, p_end, memidx);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, (uint32)memidx);
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF16);
|
||||
PUSH_I32();
|
||||
(void)memidx;
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_SLICE:
|
||||
{
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWWTF16);
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_AS_ITER:
|
||||
{
|
||||
POP_STRINGREF();
|
||||
PUSH_REF(REF_TYPE_STRINGVIEWITER);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_NEXT:
|
||||
{
|
||||
POP_REF(REF_TYPE_STRINGVIEWITER);
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_ADVANCE:
|
||||
case WASM_OP_STRINGVIEW_ITER_REWIND:
|
||||
{
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWITER);
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_ITER_SLICE:
|
||||
{
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_STRINGVIEWITER);
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_NEW_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_NEW_WTF8_ARRAY:
|
||||
{
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_ARRAYREF);
|
||||
PUSH_REF(REF_TYPE_STRINGREF);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_STRING_ENCODE_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF16_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY:
|
||||
case WASM_OP_STRING_ENCODE_WTF8_ARRAY:
|
||||
{
|
||||
POP_I32();
|
||||
POP_REF(REF_TYPE_ARRAYREF);
|
||||
POP_STRINGREF();
|
||||
PUSH_I32();
|
||||
break;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
|
||||
default:
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"%s %02x %02x", "unsupported opcode",
|
||||
|
|
|
@ -337,6 +337,56 @@ typedef enum WASMGCEXTOpcode {
|
|||
|
||||
WASM_OP_EXTERN_INTERNALIZE = 0x70, /* extern.internalize */
|
||||
WASM_OP_EXTERN_EXTERNALIZE = 0x71, /* extern.externalize */
|
||||
|
||||
WASM_OP_STRING_NEW_UTF8 = 0x80, /* string.new_utf8 */
|
||||
WASM_OP_STRING_NEW_WTF16 = 0x81, /* string.new_wtf16 */
|
||||
WASM_OP_STRING_CONST = 0x82, /* string.const */
|
||||
WASM_OP_STRING_MEASURE_UTF8 = 0x83, /* string.measure_utf8 */
|
||||
WASM_OP_STRING_MEASURE_WTF8 = 0x84, /* string.measure_wtf8 */
|
||||
WASM_OP_STRING_MEASURE_WTF16 = 0x85, /* string.measure_wtf16 */
|
||||
WASM_OP_STRING_ENCODE_UTF8 = 0x86, /* string.encode_utf8 */
|
||||
WASM_OP_STRING_ENCODE_WTF16 = 0x87, /* string.encode_wtf16 */
|
||||
WASM_OP_STRING_CONCAT = 0x88, /* string.concat */
|
||||
WASM_OP_STRING_EQ = 0x89, /* string.eq */
|
||||
WASM_OP_STRING_IS_USV_SEQUENCE = 0x8a, /* string.is_usv_sequence */
|
||||
WASM_OP_STRING_NEW_LOSSY_UTF8 = 0x8b, /* string.new_lossy_utf8 */
|
||||
WASM_OP_STRING_NEW_WTF8 = 0x8c, /* string.new_wtf8 */
|
||||
WASM_OP_STRING_ENCODE_LOSSY_UTF8 = 0x8d, /* string.encode_lossy_utf8 */
|
||||
WASM_OP_STRING_ENCODE_WTF8 = 0x8e, /* string.encode_wtf8 */
|
||||
|
||||
WASM_OP_STRING_AS_WTF8 = 0x90, /* string.as_wtf8 */
|
||||
WASM_OP_STRINGVIEW_WTF8_ADVANCE = 0x91, /* stringview_wtf8.advance */
|
||||
WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8 =
|
||||
0x92, /* stringview_wtf8.encode_utf8 */
|
||||
WASM_OP_STRINGVIEW_WTF8_SLICE = 0x93, /* stringview_wtf8.slice */
|
||||
WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8 =
|
||||
0x94, /* stringview_wtf8.encode_lossy_utf8 */
|
||||
WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8 =
|
||||
0x95, /* stringview_wtf8.encode_wtf8 */
|
||||
|
||||
WASM_OP_STRING_AS_WTF16 = 0x98, /* string.as_wtf16 */
|
||||
WASM_OP_STRINGVIEW_WTF16_LENGTH = 0x99, /* stringview_wtf16.length */
|
||||
WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT =
|
||||
0x9a, /* stringview_wtf16.get_codeunit */
|
||||
WASM_OP_STRINGVIEW_WTF16_ENCODE = 0x9b, /* stringview_wtf16.encode */
|
||||
WASM_OP_STRINGVIEW_WTF16_SLICE = 0x9c, /* stringview_wtf16.slice */
|
||||
|
||||
WASM_OP_STRING_AS_ITER = 0xa0, /* string.as_iter */
|
||||
WASM_OP_STRINGVIEW_ITER_NEXT = 0xa1, /* stringview_iter.next */
|
||||
WASM_OP_STRINGVIEW_ITER_ADVANCE = 0xa2, /* stringview_iter.advance */
|
||||
WASM_OP_STRINGVIEW_ITER_REWIND = 0xa3, /* stringview_iter.rewind */
|
||||
WASM_OP_STRINGVIEW_ITER_SLICE = 0xa4, /* stringview_iter.slice */
|
||||
|
||||
WASM_OP_STRING_NEW_UTF8_ARRAY = 0xb0, /* string.new_utf8_array */
|
||||
WASM_OP_STRING_NEW_WTF16_ARRAY = 0xb1, /* string.new_wtf16_array */
|
||||
WASM_OP_STRING_ENCODE_UTF8_ARRAY = 0xb2, /* string.encode_utf8_array */
|
||||
WASM_OP_STRING_ENCODE_WTF16_ARRAY = 0xb3, /* string.encode_wtf16_array */
|
||||
WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY =
|
||||
0xb4, /* string.new_lossy_utf8_array */
|
||||
WASM_OP_STRING_NEW_WTF8_ARRAY = 0xb5, /* string.new_wtf8_array */
|
||||
WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY =
|
||||
0xb6, /* string.encode_lossy_utf8_array */
|
||||
WASM_OP_STRING_ENCODE_WTF8_ARRAY = 0xb7, /* string.encode_wtf8_array */
|
||||
} WASMGCEXTOpcode;
|
||||
|
||||
typedef enum WASMMiscEXTOpcode {
|
||||
|
|
Loading…
Reference in New Issue
Block a user