|
@@ -13,6 +13,9 @@
|
|
|
#if WASM_ENABLE_GC != 0
|
|
#if WASM_ENABLE_GC != 0
|
|
|
#include "../common/gc/gc_object.h"
|
|
#include "../common/gc/gc_object.h"
|
|
|
#include "mem_alloc.h"
|
|
#include "mem_alloc.h"
|
|
|
|
|
+#if WASM_ENABLE_STRINGREF != 0
|
|
|
|
|
+#include "string_object.h"
|
|
|
|
|
+#endif
|
|
|
#endif
|
|
#endif
|
|
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
|
|
#include "../common/wasm_shared_memory.h"
|
|
#include "../common/wasm_shared_memory.h"
|
|
@@ -1391,6 +1394,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|
|
WASMFuncObjectRef func_obj;
|
|
WASMFuncObjectRef func_obj;
|
|
|
WASMI31ObjectRef i31_obj;
|
|
WASMI31ObjectRef i31_obj;
|
|
|
WASMExternrefObjectRef externref_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
|
|
#endif
|
|
|
|
|
|
|
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
|
@@ -2672,6 +2682,727 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|
|
HANDLE_OP_END();
|
|
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:
|
|
default:
|
|
|
{
|
|
{
|
|
|
wasm_set_exception(module, "unsupported opcode");
|
|
wasm_set_exception(module, "unsupported opcode");
|