From 1e1c69bfbc17117cc8477f4fdda57584d4d152bd Mon Sep 17 00:00:00 2001 From: ZhouGuangyuan Date: Sun, 18 May 2025 16:01:05 +0800 Subject: [PATCH] unified base string Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IC8JLO Signed-off-by: ZhouGuangyuan Change-Id: I5e4f9c781c3ae56e713c7459f4a68359cfa50cdd --- BUILD.gn | 1 + common_components/objects/base_string.cpp | 465 +++++ ecmascript/base/json_parser.cpp | 2 +- ecmascript/base/number_helper.cpp | 1 + ecmascript/builtins/builtins_ark_tools.cpp | 2 +- ecmascript/builtins/builtins_array.cpp | 4 +- ecmascript/builtins/builtins_global.cpp | 1 + ecmascript/builtins/builtins_global_uri.cpp | 4 +- ecmascript/builtins/builtins_number.cpp | 1 + .../builtins/builtins_shared_typedarray.cpp | 2 +- ecmascript/builtins/builtins_string.cpp | 4 +- .../builtins/builtins_string_iterator.cpp | 2 + ecmascript/builtins/builtins_typedarray.cpp | 2 +- .../builtins/builtins_number_stub_builder.cpp | 2 +- .../builtins/builtins_string_stub_builder.cpp | 86 +- ecmascript/compiler/builtins_lowering.cpp | 2 +- ecmascript/compiler/circuit_builder.cpp | 16 +- ecmascript/compiler/hcr_circuit_builder.h | 4 +- ecmascript/compiler/mcr_circuit_builder.cpp | 12 +- ecmascript/compiler/mcr_circuit_builder.h | 4 +- .../compiler/new_object_stub_builder.cpp | 10 +- .../compiler/string_builder_optimizer.cpp | 10 +- ecmascript/compiler/stub_builder-inl.h | 25 +- ecmascript/compiler/stub_builder.cpp | 18 +- ecmascript/compiler/typed_hcr_lowering.cpp | 6 +- .../compiler/typed_native_inline_lowering.cpp | 4 +- .../dfx/hprof/tests/js_metadata_test.cpp | 10 +- ecmascript/ecma_string-inl.h | 408 ++-- ecmascript/ecma_string.cpp | 530 +---- ecmascript/ecma_string.h | 674 ++----- ecmascript/js_handle.h | 13 +- ecmascript/js_hclass-inl.h | 4 +- ecmascript/js_hclass.h | 19 +- ecmascript/js_primitive_ref.cpp | 1 + ecmascript/js_stable_array.cpp | 8 +- ecmascript/js_typed_array.cpp | 1 + ecmascript/mem/barriers.h | 5 + ecmascript/mem/object_xray.h | 2 +- ecmascript/mem/tagged_object-inl.h | 2 +- ecmascript/mem/tagged_object.h | 6 +- ecmascript/object_factory-inl.h | 2 +- ecmascript/object_fast_operator-inl.h | 2 +- .../arm64/ecma_string_hash_internal.h | 2 +- .../common/ecma_string_hash_internal.h | 2 +- ecmascript/stubs/runtime_stubs.cpp | 4 +- ecmascript/tagged_dictionary.cpp | 2 +- ecmascript/tests/BUILD.gn | 10 +- ecmascript/tests/base_string_test.cpp | 1744 ++++++++++++++++ .../tests/ecma_string_accessor_test.cpp | 20 +- ecmascript/tests/ecma_string_equals_test.cpp | 2 +- ecmascript/tests/ecma_string_hash_test.cpp | 3 +- ecmascript/tests/ecma_string_test.cpp | 1788 ----------------- ecmascript/tests/js_thread_state_test.cpp | 100 +- test/resource/js_runtime/ohos_test.xml | 2 +- 54 files changed, 2920 insertions(+), 3136 deletions(-) create mode 100644 common_components/objects/base_string.cpp create mode 100644 ecmascript/tests/base_string_test.cpp delete mode 100644 ecmascript/tests/ecma_string_test.cpp diff --git a/BUILD.gn b/BUILD.gn index 79cc99a0f8..5e7ba46952 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1033,6 +1033,7 @@ ecma_source = [ ecma_source += [ "common_components/log/log.cpp", "common_components/objects/base_object.cpp", + "common_components/objects/base_string.cpp", ] if (ets_runtime_enable_cmc_gc) { diff --git a/common_components/objects/base_string.cpp b/common_components/objects/base_string.cpp new file mode 100644 index 0000000000..fffa9d9c58 --- /dev/null +++ b/common_components/objects/base_string.cpp @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "ecmascript/base/utf_helper.h" +#include "common_interfaces/objects/base_string.h" + +#include "ecmascript/platform/ecma_string_hash.h" +#include "ecmascript/platform/ecma_string_hash_helper.h" + +namespace panda { + constexpr size_t LOW_3BITS = 0x7; + constexpr size_t LOW_4BITS = 0xF; + constexpr size_t LOW_5BITS = 0x1F; + constexpr size_t LOW_6BITS = 0x3F; + constexpr size_t L_SURROGATE_START = 0xDC00; + constexpr size_t H_SURROGATE_START = 0xD800; + constexpr size_t SURROGATE_RAIR_START = 0x10000; + constexpr size_t OFFSET_18POS = 18; + constexpr size_t OFFSET_12POS = 12; + constexpr size_t OFFSET_10POS = 10; + constexpr size_t OFFSET_6POS = 6; + + size_t utf_utils::DebuggerConvertRegionUtf16ToUtf8(const uint16_t* utf16In, uint8_t* utf8Out, size_t utf16Len, + size_t utf8Len, size_t start, bool modify, bool isWriteBuffer) + { + return ecmascript::base::utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, utf16Len, utf8Len, + start, modify, isWriteBuffer); + } + + size_t utf_utils::Utf8ToUtf16Size(const uint8_t* utf8, size_t utf8Len) + { + return ecmascript::base::utf_helper::Utf8ToUtf16Size(utf8, utf8Len); + } + + size_t utf_utils::Utf16ToUtf8Size(const uint16_t* utf16, uint32_t length, bool modify, bool isGetBufferSize, + bool cesu8) + { + return ecmascript::base::utf_helper::Utf16ToUtf8Size(utf16, length, modify, isGetBufferSize, cesu8); + } + + size_t utf_utils::ConvertRegionUtf8ToUtf16(const uint8_t* utf8In, uint16_t* utf16Out, size_t utf8Len, + size_t utf16Len) + { + return ecmascript::base::utf_helper::ConvertRegionUtf8ToUtf16(utf8In, utf16Out, utf8Len, utf16Len); + } + + size_t utf_utils::ConvertRegionUtf16ToLatin1(const uint16_t* utf16In, uint8_t* latin1Out, size_t utf16Len, + size_t latin1Len) + { + return ecmascript::base::utf_helper::ConvertRegionUtf16ToLatin1(utf16In, latin1Out, utf16Len, latin1Len); + } + + size_t utf_utils::ConvertRegionUtf16ToUtf8(const uint16_t* utf16In, uint8_t* utf8Out, size_t utf16Len, + size_t utf8Len, size_t start, bool modify, bool isWriteBuffer, bool cesu) + { + return ecmascript::base::utf_helper::ConvertRegionUtf16ToUtf8( + utf16In, utf8Out, utf16Len, utf8Len, start, modify, isWriteBuffer, cesu); + } + + + // To change the hash algorithm of BaseString, please modify BaseString::CalculateConcatHashCode + // and BaseStringHashHelper::ComputeHashForDataPlatform simultaneously!! + template + uint32_t BaseString::ComputeHashForData(const T* data, size_t size, + uint32_t hashSeed) + { + if (size <= static_cast(ecmascript::EcmaStringHash::MIN_SIZE_FOR_UNROLLING)) { + uint32_t hash = hashSeed; + for (uint32_t i = 0; i < size; i++) { + hash = (hash << static_cast(ecmascript::EcmaStringHash::HASH_SHIFT)) - hash + data[i]; + } + return hash; + } + return ecmascript::EcmaStringHashHelper::ComputeHashForDataPlatform(data, size, hashSeed); + } + + template + uint32_t BaseString::ComputeHashForData(const uint8_t*, size_t, uint32_t); + template + uint32_t BaseString::ComputeHashForData(const uint16_t*, size_t, uint32_t); + + + /* static */ + uint32_t BaseString::ComputeHashcodeUtf8(const uint8_t* utf8Data, size_t utf8Len, bool canBeCompress) + { + if (canBeCompress) { + return ComputeHashForData(utf8Data, utf8Len, 0); + } + auto utf16Len = panda::utf_utils::Utf8ToUtf16Size(utf8Data, utf8Len); + std::vector tmpBuffer(utf16Len); + [[maybe_unused]] auto len = panda::utf_utils::ConvertRegionUtf8ToUtf16(utf8Data, tmpBuffer.data(), utf8Len, + utf16Len); + ASSERT(len == utf16Len); + return ComputeHashForData(tmpBuffer.data(), utf16Len, 0); + } + + /* static */ + uint32_t BaseString::ComputeHashcodeUtf16(const uint16_t* utf16Data, uint32_t length) + { + return ComputeHashForData(utf16Data, length, 0); + } + + + // drop the tail bytes if the remain length can't fill the length it represents. + static size_t FixUtf8Len(const uint8_t* utf8, size_t utf8Len) + { + constexpr size_t TWO_BYTES_LENGTH = 2; + constexpr size_t THREE_BYTES_LENGTH = 3; + size_t trimSize = 0; + if (utf8Len >= 1 && utf8[utf8Len - 1] >= 0xC0) { + // The last one char claim there are more than 1 byte next to it, it's invalid, so drop the last one. + trimSize = 1; + } + if (utf8Len >= TWO_BYTES_LENGTH && utf8[utf8Len - TWO_BYTES_LENGTH] >= 0xE0) { + // The second to last char claim there are more than 2 bytes next to it, it's invalid, so drop the last two. + trimSize = TWO_BYTES_LENGTH; + } + if (utf8Len >= THREE_BYTES_LENGTH && utf8[utf8Len - THREE_BYTES_LENGTH] >= 0xF0) { + // The third to last char claim there are more than 3 bytes next to it, it's invalid, so drop the last + // three. + trimSize = THREE_BYTES_LENGTH; + } + return utf8Len - trimSize; + } + + /* static */ + bool BaseString::IsUtf8EqualsUtf16(const uint8_t* utf8Data, size_t utf8Len, + const uint16_t* utf16Data, uint32_t utf16Len) + { + size_t safeUtf8Len = FixUtf8Len(utf8Data, utf8Len); + const uint8_t* utf8End = utf8Data + utf8Len; + const uint8_t* utf8SafeEnd = utf8Data + safeUtf8Len; + const uint16_t* utf16End = utf16Data + utf16Len; + while (utf8Data < utf8SafeEnd && utf16Data < utf16End) { + uint8_t src = *utf8Data; + switch (src & 0xF0) { + case 0xF0: + { + const uint8_t c2 = *(++utf8Data); + const uint8_t c3 = *(++utf8Data); + const uint8_t c4 = *(++utf8Data); + uint32_t codePoint = ((src & LOW_3BITS) << OFFSET_18POS) | ((c2 & LOW_6BITS) << OFFSET_12POS) | + ((c3 & LOW_6BITS) << OFFSET_6POS) | (c4 & LOW_6BITS); + if (codePoint >= SURROGATE_RAIR_START) { + if (utf16Data >= utf16End - 1) { + return false; + } + codePoint -= SURROGATE_RAIR_START; + if (*utf16Data++ != static_cast((codePoint >> OFFSET_10POS) | + H_SURROGATE_START)) { + return false; + } else if (*utf16Data++ != static_cast((codePoint & 0x3FF) | L_SURROGATE_START)) { + return false; + } + } else { + if (*utf16Data++ != static_cast(codePoint)) { + return false; + } + } + utf8Data++; + break; + } + case 0xE0: + { + const uint8_t c2 = *(++utf8Data); + const uint8_t c3 = *(++utf8Data); + if (*utf16Data++ != static_cast(((src & LOW_4BITS) << OFFSET_12POS) | + ((c2 & LOW_6BITS) << OFFSET_6POS) | (c3 & LOW_6BITS))) { + return false; + } + utf8Data++; + break; + } + case 0xD0: + case 0xC0: + { + const uint8_t c2 = *(++utf8Data); + if (*utf16Data++ != static_cast(((src & LOW_5BITS) << OFFSET_6POS) | (c2 & + LOW_6BITS))) { + return false; + } + utf8Data++; + break; + } + default: + do { + if (*utf16Data++ != static_cast(*utf8Data++)) { + return false; + } + } + while (utf8Data < utf8SafeEnd && utf16Data < utf16End && *utf8Data < 0x80); + break; + } + } + // The remain chars should be treated as single byte char. + while (utf8Data < utf8End && utf16Data < utf16End) { + if (*utf16Data++ != static_cast(*utf8Data++)) { + return false; + } + } + return utf8Data == utf8End && utf16Data == utf16End; + } + + // static + template + uint32_t BaseString::CalculateDataConcatHashCode(const T1* dataFirst, size_t sizeFirst, + const T2* dataSecond, size_t sizeSecond) + { + uint32_t totalHash = ComputeHashForData(dataFirst, sizeFirst, 0); + totalHash = ComputeHashForData(dataSecond, sizeSecond, totalHash); + return totalHash; + } + + template + uint32_t BaseString::CalculateDataConcatHashCode(const uint8_t* dataFirst, size_t sizeFirst, + const uint8_t* dataSecond, size_t sizeSecond); + template + uint32_t BaseString::CalculateDataConcatHashCode(const uint16_t* dataFirst, size_t sizeFirst, + const uint16_t* dataSecond, size_t sizeSecond); + template + uint32_t BaseString::CalculateDataConcatHashCode(const uint8_t* dataFirst, size_t sizeFirst, + const uint16_t* dataSecond, size_t sizeSecond); + template + uint32_t BaseString::CalculateDataConcatHashCode(const uint16_t* dataFirst, size_t sizeFirst, + const uint8_t* dataSecond, size_t sizeSecond); + + + bool BaseString::CanBeCompressed(const BaseString* string) + { + ASSERT(string->IsLineString()); + if (string->IsUtf8()) { + return CanBeCompressed(string->GetDataUtf8(), string->GetLength()); + } + return CanBeCompressed(string->GetDataUtf16(), string->GetLength()); + } + + // static + bool BaseString::CanBeCompressed(const uint8_t* utf8Data, uint32_t utf8Len) + { + uint32_t index = 0; + for (; index + 4 <= utf8Len; index += 4) { + // 4: process the data in chunks of 4 elements to improve speed + // Check if all four characters in the current block are ASCII characters + if (!IsASCIICharacter(utf8Data[index]) || + !IsASCIICharacter(utf8Data[index + 1]) || // 1: the second element of the block + !IsASCIICharacter(utf8Data[index + 2]) || // 2: the third element of the block + !IsASCIICharacter(utf8Data[index + 3])) { + // 3: the fourth element of the block + return false; + } + } + // Check remaining characters if they are ASCII + for (; index < utf8Len; ++index) { + if (!IsASCIICharacter(utf8Data[index])) { + return false; + } + } + return true; + } + + /* static */ + bool BaseString::CanBeCompressed(const uint16_t* utf16Data, uint32_t utf16Len) + { + uint32_t index = 0; + for (; index + 4 <= utf16Len; index += 4) { + // 4: process the data in chunks of 4 elements to improve speed + // Check if all four characters in the current block are ASCII characters + if (!IsASCIICharacter(utf16Data[index]) || + !IsASCIICharacter(utf16Data[index + 1]) || // 1: the second element of the block + !IsASCIICharacter(utf16Data[index + 2]) || // 2: the third element of the block + !IsASCIICharacter(utf16Data[index + 3])) { + // 3: the fourth element of the block + return false; + } + } + // Check remaining characters if they are ASCII + for (; index < utf16Len; ++index) { + if (!IsASCIICharacter(utf16Data[index])) { + return false; + } + } + return true; + } + + + bool BaseString::IsASCIICharacter(uint16_t data) + { + if (data == 0) { + return false; + } + // \0 is not considered ASCII in Ecma-Modified-UTF8 [only modify '\u0000'] + return data <= panda::utf_utils::UTF8_1B_MAX; + } + + + /* static */ + template + int32_t BaseString::IndexOf(Span& lhsSp, Span& rhsSp, int32_t pos, int32_t max) + { + ASSERT(rhsSp.size() > 0); + auto first = static_cast(rhsSp[0]); + for (int32_t i = pos; i <= max; i++) { + if (static_cast(lhsSp[i]) != first) { + i++; + while (i <= max && static_cast(lhsSp[i]) != first) { + i++; + } + } + /* Found first character, now look at the rest of rhsSp */ + if (i <= max) { + int j = i + 1; + int end = j + static_cast(rhsSp.size()) - 1; + + for (int k = 1; j < end && static_cast(lhsSp[j]) == static_cast(rhsSp[k]); j++, k++) { + } + if (j == end) { + /* Found whole string. */ + return i; + } + } + } + return -1; + } + + template + int32_t BaseString::IndexOf(Span& lhsSp, Span& rhsSp, int32_t pos, + int32_t max); + template + int32_t BaseString::IndexOf(Span& lhsSp, Span& rhsSp, + int32_t pos, int32_t max); + + template + int32_t BaseString::IndexOf(Span& lhsSp, Span& rhsSp, int32_t pos, + int32_t max); + + template + int32_t BaseString::IndexOf(Span& lhsSp, Span& rhsSp, int32_t pos, + int32_t max); + + + template + int32_t BaseString::LastIndexOf(Span& lhsSp, Span& rhsSp, int32_t pos) + { + int rhsSize = static_cast(rhsSp.size()); + ASSERT(rhsSize > 0); + auto first = rhsSp[0]; + for (int32_t i = pos; i >= 0; i--) { + if (lhsSp[i] != first) { + continue; + } + /* Found first character, now look at the rest of rhsSp */ + int j = 1; + while (j < rhsSize) { + if (rhsSp[j] != lhsSp[i + j]) { + break; + } + j++; + } + if (j == rhsSize) { + return i; + } + } + return -1; + } + + template + int32_t BaseString::LastIndexOf(Span& lhsSp, Span& rhsSp, + int32_t pos); + template + int32_t BaseString::LastIndexOf(Span& lhsSp, Span& rhsSp, + int32_t pos); + template + int32_t BaseString::LastIndexOf(Span& lhsSp, Span& rhsSp, + int32_t pos); + template + int32_t BaseString::LastIndexOf(Span& lhsSp, Span& rhsSp, + int32_t pos); + + + template + int32_t CompareStringSpan(Span& lhsSp, Span& rhsSp, int32_t count) + { + for (int32_t i = 0; i < count; ++i) { + auto left = static_cast(lhsSp[i]); + auto right = static_cast(rhsSp[i]); + if (left != right) { + return left - right; + } + } + return 0; + } + + template + int32_t CompareStringSpan(Span& lhsSp, Span& rhsSp, + int32_t count); + template + int32_t CompareStringSpan(Span& lhsSp, Span& rhsSp, + int32_t count); + template + int32_t CompareStringSpan(Span& lhsSp, Span& rhsSp, + int32_t count); + template + int32_t CompareStringSpan(Span& lhsSp, Span& rhsSp, + int32_t count); + + + template + bool IsSubStringAtSpan(Span& lhsSp, Span& rhsSp, uint32_t offset) + { + int rhsSize = static_cast(rhsSp.size()); + ASSERT(rhsSize + offset <= lhsSp.size()); + for (int i = 0; i < rhsSize; ++i) { + auto left = static_cast(lhsSp[offset + static_cast(i)]); + auto right = static_cast(rhsSp[i]); + if (left != right) { + return false; + } + } + return true; + } + + template + bool IsSubStringAtSpan(Span& lhsSp, Span& rhsSp, + uint32_t offset); + template + bool IsSubStringAtSpan(Span& lhsSp, Span& rhsSp, + uint32_t offset); + template + bool IsSubStringAtSpan(Span& lhsSp, Span& rhsSp, + uint32_t offset); + template + bool IsSubStringAtSpan(Span& lhsSp, Span& rhsSp, + uint32_t offset); + + + std::u16string Utf16ToU16String(const uint16_t* utf16Data, uint32_t dataLen) + { + auto* char16tData = reinterpret_cast(utf16Data); + std::u16string u16str(char16tData, dataLen); + return u16str; + } + + std::u16string Utf8ToU16String(const uint8_t* utf8Data, uint32_t dataLen) + { + auto* charData = reinterpret_cast(utf8Data); + std::string str(charData, dataLen); + std::u16string u16str = std::wstring_convert, char16_t>{}.from_bytes(str); + return u16str; + } +} // namespace panda::ecmascript diff --git a/ecmascript/base/json_parser.cpp b/ecmascript/base/json_parser.cpp index 1d11d1ab96..d49b396165 100644 --- a/ecmascript/base/json_parser.cpp +++ b/ecmascript/base/json_parser.cpp @@ -1107,7 +1107,7 @@ JSHandle Utf8JsonParser::Parse(const JSHandle &strHan if (LIKELY(stringAccessor.IsLineString())) { sourceString_ = strHandle; } else if (stringAccessor.IsSlicedString()) { - auto *sliced = static_cast(*strHandle); + auto *sliced = static_cast(*strHandle); slicedOffset = sliced->GetStartIndex(); sourceString_ = JSHandle(thread_, EcmaString::Cast(sliced->GetParent())); } else { diff --git a/ecmascript/base/number_helper.cpp b/ecmascript/base/number_helper.cpp index 4aafbae00d..13cf3b6a05 100644 --- a/ecmascript/base/number_helper.cpp +++ b/ecmascript/base/number_helper.cpp @@ -22,6 +22,7 @@ #include "ecmascript/base/dtoa_helper.h" #include "ecmascript/base/string_helper.h" #include "ecmascript/builtins/builtins_number.h" +#include "ecmascript/ecma_string-inl.h" #include "ecmascript/ecma_string_table.h" #include "ecmascript/global_env.h" #include "ecmascript/js_tagged_value-inl.h" diff --git a/ecmascript/builtins/builtins_ark_tools.cpp b/ecmascript/builtins/builtins_ark_tools.cpp index b547f868c7..2e37408419 100644 --- a/ecmascript/builtins/builtins_ark_tools.cpp +++ b/ecmascript/builtins/builtins_ark_tools.cpp @@ -1117,7 +1117,7 @@ JSTaggedValue BuiltinsArkTools::StringMaxLength([[maybe_unused]] EcmaRuntimeCall { RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread()); CHECK(info && info->GetArgsNumber() == 0); - return JSTaggedValue(static_cast(EcmaString::MAX_STRING_LENGTH) - 1); + return JSTaggedValue(static_cast(BaseString::MAX_STRING_LENGTH) - 1); } JSTaggedValue BuiltinsArkTools::ArrayBufferMaxByteLength([[maybe_unused]] EcmaRuntimeCallInfo *info) diff --git a/ecmascript/builtins/builtins_array.cpp b/ecmascript/builtins/builtins_array.cpp index 360249f2e0..77793cd6ec 100644 --- a/ecmascript/builtins/builtins_array.cpp +++ b/ecmascript/builtins/builtins_array.cpp @@ -1339,7 +1339,7 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv) if (len > 0) { allocateLength = sepLength * (len - 1) + len; } - if (allocateLength > EcmaString::MAX_STRING_LENGTH) { + if (allocateLength > BaseString::MAX_STRING_LENGTH) { THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } // 7. ReturnIfAbrupt(sep). @@ -1376,7 +1376,7 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_AND_POP_JOINSTACK(thread, thisHandle); concatStr.append(EcmaStringAccessor(nextStringHandle).ToU16String()); } - if (concatStr.size() > EcmaString::MAX_STRING_LENGTH) { + if (concatStr.size() > BaseString::MAX_STRING_LENGTH) { ArrayJoinStack::Pop(thread, thisHandle); THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } diff --git a/ecmascript/builtins/builtins_global.cpp b/ecmascript/builtins/builtins_global.cpp index 8a1430bd55..579d51a7e6 100644 --- a/ecmascript/builtins/builtins_global.cpp +++ b/ecmascript/builtins/builtins_global.cpp @@ -18,6 +18,7 @@ #include "ecmascript/base/utf_helper.h" #include "ecmascript/builtins/builtins_global_uri-inl.h" #include "ecmascript/containers/containers_errors.h" +#include "ecmascript/ecma_string-inl.h" #include "ecmascript/interpreter/interpreter.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/jspandafile/js_pandafile_manager.h" diff --git a/ecmascript/builtins/builtins_global_uri.cpp b/ecmascript/builtins/builtins_global_uri.cpp index 608bd0a1e6..b0e495d045 100644 --- a/ecmascript/builtins/builtins_global_uri.cpp +++ b/ecmascript/builtins/builtins_global_uri.cpp @@ -162,9 +162,9 @@ JSTaggedValue BuiltinsGlobal::Decode(JSThread *thread, const JSHandleGetParent(); + auto parent = SlicedEcmaString::Cast(string.GetTaggedValue())->GetParent(); auto parentStrAcc = EcmaStringAccessor(parent); - auto startIndex = SlicedString::Cast(string.GetTaggedValue())->GetStartIndex(); + auto startIndex = SlicedEcmaString::Cast(string.GetTaggedValue())->GetStartIndex(); if (parentStrAcc.IsLineString() && !parentStrAcc.IsUtf8()) { result = DoDecode(thread, string, IsInURISet, parentStrAcc.GetDataUtf16() + startIndex); } else { diff --git a/ecmascript/builtins/builtins_number.cpp b/ecmascript/builtins/builtins_number.cpp index a53a9c1040..767f0e66d6 100644 --- a/ecmascript/builtins/builtins_number.cpp +++ b/ecmascript/builtins/builtins_number.cpp @@ -15,6 +15,7 @@ #include "ecmascript/builtins/builtins_number.h" +#include "ecmascript/ecma_string-inl.h" #include "ecmascript/js_function.h" #include "ecmascript/js_primitive_ref.h" #ifdef ARK_SUPPORT_INTL diff --git a/ecmascript/builtins/builtins_shared_typedarray.cpp b/ecmascript/builtins/builtins_shared_typedarray.cpp index c3a4aeed58..984e5c5511 100755 --- a/ecmascript/builtins/builtins_shared_typedarray.cpp +++ b/ecmascript/builtins/builtins_shared_typedarray.cpp @@ -827,7 +827,7 @@ JSTaggedValue BuiltinsSharedTypedArray::Join(EcmaRuntimeCallInfo *argv) // sep unused, set isOneByte to default(true) isOneByte = true; } - if (allocateLength > EcmaString::MAX_STRING_LENGTH) { + if (allocateLength > BaseString::MAX_STRING_LENGTH) { THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } auto newString = EcmaStringAccessor::CreateLineString( diff --git a/ecmascript/builtins/builtins_string.cpp b/ecmascript/builtins/builtins_string.cpp index 198683ae73..58b6501326 100644 --- a/ecmascript/builtins/builtins_string.cpp +++ b/ecmascript/builtins/builtins_string.cpp @@ -989,7 +989,7 @@ JSTaggedValue BuiltinsString::Repeat(EcmaRuntimeCallInfo *argv) if (thisLen == 0) { return thisHandle.GetTaggedValue(); } - if (static_cast(count) >= static_cast(EcmaString::MAX_STRING_LENGTH) / thisLen) { + if (static_cast(count) >= static_cast(BaseString::MAX_STRING_LENGTH) / thisLen) { THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } bool isUtf8 = EcmaStringAccessor(thisHandle).IsUtf8(); @@ -2283,7 +2283,7 @@ JSTaggedValue BuiltinsString::Pad(EcmaRuntimeCallInfo *argv, bool isStart) std::u16string u16strSearch = EcmaStringAccessor(thisHandle).ToU16String(); int64_t fillLen = intMaxLength - stringLength; int64_t len = static_cast(stringBuilder.length()); - if (static_cast(intMaxLength) >= EcmaString::MAX_STRING_LENGTH) { + if (static_cast(intMaxLength) >= BaseString::MAX_STRING_LENGTH) { THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } std::u16string fiString; diff --git a/ecmascript/builtins/builtins_string_iterator.cpp b/ecmascript/builtins/builtins_string_iterator.cpp index a963d6bd59..ab1eee5676 100644 --- a/ecmascript/builtins/builtins_string_iterator.cpp +++ b/ecmascript/builtins/builtins_string_iterator.cpp @@ -14,6 +14,8 @@ */ #include "ecmascript/builtins/builtins_string_iterator.h" + +#include "ecmascript/ecma_string-inl.h" #include "ecmascript/ecma_string_table.h" #include "ecmascript/js_iterator.h" #include "ecmascript/js_string_iterator.h" diff --git a/ecmascript/builtins/builtins_typedarray.cpp b/ecmascript/builtins/builtins_typedarray.cpp index ed3da4c95b..d090a7e444 100644 --- a/ecmascript/builtins/builtins_typedarray.cpp +++ b/ecmascript/builtins/builtins_typedarray.cpp @@ -902,7 +902,7 @@ JSTaggedValue BuiltinsTypedArray::Join(EcmaRuntimeCallInfo *argv) } } allocateLength += static_cast(sepLength) * (length - 1); - if (allocateLength > EcmaString::MAX_STRING_LENGTH) { + if (allocateLength > BaseString::MAX_STRING_LENGTH) { THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } auto newString = diff --git a/ecmascript/compiler/builtins/builtins_number_stub_builder.cpp b/ecmascript/compiler/builtins/builtins_number_stub_builder.cpp index fae53c8b2b..ffe28db0a1 100644 --- a/ecmascript/compiler/builtins/builtins_number_stub_builder.cpp +++ b/ecmascript/compiler/builtins/builtins_number_stub_builder.cpp @@ -429,7 +429,7 @@ GateRef BuiltinsNumberStubBuilder::NumberToString(GateRef number, GateRef radix) newBuilder.AllocLineStringObject(&result, &afterNew, *length, true); Bind(&afterNew); { - GateRef dst = ChangeTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dst = ChangeTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); DEFVARIABLE(cursor, VariableType::INT32(), Int32Sub(*length, Int32(1))); DEFVARIABLE(digit, VariableType::INT32(), Int32(0)); DEFVARIABLE(dstTmp, VariableType::NATIVE_POINTER(), dst); diff --git a/ecmascript/compiler/builtins/builtins_string_stub_builder.cpp b/ecmascript/compiler/builtins/builtins_string_stub_builder.cpp index 054a704ea8..48905cbce0 100644 --- a/ecmascript/compiler/builtins/builtins_string_stub_builder.cpp +++ b/ecmascript/compiler/builtins/builtins_string_stub_builder.cpp @@ -87,7 +87,7 @@ void BuiltinsStringStubBuilder::FromCharCode(GateRef glue, [[maybe_unused]] Gate Bind(&afterNew1); { GateRef dst = ChangeStringTaggedPointerToInt64( - PtrAdd(res->ReadVariable(), IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(res->ReadVariable(), IntPtr(LineString::DATA_OFFSET))); Store(VariableType::INT16(), glue, dst, IntPtr(0), *value); Jump(exit); } @@ -206,7 +206,7 @@ GateRef BuiltinsStringStubBuilder::FastStringCharCodeAt(GateRef glue, GateRef th StringInfoGateRef stringInfoGate(&thisFlat); Label getCharByIndex(env); GateRef stringData = Circuit::NullGate(); - stringData = PtrAdd(stringInfoGate.GetString(), IntPtr(LineEcmaString::DATA_OFFSET)); + stringData = PtrAdd(stringInfoGate.GetString(), IntPtr(LineString::DATA_OFFSET)); Jump(&getCharByIndex); Label isUtf16(env); Label isUtf8(env); @@ -745,7 +745,7 @@ GateRef BuiltinsStringStubBuilder::GetSubString(GateRef glue, GateRef thisValue, } } Bind(¬SingleChar); - BRANCH(Int32GreaterThanOrEqual(len, Int32(SlicedString::MIN_SLICED_ECMASTRING_LENGTH)), + BRANCH(Int32GreaterThanOrEqual(len, Int32(SlicedString::MIN_SLICED_STRING_LENGTH)), &mayGetSliceString, &fastSubstring); Bind(&mayGetSliceString); { @@ -766,7 +766,7 @@ GateRef BuiltinsStringStubBuilder::GetSubString(GateRef glue, GateRef thisValue, { GateRef source1 = PtrAdd(GetNormalStringData(glue, stringInfoGate), fromOffset); GateRef dst = - ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); CopyUtf16AsUtf8(glue, dst, source1, len); Jump(&exit); } @@ -1142,7 +1142,7 @@ GateRef BuiltinsStringStubBuilder::GetSingleCharCodeFromLineString(GateRef str, Label entry(env); env->SubCfgEntry(&entry); DEFVARIABLE(result, VariableType::INT32(), Int32(0)); - GateRef dataAddr = ChangeStringTaggedPointerToInt64(PtrAdd(str, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dataAddr = ChangeStringTaggedPointerToInt64(PtrAdd(str, IntPtr(LineString::DATA_OFFSET))); Label isUtf16(env); Label isUtf8(env); Label exit(env); @@ -1210,7 +1210,7 @@ GateRef BuiltinsStringStubBuilder::CreateStringBySingleCharCode(GateRef glue, Ga { Label isUtf8Copy(env); Label isUtf16Copy(env); - GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); BRANCH(canStoreAsUtf8, &isUtf8Copy, &isUtf16Copy); Bind(&isUtf8Copy); { @@ -1282,7 +1282,7 @@ GateRef BuiltinsStringStubBuilder::CreateFromEcmaString(GateRef glue, GateRef in { Label isUtf8Copy(env); Label isUtf16Copy(env); - GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); BRANCH(*canBeCompressed, &isUtf8Copy, &isUtf16Copy); Bind(&isUtf8Copy); { @@ -1369,7 +1369,7 @@ GateRef BuiltinsStringStubBuilder::FastSubUtf8String(GateRef glue, GateRef from, newBuilder.AllocLineStringObject(&result, &afterNew, len, true); Bind(&afterNew); { - GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); GateRef source = PtrAdd(GetNormalStringData(glue, stringInfoGate), ZExtInt32ToPtr(from)); CopyChars(glue, dst, source, len, IntPtr(sizeof(uint8_t)), VariableType::INT8()); Jump(&exit); @@ -1412,7 +1412,7 @@ GateRef BuiltinsStringStubBuilder::FastSubUtf16String(GateRef glue, GateRef from Bind(&afterNew); { GateRef source1 = PtrAdd(GetNormalStringData(glue, stringInfoGate), fromOffset); - GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); BRANCH(canBeCompressed, &isUtf8Next, &isUtf16Next); Bind(&isUtf8Next); { @@ -2161,7 +2161,7 @@ void BuiltinsStringStubBuilder::ToLowerCase(GateRef glue, GateRef thisValue, [[m StringInfoGateRef stringInfoGate(&thisFlat); GateRef dataUtf8 = GetNormalStringData(glue, stringInfoGate); GateRef dst = ChangeStringTaggedPointerToInt64(PtrAdd(res->ReadVariable(), - IntPtr(LineEcmaString::DATA_OFFSET))); + IntPtr(LineString::DATA_OFFSET))); DEFVARIABLE(dstTmp, VariableType::NATIVE_POINTER(), dst); DEFVARIABLE(sourceTmp, VariableType::NATIVE_POINTER(), dataUtf8); Label loopHead(env); @@ -2245,11 +2245,11 @@ GateRef BuiltinsStringStubBuilder::StringAdd(GateRef glue, GateRef leftString, G Label stringConcatOpt(&builder_); GateRef newLength = builder_.Int32Add(leftLength, rightLength); BRANCH_CIR(builder_.Int32LessThan(newLength, - builder_.Int32(SlicedString::MIN_SLICED_ECMASTRING_LENGTH)), &slowPath, &stringConcatOpt); + builder_.Int32(SlicedString::MIN_SLICED_STRING_LENGTH)), &slowPath, &stringConcatOpt); builder_.Bind(&stringConcatOpt); { GateRef backStoreLength = - builder_.Int32Mul(newLength, builder_.Int32(LineEcmaString::INIT_LENGTH_TIMES)); + builder_.Int32Mul(newLength, builder_.Int32(LineString::INIT_LENGTH_TIMES)); GateRef leftIsUtf8 = builder_.IsUtf8String(left); GateRef rightIsUtf8 = builder_.IsUtf8String(right); GateRef canBeCompressed = builder_.BitAnd(leftIsUtf8, rightIsUtf8); @@ -2264,7 +2264,7 @@ GateRef BuiltinsStringStubBuilder::StringAdd(GateRef glue, GateRef leftString, G Label canBeCompress(&builder_); Label canNotBeCompress(&builder_); Label newSlicedStr(&builder_); - BRANCH_CIR(builder_.Int32LessThan(builder_.Int32(LineEcmaString::MAX_LENGTH), + BRANCH_CIR(builder_.Int32LessThan(builder_.Int32(LineString::MAX_LENGTH), backStoreLength), &slowPath, &fastPath); builder_.Bind(&fastPath); { @@ -2274,11 +2274,11 @@ GateRef BuiltinsStringStubBuilder::StringAdd(GateRef glue, GateRef leftString, G { lineString = AllocateLineString(glue, backStoreLength, canBeCompressed); GateRef leftSource = ChangeStringTaggedPointerToInt64( - PtrAdd(left, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(left, IntPtr(LineString::DATA_OFFSET))); GateRef rightSource = ChangeStringTaggedPointerToInt64( - PtrAdd(right, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(right, IntPtr(LineString::DATA_OFFSET))); GateRef leftDst = builder_.TaggedPointerToInt64( - builder_.PtrAdd(*lineString, builder_.IntPtr(LineEcmaString::DATA_OFFSET))); + builder_.PtrAdd(*lineString, builder_.IntPtr(LineString::DATA_OFFSET))); BRANCH_CIR(canBeCompressed, &canBeCompress, &canNotBeCompress); builder_.Bind(&canBeCompress); { @@ -2349,21 +2349,21 @@ GateRef BuiltinsStringStubBuilder::StringAdd(GateRef glue, GateRef leftString, G Label newLineStr(&builder_); Label canBeCompress(&builder_); Label canNotBeCompress(&builder_); - // The new backing store will have a length of min(2*length, LineEcmaString::MAX_LENGTH). + // The new backing store will have a length of min(2*length, LineString::MAX_LENGTH). GateRef newBackStoreLength = builder_.Int32Mul(newLength, builder_.Int32(2)); BRANCH_CIR(builder_.Int32LessThan(newBackStoreLength, - builder_.Int32(LineEcmaString::MAX_LENGTH)), &newLineStr, &slowPath); + builder_.Int32(LineString::MAX_LENGTH)), &newLineStr, &slowPath); builder_.Bind(&newLineStr); { GateRef newBackingStore = AllocateLineString(glue, newBackStoreLength, canBeCompressed); GateRef leftSource = ChangeStringTaggedPointerToInt64( - PtrAdd(*lineString, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(*lineString, IntPtr(LineString::DATA_OFFSET))); GateRef rightSource = ChangeStringTaggedPointerToInt64( - PtrAdd(right, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(right, IntPtr(LineString::DATA_OFFSET))); GateRef leftDst = builder_.TaggedPointerToInt64( builder_.PtrAdd(newBackingStore, - builder_.IntPtr(LineEcmaString::DATA_OFFSET))); + builder_.IntPtr(LineString::DATA_OFFSET))); BRANCH_CIR(canBeCompressed, &canBeCompress, &canNotBeCompress); builder_.Bind(&canBeCompress); { @@ -2403,9 +2403,9 @@ GateRef BuiltinsStringStubBuilder::StringAdd(GateRef glue, GateRef leftString, G Label canBeCompress(&builder_); Label canNotBeCompress(&builder_); GateRef rightSource = ChangeStringTaggedPointerToInt64( - PtrAdd(right, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(right, IntPtr(LineString::DATA_OFFSET))); GateRef leftDst = builder_.TaggedPointerToInt64( - builder_.PtrAdd(*lineString, builder_.IntPtr(LineEcmaString::DATA_OFFSET))); + builder_.PtrAdd(*lineString, builder_.IntPtr(LineString::DATA_OFFSET))); BRANCH_CIR(canBeCompressed, &canBeCompress, &canNotBeCompress); builder_.Bind(&canBeCompress); { @@ -2484,7 +2484,7 @@ GateRef BuiltinsStringStubBuilder::AllocateLineString(GateRef glue, GateRef leng builder_.IntPtr(0), stringClass, MemoryAttribute::NeedBarrierAndAtomic()); InitStringLengthAndFlags(glue, lineString, length, canBeCompressed); builder_.Store(VariableType::INT32(), glue, lineString, - builder_.IntPtr(EcmaString::RAW_HASHCODE_OFFSET), builder_.Int32(0)); + builder_.IntPtr(BaseString::RAW_HASHCODE_OFFSET), builder_.Int32(0)); auto ret = builder_.FinishAllocate(lineString); builder_.SubCfgExit(); return ret; @@ -2510,7 +2510,7 @@ GateRef BuiltinsStringStubBuilder::AllocateSlicedString(GateRef glue, GateRef fl builder_.IntPtr(0), stringClass, MemoryAttribute::NeedBarrierAndAtomic()); InitStringLengthAndFlags(glue, slicedString, length, canBeCompressed); builder_.Store(VariableType::INT32(), glue, slicedString, - builder_.IntPtr(EcmaString::RAW_HASHCODE_OFFSET), builder_.Int32(0)); + builder_.IntPtr(BaseString::RAW_HASHCODE_OFFSET), builder_.Int32(0)); builder_.Store(VariableType::JS_POINTER(), glue, slicedString, builder_.IntPtr(SlicedString::PARENT_OFFSET), flatString); StoreStartIndexAndBackingStore(glue, slicedString, builder_.Int32(0), builder_.Boolean(true)); @@ -2546,8 +2546,8 @@ GateRef BuiltinsStringStubBuilder::IsFirstConcatInStringAdd(GateRef init, GateRe { auto env = GetEnvironment(); auto judgeStatus = LogicOrBuilder(env) - .Or(Int32Equal(status, Int32(EcmaString::BEGIN_STRING_ADD))) - .Or(Int32Equal(status, Int32(EcmaString::IN_STRING_ADD))) + .Or(Int32Equal(status, Int32(BaseString::BEGIN_STRING_ADD))) + .Or(Int32Equal(status, Int32(BaseString::IN_STRING_ADD))) .Done(); return LogicAndBuilder(env).And(init).And(judgeStatus).Done(); } @@ -2556,9 +2556,9 @@ GateRef BuiltinsStringStubBuilder::ConcatIsInStringAdd(GateRef init, GateRef sta { auto env = GetEnvironment(); auto judgeStatus = LogicOrBuilder(env) - .Or(Int32Equal(status, Int32(EcmaString::BEGIN_STRING_ADD))) - .Or(Int32Equal(status, Int32(EcmaString::IN_STRING_ADD))) - .Or(Int32Equal(status, Int32(EcmaString::CONFIRMED_IN_STRING_ADD))) + .Or(Int32Equal(status, Int32(BaseString::BEGIN_STRING_ADD))) + .Or(Int32Equal(status, Int32(BaseString::IN_STRING_ADD))) + .Or(Int32Equal(status, Int32(BaseString::CONFIRMED_IN_STRING_ADD))) .Done(); return LogicAndBuilder(env).And(init).And(judgeStatus).Done(); } @@ -2578,7 +2578,7 @@ GateRef BuiltinsStringStubBuilder::StringConcat(GateRef glue, GateRef leftString GateRef leftLength = GetLengthFromString(leftString); GateRef rightLength = GetLengthFromString(rightString); GateRef newLength = Int32Add(leftLength, rightLength); - BRANCH(Int32UnsignedGreaterThanOrEqual(newLength, Int32(EcmaString::MAX_STRING_LENGTH)), &throwError, &lessThanMax); + BRANCH(Int32UnsignedGreaterThanOrEqual(newLength, Int32(BaseString::MAX_STRING_LENGTH)), &throwError, &lessThanMax); Bind(&throwError); { GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(InvalidStringLength)); @@ -2623,8 +2623,8 @@ GateRef BuiltinsStringStubBuilder::StringConcat(GateRef glue, GateRef leftString NewObjectStubBuilder newBuilder(this); newBuilder.SetParameters(glue, 0); GateRef isTreeOrSlicedString = Int32UnsignedLessThan(newLength, - Int32(std::min(TreeEcmaString::MIN_TREE_ECMASTRING_LENGTH, - SlicedString::MIN_SLICED_ECMASTRING_LENGTH))); + Int32(std::min(TreeString::MIN_TREE_STRING_LENGTH, + SlicedString::MIN_SLICED_STRING_LENGTH))); BRANCH(isTreeOrSlicedString, &newLineString, &newTreeString); Bind(&newLineString); { @@ -2644,11 +2644,11 @@ GateRef BuiltinsStringStubBuilder::StringConcat(GateRef glue, GateRef leftString Bind(&isUtf8Next); { GateRef leftSource = ChangeStringTaggedPointerToInt64( - PtrAdd(leftString, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(leftString, IntPtr(LineString::DATA_OFFSET))); GateRef rightSource = ChangeStringTaggedPointerToInt64( - PtrAdd(rightString, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(rightString, IntPtr(LineString::DATA_OFFSET))); GateRef leftDst = ChangeStringTaggedPointerToInt64( - PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); GateRef rightDst = ChangeStringTaggedPointerToInt64(PtrAdd(leftDst, ZExtInt32ToPtr(leftLength))); CopyChars(glue, leftDst, leftSource, leftLength, IntPtr(sizeof(uint8_t)), VariableType::INT8()); CopyChars(glue, rightDst, rightSource, rightLength, IntPtr(sizeof(uint8_t)), VariableType::INT8()); @@ -2661,11 +2661,11 @@ GateRef BuiltinsStringStubBuilder::StringConcat(GateRef glue, GateRef leftString Label rightIsUtf8L(env); Label rightIsUtf16L(env); GateRef leftSource = ChangeStringTaggedPointerToInt64( - PtrAdd(leftString, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(leftString, IntPtr(LineString::DATA_OFFSET))); GateRef rightSource = ChangeStringTaggedPointerToInt64( - PtrAdd(rightString, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(rightString, IntPtr(LineString::DATA_OFFSET))); GateRef leftDst = ChangeStringTaggedPointerToInt64( - PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); GateRef rightDst = ChangeStringTaggedPointerToInt64( PtrAdd(leftDst, PtrMul(ZExtInt32ToPtr(leftLength), IntPtr(sizeof(uint16_t))))); BRANCH(leftIsUtf8, &leftIsUtf8L, &leftIsUtf16L); @@ -3399,7 +3399,7 @@ void BuiltinsStringStubBuilder::PadStart(GateRef glue, GateRef thisValue, GateRe Bind(&lengthIsInt); { newStringLength = GetInt32OfTInt(newLength); - BRANCH(Int32GreaterThanOrEqual(*newStringLength, Int32(EcmaString::MAX_STRING_LENGTH)), + BRANCH(Int32GreaterThanOrEqual(*newStringLength, Int32(BaseString::MAX_STRING_LENGTH)), slowPath, &next); } Bind(&lengthNotInt); @@ -3410,7 +3410,7 @@ void BuiltinsStringStubBuilder::PadStart(GateRef glue, GateRef thisValue, GateRe Bind(&newLengthIsNotNaN); BRANCH(DoubleIsINF(GetDoubleOfTDouble(newLength)), slowPath, &newLengthIsNotINF); Bind(&newLengthIsNotINF); - BRANCH(DoubleGreaterThanOrEqual(GetDoubleOfTDouble(newLength), Double(EcmaString::MAX_STRING_LENGTH)), + BRANCH(DoubleGreaterThanOrEqual(GetDoubleOfTDouble(newLength), Double(BaseString::MAX_STRING_LENGTH)), slowPath, &newLengthInRange); Bind(&newLengthInRange); newStringLength = DoubleToInt(glue, GetDoubleOfTDouble(newLength)); @@ -3524,7 +3524,7 @@ void BuiltinsStringStubBuilder::PadEnd(GateRef glue, GateRef thisValue, GateRef Bind(&lengthIsInt); { newStringLength = GetInt32OfTInt(newLength); - BRANCH(Int32GreaterThanOrEqual(*newStringLength, Int32(EcmaString::MAX_STRING_LENGTH)), + BRANCH(Int32GreaterThanOrEqual(*newStringLength, Int32(BaseString::MAX_STRING_LENGTH)), slowPath, &next); } Bind(&lengthNotInt); @@ -3535,7 +3535,7 @@ void BuiltinsStringStubBuilder::PadEnd(GateRef glue, GateRef thisValue, GateRef Bind(&padLengthIsNotNaN); BRANCH(DoubleIsINF(GetDoubleOfTDouble(newLength)), slowPath, &padLengthIsNotINF); Bind(&padLengthIsNotINF); - BRANCH(DoubleGreaterThanOrEqual(GetDoubleOfTDouble(newLength), Double(EcmaString::MAX_STRING_LENGTH)), + BRANCH(DoubleGreaterThanOrEqual(GetDoubleOfTDouble(newLength), Double(BaseString::MAX_STRING_LENGTH)), slowPath, &newLengthInRange); Bind(&newLengthInRange); newStringLength = DoubleToInt(glue, GetDoubleOfTDouble(newLength)); diff --git a/ecmascript/compiler/builtins_lowering.cpp b/ecmascript/compiler/builtins_lowering.cpp index b79b6303f2..19861d34ee 100644 --- a/ecmascript/compiler/builtins_lowering.cpp +++ b/ecmascript/compiler/builtins_lowering.cpp @@ -500,7 +500,7 @@ void BuiltinLowering::LowerNumberConstructor(GateRef gate) builder_.Bind(&nonZeroLength); Label isInteger(env); BuiltinsStringStubBuilder stringStub(builder_.GetCurrentEnvironment(), builder_.GetGlobalEnv(glue)); - GateRef dataUtf8 = builder_.PtrAdd(param, builder_.IntPtr(LineEcmaString::DATA_OFFSET)); + GateRef dataUtf8 = builder_.PtrAdd(param, builder_.IntPtr(LineString::DATA_OFFSET)); GateRef res = stringStub.StringDataToUint(dataUtf8, length, std::numeric_limits::max()); BRANCH_CIR(builder_.Int64NotEqual(res, builder_.Int64(-1)), &isInteger, ¬LineUtf8String); builder_.Bind(&isInteger); diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 9d8d996322..9526f6339b 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -540,25 +540,25 @@ GateRef CircuitBuilder::HasPendingException(GateRef glue) GateRef CircuitBuilder::IsUtf8String(GateRef string) { // compressedStringsEnabled fixed to true constant - GateRef len = LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); + GateRef len = LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); return Int32Equal( - Int32And(len, Int32((1 << EcmaString::CompressedStatusBit::SIZE) - 1)), - Int32(EcmaString::STRING_COMPRESSED)); + Int32And(len, Int32((1 << BaseString::CompressedStatusBit::SIZE) - 1)), + Int32(BaseString::STRING_COMPRESSED)); } GateRef CircuitBuilder::IsUtf16String(GateRef string) { // compressedStringsEnabled fixed to true constant - GateRef len = LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); + GateRef len = LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); return Int32Equal( - Int32And(len, Int32((1 << EcmaString::CompressedStatusBit::SIZE) - 1)), - Int32(EcmaString::STRING_UNCOMPRESSED)); + Int32And(len, Int32((1 << BaseString::CompressedStatusBit::SIZE) - 1)), + Int32(BaseString::STRING_UNCOMPRESSED)); } GateRef CircuitBuilder::IsInternString(GateRef string) { - GateRef len = LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); - return Int32NotEqual(Int32And(len, Int32(1 << EcmaString::IsInternBit::START_BIT)), Int32(0)); + GateRef len = LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); + return Int32NotEqual(Int32And(len, Int32(1 << BaseString::IsInternBit::START_BIT)), Int32(0)); } GateRef CircuitBuilder::GetGlobalEnv(GateRef glue) diff --git a/ecmascript/compiler/hcr_circuit_builder.h b/ecmascript/compiler/hcr_circuit_builder.h index 1a9c4ee94c..edf96c83a6 100644 --- a/ecmascript/compiler/hcr_circuit_builder.h +++ b/ecmascript/compiler/hcr_circuit_builder.h @@ -138,12 +138,12 @@ GateRef CircuitBuilder::IsLineString(GateRef glue, GateRef obj) GateRef CircuitBuilder::ComputeSizeUtf8(GateRef length) { - return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), length); + return PtrAdd(IntPtr(LineString::DATA_OFFSET), length); } GateRef CircuitBuilder::ComputeSizeUtf16(GateRef length) { - return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t)))); + return PtrAdd(IntPtr(LineString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t)))); } GateRef CircuitBuilder::AlignUp(GateRef x, GateRef alignment) diff --git a/ecmascript/compiler/mcr_circuit_builder.cpp b/ecmascript/compiler/mcr_circuit_builder.cpp index c4b8491596..6a8dca57fb 100644 --- a/ecmascript/compiler/mcr_circuit_builder.cpp +++ b/ecmascript/compiler/mcr_circuit_builder.cpp @@ -1305,13 +1305,13 @@ GateRef CircuitBuilder::InsertLoadArrayLength(GateRef array, GateRef length, boo void CircuitBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode) { - Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::RAW_HASHCODE_OFFSET), rawHashcode); + Store(VariableType::INT32(), glue, str, IntPtr(BaseString::RAW_HASHCODE_OFFSET), rawHashcode); } GateRef CircuitBuilder::GetLengthFromString(GateRef value) { - GateRef len = LoadWithoutBarrier(VariableType::INT32(), value, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); - return Int32LSR(len, Int32(EcmaString::LengthBits::START_BIT)); + GateRef len = LoadWithoutBarrier(VariableType::INT32(), value, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); + return Int32LSR(len, Int32(BaseString::LengthBits::START_BIT)); } GateRef CircuitBuilder::Rotl(GateRef word, uint32_t shift) @@ -1358,12 +1358,12 @@ GateRef CircuitBuilder::GetHashcodeFromString(GateRef glue, GateRef value, GateR Label noRawHashcode(env_); Label exit(env_); DEFVALUE(hashcode, env_, VariableType::INT32(), Int32(0)); - hashcode = LoadWithoutBarrier(VariableType::INT32(), value, IntPtr(EcmaString::RAW_HASHCODE_OFFSET)); + hashcode = LoadWithoutBarrier(VariableType::INT32(), value, IntPtr(BaseString::RAW_HASHCODE_OFFSET)); BRANCH(Int32Equal(*hashcode, Int32(0)), &noRawHashcode, &exit); Bind(&noRawHashcode); { hashcode = CallCommonStub(glue, hir, CommonStubCSigns::ComputeStringHashcode, {glue, value}); - Store(VariableType::INT32(), glue, value, IntPtr(EcmaString::RAW_HASHCODE_OFFSET), *hashcode); + Store(VariableType::INT32(), glue, value, IntPtr(BaseString::RAW_HASHCODE_OFFSET), *hashcode); Jump(&exit); } Bind(&exit); @@ -1381,7 +1381,7 @@ GateRef CircuitBuilder::TryGetHashcodeFromString(GateRef string) Label exit(env_); DEFVALUE(result, env_, VariableType::INT64(), Int64(-1)); GateRef hashCode = ZExtInt32ToInt64( - LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(EcmaString::RAW_HASHCODE_OFFSET))); + LoadWithoutBarrier(VariableType::INT32(), string, IntPtr(BaseString::RAW_HASHCODE_OFFSET))); BRANCH(Int64Equal(hashCode, Int64(0)), &noRawHashcode, &storeHash); Bind(&noRawHashcode); { diff --git a/ecmascript/compiler/mcr_circuit_builder.h b/ecmascript/compiler/mcr_circuit_builder.h index ba75ee9ac6..44be09d9df 100644 --- a/ecmascript/compiler/mcr_circuit_builder.h +++ b/ecmascript/compiler/mcr_circuit_builder.h @@ -762,13 +762,13 @@ GateRef CircuitBuilder::TreeStringIsFlat(GateRef glue, GateRef string) GateRef CircuitBuilder::GetFirstFromTreeString(GateRef glue, GateRef string) { - GateRef offset = IntPtr(TreeEcmaString::FIRST_OFFSET); + GateRef offset = IntPtr(TreeString::FIRST_OFFSET); return Load(VariableType::JS_POINTER(), glue, string, offset); } GateRef CircuitBuilder::GetSecondFromTreeString(GateRef glue, GateRef string) { - GateRef offset = IntPtr(TreeEcmaString::SECOND_OFFSET); + GateRef offset = IntPtr(TreeString::SECOND_OFFSET); return Load(VariableType::JS_POINTER(), glue, string, offset); } diff --git a/ecmascript/compiler/new_object_stub_builder.cpp b/ecmascript/compiler/new_object_stub_builder.cpp index e23a54a17a..90a8fbd760 100644 --- a/ecmascript/compiler/new_object_stub_builder.cpp +++ b/ecmascript/compiler/new_object_stub_builder.cpp @@ -1743,8 +1743,8 @@ void NewObjectStubBuilder::AllocSlicedStringObject(Variable *result, Label *exit Bind(&afterAllocate); StoreHClass(glue_, result->ReadVariable(), stringClass); GateRef mixLength = LoadPrimitive(VariableType::INT32(), flatString->GetFlatString(), - IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); - GateRef compressedStatus = TruncInt32ToInt1(Int32And(Int32((1 << EcmaString::CompressedStatusBit::SIZE) - 1), + IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); + GateRef compressedStatus = TruncInt32ToInt1(Int32And(Int32((1 << BaseString::CompressedStatusBit::SIZE) - 1), mixLength)); InitStringLengthAndFlags(glue_, result->ReadVariable(), length, BoolNot(compressedStatus)); // decode compressedStatus to bool @@ -1763,7 +1763,7 @@ void NewObjectStubBuilder::AllocTreeStringObject(Variable *result, Label *exit, { auto env = GetEnvironment(); - size_ = AlignUp(IntPtr(TreeEcmaString::SIZE), IntPtr(static_cast(MemAlignment::MEM_ALIGN_OBJECT))); + size_ = AlignUp(IntPtr(TreeString::SIZE), IntPtr(static_cast(MemAlignment::MEM_ALIGN_OBJECT))); Label afterAllocate(env); GateRef stringClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue_, ConstantIndex::TREE_STRING_CLASS_INDEX); @@ -1773,8 +1773,8 @@ void NewObjectStubBuilder::AllocTreeStringObject(Variable *result, Label *exit, StoreHClass(glue_, result->ReadVariable(), stringClass); InitStringLengthAndFlags(glue_, result->ReadVariable(), length, compressed); SetRawHashcode(glue_, result->ReadVariable(), Int32(0)); - Store(VariableType::JS_POINTER(), glue_, result->ReadVariable(), IntPtr(TreeEcmaString::FIRST_OFFSET), first); - Store(VariableType::JS_POINTER(), glue_, result->ReadVariable(), IntPtr(TreeEcmaString::SECOND_OFFSET), second); + Store(VariableType::JS_POINTER(), glue_, result->ReadVariable(), IntPtr(TreeString::FIRST_OFFSET), first); + Store(VariableType::JS_POINTER(), glue_, result->ReadVariable(), IntPtr(TreeString::SECOND_OFFSET), second); Jump(exit); } diff --git a/ecmascript/compiler/string_builder_optimizer.cpp b/ecmascript/compiler/string_builder_optimizer.cpp index 16ee3e794e..1247867f2f 100644 --- a/ecmascript/compiler/string_builder_optimizer.cpp +++ b/ecmascript/compiler/string_builder_optimizer.cpp @@ -198,19 +198,19 @@ void StringBuilderOptimizer::StatusTransfer(GateRef gate) Status status = GetStatus(gate); switch (status.state) { case State::BEGIN_STRING_BUILDER: - acc_.SetStringStatus(gate, EcmaString::BEGIN_STRING_ADD); + acc_.SetStringStatus(gate, BaseString::BEGIN_STRING_ADD); break; case State::IN_STRING_BUILDER: - acc_.SetStringStatus(gate, EcmaString::IN_STRING_ADD); + acc_.SetStringStatus(gate, BaseString::IN_STRING_ADD); break; case State::CONFIRMED_IN_STRING_BUILDER: - acc_.SetStringStatus(gate, EcmaString::CONFIRMED_IN_STRING_ADD); + acc_.SetStringStatus(gate, BaseString::CONFIRMED_IN_STRING_ADD); break; case State::END_STRING_BUILDER: - acc_.SetStringStatus(gate, EcmaString::END_STRING_ADD); + acc_.SetStringStatus(gate, BaseString::END_STRING_ADD); break; default: { - acc_.SetStringStatus(gate, EcmaString::INVALID_STRING_ADD); + acc_.SetStringStatus(gate, BaseString::INVALID_STRING_ADD); break; } } diff --git a/ecmascript/compiler/stub_builder-inl.h b/ecmascript/compiler/stub_builder-inl.h index d2b0406296..5186779cbc 100644 --- a/ecmascript/compiler/stub_builder-inl.h +++ b/ecmascript/compiler/stub_builder-inl.h @@ -806,7 +806,8 @@ inline GateRef StubBuilder::TaggedIsSpecial(GateRef x) inline GateRef StubBuilder::TaggedIsRegularObject(GateRef glue, GateRef x) { GateRef objectType = GetObjectType(LoadHClass(glue, x)); - return Int32LessThan(objectType, Int32(static_cast(JSType::JS_API_ARRAY_LIST))); + return BitAnd(Int32LessThan(objectType, Int32(static_cast(JSType::JS_API_ARRAY_LIST))), + Int32GreaterThan(objectType, Int32(static_cast(JSType::STRING_LAST)))); } inline GateRef StubBuilder::TaggedIsHeapObject(GateRef x) @@ -2587,7 +2588,9 @@ inline GateRef StubBuilder::GetValueFromMutantTaggedArray(GateRef elements, Gate inline GateRef StubBuilder::IsSpecialIndexedObj(GateRef jsType) { - return Int32GreaterThan(jsType, Int32(static_cast(JSType::JS_ARRAY))); + return BitOr(Int32GreaterThan(jsType, Int32(static_cast(JSType::JS_ARRAY))), + BitAnd(Int32GreaterThanOrEqual(jsType, Int32(static_cast(JSType::STRING_FIRST))), + Int32LessThanOrEqual(jsType, Int32(static_cast(JSType::STRING_LAST))))); } inline void StubBuilder::SharedObjectStoreBarrierWithTypeCheck(bool isDicMode, Variable *result, GateRef glue, @@ -3831,12 +3834,12 @@ inline GateRef StubBuilder::GetBuiltinId(GateRef method) inline GateRef StubBuilder::ComputeSizeUtf8(GateRef length) { - return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), length); + return PtrAdd(IntPtr(LineString::DATA_OFFSET), length); } inline GateRef StubBuilder::ComputeSizeUtf16(GateRef length) { - return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t)))); + return PtrAdd(IntPtr(LineString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t)))); } inline GateRef StubBuilder::AlignUp(GateRef x, GateRef alignment) @@ -3852,21 +3855,21 @@ inline GateRef StubBuilder::AlignDown(GateRef x, GateRef alignment) inline void StubBuilder::InitStringLengthAndFlags(GateRef glue, GateRef str, GateRef length, bool compressed) { - GateRef len = Int32LSL(length, Int32(EcmaString::LengthBits::START_BIT)); + GateRef len = Int32LSL(length, Int32(BaseString::LengthBits::START_BIT)); GateRef mixLength; if (compressed) { - mixLength = Int32Or(len, Int32(EcmaString::STRING_COMPRESSED)); + mixLength = Int32Or(len, Int32(BaseString::STRING_COMPRESSED)); } else { - mixLength = Int32Or(len, Int32(EcmaString::STRING_UNCOMPRESSED)); + mixLength = Int32Or(len, Int32(BaseString::STRING_UNCOMPRESSED)); } - Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET), mixLength); + Store(VariableType::INT32(), glue, str, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET), mixLength); } inline void StubBuilder::InitStringLengthAndFlags(GateRef glue, GateRef str, GateRef length, GateRef isCompressed) { - GateRef len = Int32LSL(length, Int32(EcmaString::LengthBits::START_BIT)); + GateRef len = Int32LSL(length, Int32(BaseString::LengthBits::START_BIT)); GateRef mixLength = Int32Or(len, ZExtInt1ToInt32(BoolNot(isCompressed))); // encode bool to CompressedStatus - Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET), mixLength); + Store(VariableType::INT32(), glue, str, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET), mixLength); } inline void StubBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode) @@ -4233,7 +4236,7 @@ inline GateRef StubBuilder::HashFromHclassAndStringKey([[maybe_unused]] GateRef Int64LSR(hclassRef, Int64(MegaICCache::PRIMARY_LENGTH_BIT)))); // skip 8bytes GateRef keyHash = Load(VariableType::INT32(), glue, key, - IntPtr(EcmaString::RAW_HASHCODE_OFFSET)); + IntPtr(BaseString::RAW_HASHCODE_OFFSET)); GateRef temp = Int32Add(clsHash, keyHash); return Int32And(temp, Int32(MegaICCache::PRIMARY_LENGTH_MASK)); } diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 53349385bf..b9491cc2ab 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -2244,19 +2244,19 @@ GateRef StubBuilder::TaggedIsInternalAccessor(GateRef glue, GateRef x) GateRef StubBuilder::IsUtf16String(GateRef string) { // compressedStringsEnabled fixed to true constant - GateRef len = LoadPrimitive(VariableType::INT32(), string, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); + GateRef len = LoadPrimitive(VariableType::INT32(), string, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); return Int32Equal( - Int32And(len, Int32((1 << EcmaString::CompressedStatusBit::SIZE) - 1)), - Int32(EcmaString::STRING_UNCOMPRESSED)); + Int32And(len, Int32((1 << BaseString::CompressedStatusBit::SIZE) - 1)), + Int32(BaseString::STRING_UNCOMPRESSED)); } GateRef StubBuilder::IsUtf8String(GateRef string) { // compressedStringsEnabled fixed to true constant - GateRef len = LoadPrimitive(VariableType::INT32(), string, IntPtr(EcmaString::LENGTH_AND_FLAGS_OFFSET)); + GateRef len = LoadPrimitive(VariableType::INT32(), string, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET)); return Int32Equal( - Int32And(len, Int32((1 << EcmaString::CompressedStatusBit::SIZE) - 1)), - Int32(EcmaString::STRING_COMPRESSED)); + Int32And(len, Int32((1 << BaseString::CompressedStatusBit::SIZE) - 1)), + Int32(BaseString::STRING_COMPRESSED)); } GateRef StubBuilder::IsDigit(GateRef ch) @@ -9904,7 +9904,7 @@ GateRef StubBuilder::GetNormalStringData([[maybe_unused]] GateRef glue, const St Label isUtf16(env); DEFVARIABLE(result, VariableType::NATIVE_POINTER(), Undefined()); GateRef data = ChangeTaggedPointerToInt64( - PtrAdd(stringInfoGate.GetString(), IntPtr(LineEcmaString::DATA_OFFSET))); + PtrAdd(stringInfoGate.GetString(), IntPtr(LineString::DATA_OFFSET))); BRANCH(IsUtf8String(stringInfoGate.GetString()), &isUtf8, &isUtf16); Bind(&isUtf8); { @@ -10429,7 +10429,7 @@ GateRef StubBuilder::IntToEcmaString(GateRef glue, GateRef number) newBuilder.AllocLineStringObject(&result, &afterNew, Int32(1), true); Bind(&afterNew); n = Int32Add(Int32('0'), *n); - GateRef dst = ChangeTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET))); + GateRef dst = ChangeTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineString::DATA_OFFSET))); Store(VariableType::INT8(), glue, dst, IntPtr(0), TruncInt32ToInt8(*n)); Jump(&exit); } @@ -12867,7 +12867,7 @@ void StubBuilder::ComputeRawHashcode(GateRef glue, Label *exit, Variable* result Label loopHead(env); Label loopEnd(env); Label doLoop(env); - GateRef hashShift = Int32(static_cast(EcmaStringHash::HASH_SHIFT)); + GateRef hashShift = Int32(static_cast(BaseString::HASH_SHIFT)); GateRef length = stringGate.GetLength(); GateRef data = GetNormalStringData(glue, stringGate); DEFVARIABLE(i, VariableType::INT32(), Int32(0)); diff --git a/ecmascript/compiler/typed_hcr_lowering.cpp b/ecmascript/compiler/typed_hcr_lowering.cpp index 7bd22ffbaf..a8e44bd9c8 100644 --- a/ecmascript/compiler/typed_hcr_lowering.cpp +++ b/ecmascript/compiler/typed_hcr_lowering.cpp @@ -552,9 +552,9 @@ void TypedHCRLowering::LowerFlattenTreeStringCheck(GateRef gate, GateRef glue) GateRef TypedHCRLowering::GetLengthFromString(GateRef gate) { - GateRef shiftCount = builder_.Int32(EcmaString::LengthBits::START_BIT); + GateRef shiftCount = builder_.Int32(BaseString::LengthBits::START_BIT); return builder_.Int32LSR( - builder_.LoadConstOffset(VariableType::INT32(), gate, EcmaString::LENGTH_AND_FLAGS_OFFSET), shiftCount); + builder_.LoadConstOffset(VariableType::INT32(), gate, BaseString::LENGTH_AND_FLAGS_OFFSET), shiftCount); } void TypedHCRLowering::LowerStringLength(GateRef gate) @@ -3273,7 +3273,7 @@ void TypedHCRLowering::LowerStringFromSingleCharCode(GateRef gate, GateRef glue) builder_.Bind(&afterNew1); { GateRef dst = builder_.ChangeTaggedPointerToInt64( - builder_.PtrAdd(*res, builder_.IntPtr(LineEcmaString::DATA_OFFSET))); + builder_.PtrAdd(*res, builder_.IntPtr(LineString::DATA_OFFSET))); builder_.Store(VariableType::INT16(), glue, dst, builder_.IntPtr(0), *value); builder_.Jump(&exit); } diff --git a/ecmascript/compiler/typed_native_inline_lowering.cpp b/ecmascript/compiler/typed_native_inline_lowering.cpp index d70f139b19..95ab864a26 100644 --- a/ecmascript/compiler/typed_native_inline_lowering.cpp +++ b/ecmascript/compiler/typed_native_inline_lowering.cpp @@ -1174,7 +1174,7 @@ void TypedNativeInlineLowering::LowerNewNumber(GateRef gate) auto length = builder_.GetLengthFromString(param); builder_.DeoptCheck(builder_.NotEqual(length, builder_.Int32(0)), FindFrameState(gate), DeoptType::NOTINT1); BuiltinsStringStubBuilder stringStub(builder_.GetCurrentEnvironment(), builder_.GetGlobalEnv(glue)); - GateRef dataUtf8 = builder_.PtrAdd(param, builder_.IntPtr(LineEcmaString::DATA_OFFSET)); + GateRef dataUtf8 = builder_.PtrAdd(param, builder_.IntPtr(LineString::DATA_OFFSET)); GateRef res = stringStub.StringDataToUint(dataUtf8, length, std::numeric_limits::max()); builder_.DeoptCheck(builder_.NotEqual(res, builder_.Int64(-1)), FindFrameState(gate), DeoptType::NOTINT1); result = builder_.ToTaggedIntPtr(res); @@ -2000,7 +2000,7 @@ GateRef TypedNativeInlineLowering::CheckAndConvertToUInt(GateRef glue, GateRef m BRANCH_CIR(builder_.Equal(length, builder_.Int32(0)), notIntegerStr, nonZeroLength); builder_.Bind(nonZeroLength); BuiltinsStringStubBuilder stringStub(builder_.GetCurrentEnvironment(), builder_.GetGlobalEnv(glue)); - GateRef dataUtf8 = builder_.PtrAdd(msg, builder_.IntPtr(LineEcmaString::DATA_OFFSET)); + GateRef dataUtf8 = builder_.PtrAdd(msg, builder_.IntPtr(LineString::DATA_OFFSET)); return stringStub.StringDataToUint(dataUtf8, length, std::numeric_limits::max()); } diff --git a/ecmascript/dfx/hprof/tests/js_metadata_test.cpp b/ecmascript/dfx/hprof/tests/js_metadata_test.cpp index 2c94ef1c35..ea843afb19 100644 --- a/ecmascript/dfx/hprof/tests/js_metadata_test.cpp +++ b/ecmascript/dfx/hprof/tests/js_metadata_test.cpp @@ -897,7 +897,7 @@ public: {JSType::JS_WEAK_SET, { JSWeakSet::LINKED_SET_OFFSET, JSWeakSet::SIZE - JSWeakSet::LINKED_SET_OFFSET}}, {JSType::LEXICAL_ENV, {TaggedArray::SIZE - TaggedArray::SIZE}}, - {JSType::LINE_STRING, {LineEcmaString::SIZE - LineEcmaString::SIZE}}, + {JSType::LINE_STRING, {LineString::SIZE - LineString::SIZE}}, {JSType::LINKED_NODE, {LinkedNode::NEXT_OFFSET, LinkedNode::LAST_OFFSET - LinkedNode::NEXT_OFFSET}}, {JSType::LOCAL_EXPORTENTRY_RECORD, { LocalExportEntry::LOCAL_EXPORT_ENTRY_OFFSET, @@ -1017,8 +1017,8 @@ public: TransWithProtoHandler::TRANSITION_HCLASS_OFFSET, TransWithProtoHandler::PROTO_CELL_OFFSET, TransWithProtoHandler::SIZE - TransWithProtoHandler::HANDLER_INFO_OFFSET}}, - {JSType::TREE_STRING, {TreeEcmaString::FIRST_OFFSET, TreeEcmaString::SECOND_OFFSET, - TreeEcmaString::SIZE - TreeEcmaString::FIRST_OFFSET}}, + {JSType::TREE_STRING, {TreeString::FIRST_OFFSET, TreeString::SECOND_OFFSET, + TreeString::SIZE - TreeString::FIRST_OFFSET}}, {JSType::VTABLE, {TaggedArray::LAST_OFFSET - TaggedArray::LENGTH_OFFSET}} }; // { typeName: [all parents of this type]} @@ -1745,8 +1745,8 @@ public: TransWithProtoHandler::TRANSITION_HCLASS_OFFSET - TransWithProtoHandler::HANDLER_INFO_OFFSET, TransWithProtoHandler::PROTO_CELL_OFFSET - TransWithProtoHandler::TRANSITION_HCLASS_OFFSET, TransWithProtoHandler::SIZE - TransWithProtoHandler::PROTO_CELL_OFFSET}}, - {JSType::TREE_STRING, {TreeEcmaString::SECOND_OFFSET - TreeEcmaString::FIRST_OFFSET, - TreeEcmaString::SIZE - TreeEcmaString::SECOND_OFFSET}}, + {JSType::TREE_STRING, {TreeString::SECOND_OFFSET - TreeString::FIRST_OFFSET, + TreeString::SIZE - TreeString::SECOND_OFFSET}}, {JSType::VTABLE, {}} }; } diff --git a/ecmascript/ecma_string-inl.h b/ecmascript/ecma_string-inl.h index 4d2db5f692..6eeb47aa41 100644 --- a/ecmascript/ecma_string-inl.h +++ b/ecmascript/ecma_string-inl.h @@ -24,12 +24,13 @@ #include "ecmascript/mem/space.h" #include "ecmascript/object_factory-inl.h" #include "ecmascript/debugger/js_debugger_manager.h" +#include "common_interfaces/objects/string/base_string-inl2.h" namespace panda::ecmascript { /* static */ inline EcmaString *EcmaString::CreateEmptyString(const EcmaVM *vm) { - auto string = vm->GetFactory()->AllocNonMovableLineStringObject(EcmaString::SIZE); + auto string = vm->GetFactory()->AllocNonMovableLineStringObject(BaseString::SIZE); string->InitLengthAndFlags(0, true); string->SetRawHashcode(0); return string; @@ -42,23 +43,12 @@ inline EcmaString *EcmaString::CreateFromUtf8(const EcmaVM *vm, const uint8_t *u if (utf8Len == 0) { return vm->GetFactory()->GetEmptyString().GetObject(); } - EcmaString *string = nullptr; - if (canBeCompress) { - string = CreateLineStringWithSpaceType(vm, utf8Len, true, type); - ASSERT(string != nullptr); - std::copy(utf8Data, utf8Data + utf8Len, string->GetDataUtf8Writable()); - } else { - auto utf16Len = base::utf_helper::Utf8ToUtf16Size(utf8Data, utf8Len); - string = CreateLineStringWithSpaceType(vm, utf16Len, false, type); - ASSERT(string != nullptr); - - [[maybe_unused]] auto len = - base::utf_helper::ConvertRegionUtf8ToUtf16(utf8Data, string->GetDataUtf16Writable(), utf8Len, utf16Len); - ASSERT(len == utf16Len); - } - - ASSERT_PRINT(canBeCompress == CanBeCompressed(string), "Bad input canBeCompress!"); - return string; + auto allocator = [vm, type](size_t size, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::LINE_STRING && "Can only allocate line string"); + return EcmaString::AllocLineString(vm, size, type)->ToBaseString(); + }; + BaseString *str = BaseString::CreateFromUtf8(std::move(allocator), utf8Data, utf8Len, canBeCompress); + return EcmaString::FromBaseString(str); } /* static */ @@ -68,13 +58,13 @@ inline EcmaString *EcmaString::CreateFromUtf8CompressedSubString(const EcmaVM *v if (UNLIKELY(utf8Len == 0)) { return vm->GetFactory()->GetEmptyString().GetObject(); } - EcmaString *subString = CreateLineStringWithSpaceType(vm, utf8Len, true, type); - ASSERT(subString != nullptr); - auto *utf8Data = string->GetDataUtf8() + offset; - std::copy(utf8Data, utf8Data + utf8Len, subString->GetDataUtf8Writable()); - ASSERT_PRINT(CanBeCompressed(subString), "String cannot be compressed!"); - return subString; + auto allocator = [vm, type](size_t size, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::LINE_STRING && "Can only allocate line string"); + return EcmaString::AllocLineString(vm, size, type)->ToBaseString(); + }; + BaseString *str = BaseString::CreateFromUtf8CompressedSubString(std::move(allocator), string, offset, utf8Len); + return EcmaString::FromBaseString(str); } inline EcmaString *EcmaString::CreateUtf16StringFromUtf8(const EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf16Len, @@ -112,51 +102,51 @@ inline EcmaString *EcmaString::CreateFromUtf16(const EcmaVM *vm, const uint16_t if (utf16Len == 0) { return vm->GetFactory()->GetEmptyString().GetObject(); } - auto string = CreateLineStringWithSpaceType(vm, utf16Len, canBeCompress, type); - ASSERT(string != nullptr); - if (canBeCompress) { - CopyChars(string->GetDataUtf8Writable(), utf16Data, utf16Len); - } else { - uint32_t len = utf16Len * (sizeof(uint16_t) / sizeof(uint8_t)); - if (memcpy_s(string->GetDataUtf16Writable(), len, utf16Data, len) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - } - - ASSERT_PRINT(canBeCompress == CanBeCompressed(string), "Bad input canBeCompress!"); - return string; + auto allocator = [vm, type](size_t size, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::LINE_STRING && "Can only allocate line string"); + return EcmaString::AllocLineString(vm, size, type)->ToBaseString(); + }; + BaseString *str = BaseString::CreateFromUtf16(std::move(allocator), utf16Data, utf16Len, canBeCompress); + return EcmaString::FromBaseString(str); } /* static */ inline EcmaString *EcmaString::CreateLineString(const EcmaVM *vm, size_t length, bool compressed) { - size_t size = compressed ? LineEcmaString::ComputeSizeUtf8(length) : LineEcmaString::ComputeSizeUtf16(length); - auto string = vm->GetFactory()->AllocLineStringObject(size); - string->InitLengthAndFlags(length, compressed); - string->SetRawHashcode(0); - return string; + auto allocator = [vm](size_t size, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::LINE_STRING && "Can only allocate line string"); + EcmaString* string = vm->GetFactory()->AllocLineStringObject(size); +#ifdef USE_CMC_GC + JSTaggedValue hclass = vm->GetJSThread()->GlobalConstants()->GetLineStringClass(); + string->SetBaseClassNoBarrier(reinterpret_cast(hclass.GetTaggedObject())); +#endif + return string; + }; + BaseString *str = BaseString::CreateLineString(std::move(allocator), length, compressed); + return EcmaString::FromBaseString(str); } /* static */ inline EcmaString *EcmaString::CreateLineStringNoGC(const EcmaVM *vm, size_t length, bool compressed) { - size_t size = compressed ? LineEcmaString::ComputeSizeUtf8(length) : LineEcmaString::ComputeSizeUtf16(length); - size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - auto string = vm->GetFactory()->AllocLineStringObjectNoGC(size); - string->InitLengthAndFlags(length, compressed); - string->SetRawHashcode(0); - return string; + auto allocator = [vm](size_t size, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::LINE_STRING && "Can only allocate line string"); + size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); + EcmaString* string = vm->GetFactory()->AllocLineStringObjectNoGC(size); +#ifdef USE_CMC_GC + JSTaggedValue hclass = vm->GetJSThread()->GlobalConstants()->GetLineStringClass(); + string->SetBaseClassNoBarrier(reinterpret_cast(hclass.GetTaggedObject())); +#endif + return string; + }; + BaseString *str = BaseString::CreateLineString(std::move(allocator), length, compressed); + return EcmaString::FromBaseString(str); } -/* static */ -inline EcmaString *EcmaString::CreateLineStringWithSpaceType(const EcmaVM *vm, size_t length, bool compressed, - MemSpaceType type) +inline EcmaString* EcmaString::AllocLineString(const EcmaVM* vm, size_t size, MemSpaceType type) { - ASSERT(IsSMemSpace(type)); - size_t size = compressed ? LineEcmaString::ComputeSizeUtf8(length) : LineEcmaString::ComputeSizeUtf16(length); - EcmaString *string = nullptr; + EcmaString* string = nullptr; switch (type) { case MemSpaceType::SHARED_OLD_SPACE: string = vm->GetFactory()->AllocOldSpaceLineStringObject(size); @@ -171,17 +161,43 @@ inline EcmaString *EcmaString::CreateLineStringWithSpaceType(const EcmaVM *vm, s LOG_ECMA(FATAL) << "this branch is unreachable"; UNREACHABLE(); } - string->InitLengthAndFlags(length, compressed); - string->SetRawHashcode(0); +#ifdef USE_CMC_GC + JSTaggedValue hclass = vm->GetJSThread()->GlobalConstants()->GetLineStringClass(); + string->SetBaseClassNoBarrier(reinterpret_cast(hclass.GetTaggedObject())); +#endif return string; } -inline SlicedString *EcmaString::CreateSlicedString(const EcmaVM *vm, MemSpaceType type) +/* static */ +inline EcmaString *EcmaString::CreateLineStringWithSpaceType(const EcmaVM *vm, size_t length, bool compressed, + MemSpaceType type) +{ + auto allocator = [vm, type](size_t size, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::LINE_STRING && "Can only allocate line string"); + ASSERT(IsSMemSpace(type)); + return AllocLineString(vm, size, type); + }; + BaseString *str = BaseString::CreateLineString(std::move(allocator), length, compressed); + return EcmaString::FromBaseString(str); +} + +inline SlicedEcmaString* EcmaString::CreateSlicedString(const EcmaVM* vm, JSHandle parent, + MemSpaceType type) { - auto slicedString = SlicedString::Cast(vm->GetFactory()->AllocSlicedStringObject(type)); - slicedString->SetRawHashcode(0); - slicedString->SetParent(vm->GetJSThread(), JSTaggedValue::Undefined(), BarrierMode::SKIP_BARRIER); - return slicedString; + auto allocator = [vm, type](size_t, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::SLICED_STRING && "Can only allocate sliced string"); + EcmaString* string = vm->GetFactory()->AllocSlicedStringObject(type); +#ifdef USE_CMC_GC + JSTaggedValue hclass = vm->GetJSThread()->GlobalConstants()->GetSlicedStringClass(); + string->SetBaseClassNoBarrier(reinterpret_cast(hclass.GetTaggedObject())); +#endif + return string; + }; + auto writeBarrier = [vm](void* obj, size_t offset, BaseObject* str) { + Barriers::SetObject(vm->GetJSThread(), obj, offset, reinterpret_cast(str)); + }; + SlicedString* slicedString = BaseString::CreateSlicedString(std::move(allocator), std::move(writeBarrier), parent); + return SlicedEcmaString::FromBaseString(slicedString); } /* @@ -210,12 +226,22 @@ inline EcmaString *EcmaString::CreateTreeString(const EcmaVM *vm, ECMA_STRING_CHECK_LENGTH_AND_TRHOW(vm, length); JSThread *thread = nullptr; GetDebuggerThread(vm, &thread); - auto string = TreeEcmaString::Cast(vm->GetFactory()->AllocTreeStringObject()); - string->InitLengthAndFlags(length, compressed); - string->SetRawHashcode(0); - string->SetFirst(thread, left.GetTaggedValue()); - string->SetSecond(thread, right.GetTaggedValue()); - return string; + + auto allocator = [vm](size_t, CommonType stringType) -> BaseObject* { + ASSERT(stringType == CommonType::TREE_STRING && "Can only allocate tree string"); + EcmaString* string = vm->GetFactory()->AllocTreeStringObject(); +#ifdef USE_CMC_GC + JSTaggedValue hclass = vm->GetJSThread()->GlobalConstants()->GetTreeStringClass(); + string->SetBaseClassNoBarrier(reinterpret_cast(hclass.GetTaggedObject())); +#endif + return string; + }; + auto writeBarrier = [thread](void* obj, size_t offset, BaseObject* str) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + }; + TreeString* treeString = BaseString::CreateTreeString(std::move(allocator), std::move(writeBarrier), left, right, + length, compressed); + return TreeEcmaString::FromBaseString(treeString); } /* static */ @@ -244,7 +270,7 @@ EcmaString *EcmaString::FastSubUtf16String(const EcmaVM *vm, const JSHandleGetDataUtf8Writable(), srcFlat.GetDataUtf16() + start, length); + BaseString::CopyChars(string->GetDataUtf8Writable(), srcFlat.GetDataUtf16() + start, length); } else { uint32_t len = length * (sizeof(uint16_t) / sizeof(uint8_t)); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -256,199 +282,123 @@ EcmaString *EcmaString::FastSubUtf16String(const EcmaVM *vm, const JSHandleGetData(); + return ToBaseString()->GetDataUtf8(); } -inline const uint8_t *EcmaString::GetDataUtf8() const +inline const uint16_t* EcmaString::GetDataUtf16() const { - ASSERT_PRINT(IsUtf8(), "EcmaString: Read data as utf8 for utf16 string"); - return reinterpret_cast(GetData()); + return ToBaseString()->GetDataUtf16(); } -inline const uint16_t *EcmaString::GetDataUtf16() const +// require is LineString +inline uint8_t* EcmaString::GetDataUtf8Writable() { - LOG_ECMA_IF(!IsUtf16(), FATAL) << "EcmaString: Read data as utf16 for utf8 string"; - return GetData(); + return ToBaseString()->GetDataUtf8Writable(); } -inline uint8_t *EcmaString::GetDataUtf8Writable() +inline uint16_t* EcmaString::GetDataUtf16Writable() { - ASSERT_PRINT(IsUtf8(), "EcmaString: Read data as utf8 for utf16 string"); - return reinterpret_cast(GetData()); -} - -inline uint16_t *EcmaString::GetDataUtf16Writable() -{ - LOG_ECMA_IF(!IsUtf16(), FATAL) << "EcmaString: Read data as utf16 for utf8 string"; - return GetData(); + return ToBaseString()->GetDataUtf16Writable(); } inline size_t EcmaString::GetUtf8Length(bool modify, bool isGetBufferSize) const { - if (!IsUtf16()) { - return GetLength() + 1; // add place for zero in the end - } - CVector tmpBuf; - const uint16_t *data = GetUtf16DataFlat(this, tmpBuf); - return base::utf_helper::Utf16ToUtf8Size(data, GetLength(), modify, isGetBufferSize); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->GetUtf8Length(std::move(readBarrier), modify, isGetBufferSize); } -template -inline uint16_t EcmaString::At(int32_t index) const +template +uint16_t EcmaString::At(int32_t index) const { - int32_t length = static_cast(GetLength()); - if constexpr (verify) { - if ((index < 0) || (index >= length)) { - return 0; - } - } - switch (GetStringType()) { - case JSType::LINE_STRING: - return LineEcmaString::Cast(this)->Get(index); - case JSType::SLICED_STRING: - return SlicedString::Cast(this)->Get(index); - case JSType::TREE_STRING: - return TreeEcmaString::Cast(this)->Get(index); - default: - LOG_ECMA(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->At(std::move(readBarrier), index); } inline void EcmaString::WriteData(uint32_t index, uint16_t src) { - ASSERT(index < GetLength()); - ASSERT(IsLineString()); - LineEcmaString::Cast(this)->Set(index, src); + return ToBaseString()->WriteData(index, src); } inline bool EcmaString::IsFlat() const { - if (!JSTaggedValue(this).IsTreeString()) { - return true; - } - return TreeEcmaString::Cast(this)->IsFlat(); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->IsFlat(std::move(readBarrier)); } template -void EcmaString::WriteToFlat(EcmaString *src, Char *buf, uint32_t maxLength) +void EcmaString::WriteToFlat(EcmaString* src, Char* buf, uint32_t maxLength) { - DISALLOW_GARBAGE_COLLECTION; - uint32_t length = src->GetLength(); - if (length == 0) { - return; - } - while (true) { - ASSERT(length <= maxLength && length > 0); - ASSERT(length <= src->GetLength()); - switch (src->GetStringType()) { - case JSType::LINE_STRING: { - if (src->IsUtf8()) { - CopyChars(buf, src->GetDataUtf8(), length); - } else { - CopyChars(buf, src->GetDataUtf16(), length); - } - return; - } - case JSType::TREE_STRING: { - TreeEcmaString *treeSrc = TreeEcmaString::Cast(src); - EcmaString *first = EcmaString::Cast(treeSrc->GetFirst()); - EcmaString *second = EcmaString::Cast(treeSrc->GetSecond()); - uint32_t firstLength = first->GetLength(); - uint32_t secondLength = second->GetLength(); - if (secondLength >= firstLength) { - // second string is longer. So recurse over first. - WriteToFlat(first, buf, maxLength); - if (first == second) { - CopyChars(buf + firstLength, buf, firstLength); - return; - } - buf += firstLength; - maxLength -= firstLength; - src = second; - length -= firstLength; - } else { - // first string is longer. So recurse over second. - // if src{first:A,second:B} is half flat to {first:A+B,second:empty} by another thread - // but the other thread didn't end, and this thread get {first:A+B,second:B} - // it may cause write buffer overflower in line 424, buf + firstLength is overflower. - // so use 'length > firstLength' instead of 'secondLength > 0' - if (length > firstLength) { - if (secondLength == 1) { - buf[firstLength] = static_cast(second->At(0)); - } else if ((second->IsLineString()) && second->IsUtf8()) { - CopyChars(buf + firstLength, second->GetDataUtf8(), secondLength); - } else { - WriteToFlat(second, buf + firstLength, maxLength - firstLength); - } - length -= secondLength; - } - maxLength = firstLength; - src = first; - } - continue; - } - case JSType::SLICED_STRING: { - EcmaString *parent = EcmaString::Cast(SlicedString::Cast(src)->GetParent()); - if (src->IsUtf8()) { - CopyChars(buf, parent->GetDataUtf8() + SlicedString::Cast(src)->GetStartIndex(), length); - } else { - CopyChars(buf, parent->GetDataUtf16() + SlicedString::Cast(src)->GetStartIndex(), length); - } - return; - } - default: - LOG_ECMA(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } - } + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::WriteToFlat(std::move(readBarrier), src->ToBaseString(), buf, maxLength); } template -void EcmaString::WriteToFlatWithPos(EcmaString *src, Char *buf, uint32_t length, uint32_t pos) +void EcmaString::WriteToFlatWithPos(EcmaString* src, Char* buf, uint32_t length, uint32_t pos) { - DISALLOW_GARBAGE_COLLECTION; - [[ maybe_unused ]] uint32_t maxLength = src->GetLength(); - if (length == 0) { - return; - } - while (true) { - ASSERT(length + pos <= maxLength && length > 0); - ASSERT(length <= src->GetLength()); - ASSERT(pos >= 0); - switch (src->GetStringType()) { - case JSType::LINE_STRING: { - if (src->IsUtf8()) { - CopyChars(buf, src->GetDataUtf8() + pos, length); - } else { - CopyChars(buf, src->GetDataUtf16() + pos, length); - } - return; - } - case JSType::TREE_STRING: { - TreeEcmaString *treeSrc = TreeEcmaString::Cast(src); - EcmaString *first = EcmaString::Cast(treeSrc->GetFirst()); - ASSERT(first->IsLineString()); - src = first; - continue; - } - case JSType::SLICED_STRING: { - EcmaString *parent = EcmaString::Cast(SlicedString::Cast(src)->GetParent()); - if (src->IsUtf8()) { - CopyChars(buf, parent->GetDataUtf8() + SlicedString::Cast(src)->GetStartIndex() + pos, length); - } else { - CopyChars(buf, parent->GetDataUtf16() + SlicedString::Cast(src)->GetStartIndex() + pos, length); - } - return; - } - default: - LOG_ECMA(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } - } + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::WriteToFlatWithPos(std::move(readBarrier), src->ToBaseString(), buf, length, pos); +} + +// It allows user to copy into buffer even if maxLength < length +inline size_t EcmaString::WriteUtf8(uint8_t* buf, size_t maxLength, bool isWriteBuffer) const +{ + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->WriteUtf8(std::move(readBarrier), buf, maxLength, isWriteBuffer); +} + +// It allows user to copy into buffer even if maxLength < length +inline size_t EcmaString::WriteUtf16(uint16_t* buf, uint32_t targetLength, uint32_t bufLength) const +{ + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->WriteUtf16(std::move(readBarrier), buf, targetLength, bufLength); +} + +inline size_t EcmaString::WriteOneByte(uint8_t* buf, size_t maxLength) const +{ + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->WriteOneByte(std::move(readBarrier), buf, maxLength); +} + +inline uint32_t EcmaString::CopyDataUtf16(uint16_t* buf, uint32_t maxLength) const +{ + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->CopyDataUtf16(std::move(readBarrier), buf, maxLength); +} + +inline Span EcmaString::ToUtf8Span(CVector& buf, bool modify, bool cesu8) +{ + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->ToUtf8Span(std::move(readBarrier), buf, modify, cesu8); +} + +inline Span EcmaString::DebuggerToUtf8Span(CVector& buf, bool modify) +{ + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->DebuggerToUtf8Span(std::move(readBarrier), buf, modify); } inline const uint8_t *FlatStringInfo::GetDataUtf8() const diff --git a/ecmascript/ecma_string.cpp b/ecmascript/ecma_string.cpp index cd3e2a6024..6da255c030 100755 --- a/ecmascript/ecma_string.cpp +++ b/ecmascript/ecma_string.cpp @@ -15,6 +15,7 @@ #include "ecmascript/ecma_string-inl.h" +#include "common_interfaces/objects/base_string.h" #include "ecmascript/base/json_helper.h" namespace panda::ecmascript { @@ -55,7 +56,7 @@ EcmaString *EcmaString::Concat(const EcmaVM *vm, } // if the result string is small, make a LineString bool compressed = (strLeft->IsUtf8() && strRight->IsUtf8()); - if (newLength < TreeEcmaString::MIN_TREE_ECMASTRING_LENGTH) { + if (newLength < TreeString::MIN_TREE_STRING_LENGTH) { ASSERT(strLeft->IsLineString()); ASSERT(strRight->IsLineString()); auto newString = CreateLineStringWithSpaceType(vm, newLength, compressed, type); @@ -75,7 +76,7 @@ EcmaString *EcmaString::Concat(const EcmaVM *vm, // copy left part Span sp(newString->GetDataUtf16Writable(), newLength); if (strLeft->IsUtf8()) { - EcmaString::CopyChars(sp.data(), strLeft->GetDataUtf8(), leftLength); + BaseString::CopyChars(sp.data(), strLeft->GetDataUtf8(), leftLength); } else { Span srcLeft(strLeft->GetDataUtf16(), leftLength); EcmaString::MemCopyChars(sp, newLength << 1U, srcLeft, leftLength << 1U); @@ -83,7 +84,7 @@ EcmaString *EcmaString::Concat(const EcmaVM *vm, // copy right part sp = sp.SubSpan(leftLength); if (strRight->IsUtf8()) { - EcmaString::CopyChars(sp.data(), strRight->GetDataUtf8(), rightLength); + BaseString::CopyChars(sp.data(), strRight->GetDataUtf8(), rightLength); } else { Span srcRight(strRight->GetDataUtf16(), rightLength); EcmaString::MemCopyChars(sp, rightLength << 1U, srcRight, rightLength << 1U); @@ -111,7 +112,7 @@ EcmaString *EcmaString::CopyStringToOldSpace(const EcmaVM *vm, const JSHandle sp(newString->GetDataUtf16Writable(), length); if (strOrigin.IsUtf8()) { - EcmaString::CopyChars(sp.data(), strOrigin.GetDataUtf8(), length); + BaseString::CopyChars(sp.data(), strOrigin.GetDataUtf8(), length); } else { Span srcSp(strOrigin.GetDataUtf16(), length); EcmaString::MemCopyChars(sp, length << 1U, srcSp, length << 1U); @@ -143,12 +144,12 @@ EcmaString *EcmaString::GetSlicedString(const EcmaVM *vm, const JSHandle &src, uint32_t start, uint32_t length) { ASSERT((start + length) <= src->GetLength()); - JSHandle slicedString(vm->GetJSThread(), CreateSlicedString(vm)); FlatStringInfo srcFlat = FlattenAllString(vm, src); - slicedString->InitLengthAndFlags(length, srcFlat.GetString()->IsUtf8()); - slicedString->SetParent(vm->GetJSThread(), JSTaggedValue(srcFlat.GetString())); + JSHandle flatString(vm->GetJSThread(), srcFlat.GetString()); + SlicedEcmaString *slicedString = CreateSlicedString(vm, flatString); + slicedString->InitLengthAndFlags(length, flatString->IsUtf8()); slicedString->SetStartIndex(start + srcFlat.GetStartIndex()); - return *slicedString; + return slicedString; } /* static */ @@ -164,7 +165,7 @@ EcmaString *EcmaString::GetSubString(const EcmaVM *vm, return EcmaString::Cast(singleCharTable->GetStringFromSingleCharTable(res).GetTaggedObject()); } } - if (static_cast(length) >= SlicedString::MIN_SLICED_ECMASTRING_LENGTH) { + if (static_cast(length) >= SlicedString::MIN_SLICED_STRING_LENGTH) { if (start == 0 && length == src->GetLength()) { return *src; } @@ -174,7 +175,7 @@ EcmaString *EcmaString::GetSubString(const EcmaVM *vm, if (canBeCompressed) { JSHandle string(vm->GetJSThread(), CreateLineString(vm, length, canBeCompressed)); srcFlat = FlattenAllString(vm, src); - CopyChars(string->GetDataUtf8Writable(), srcFlat.GetDataUtf16() + start, length); + BaseString::CopyChars(string->GetDataUtf8Writable(), srcFlat.GetDataUtf16() + start, length); return *string; } } @@ -199,48 +200,10 @@ bool EcmaString::SubStringIsUtf8(const EcmaVM *vm, void EcmaString::WriteData(EcmaString *src, uint32_t start, uint32_t destSize, uint32_t length) { - ASSERT(IsLineString()); - if (IsUtf8()) { - ASSERT(src->IsUtf8()); - CVector buf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(src, buf); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - if (length != 0 && memcpy_s(GetDataUtf8Writable() + start, destSize, data, length) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - } else if (src->IsUtf8()) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - CVector buf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(src, buf); - Span to(GetDataUtf16Writable() + start, length); - Span from(data, length); - for (uint32_t i = 0; i < length; i++) { - to[i] = from[i]; - } - } else { - CVector buf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(src, buf); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - if (length != 0 && memcpy_s(GetDataUtf16Writable() + start, - destSize * sizeof(uint16_t), data, length * sizeof(uint16_t)) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - } -} - -template -int32_t CompareStringSpan(Span &lhsSp, Span &rhsSp, int32_t count) -{ - for (int32_t i = 0; i < count; ++i) { - auto left = static_cast(lhsSp[i]); - auto right = static_cast(rhsSp[i]); - if (left != right) { - return left - right; - } - } - return 0; + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + ToBaseString()->WriteData(std::move(readBarrier), src->ToBaseString(), start, destSize, length); } int32_t EcmaString::Compare(const EcmaVM *vm, const JSHandle &left, const JSHandle &right) @@ -288,22 +251,6 @@ int32_t EcmaString::Compare(const EcmaVM *vm, const JSHandle &left, return countDiff; } -template -bool IsSubStringAtSpan(Span &lhsSp, Span &rhsSp, uint32_t offset) -{ - int rhsSize = static_cast(rhsSp.size()); - ASSERT(rhsSize + offset <= lhsSp.size()); - for (int i = 0; i < rhsSize; ++i) { - auto left = static_cast(lhsSp[offset + static_cast(i)]); - auto right = static_cast(rhsSp[i]); - if (left != right) { - return false; - } - } - return true; -} - - /** * left: text string * right: pattern string @@ -343,54 +290,13 @@ bool EcmaString::IsSubStringAt(const EcmaVM *vm, const JSHandle& lef template int32_t EcmaString::IndexOf(Span &lhsSp, Span &rhsSp, int32_t pos, int32_t max) { - ASSERT(rhsSp.size() > 0); - auto first = static_cast(rhsSp[0]); - for (int32_t i = pos; i <= max; i++) { - if (static_cast(lhsSp[i]) != first) { - i++; - while (i <= max && static_cast(lhsSp[i]) != first) { - i++; - } - } - /* Found first character, now look at the rest of rhsSp */ - if (i <= max) { - int j = i + 1; - int end = j + static_cast(rhsSp.size()) - 1; - - for (int k = 1; j < end && static_cast(lhsSp[j]) == static_cast(rhsSp[k]); j++, k++) { - } - if (j == end) { - /* Found whole string. */ - return i; - } - } - } - return -1; + return BaseString::IndexOf(lhsSp, rhsSp, pos, max); } template int32_t EcmaString::LastIndexOf(Span &lhsSp, Span &rhsSp, int32_t pos) { - int rhsSize = static_cast(rhsSp.size()); - ASSERT(rhsSize > 0); - auto first = rhsSp[0]; - for (int32_t i = pos; i >= 0; i--) { - if (lhsSp[i] != first) { - continue; - } - /* Found first character, now look at the rest of rhsSp */ - int j = 1; - while (j < rhsSize) { - if (rhsSp[j] != lhsSp[i + j]) { - break; - } - j++; - } - if (j == rhsSize) { - return i; - } - } - return -1; + return BaseString::LastIndexOf(lhsSp, rhsSp, pos); } int32_t EcmaString::IndexOf(const EcmaVM *vm, @@ -501,18 +407,10 @@ int32_t EcmaString::LastIndexOf(const EcmaVM *vm, std::u16string EcmaString::ToU16String(uint32_t len) { - uint32_t length = len > 0 ? len : GetLength(); - std::u16string result; - if (IsUtf16()) { - CVector buf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(this, buf); - result = base::StringHelper::Utf16ToU16String(data, length); - } else { - CVector buf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf); - result = base::StringHelper::Utf8ToU16String(data, length); - } - return result; + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->ToU16String(std::move(readBarrier), len); } // static @@ -521,25 +419,14 @@ template uint32_t EcmaString::CalculateDataConcatHashCode(const T1 *dataFirst, size_t sizeFirst, const T2 *dataSecond, size_t sizeSecond) { - uint32_t totalHash = ComputeHashForData(dataFirst, sizeFirst, 0); - totalHash = ComputeHashForData(dataSecond, sizeSecond, totalHash); - return totalHash; + return BaseString::CalculateDataConcatHashCode(dataFirst, sizeFirst, dataSecond, sizeSecond); } #else template uint32_t EcmaString::CalculateDataConcatHashCode(const T1 *dataFirst, size_t sizeFirst, const T2 *dataSecond, size_t sizeSecond) { - uint32_t totalHash = 0; - constexpr uint32_t hashShift = static_cast(EcmaStringHash::HASH_SHIFT); - // The concatenated length of the two strings is less than MIN_SIZE_FOR_UNROLLING. - for (uint32_t i = 0; i < sizeFirst; i++) { - totalHash = (totalHash << hashShift) - totalHash + dataFirst[i]; - } - for (uint32_t i = 0; i < sizeSecond; i++) { - totalHash = (totalHash << hashShift) - totalHash + dataSecond[i]; - } - return totalHash; + return BaseString::CalculateDataConcatHashCode(dataFirst, sizeFirst, dataSecond, sizeSecond); } #endif @@ -584,115 +471,37 @@ uint32_t EcmaString::CalculateConcatHashCode(const JSHandle &firstSt // static bool EcmaString::CanBeCompressed(const EcmaString *string) { - ASSERT(string->IsLineString()); - if (string->IsUtf8()) { - return CanBeCompressed(string->GetDataUtf8(), string->GetLength()); - } - return CanBeCompressed(string->GetDataUtf16(), string->GetLength()); + return BaseString::CanBeCompressed(string->ToBaseString()); } // static bool EcmaString::CanBeCompressed(const uint8_t *utf8Data, uint32_t utf8Len) { - uint32_t index = 0; - for (; index + 4 <= utf8Len; index += 4) { // 4: process the data in chunks of 4 elements to improve speed - // Check if all four characters in the current block are ASCII characters - if (!IsASCIICharacter(utf8Data[index]) || - !IsASCIICharacter(utf8Data[index + 1]) || // 1: the second element of the block - !IsASCIICharacter(utf8Data[index + 2]) || // 2: the third element of the block - !IsASCIICharacter(utf8Data[index + 3])) { // 3: the fourth element of the block - return false; - } - } - // Check remaining characters if they are ASCII - for (; index < utf8Len; ++index) { - if (!IsASCIICharacter(utf8Data[index])) { - return false; - } - } - return true; + return BaseString::CanBeCompressed(utf8Data, utf8Len); } /* static */ bool EcmaString::CanBeCompressed(const uint16_t *utf16Data, uint32_t utf16Len) { - uint32_t index = 0; - for (; index + 4 <= utf16Len; index += 4) { // 4: process the data in chunks of 4 elements to improve speed - // Check if all four characters in the current block are ASCII characters - if (!IsASCIICharacter(utf16Data[index]) || - !IsASCIICharacter(utf16Data[index + 1]) || // 1: the second element of the block - !IsASCIICharacter(utf16Data[index + 2]) || // 2: the third element of the block - !IsASCIICharacter(utf16Data[index + 3])) { // 3: the fourth element of the block - return false; - } - } - // Check remaining characters if they are ASCII - for (; index < utf16Len; ++index) { - if (!IsASCIICharacter(utf16Data[index])) { - return false; - } - } - return true; + return BaseString::CanBeCompressed(utf16Data, utf16Len); } bool EcmaString::EqualToSplicedString(const EcmaString *str1, const EcmaString *str2) { - ASSERT(NotTreeString()); - ASSERT(str1->NotTreeString() && str2->NotTreeString()); - if (GetLength() != str1->GetLength() + str2->GetLength()) { - return false; - } - if (IsUtf16()) { - CVector buf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(this, buf); - if (EcmaString::StringsAreEqualUtf16(str1, data, str1->GetLength())) { - return EcmaString::StringsAreEqualUtf16(str2, data + str1->GetLength(), str2->GetLength()); - } - } else { - CVector buf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf); - if (EcmaString::StringIsEqualUint8Data(str1, data, str1->GetLength(), this->IsUtf8())) { - return EcmaString::StringIsEqualUint8Data(str2, data + str1->GetLength(), - str2->GetLength(), this->IsUtf8()); - } - } - return false; + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->EqualToSplicedString(std::move(readBarrier), str1->ToBaseString(), str2->ToBaseString()); } /* static */ bool EcmaString::StringsAreEqualDiffUtfEncoding(EcmaString *left, EcmaString *right) { - CVector bufLeftUft16; - CVector bufRightUft16; - CVector bufLeftUft8; - CVector bufRightUft8; - int32_t lhsCount = static_cast(left->GetLength()); - int32_t rhsCount = static_cast(right->GetLength()); - if (!left->IsUtf16() && !right->IsUtf16()) { - const uint8_t *data1 = EcmaString::GetUtf8DataFlat(left, bufLeftUft8); - const uint8_t *data2 = EcmaString::GetUtf8DataFlat(right, bufRightUft8); - Span lhsSp(data1, lhsCount); - Span rhsSp(data2, rhsCount); - return EcmaString::StringsAreEquals(lhsSp, rhsSp); - } else if (!left->IsUtf16()) { - const uint8_t *data1 = EcmaString::GetUtf8DataFlat(left, bufLeftUft8); - const uint16_t *data2 = EcmaString::GetUtf16DataFlat(right, bufRightUft16); - Span lhsSp(data1, lhsCount); - Span rhsSp(data2, rhsCount); - return EcmaString::StringsAreEquals(lhsSp, rhsSp); - } else if (!right->IsUtf16()) { - const uint16_t *data1 = EcmaString::GetUtf16DataFlat(left, bufLeftUft16); - const uint8_t *data2 = EcmaString::GetUtf8DataFlat(right, bufRightUft8); - Span lhsSp(data1, lhsCount); - Span rhsSp(data2, rhsCount); - return EcmaString::StringsAreEquals(lhsSp, rhsSp); - } else { - const uint16_t *data1 = EcmaString::GetUtf16DataFlat(left, bufLeftUft16); - const uint16_t *data2 = EcmaString::GetUtf16DataFlat(right, bufRightUft16); - Span lhsSp(data1, lhsCount); - Span rhsSp(data2, rhsCount); - return EcmaString::StringsAreEquals(lhsSp, rhsSp); - } + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::StringsAreEqualDiffUtfEncoding(std::move(readBarrier), left->ToBaseString(), + right->ToBaseString()); } /* static */ @@ -750,69 +559,32 @@ bool EcmaString::StringsAreEqual(const EcmaVM *vm, const JSHandle &s } /* static */ -bool EcmaString::StringsAreEqual(EcmaString *str1, EcmaString *str2) +bool EcmaString::StringsAreEqual(EcmaString* str1, EcmaString* str2) { - ASSERT(str1 != nullptr && str2 != nullptr); - if (str1 == str2) { - return true; - } - uint32_t str1Len = str1->GetLength(); - if (str1Len != str2->GetLength()) { - return false; - } - if (str1Len == 0) { - return true; - } - - uint32_t str1Hash; - uint32_t str2Hash; - if (str1->TryGetHashCode(&str1Hash) && str2->TryGetHashCode(&str2Hash)) { - if (str1Hash != str2Hash) { - return false; - } - } - return StringsAreEqualDiffUtfEncoding(str1, str2); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::StringsAreEqual(std::move(readBarrier), str1->ToBaseString(), str2->ToBaseString()); } /* static */ -bool EcmaString::StringIsEqualUint8Data(const EcmaString *str1, const uint8_t *dataAddr, uint32_t dataLen, +bool EcmaString::StringIsEqualUint8Data(const EcmaString* str1, const uint8_t* dataAddr, uint32_t dataLen, bool canBeCompressToUtf8) { - if (!str1->IsSlicedString() && canBeCompressToUtf8 != str1->IsUtf8()) { - return false; - } - if (canBeCompressToUtf8 && str1->GetLength() != dataLen) { - return false; - } - if (str1->IsUtf8()) { - CVector buf; - Span data1(EcmaString::GetUtf8DataFlat(str1, buf), dataLen); - Span data2(dataAddr, dataLen); - return EcmaString::StringsAreEquals(data1, data2); - } - CVector buf; - uint32_t length = str1->GetLength(); - const uint16_t *data = EcmaString::GetUtf16DataFlat(str1, buf); - return IsUtf8EqualsUtf16(dataAddr, dataLen, data, length); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::StringIsEqualUint8Data(std::move(readBarrier), str1->ToBaseString(), dataAddr, dataLen, + canBeCompressToUtf8); } /* static */ bool EcmaString::StringsAreEqualUtf16(const EcmaString *str1, const uint16_t *utf16Data, uint32_t utf16Len) { - uint32_t length = str1->GetLength(); - if (length != utf16Len) { - return false; - } - if (str1->IsUtf8()) { - CVector buf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(str1, buf); - return IsUtf8EqualsUtf16(data, length, utf16Data, utf16Len); - } else { - CVector buf; - Span data1(EcmaString::GetUtf16DataFlat(str1, buf), length); - Span data2(utf16Data, utf16Len); - return EcmaString::StringsAreEquals(data1, data2); - } + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::StringsAreEqualUtf16(std::move(readBarrier), str1->ToBaseString(), utf16Data, utf16Len); } template @@ -830,140 +602,22 @@ bool EcmaString::MemCopyChars(Span &dst, size_t dstMax, Span &src, s // hashSeed only be used when computing two separate strings merged hashcode. uint32_t EcmaString::ComputeRawHashcode() const { - uint32_t length = GetLength(); - if (length == 0) { - return 0; - } - - if (IsUtf8()) { - CVector buf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf); - // String can not convert to integer number, using normal hashcode computing algorithm. - return ComputeHashForData(data, length, 0); - } else { - CVector buf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(this, buf); - // If rawSeed has certain value, and second string uses UTF16 encoding, - // then merged string can not be small integer number. - return ComputeHashForData(data, length, 0); - } + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToBaseString()->ComputeRawHashcode(std::move(readBarrier)); } /* static */ uint32_t EcmaString::ComputeHashcodeUtf8(const uint8_t *utf8Data, size_t utf8Len, bool canBeCompress) { - if (canBeCompress) { - return ComputeHashForData(utf8Data, utf8Len, 0); - } else { - auto utf16Len = base::utf_helper::Utf8ToUtf16Size(utf8Data, utf8Len); - CVector tmpBuffer(utf16Len); - [[maybe_unused]] auto len = base::utf_helper::ConvertRegionUtf8ToUtf16(utf8Data, tmpBuffer.data(), utf8Len, - utf16Len); - ASSERT(len == utf16Len); - return ComputeHashForData(tmpBuffer.data(), utf16Len, 0); - } - LOG_ECMA(FATAL) << "this branch is unreachable"; - UNREACHABLE(); + return BaseString::ComputeHashcodeUtf8(utf8Data, utf8Len, canBeCompress); } /* static */ uint32_t EcmaString::ComputeHashcodeUtf16(const uint16_t *utf16Data, uint32_t length) { - return ComputeHashForData(utf16Data, length, 0); -} - -// drop the tail bytes if the remain length can't fill the length it represents. -static size_t FixUtf8Len(const uint8_t* utf8, size_t utf8Len) -{ - constexpr size_t TWO_BYTES_LENGTH = 2; - constexpr size_t THREE_BYTES_LENGTH = 3; - size_t trimSize = 0; - if (utf8Len >= 1 && utf8[utf8Len - 1] >= 0xC0) { - // The last one char claim there are more than 1 byte next to it, it's invalid, so drop the last one. - trimSize = 1; - } - if (utf8Len >= TWO_BYTES_LENGTH && utf8[utf8Len - TWO_BYTES_LENGTH] >= 0xE0) { - // The second to last char claim there are more than 2 bytes next to it, it's invalid, so drop the last two. - trimSize = TWO_BYTES_LENGTH; - } - if (utf8Len >= THREE_BYTES_LENGTH && utf8[utf8Len - THREE_BYTES_LENGTH] >= 0xF0) { - // The third to last char claim there are more than 3 bytes next to it, it's invalid, so drop the last three. - trimSize = THREE_BYTES_LENGTH; - } - return utf8Len - trimSize; -} - - -/* static */ -bool EcmaString::IsUtf8EqualsUtf16(const uint8_t *utf8Data, size_t utf8Len, - const uint16_t *utf16Data, uint32_t utf16Len) -{ - size_t safeUtf8Len = FixUtf8Len(utf8Data, utf8Len); - const uint8_t *utf8End = utf8Data + utf8Len; - const uint8_t *utf8SafeEnd = utf8Data + safeUtf8Len; - const uint16_t *utf16End = utf16Data + utf16Len; - while (utf8Data < utf8SafeEnd && utf16Data < utf16End) { - uint8_t src = *utf8Data; - switch (src & 0xF0) { - case 0xF0: { - const uint8_t c2 = *(++utf8Data); - const uint8_t c3 = *(++utf8Data); - const uint8_t c4 = *(++utf8Data); - uint32_t codePoint = ((src & LOW_3BITS) << OFFSET_18POS) | ((c2 & LOW_6BITS) << OFFSET_12POS) | - ((c3 & LOW_6BITS) << OFFSET_6POS) | (c4 & LOW_6BITS); - if (codePoint >= SURROGATE_RAIR_START) { - if (utf16Data >= utf16End - 1) { - return false; - } - codePoint -= SURROGATE_RAIR_START; - if (*utf16Data++ != static_cast((codePoint >> OFFSET_10POS) | H_SURROGATE_START)) { - return false; - } else if (*utf16Data++ != static_cast((codePoint & 0x3FF) | L_SURROGATE_START)) { - return false; - } - } else { - if (*utf16Data++ != static_cast(codePoint)) { - return false; - } - } - utf8Data++; - break; - } - case 0xE0: { - const uint8_t c2 = *(++utf8Data); - const uint8_t c3 = *(++utf8Data); - if (*utf16Data++ != static_cast(((src & LOW_4BITS) << OFFSET_12POS) | - ((c2 & LOW_6BITS) << OFFSET_6POS) | (c3 & LOW_6BITS))) { - return false; - } - utf8Data++; - break; - } - case 0xD0: - case 0xC0: { - const uint8_t c2 = *(++utf8Data); - if (*utf16Data++ != static_cast(((src & LOW_5BITS) << OFFSET_6POS) | (c2 & LOW_6BITS))) { - return false; - } - utf8Data++; - break; - } - default: - do { - if (*utf16Data++ != static_cast(*utf8Data++)) { - return false; - } - } while (utf8Data < utf8SafeEnd && utf16Data < utf16End && *utf8Data < 0x80); - break; - } - } - // The remain chars should be treated as single byte char. - while (utf8Data < utf8End && utf16Data < utf16End) { - if (*utf16Data++ != static_cast(*utf8Data++)) { - return false; - } - } - return utf8Data == utf8End && utf16Data == utf16End; + return BaseString::ComputeHashcodeUtf16(utf16Data, length); } bool EcmaString::ToElementIndex(uint32_t *index) @@ -1284,8 +938,8 @@ FlatStringInfo EcmaString::FlattenAllString(const EcmaVM *vm, const JSHandleGetFirst()); } } else if (string->IsSlicedString()) { - s = EcmaString::Cast(SlicedString::Cast(*string)->GetParent()); - startIndex = SlicedString::Cast(*string)->GetStartIndex(); + s = EcmaString::Cast(SlicedEcmaString::Cast(*string)->GetParent()); + startIndex = SlicedEcmaString::Cast(*string)->GetStartIndex(); } return FlatStringInfo(s, startIndex, string->GetLength()); } @@ -1315,7 +969,7 @@ EcmaString *EcmaString::FlattenNoGCForSnapshot(const EcmaVM *vm, EcmaString *str return result; } } else if (string->IsSlicedString()) { - SlicedString *str = SlicedString::Cast(string); + SlicedEcmaString *str = SlicedEcmaString::Cast(string); uint32_t length = str->GetLength(); EcmaString *result = nullptr; if (str->IsUtf8()) { @@ -1332,68 +986,34 @@ EcmaString *EcmaString::FlattenNoGCForSnapshot(const EcmaVM *vm, EcmaString *str const uint8_t *EcmaString::GetUtf8DataFlat(const EcmaString *src, CVector &buf) { - ASSERT(src->IsUtf8()); - uint32_t length = src->GetLength(); - EcmaString *string = const_cast(src); - if (string->IsTreeString()) { - if (string->IsFlat()) { - string = EcmaString::Cast(TreeEcmaString::Cast(string)->GetFirst()); - } else { - buf.reserve(length); - WriteToFlat(string, buf.data(), length); - return buf.data(); - } - } else if (string->IsSlicedString()) { - SlicedString *str = SlicedString::Cast(string); - return EcmaString::Cast(str->GetParent())->GetDataUtf8() + str->GetStartIndex(); - } - return string->GetDataUtf8(); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::GetUtf8DataFlat(std::move(readBarrier), src->ToBaseString(), buf); } const uint8_t *EcmaString::GetNonTreeUtf8Data(const EcmaString *src) { - ASSERT(src->IsUtf8()); - ASSERT(!src->IsTreeString()); - EcmaString *string = const_cast(src); - if (string->IsSlicedString()) { - SlicedString *str = SlicedString::Cast(string); - return EcmaString::Cast(str->GetParent())->GetDataUtf8() + str->GetStartIndex(); - } - ASSERT(src->IsLineString()); - return string->GetDataUtf8(); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::GetNonTreeUtf8Data(std::move(readBarrier), src->ToBaseString()); } const uint16_t *EcmaString::GetUtf16DataFlat(const EcmaString *src, CVector &buf) { - ASSERT(src->IsUtf16()); - uint32_t length = src->GetLength(); - EcmaString *string = const_cast(src); - if (string->IsTreeString()) { - if (string->IsFlat()) { - string = EcmaString::Cast(TreeEcmaString::Cast(string)->GetFirst()); - } else { - buf.reserve(length); - WriteToFlat(string, buf.data(), length); - return buf.data(); - } - } else if (string->IsSlicedString()) { - SlicedString *str = SlicedString::Cast(string); - return EcmaString::Cast(str->GetParent())->GetDataUtf16() + str->GetStartIndex(); - } - return string->GetDataUtf16(); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::GetUtf16DataFlat(std::move(readBarrier), src->ToBaseString(), buf); } const uint16_t *EcmaString::GetNonTreeUtf16Data(const EcmaString *src) { - ASSERT(src->IsUtf16()); - ASSERT(!src->IsTreeString()); - EcmaString *string = const_cast(src); - if (string->IsSlicedString()) { - SlicedString *str = SlicedString::Cast(string); - return EcmaString::Cast(str->GetParent())->GetDataUtf16() + str->GetStartIndex(); - } - ASSERT(src->IsLineString()); - return string->GetDataUtf16(); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return BaseString::GetNonTreeUtf16Data(std::move(readBarrier), src->ToBaseString()); } std::u16string FlatStringInfo::ToU16String(uint32_t len) diff --git a/ecmascript/ecma_string.h b/ecmascript/ecma_string.h index 6dc2e2e985..1b7ee6da45 100755 --- a/ecmascript/ecma_string.h +++ b/ecmascript/ecma_string.h @@ -28,8 +28,10 @@ #include "ecmascript/mem/barriers.h" #include "ecmascript/mem/space.h" #include "ecmascript/mem/tagged_object.h" -#include "ecmascript/platform/ecma_string_hash_helper.h" - +#include "common_interfaces/objects/string/line_string.h" +#include "common_interfaces/objects/string/sliced_string.h" +#include "common_interfaces/objects/string/tree_string.h" +#include "common_interfaces/objects/string/base_string-inl1.h" #include "libpandabase/macros.h" #include "securec.h" #include "unicode/locid.h" @@ -46,32 +48,36 @@ class JSPandaFile; class EcmaVM; class LineEcmaString; class TreeEcmaString; -class SlicedString; +class SlicedEcmaString; class FlatStringInfo; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define ECMA_STRING_CHECK_LENGTH_AND_TRHOW(vm, length) \ - if ((length) >= MAX_STRING_LENGTH) { \ + if ((length) >= BaseString::MAX_STRING_LENGTH) { \ THROW_RANGE_ERROR_AND_RETURN((vm)->GetJSThread(), "Invalid string length", nullptr); \ } class EcmaString : public TaggedObject { +private: + using TaggedObject::SIZE; + public: CAST_CHECK(EcmaString, IsString); - static constexpr size_t MAX_STRING_LENGTH = 0x40000000U; // 30 bits for string length, 2 bits for special meaning - static constexpr uint32_t MAX_INTEGER_HASH_NUMBER = 0x3B9AC9FF; - static constexpr uint32_t MAX_CACHED_INTEGER_SIZE = 9; + BaseString* ToBaseString() + { + return BaseString::Cast(this); + } - static constexpr size_t LENGTH_AND_FLAGS_OFFSET = TaggedObjectSize(); - ACCESSORS_PRIMITIVE_FIELD(LengthAndFlags, uint32_t, LENGTH_AND_FLAGS_OFFSET, RAW_HASHCODE_OFFSET) - // In last bit of mix_hash we store if this string is small-integer number or not. - ACCESSORS_PRIMITIVE_FIELD(RawHashcode, uint32_t, RAW_HASHCODE_OFFSET, SIZE) + const BaseString* ToBaseString() const + { + return BaseString::ConstCast(this); + } - enum CompressedStatus { - STRING_COMPRESSED, - STRING_UNCOMPRESSED, - }; + static EcmaString* FromBaseString(BaseString* str) + { + return reinterpret_cast(str); + } enum TrimMode : uint8_t { TRIM, @@ -79,27 +85,17 @@ public: TRIM_END, }; - enum ConcatOptStatus { - BEGIN_STRING_ADD = 1, - IN_STRING_ADD, - CONFIRMED_IN_STRING_ADD, - END_STRING_ADD, - INVALID_STRING_ADD, - }; - - static constexpr uint32_t STRING_LENGTH_BITS_NUM = 30; - static constexpr uint32_t BITS_PER_BYTE = 8; + void SetRawHashcode(uint32_t rawHashCode) + { + return ToBaseString()->SetRawHashcode(rawHashCode); + } - using CompressedStatusBit = BitField; // 1 - using IsInternBit = CompressedStatusBit::NextFlag; // 1 - using LengthBits = IsInternBit::NextField; // 30 - static_assert(LengthBits::START_BIT + LengthBits::SIZE == sizeof(uint32_t) * BITS_PER_BYTE, - "LengthBits does not match the field size"); private: + friend class EcmaStringAccessor; friend class LineEcmaString; friend class TreeEcmaString; - friend class SlicedString; + friend class SlicedEcmaString; friend class FlatStringInfo; friend class NameDictionary; friend class panda::test::EcmaStringEqualsTest; @@ -114,11 +110,13 @@ private: MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE); static EcmaString *CreateFromUtf16(const EcmaVM *vm, const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE); - static SlicedString *CreateSlicedString(const EcmaVM *vm, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE); + static SlicedEcmaString* CreateSlicedString(const EcmaVM* vm, JSHandle parent, + MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE); static EcmaString *CreateLineString(const EcmaVM *vm, size_t length, bool compressed); static EcmaString *CreateLineStringNoGC(const EcmaVM *vm, size_t length, bool compressed); + static EcmaString *AllocLineString(const EcmaVM* vm, size_t size, MemSpaceType type); static EcmaString *CreateLineStringWithSpaceType(const EcmaVM *vm, - size_t length, bool compressed, MemSpaceType type); + size_t length, bool compressed, MemSpaceType type); static EcmaString *CreateTreeString(const EcmaVM *vm, const JSHandle &left, const JSHandle &right, uint32_t length, bool compressed); static EcmaString *Concat(const EcmaVM *vm, const JSHandle &left, @@ -150,18 +148,14 @@ private: inline bool IsUtf8() const { - uint32_t bits = GetLengthAndFlags(); - return CompressedStatusBit::Decode(bits) == STRING_COMPRESSED; + return ToBaseString()->IsUtf8(); } inline bool IsUtf16() const { - uint32_t bits = GetLengthAndFlags(); - return CompressedStatusBit::Decode(bits) == STRING_UNCOMPRESSED; + return ToBaseString()->IsUtf16(); } - // require is LineString - inline uint16_t *GetData() const; inline const uint8_t *GetDataUtf8() const; inline const uint16_t *GetDataUtf16() const; @@ -171,57 +165,41 @@ private: inline uint32_t GetLength() const { - uint32_t bits = GetLengthAndFlags(); - return LengthBits::Decode(bits); + return ToBaseString()->GetLength(); } inline void InitLengthAndFlags(uint32_t length, bool compressed = false, bool isIntern = false) { - ASSERT(length < MAX_STRING_LENGTH); - uint32_t newVal = 0; - newVal = IsInternBit::Update(newVal, isIntern); - newVal = CompressedStatusBit::Update(newVal, (compressed ? STRING_COMPRESSED : STRING_UNCOMPRESSED)); - newVal = LengthBits::Update(newVal, length); - SetLengthAndFlags(newVal); + ToBaseString()->InitLengthAndFlags(length, compressed, isIntern); } inline size_t GetUtf8Length(bool modify = true, bool isGetBufferSize = false) const; inline void SetIsInternString() { - uint32_t bits = GetLengthAndFlags(); - uint32_t newVal = IsInternBit::Update(bits, true); - SetLengthAndFlags(newVal); + ToBaseString()->SetIsInternString(); } inline bool IsInternString() const { - uint32_t bits = GetLengthAndFlags(); - return IsInternBit::Decode(bits); + return ToBaseString()->IsInternString(); } inline void ClearInternStringFlag() { - uint32_t bits = GetLengthAndFlags(); - uint32_t newVal = IsInternBit::Update(bits, false); - SetLengthAndFlags(newVal); + ToBaseString()->ClearInternStringFlag(); } inline bool TryGetHashCode(uint32_t *hash) { - uint32_t hashcode = GetRawHashcode(); - if (hashcode == 0 && GetLength() != 0) { - return false; - } - *hash = hashcode; - return true; + return ToBaseString()->TryGetHashCode(hash); } // not change this data structure. // if string is not flat, this func has low efficiency. uint32_t PUBLIC_API GetHashcode() { - uint32_t hashcode = GetRawHashcode(); + uint32_t hashcode = ToBaseString()->GetRawHashcode(); // GetLength() == 0 means it's an empty array.No need to computeHashCode again when hashseed is 0. if (hashcode == 0 && GetLength() != 0) { hashcode = ComputeRawHashcode(); @@ -230,12 +208,6 @@ private: return hashcode; } - template - inline static bool IsDecimalDigitChar(const T c) - { - return (c >= '0' && c <= '9'); - } - uint32_t PUBLIC_API ComputeRawHashcode() const; static uint32_t ComputeHashcodeUtf8(const uint8_t *utf8Data, size_t utf8Len, bool canBeCompress); @@ -258,25 +230,9 @@ private: template static bool StringsAreEquals(Span &str1, Span &str2) { - ASSERT(str1.Size() <= str2.Size()); - size_t size = str1.Size(); - if constexpr (std::is_same_v) { - return !memcmp(str1.data(), str2.data(), size * sizeof(T)); - } else { - for (size_t i = 0; i < size; i++) { - auto left = static_cast(str1[i]); - auto right = static_cast(str2[i]); - if (left != right) { - return false; - } - } - return true; - } + return BaseString::StringsAreEquals(str1, str2); } - // Converts utf8Data to utf16 and compare it with given utf16_data. - static bool IsUtf8EqualsUtf16(const uint8_t *utf8Data, size_t utf8Len, const uint16_t *utf16Data, - uint32_t utf16Len); // Compares string1 + string2 by bytes, It doesn't check canonical unicode equivalence. bool EqualToSplicedString(const EcmaString *str1, const EcmaString *str2); // Compares strings by bytes, It doesn't check canonical unicode equivalence. @@ -305,200 +261,21 @@ private: static int32_t LastIndexOf(const EcmaVM *vm, const JSHandle &receiver, const JSHandle &search, int pos = 0); - inline size_t CopyDataUtf8(uint8_t *buf, size_t maxLength, bool modify = true) const - { - if (maxLength == 0) { - return 1; // maxLength was -1 at napi - } - size_t length = GetLength(); - if (length > maxLength) { - return 0; - } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - buf[maxLength - 1] = '\0'; - // Put comparison here so that internal usage and napi can use the same CopyDataRegionUtf8 - return CopyDataRegionUtf8(buf, 0, length, maxLength, modify) + 1; // add place for zero in the end - } - // It allows user to copy into buffer even if maxLength < length - inline size_t WriteUtf8(uint8_t *buf, size_t maxLength, bool isWriteBuffer = false) const - { - if (maxLength == 0) { - return 1; // maxLength was -1 at napi - } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - buf[maxLength - 1] = '\0'; - return CopyDataRegionUtf8(buf, 0, GetLength(), maxLength, true, isWriteBuffer) + 1; - } - - size_t CopyDataToUtf16(uint16_t *buf, uint32_t length, uint32_t bufLength) const - { - if (IsUtf16()) { - CVector tmpBuf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(this, tmpBuf); - if (length > bufLength) { - if (memcpy_s(buf, bufLength * sizeof(uint16_t), data, bufLength * sizeof(uint16_t)) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed when length > bufLength"; - UNREACHABLE(); - } - return bufLength; - } - if (memcpy_s(buf, bufLength * sizeof(uint16_t), data, length * sizeof(uint16_t)) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - return length; - } - CVector tmpBuf; - const uint8_t *data = EcmaString::GetUtf8DataFlat(this, tmpBuf); - if (length > bufLength) { - return base::utf_helper::ConvertRegionUtf8ToUtf16(data, buf, bufLength, bufLength); - } - return base::utf_helper::ConvertRegionUtf8ToUtf16(data, buf, length, bufLength); - } + size_t WriteUtf8(uint8_t *buf, size_t maxLength, bool isWriteBuffer = false) const; // It allows user to copy into buffer even if maxLength < length - inline size_t WriteUtf16(uint16_t *buf, uint32_t targetLength, uint32_t bufLength) const - { - if (bufLength == 0) { - return 0; - } - // Returns a number representing a valid backrest length. - return CopyDataToUtf16(buf, targetLength, bufLength); - } - - size_t WriteOneByte(uint8_t *buf, size_t maxLength) const - { - if (maxLength == 0) { - return 0; - } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - buf[maxLength - 1] = '\0'; - uint32_t length = GetLength(); - if (!IsUtf16()) { - CVector tmpBuf; - const uint8_t *data = GetUtf8DataFlat(this, tmpBuf); - if (length > maxLength) { - length = maxLength; - } - if (memcpy_s(buf, maxLength, data, length) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed when write one byte"; - UNREACHABLE(); - } - return length; - } + size_t WriteUtf16(uint16_t *buf, uint32_t targetLength, uint32_t bufLength) const; - CVector tmpBuf; - const uint16_t *data = GetUtf16DataFlat(this, tmpBuf); - if (length > maxLength) { - return base::utf_helper::ConvertRegionUtf16ToLatin1(data, buf, maxLength, maxLength); - } - return base::utf_helper::ConvertRegionUtf16ToLatin1(data, buf, length, maxLength); - } + size_t WriteOneByte(uint8_t *buf, size_t maxLength) const; - size_t CopyDataRegionUtf8(uint8_t *buf, size_t start, size_t length, size_t maxLength, - bool modify = true, bool isWriteBuffer = false) const - { - uint32_t len = GetLength(); - if (start + length > len) { - return 0; - } - if (!IsUtf16()) { - if (length > std::numeric_limits::max() / 2 - 1) { // 2: half - LOG_FULL(FATAL) << " length is higher than half of size_t::max"; - UNREACHABLE(); - } - CVector tmpBuf; - const uint8_t *data = GetUtf8DataFlat(this, tmpBuf) + start; - // Only copy maxLength number of chars into buffer if length > maxLength - auto dataLen = std::min(length, maxLength); - std::copy(data, data + dataLen, buf); - return dataLen; - } - CVector tmpBuf; - const uint16_t *data = GetUtf16DataFlat(this, tmpBuf); - if (length > maxLength) { - return base::utf_helper::ConvertRegionUtf16ToUtf8(data, buf, maxLength, maxLength, start, - modify, isWriteBuffer); - } - return base::utf_helper::ConvertRegionUtf16ToUtf8(data, buf, length, maxLength, start, - modify, isWriteBuffer); - } - - inline uint32_t CopyDataUtf16(uint16_t *buf, uint32_t maxLength) const - { - uint32_t length = GetLength(); - if (length > maxLength) { - return 0; - } - if (IsUtf16()) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - CVector tmpBuf; - const uint16_t *data = GetUtf16DataFlat(this, tmpBuf); - if (memcpy_s(buf, maxLength * sizeof(uint16_t), data, length * sizeof(uint16_t)) != EOK) { - LOG_FULL(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - return length; - } - CVector tmpBuf; - const uint8_t *data = GetUtf8DataFlat(this, tmpBuf); - return base::utf_helper::ConvertRegionUtf8ToUtf16(data, buf, length, maxLength); - } + uint32_t CopyDataUtf16(uint16_t *buf, uint32_t maxLength) const; std::u16string ToU16String(uint32_t len = 0); - std::unique_ptr ToOneByteDataForced() - { - uint8_t *buf = nullptr; - auto length = GetLength(); - if (IsUtf16()) { - auto size = length * sizeof(uint16_t); - buf = new uint8_t[size](); - CopyDataUtf16(reinterpret_cast(buf), length); - } else { - buf = new uint8_t[length + 1](); - CopyDataUtf8(buf, length + 1); - } - return std::unique_ptr(buf); - } - - Span ToUtf8Span(CVector &buf, bool modify = true, bool cesu8 = false) - { - Span str; - uint32_t strLen = GetLength(); - if (UNLIKELY(IsUtf16())) { - CVector tmpBuf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(this, tmpBuf); - ASSERT(base::utf_helper::Utf16ToUtf8Size(data, strLen, modify, false, cesu8) > 0); - size_t len = base::utf_helper::Utf16ToUtf8Size(data, strLen, modify, false, cesu8) - 1; - buf.reserve(len); - len = base::utf_helper::ConvertRegionUtf16ToUtf8(data, buf.data(), strLen, len, 0, modify, false, cesu8); - str = Span(buf.data(), len); - } else { - const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf); - str = Span(data, strLen); - } - return str; - } + Span ToUtf8Span(CVector &buf, bool modify = true, bool cesu8 = false); - Span DebuggerToUtf8Span(CVector &buf, bool modify = true) - { - Span str; - uint32_t strLen = GetLength(); - if (UNLIKELY(IsUtf16())) { - CVector tmpBuf; - const uint16_t *data = EcmaString::GetUtf16DataFlat(this, tmpBuf); - size_t len = base::utf_helper::Utf16ToUtf8Size(data, strLen, modify) - 1; - buf.reserve(len); - len = base::utf_helper::DebuggerConvertRegionUtf16ToUtf8(data, buf.data(), strLen, len, 0, modify); - str = Span(buf.data(), len); - } else { - const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf); - str = Span(data, strLen); - } - return str; - } + Span DebuggerToUtf8Span(CVector &buf, bool modify = true); void WriteData(EcmaString *src, uint32_t start, uint32_t destSize, uint32_t length); @@ -514,54 +291,15 @@ private: bool PUBLIC_API ToTypedArrayIndex(uint32_t *index); - template - static EcmaString *ConvertCase(const EcmaVM *vm, const JSHandle &src); - - template - static EcmaString *LocaleConvertCase(const EcmaVM *vm, const JSHandle &src, const icu::Locale &locale); - template static EcmaString *TrimBody(const JSThread *thread, const JSHandle &src, Span &data, TrimMode mode); static EcmaString *Trim(const JSThread *thread, const JSHandle &src, TrimMode mode = TrimMode::TRIM); - // single char copy for loop - template - static void CopyChars(DstType *dst, SrcType *src, uint32_t count) - { - Span srcSp(src, count); - Span dstSp(dst, count); - for (uint32_t i = 0; i < count; i++) { - dstSp[i] = srcSp[i]; - } - } - // memory block copy template static bool MemCopyChars(Span &dst, size_t dstMax, Span &src, size_t count); - // To change the hash algorithm of EcmaString, please modify EcmaString::CalculateConcatHashCode - // and EcmaStringHashHelper::ComputeHashForDataPlatform simultaneously!! - template - static uint32_t ComputeHashForData(const T *data, size_t size, - uint32_t hashSeed) - { - uint32_t hash = hashSeed; - for (uint32_t i = 0; i < size; i++) { - hash = (hash << static_cast(EcmaStringHash::HASH_SHIFT)) - hash + data[i]; - } - return hash; - } - - static bool IsASCIICharacter(uint16_t data) - { - if (data == 0) { - return false; - } - // \0 is not considered ASCII in Ecma-Modified-UTF8 [only modify '\u0000'] - return data <= base::utf_helper::UTF8_1B_MAX; - } - template static int32_t IndexOf(Span &lhsSp, Span &rhsSp, int32_t pos, int32_t max); @@ -572,28 +310,22 @@ private: bool IsLineString() const { - return GetClass()->IsLineString(); + return ToBaseString()->IsLineString(); } bool IsSlicedString() const { - return GetClass()->IsSlicedString(); + return ToBaseString()->IsSlicedString(); } bool IsTreeString() const { - return GetClass()->IsTreeString(); + return ToBaseString()->IsTreeString(); } + bool NotTreeString() const { return !IsTreeString(); } - JSType GetStringType() const - { - JSType type = GetClass()->GetObjectType(); - ASSERT(type >= JSType::STRING_FIRST && type <= JSType::STRING_LAST); - return type; - } - template static void WriteToFlat(EcmaString *src, Char *buf, uint32_t maxLength); @@ -637,18 +369,24 @@ private: // The LineEcmaString abstract class captures sequential string values, only LineEcmaString can store chars data class LineEcmaString : public EcmaString { +private: + using TaggedObject::SIZE; public: - static constexpr uint32_t MAX_LENGTH = (1 << 28) - 16; - static constexpr uint32_t INIT_LENGTH_TIMES = 4; - // DATA_OFFSET: the string data stored after the string header. - // Data can be stored in utf8 or utf16 form according to compressed bit. - static constexpr size_t DATA_OFFSET = EcmaString::SIZE; // DATA_OFFSET equal to Empty String size + LineString* ToLineString() + { + return LineString::Cast(this); + } + + const LineString* ToLineString() const + { + return LineString::ConstCast(this); + } CAST_CHECK(LineEcmaString, IsLineString); - DECL_VISIT_ARRAY(DATA_OFFSET, 0, GetPointerLength()); + DECL_VISIT_ARRAY(LineString::DATA_OFFSET, 0, GetPointerLength()); - static LineEcmaString *Cast(EcmaString *str) + static LineEcmaString* Cast(EcmaString* str) { return static_cast(str); } @@ -660,24 +398,22 @@ public: static size_t ComputeSizeUtf8(uint32_t utf8Len) { - return DATA_OFFSET + utf8Len; + return LineString::ComputeSizeUtf8(utf8Len); } static size_t ComputeSizeUtf16(uint32_t utf16Len) { - return DATA_OFFSET + utf16Len * sizeof(uint16_t); + return LineString::ComputeSizeUtf16(utf16Len); } static size_t ObjectSize(EcmaString *str) { - uint32_t length = str->GetLength(); - return str->IsUtf16() ? ComputeSizeUtf16(length) : ComputeSizeUtf8(length); + return LineString::ObjectSize(str->ToBaseString()); } static size_t DataSize(EcmaString *str) { - uint32_t length = str->GetLength(); - return str->IsUtf16() ? length * sizeof(uint16_t) : length; + return LineString::DataSize(str->ToBaseString()); } size_t GetPointerLength() @@ -686,99 +422,101 @@ public: return AlignUp(byteSize, static_cast(MemAlignment::MEM_ALIGN_OBJECT)) / sizeof(JSTaggedType); } - uint16_t *GetData() const - { - return reinterpret_cast(ToUintPtr(this) + DATA_OFFSET); - } - template uint16_t Get(int32_t index) const { - int32_t length = static_cast(GetLength()); - if (verify) { - if ((index < 0) || (index >= length)) { - return 0; - } - } - if (!IsUtf16()) { - Span sp(GetDataUtf8(), length); - return sp[index]; - } - Span sp(GetDataUtf16(), length); - return sp[index]; + return ToLineString()->Get(index); } void Set(uint32_t index, uint16_t src) { - ASSERT(index < GetLength()); - if (IsUtf8()) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - *(reinterpret_cast(GetData()) + index) = static_cast(src); - } else { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - *(GetData() + index) = src; - } + return ToLineString()->Set(index, src); } }; -static_assert((LineEcmaString::DATA_OFFSET % static_cast(MemAlignment::MEM_ALIGN_OBJECT)) == 0); +// static_assert((LineString::DATA_OFFSET % static_cast(MemAlignment::MEM_ALIGN_OBJECT)) == 0); // The substrings of another string use SlicedString to describe. -class SlicedString : public EcmaString { +class SlicedEcmaString : public EcmaString { +private: + using TaggedObject::SIZE; public: - static constexpr uint32_t MIN_SLICED_ECMASTRING_LENGTH = 13; - static constexpr size_t PARENT_OFFSET = EcmaString::SIZE; - static constexpr uint32_t START_INDEX_BITS_NUM = 30U; - using HasBackingStoreBit = BitField; // 1 - using ReserveBit = HasBackingStoreBit::NextFlag; // 1 - using StartIndexBits = ReserveBit::NextField; // 30 - static_assert(StartIndexBits::START_BIT + StartIndexBits::SIZE == sizeof(uint32_t) * BITS_PER_BYTE, - "StartIndexBits does not match the field size"); - static_assert(StartIndexBits::SIZE == LengthBits::SIZE, "The size of startIndex should be same with Length"); + DECL_VISIT_OBJECT(SlicedString::PARENT_OFFSET, SlicedString::STARTINDEX_AND_FLAGS_OFFSET); - ACCESSORS(Parent, PARENT_OFFSET, STARTINDEX_AND_FLAGS_OFFSET); - ACCESSORS_PRIMITIVE_FIELD(StartIndexAndFlags, uint32_t, STARTINDEX_AND_FLAGS_OFFSET, SIZE); + CAST_CHECK(SlicedEcmaString, IsSlicedString); - DECL_VISIT_OBJECT(PARENT_OFFSET, STARTINDEX_AND_FLAGS_OFFSET); + SlicedString* ToSlicedString() + { + return SlicedString::Cast(this); + } - CAST_CHECK(SlicedString, IsSlicedString); + const SlicedString* ToSlicedString() const + { + return SlicedString::ConstCast(this); + } + + static SlicedEcmaString* FromBaseString(SlicedString* str) + { + return reinterpret_cast(str); + } uint32_t GetStartIndex() const { - uint32_t bits = GetStartIndexAndFlags(); - return StartIndexBits::Decode(bits); + return ToSlicedString()->GetStartIndex(); } void SetStartIndex(uint32_t startIndex) { - ASSERT(startIndex <= SlicedString::MAX_STRING_LENGTH); - uint32_t bits = GetStartIndexAndFlags(); - uint32_t newVal = StartIndexBits::Update(bits, startIndex); - SetStartIndexAndFlags(newVal); + ToSlicedString()->SetStartIndex(startIndex); } bool GetHasBackingStore() const { - uint32_t bits = GetStartIndexAndFlags(); - return HasBackingStoreBit::Decode(bits); + return ToSlicedString()->GetHasBackingStore(); } void SetHasBackingStore(bool hasBackingStore) { - uint32_t bits = GetStartIndexAndFlags(); - uint32_t newVal = HasBackingStoreBit::Update(bits, hasBackingStore); - SetStartIndexAndFlags(newVal); + return ToSlicedString()->SetHasBackingStore(hasBackingStore); } + JSTaggedValue GetParent() const + { + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return JSTaggedValue(ToSlicedString()->GetParent(std::move(readBarrier))); + } + + template + void SetParent(const JSThread* thread, JSHandle value, BarrierMode mode = WRITE_BARRIER) + { + auto writeBarrier = [thread, mode](void* obj, size_t offset, BaseObject* str) { + if (mode == WRITE_BARRIER) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + } else { Barriers::SetPrimitive(obj, offset, reinterpret_cast(str)); } + }; + ToSlicedString()->SetParent(std::move(writeBarrier), value.GetTaggedValue().GetTaggedObject()); + } + + void SetParent(const JSThread* thread, JSTaggedValue value, BarrierMode mode = WRITE_BARRIER) + { + auto writeBarrier = [thread, mode](void* obj, size_t offset, BaseObject* str) { + if (mode == WRITE_BARRIER) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + } else { Barriers::SetPrimitive(obj, offset, reinterpret_cast(str)); } + }; + ToSlicedString()->SetParent(std::move(writeBarrier), value.GetTaggedObject()); + }; private: friend class EcmaString; - static SlicedString *Cast(EcmaString *str) + static SlicedEcmaString *Cast(EcmaString *str) { - return static_cast(str); + return static_cast(str); } - static SlicedString *Cast(const EcmaString *str) + static SlicedEcmaString *Cast(const EcmaString *str) { - return SlicedString::Cast(const_cast(str)); + return SlicedEcmaString::Cast(const_cast(str)); } static size_t ObjectSize() @@ -790,81 +528,119 @@ private: template uint16_t Get(int32_t index) const { - int32_t length = static_cast(GetLength()); - if (verify) { - if ((index < 0) || (index >= length)) { - return 0; - } - } - EcmaString *parent = EcmaString::Cast(GetParent()); - ASSERT(parent->IsLineString()); - if (parent->IsUtf8()) { - Span sp(parent->GetDataUtf8() + GetStartIndex(), length); - return sp[index]; - } - Span sp(parent->GetDataUtf16() + GetStartIndex(), length); - return sp[index]; + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToSlicedString()->Get(std::move(readBarrier), index); } }; class TreeEcmaString : public EcmaString { +private: + using TaggedObject::SIZE; public: - // Minimum length for a tree string - static constexpr uint32_t MIN_TREE_ECMASTRING_LENGTH = 13; + DECL_VISIT_OBJECT(TreeString::FIRST_OFFSET, TreeString::SIZE); - static constexpr size_t FIRST_OFFSET = EcmaString::SIZE; - ACCESSORS(First, FIRST_OFFSET, SECOND_OFFSET); - ACCESSORS(Second, SECOND_OFFSET, SIZE); + CAST_CHECK(TreeEcmaString, IsTreeString); - DECL_VISIT_OBJECT(FIRST_OFFSET, SIZE); + static TreeEcmaString* Cast(EcmaString* str) + { + return static_cast(str); + } - CAST_CHECK(TreeEcmaString, IsTreeString); + static TreeEcmaString* Cast(const EcmaString* str) + { + return TreeEcmaString::Cast(const_cast(str)); + } - static TreeEcmaString *Cast(EcmaString *str) + TreeString* ToTreeString() { - return static_cast(str); + return TreeString::Cast(this); } - static TreeEcmaString *Cast(const EcmaString *str) + const TreeString* ToTreeString() const { - return TreeEcmaString::Cast(const_cast(str)); + return TreeString::ConstCast(this); } + static TreeEcmaString* FromBaseString(TreeString* str) + { + return reinterpret_cast(str); + } + + JSTaggedValue GetFirst() const + { + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return JSTaggedValue(ToTreeString()->GetFirst(std::move(readBarrier))); + } + + template + void SetFirst(const JSThread* thread, JSHandle value, BarrierMode mode = WRITE_BARRIER) + { + auto writeBarrier = [thread, mode](void* obj, size_t offset, BaseObject* str) { + if (mode == WRITE_BARRIER) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + } else { Barriers::SetPrimitive(obj, offset, reinterpret_cast(str)); } + }; + ToTreeString()->SetFirst(std::move(writeBarrier), value->GetTaggedObject()); + } + + void SetFirst(const JSThread* thread, JSTaggedValue value, BarrierMode mode = WRITE_BARRIER) + { + auto writeBarrier = [thread, mode](void* obj, size_t offset, BaseObject* str) { + if (mode == WRITE_BARRIER) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + } else { Barriers::SetPrimitive(obj, offset, reinterpret_cast(str)); } + }; + ToTreeString()->SetFirst(std::move(writeBarrier), value.GetTaggedObject()); + }; + + JSTaggedValue GetSecond() const + { + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return JSTaggedValue(ToTreeString()->GetSecond(std::move(readBarrier))); + } + + template + void SetSecond(const JSThread* thread, JSHandle value, BarrierMode mode = WRITE_BARRIER) + { + auto writeBarrier = [thread, mode](void* obj, size_t offset, BaseObject* str) { + if (mode == WRITE_BARRIER) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + } else { Barriers::SetPrimitive(obj, offset, reinterpret_cast(str)); } + }; + ToTreeString()->SetSecond(std::move(writeBarrier), value->GetTaggedObject()); + } + + void SetSecond(const JSThread* thread, JSTaggedValue value, BarrierMode mode = WRITE_BARRIER) + { + auto writeBarrier = [thread, mode](void* obj, size_t offset, BaseObject* str) { + if (mode == WRITE_BARRIER) { + Barriers::SetObject(thread, obj, offset, reinterpret_cast(str)); + } else { Barriers::SetPrimitive(obj, offset, reinterpret_cast(str)); } + }; + ToTreeString()->SetSecond(std::move(writeBarrier), value.GetTaggedObject()); + }; + bool IsFlat() const { - auto strSecond = EcmaString::Cast(GetSecond()); - return strSecond->GetLength() == 0; + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToTreeString()->IsFlat(std::move(readBarrier)); } template uint16_t Get(int32_t index) const { - int32_t length = static_cast(GetLength()); - if (verify) { - if ((index < 0) || (index >= length)) { - return 0; - } - } - - if (IsFlat()) { - EcmaString *first = EcmaString::Cast(GetFirst()); - return first->At(index); - } - EcmaString *string = const_cast(this); - while (true) { - if (string->IsTreeString()) { - EcmaString *first = EcmaString::Cast(TreeEcmaString::Cast(string)->GetFirst()); - if (static_cast(first->GetLength()) > index) { - string = first; - } else { - index -= static_cast(first->GetLength()); - string = EcmaString::Cast(TreeEcmaString::Cast(string)->GetSecond()); - } - } else { - return string->At(index); - } - } - UNREACHABLE(); + auto readBarrier = [](const void* obj, size_t offset)-> TaggedObject* { + return Barriers::GetTaggedObject(obj, offset); + }; + return ToTreeString()->Get(std::move(readBarrier), index); } }; @@ -1029,7 +805,7 @@ public: if (string_->IsLineString()) { return LineEcmaString::ObjectSize(string_); } else { - return TreeEcmaString::SIZE; + return TreeString::SIZE; } } @@ -1068,12 +844,6 @@ public: return string_->ToU16String(len); } - // not change string data structure. - // if string is not flat, this func has low efficiency. - std::unique_ptr ToOneByteDataForced() - { - return string_->ToOneByteDataForced(); - } // not change string data structure. // if string is not flat, this func has low efficiency. @@ -1162,11 +932,6 @@ public: return string_->GetHashcode(); } - uint32_t GetRawHashcode() - { - return string_->GetRawHashcode(); - } - uint32_t ComputeHashcode() { return string_->ComputeRawHashcode(); @@ -1350,11 +1115,6 @@ public: return string_->IsSlicedString(); } - JSType GetStringType() const - { - return string_->GetStringType(); - } - bool IsTreeString() const { return string_->IsTreeString(); diff --git a/ecmascript/js_handle.h b/ecmascript/js_handle.h index 57b0d5a0d7..9d66de6fdd 100644 --- a/ecmascript/js_handle.h +++ b/ecmascript/js_handle.h @@ -22,7 +22,7 @@ #include "ecmascript/js_tagged_value.h" #include "ecmascript/mem/assert_scope.h" #include "ecmascript/mem/barriers.h" - +#include "common_interfaces/objects/readonly_handle.h" /* * JSHandle: A JSHandle provides a reference to an object that survives relocation by the garbage collector. * @@ -183,6 +183,17 @@ public: GetTaggedValue().D(); } + template + operator ReadOnlyHandle() + { + return ReadOnlyHandle(address_); + } + + template + operator const ReadOnlyHandle() const + { + return ReadOnlyHandle(address_); + } private: inline explicit JSHandle(const JSTaggedType *slot) : address_(reinterpret_cast(slot)) {} inline explicit JSHandle(const T *const *slot) : address_(reinterpret_cast(slot)) {} diff --git a/ecmascript/js_hclass-inl.h b/ecmascript/js_hclass-inl.h index c31ec17bd8..d65f17eb99 100644 --- a/ecmascript/js_hclass-inl.h +++ b/ecmascript/js_hclass-inl.h @@ -245,11 +245,11 @@ inline size_t JSHClass::SizeFromJSHClass(TaggedObject *header) size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); break; case JSType::LINE_STRING: - size = LineEcmaString::ObjectSize(reinterpret_cast(header)); + size = LineString::ObjectSize(reinterpret_cast(header)); size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); break; case JSType::TREE_STRING: - size = TreeEcmaString::SIZE; + size = TreeString::SIZE; size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); break; case JSType::SLICED_STRING: diff --git a/ecmascript/js_hclass.h b/ecmascript/js_hclass.h index 1619f9361f..cefefa434b 100644 --- a/ecmascript/js_hclass.h +++ b/ecmascript/js_hclass.h @@ -82,6 +82,11 @@ struct Reference; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define JSTYPE_DECL /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ INVALID = 0, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ + /* COMMON_TYPE ////////////////////////////////////////////////////////////////////////// */ \ + LINE_STRING, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ + SLICED_STRING, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ + TREE_STRING, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ + \ JS_OBJECT, /* JS_OBJECT_FIRST ////////////////////////////////////////////////////////////////////// */ \ JS_SHARED_OBJECT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ JS_REALM, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ @@ -231,9 +236,6 @@ struct Reference; JS_PROXY, /* ECMA_OBJECT_LAST ///////////////////////////////////////////////////////////////////////////// */ \ \ HCLASS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ - LINE_STRING, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ - SLICED_STRING, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ - TREE_STRING, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ BIGINT, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \ @@ -344,6 +346,13 @@ enum class JSType : uint8_t { JSTYPE_DECL, }; +static_assert(static_cast(JSType::LINE_STRING) == static_cast(CommonType::LINE_STRING) && + "line string type should be same with common type"); +static_assert(static_cast(JSType::SLICED_STRING) == static_cast(CommonType::SLICED_STRING) && + "sliced string type should be same with common type"); +static_assert(static_cast(JSType::TREE_STRING) == static_cast(CommonType::TREE_STRING) && + "tree string type should be same with common type"); + struct TransitionResult { bool isTagged; bool isTransition; @@ -527,9 +536,9 @@ public: inline void ClearBitField() { - SetProfileType(0ULL); SetBitField(0UL); SetBitField1(0UL); + SetProfileType(0ULL); } inline JSType GetObjectType() const @@ -1193,7 +1202,7 @@ public: inline bool IsRegularObject() const { - return GetObjectType() < JSType::JS_API_ARRAY_LIST; + return GetObjectType() < JSType::JS_API_ARRAY_LIST && GetObjectType() > JSType::STRING_LAST; } inline bool IsJSAPIArrayList() const diff --git a/ecmascript/js_primitive_ref.cpp b/ecmascript/js_primitive_ref.cpp index 3f9c3eb2ba..0766e46b57 100644 --- a/ecmascript/js_primitive_ref.cpp +++ b/ecmascript/js_primitive_ref.cpp @@ -16,6 +16,7 @@ #include "ecmascript/js_primitive_ref.h" #include "ecmascript/global_env.h" +#include "ecmascript/ecma_string-inl.h" namespace panda::ecmascript { // ES6 9.4.3.4 StringCreate( value, prototype) diff --git a/ecmascript/js_stable_array.cpp b/ecmascript/js_stable_array.cpp index 81093ecdae..64ddc79d84 100644 --- a/ecmascript/js_stable_array.cpp +++ b/ecmascript/js_stable_array.cpp @@ -425,7 +425,7 @@ bool JSStableArray::WorthUseTreeString(uint32_t sepLength, size_t allocateLength // otherwise, the num of elements is (len-1)(string in vector) + (len -1)(num of seps) size_t treeStringElementNum = (sepLength == 0) ? (len - 1) : (2 * (len - 1)); - if (treeStringElementNum * TreeEcmaString::SIZE <= allocateLength) { + if (treeStringElementNum * TreeString::SIZE <= allocateLength) { // heuristic: if tree string uses less memory than linestring, it is worth. // In other words, we hope tree string can work for the large strings join. return true; @@ -511,7 +511,7 @@ JSTaggedValue JSStableArray::DoStableArrayJoin(JSThread *thread, JSHandle 0) { allocateLength += static_cast(sepLength) * (len - 1); } - if (allocateLength > EcmaString::MAX_STRING_LENGTH) { + if (allocateLength > BaseString::MAX_STRING_LENGTH) { ArrayJoinStack::Pop(thread, receiverValue); THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } @@ -631,7 +631,7 @@ bool JSStableArray::WorthUseTreeString(int sep, size_t allocateLength, uint32_t size_t treeStringElementNum = (sep == MINUS_TWO) ? (len - 1) : (2 * (len - 1)); // if sep is MINUS_TWO, means all the elements in treeString is len -1; // otherwise, the num of elements is (len-1)(string in vector) + (len -1)(num of seps) - if (treeStringElementNum * TreeEcmaString::SIZE <= allocateLength) { + if (treeStringElementNum * TreeString::SIZE <= allocateLength) { // heuristic: if tree string uses less memory than linestring, it is worth. // In other words, we hope tree string can work for the large strings join. return true; @@ -735,7 +735,7 @@ JSTaggedValue JSStableArray::Join(JSHandle receiverValue, EcmaRun if (len > 0) { allocateLength += static_cast(sepLength) * (len - 1); } - if (allocateLength > EcmaString::MAX_STRING_LENGTH) { + if (allocateLength > BaseString::MAX_STRING_LENGTH) { ArrayJoinStack::Pop(thread, receiverValue); THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception()); } diff --git a/ecmascript/js_typed_array.cpp b/ecmascript/js_typed_array.cpp index 729fb4ed0d..4b936e1599 100644 --- a/ecmascript/js_typed_array.cpp +++ b/ecmascript/js_typed_array.cpp @@ -16,6 +16,7 @@ #include "ecmascript/js_typed_array.h" #include "ecmascript/base/typed_array_helper-inl.h" +#include "ecmascript/ecma_string-inl.h" #include "ecmascript/shared_objects/js_sendable_arraybuffer.h" namespace panda::ecmascript { diff --git a/ecmascript/mem/barriers.h b/ecmascript/mem/barriers.h index 90a3a650a9..1f2b97a276 100644 --- a/ecmascript/mem/barriers.h +++ b/ecmascript/mem/barriers.h @@ -89,6 +89,11 @@ public: return *addr; } + static inline ARK_INLINE TaggedObject* GetTaggedObject(const void* obj, size_t offset) + { + return JSTaggedValue(GetTaggedValue(obj, offset)).GetTaggedObject(); + } + static inline JSTaggedType GetTaggedValue(const void *obj, size_t offset) { #ifdef USE_READ_BARRIER diff --git a/ecmascript/mem/object_xray.h b/ecmascript/mem/object_xray.h index 98efb29361..49102d9a8a 100644 --- a/ecmascript/mem/object_xray.h +++ b/ecmascript/mem/object_xray.h @@ -422,7 +422,7 @@ public: TreeEcmaString::Cast(object)->VisitRangeSlot(visitor); break; case JSType::SLICED_STRING: - SlicedString::Cast(object)->VisitRangeSlot(visitor); + SlicedEcmaString::Cast(object)->VisitRangeSlot(visitor); break; case JSType::JS_NATIVE_POINTER: if constexpr ((visitType == VisitType::SNAPSHOT_VISIT) || (visitType == VisitType::ALL_VISIT)) { diff --git a/ecmascript/mem/tagged_object-inl.h b/ecmascript/mem/tagged_object-inl.h index 5e3ef736f3..abd4049414 100644 --- a/ecmascript/mem/tagged_object-inl.h +++ b/ecmascript/mem/tagged_object-inl.h @@ -79,7 +79,7 @@ inline bool TaggedObject::IsInSharedHeap() const #else inline void TaggedObject::SetClassWithoutBarrier(JSHClass *hclass) { - class_ = reinterpret_cast(hclass); + SetBaseClassWithoutBarrier(reinterpret_cast(hclass)); } inline void TaggedObject::TransitionClassWithoutBarrier(JSHClass *hclass) diff --git a/ecmascript/mem/tagged_object.h b/ecmascript/mem/tagged_object.h index cfd98011b4..f12f78b61b 100644 --- a/ecmascript/mem/tagged_object.h +++ b/ecmascript/mem/tagged_object.h @@ -66,7 +66,7 @@ public: #else JSHClass *GetClass() const { - return reinterpret_cast(class_); + return reinterpret_cast(GetBaseClass()); } size_t GetSize(); @@ -91,10 +91,6 @@ public: private: void SetClass(const JSThread *thread, JSHClass *hclass); -#ifndef USE_CMC_GC - MarkWordType class_; -#endif - friend class BaseHeap; friend class Heap; friend class SharedHeap; diff --git a/ecmascript/object_factory-inl.h b/ecmascript/object_factory-inl.h index 14d7ab023f..a7d05cce64 100644 --- a/ecmascript/object_factory-inl.h +++ b/ecmascript/object_factory-inl.h @@ -85,7 +85,7 @@ EcmaString *ObjectFactory::AllocTreeStringObject() NewSObjectHook(); return reinterpret_cast(sHeap_->AllocateOldOrHugeObject( thread_, JSHClass::Cast(thread_->GlobalConstants()->GetTreeStringClass().GetTaggedObject()), - TreeEcmaString::SIZE)); + TreeString::SIZE)); } JSHandle ObjectFactory::NewJSNativePointer(void *externalPointer, diff --git a/ecmascript/object_fast_operator-inl.h b/ecmascript/object_fast_operator-inl.h index c4eacb7fa4..8f8cd56242 100644 --- a/ecmascript/object_fast_operator-inl.h +++ b/ecmascript/object_fast_operator-inl.h @@ -1061,7 +1061,7 @@ bool ObjectFastOperator::ShouldCallSetter(JSTaggedValue receiver, JSTaggedValue bool ObjectFastOperator::IsSpecialIndexedObj(JSType jsType) { - return jsType > JSType::JS_ARRAY; + return jsType > JSType::JS_ARRAY || IsString(jsType); } bool ObjectFastOperator::IsJSSharedArray(JSType jsType) diff --git a/ecmascript/platform/arm64/ecma_string_hash_internal.h b/ecmascript/platform/arm64/ecma_string_hash_internal.h index 2b0b13a683..f2625e8dd9 100644 --- a/ecmascript/platform/arm64/ecma_string_hash_internal.h +++ b/ecmascript/platform/arm64/ecma_string_hash_internal.h @@ -19,7 +19,7 @@ #include #include - +#include "ecmascript/base/config.h" #include "ecmascript/platform/ecma_string_hash.h" namespace panda::ecmascript { diff --git a/ecmascript/platform/common/ecma_string_hash_internal.h b/ecmascript/platform/common/ecma_string_hash_internal.h index 67f6485db7..44902dbb75 100644 --- a/ecmascript/platform/common/ecma_string_hash_internal.h +++ b/ecmascript/platform/common/ecma_string_hash_internal.h @@ -17,7 +17,7 @@ #define ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_COMMON_H #include - +#include "ecmascript/base/config.h" #include "ecmascript/platform/ecma_string_hash.h" namespace panda::ecmascript { diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index 1dafe46419..a8d41a9811 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -3303,9 +3303,9 @@ DEF_RUNTIME_STUBS(DecodeURIComponent) } } else { ASSERT(stringAcc.IsSlicedString()); - auto parent = SlicedString::Cast(string.GetTaggedValue())->GetParent(); + auto parent = SlicedEcmaString::Cast(string.GetTaggedValue())->GetParent(); auto parentStrAcc = EcmaStringAccessor(parent); - auto startIndex = SlicedString::Cast(string.GetTaggedValue())->GetStartIndex(); + auto startIndex = SlicedEcmaString::Cast(string.GetTaggedValue())->GetStartIndex(); #if !ENABLE_NEXT_OPTIMIZATION if (parentStrAcc.IsLineString()) { if (parentStrAcc.IsUtf8()) { diff --git a/ecmascript/tagged_dictionary.cpp b/ecmascript/tagged_dictionary.cpp index 883e9313ac..fe4ba21854 100644 --- a/ecmascript/tagged_dictionary.cpp +++ b/ecmascript/tagged_dictionary.cpp @@ -39,7 +39,7 @@ int NameDictionary::Hash(const JSTaggedValue &key) // for ohmurl path to compute hash code int NameDictionary::Hash(const uint8_t* str, int strSize) { - return EcmaString::ComputeHashForData(str, strSize, 0); + return BaseString::ComputeHashForData(str, strSize, 0); } bool NameDictionary::IsMatch(const JSTaggedValue &key, const JSTaggedValue &other) diff --git a/ecmascript/tests/BUILD.gn b/ecmascript/tests/BUILD.gn index 2f6eee3838..310e6357a2 100644 --- a/ecmascript/tests/BUILD.gn +++ b/ecmascript/tests/BUILD.gn @@ -205,12 +205,12 @@ host_unittest_action("ECMA_StringHash_Test") { deps += hiviewdfx_deps } -host_unittest_action("ECMA_String_Test") { +host_unittest_action("BASE_String_Test") { module_out_path = module_output_path sources = [ # test file - #"ecma_string_test.cpp", + "base_string_test.cpp", ] configs = [ @@ -3446,7 +3446,7 @@ group("unittest") { ":ECMA_StringHash_Test", ":ECMA_StringTable_Test", - #":ECMA_String_Test", + ":BASE_String_Test", ":ECMA_VM_Test", ":GC_ConcurrentMarking_Test", ":GC_ConcurrentSweep_Test", @@ -3591,7 +3591,7 @@ group("host_unittest") { ":ECMA_StringHash_TestAction", ":ECMA_StringTable_TestAction", - #":ECMA_String_TestAction", + ":BASE_String_TestAction", ":ECMA_VM_TestAction", ":GC_ConcurrentMarking_TestAction", ":GC_ConcurrentSweep_TestAction", @@ -3726,7 +3726,7 @@ group("host_unittest") { ":ECMA_StringHash_TestAction", ":ECMA_StringTable_TestAction", - #":ECMA_String_TestAction", + ":BASE_String_TestAction", ":ECMA_VM_TestAction", ":GC_ConcurrentMarking_TestAction", ":GC_ConcurrentSweep_TestAction", diff --git a/ecmascript/tests/base_string_test.cpp b/ecmascript/tests/base_string_test.cpp new file mode 100644 index 0000000000..b038cf1292 --- /dev/null +++ b/ecmascript/tests/base_string_test.cpp @@ -0,0 +1,1744 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecmascript/ecma_string-inl.h" +#include "common_interfaces/objects/string/base_string_impl.h" +#include "ecmascript/object_factory.h" +#include "ecmascript/tests/ecma_test_common.h" + +using namespace panda::ecmascript; + +namespace panda::test { + class BaseStringTest : public BaseTestWithScope { + public: + static void SetUpTestCase() + { + GTEST_LOG_(INFO) << "SetUpTestCase"; + uint8_t arrayU8[] = {12, 34, 77, 127, 99, 1}; + uint16_t arrayU16Comp[] = {1, 4, 37, 91, 127, 1}; + uint16_t arrayU16NotComp[] = {72, 43, 337, 961, 1317, 65535}; + EXPECT_TRUE(BaseString::CanBeCompressed(arrayU8, sizeof(arrayU8) / sizeof(arrayU8[0]))); + EXPECT_TRUE(BaseString::CanBeCompressed(arrayU16Comp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); + EXPECT_FALSE(BaseString::CanBeCompressed(arrayU16NotComp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); + } + }; + + /* + * @tc.name: CanBeCompressed + * @tc.desc: Check whether the bool returned through calling CanBeCompressed function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CanBeCompressed) + { + uint8_t arrayU8[] = {12, 34, 77, 127, 99, 1}; + uint16_t arrayU16Comp[] = {1, 4, 37, 91, 127, 1}; + uint16_t arrayU16NotComp[] = {72, 43, 337, 961, 1317, 65535}; + EXPECT_TRUE(BaseString::CanBeCompressed(arrayU8, sizeof(arrayU8) / sizeof(arrayU8[0]))); + EXPECT_TRUE(BaseString::CanBeCompressed(arrayU16Comp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); + EXPECT_FALSE(BaseString::CanBeCompressed(arrayU16NotComp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); + } + + /* + * @tc.name: CreateEmptyString + * @tc.desc: Check whether the EcmaString created through calling CreateEmptyString function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CreateEmptyString) + { + JSHandle handleEcmaStrEmpty(thread, EcmaStringAccessor::CreateEmptyString(instance)); + EXPECT_EQ(handleEcmaStrEmpty->ToBaseString()->GetLength(), 0U); + EXPECT_TRUE(handleEcmaStrEmpty->ToBaseString()->IsUtf8()); + EXPECT_FALSE(handleEcmaStrEmpty->ToBaseString()->IsUtf16()); + } + + /* + * @tc.name: CreateLineString + * @tc.desc: Check whether the EcmaString created through calling CreateLineString function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CreateLineString) + { + // CreateLineString( , true, ). + size_t sizeAllocComp = 5; + JSHandle handleEcmaStrAllocComp( + thread, EcmaStringAccessor::CreateLineString(instance, sizeAllocComp, true)); + EXPECT_EQ(handleEcmaStrAllocComp->ToBaseString()->GetLength(), sizeAllocComp); + EXPECT_TRUE(handleEcmaStrAllocComp->ToBaseString()->IsUtf8()); + EXPECT_FALSE(handleEcmaStrAllocComp->ToBaseString()->IsUtf16()); + + // CreateLineString( , false, ). + size_t sizeAllocNotComp = 5; + JSHandle handleEcmaStrAllocNotComp(thread, + EcmaStringAccessor::CreateLineString( + instance, sizeAllocNotComp, false)); + EXPECT_EQ(handleEcmaStrAllocNotComp->ToBaseString()->GetLength(), sizeAllocNotComp); + EXPECT_FALSE(handleEcmaStrAllocNotComp->ToBaseString()->IsUtf8()); + EXPECT_TRUE(handleEcmaStrAllocNotComp->ToBaseString()->IsUtf16()); + } + + /* + * @tc.name: CreateFromUtf8 + * @tc.desc: Check whether the EcmaString created through calling CreateFromUtf8 function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CreateFromUtf8) + { + uint8_t arrayU8[] = {"xyz123!@#"}; + size_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { + EXPECT_EQ(arrayU8[i], handleEcmaStrU8->ToBaseString()->At(Barriers::GetTaggedObject, i)); + } + EXPECT_EQ(handleEcmaStrU8->ToBaseString()->GetLength(), lengthEcmaStrU8); + EXPECT_TRUE(handleEcmaStrU8->ToBaseString()->IsUtf8()); + EXPECT_FALSE(handleEcmaStrU8->ToBaseString()->IsUtf16()); + } + + /* + * @tc.name: CreateFromUtf16 + * @tc.desc: Check whether the EcmaString created through calling CreateFromUtf16 function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CreateFromUtf16) + { + // CreateFromUtf16( , , , true). + uint16_t arrayU16Comp[] = {1, 23, 45, 67, 127}; + size_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + EXPECT_EQ(handleEcmaStrU16Comp->ToBaseString()->GetLength(), lengthEcmaStrU16Comp); + EXPECT_TRUE(handleEcmaStrU16Comp->ToBaseString()->IsUtf8()); + EXPECT_FALSE(handleEcmaStrU16Comp->ToBaseString()->IsUtf16()); + + // CreateFromUtf16( , , , false). + uint16_t arrayU16NotComp[] = {127, 33, 128, 12, 256, 11100, 65535}; + size_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, + false)); + EXPECT_EQ(handleEcmaStrU16NotComp->ToBaseString()->GetLength(), lengthEcmaStrU16NotComp); + EXPECT_FALSE(handleEcmaStrU16NotComp->ToBaseString()->IsUtf8()); + EXPECT_TRUE(handleEcmaStrU16NotComp->ToBaseString()->IsUtf16()); + } + + /* + * @tc.name: ObjectSize + * @tc.desc: Check whether the value returned through calling ObjectSize function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, ObjectSize) + { + JSHandle handleEcmaStrEmpty(thread, EcmaStringAccessor::CreateEmptyString(instance)); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrEmpty).ObjectSize(), BaseString::SIZE + 0); + + size_t lengthEcmaStrAllocComp = 5; + JSHandle handleEcmaStrAllocComp(thread, + EcmaStringAccessor::CreateLineString( + instance, lengthEcmaStrAllocComp, true)); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrAllocComp).ObjectSize(), + BaseString::SIZE + sizeof(uint8_t) * lengthEcmaStrAllocComp); + + size_t lengthEcmaStrAllocNotComp = 5; + JSHandle handleEcmaStrAllocNotComp(thread, + EcmaStringAccessor::CreateLineString( + instance, lengthEcmaStrAllocNotComp, false)); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrAllocNotComp).ObjectSize(), + BaseString::SIZE + sizeof(uint16_t) * lengthEcmaStrAllocNotComp); + + uint8_t arrayU8[] = {"abcde"}; + size_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU8).ObjectSize(), + BaseString::SIZE + sizeof(uint8_t) * lengthEcmaStrU8); + + // ObjectSize(). EcmaString made by CreateFromUtf16( , , , true). + uint16_t arrayU16Comp[] = {1, 23, 45, 67, 127}; + size_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU16Comp).ObjectSize(), + BaseString::SIZE + sizeof(uint8_t) * lengthEcmaStrU16Comp); + + // ObjectSize(). EcmaString made by CreateFromUtf16( , , , false). + uint16_t arrayU16NotComp[] = {127, 128, 256, 11100, 65535}; + size_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, + false)); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU16NotComp).ObjectSize(), + BaseString::SIZE + sizeof(uint16_t) * lengthEcmaStrU16NotComp); + } + + /* + * @tc.name: Compare_001 + * @tc.desc: Check whether the value returned through calling Compare function between EcmaStrings made by + * CreateFromUtf8() is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Compare_001) + { + // Compare(). Between EcmaStrings made by CreateFromUtf8(). + uint8_t arrayU8No1[3] = {1, 23}; + uint8_t arrayU8No2[4] = {1, 23, 49}; + uint8_t arrayU8No3[6] = {1, 23, 45, 97, 127}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; + uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU8No2(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); + JSHandle handleEcmaStrU8No3(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No1, handleEcmaStrU8No2), -1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No2, handleEcmaStrU8No1), 1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No2, handleEcmaStrU8No3), 49 - 45); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No3, handleEcmaStrU8No2), 45 - 49); + } + + /* + * @tc.name: Compare_002 + * @tc.desc: Check whether the value returned through calling Compare function between EcmaStrings made by + * CreateFromUtf16( , , , true) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Compare_002) + { + // Compare(). Between EcmaStrings made by CreateFromUtf16( , , , true). + uint16_t arrayU16CompNo1[] = {1, 23}; + uint16_t arrayU16CompNo2[] = {1, 23, 49}; + uint16_t arrayU16CompNo3[] = {1, 23, 45, 97, 127}; + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16CompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo1, handleEcmaStrU16CompNo2), -1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo2, handleEcmaStrU16CompNo1), 1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo2, handleEcmaStrU16CompNo3), 49 - 45); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo3, handleEcmaStrU16CompNo2), 45 - 49); + } + + /* + * @tc.name: Compare_003 + * @tc.desc: Check whether the value returned through calling Compare function between EcmaString made by + * CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , true) made by CreateFromUtf16( , , , true) is + * within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Compare_003) + { + // Compare(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , true). + uint8_t arrayU8No1[3] = {1, 23}; + uint8_t arrayU8No2[4] = {1, 23, 49}; + uint16_t arrayU16CompNo1[] = {1, 23}; + uint16_t arrayU16CompNo2[] = {1, 23, 49}; + uint16_t arrayU16CompNo3[] = {1, 23, 45, 97, 127}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU8No2(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16CompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No1, handleEcmaStrU16CompNo1), 0); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo1, handleEcmaStrU8No1), 0); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No1, handleEcmaStrU16CompNo2), -1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo2, handleEcmaStrU8No1), 1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No2, handleEcmaStrU16CompNo3), 49 - 45); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo3, handleEcmaStrU8No2), 45 - 49); + } + + /* + * @tc.name: Compare_004 + * @tc.desc: Check whether the value returned through calling Compare function between EcmaStrings made by + * CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Compare_004) + { + // Compare(). Between EcmaStrings made by CreateFromUtf16( , , , false). + uint16_t arrayU16NotCompNo1[] = {1, 23}; + uint16_t arrayU16NotCompNo2[] = {1, 23, 49}; + uint16_t arrayU16NotCompNo3[] = {1, 23, 456, 6789, 65535, 127}; + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); + uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, true)); + JSHandle handleEcmaStrU16NotCompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo2[0], + lengthEcmaStrU16NotCompNo2, true)); + JSHandle handleEcmaStrU16NotCompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo3[0], + lengthEcmaStrU16NotCompNo3, false)); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo1, handleEcmaStrU16NotCompNo2), -1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo2, handleEcmaStrU16NotCompNo1), 1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo2, handleEcmaStrU16NotCompNo3), + 49 - 456); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo3, handleEcmaStrU16NotCompNo2), + 456 - 49); + } + + /* + * @tc.name: Compare_005 + * @tc.desc: Check whether the value returned through calling Compare function between EcmaString made by + * CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Compare_005) + { + // Compare(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false). + uint8_t arrayU8No1[3] = {1, 23}; + uint8_t arrayU8No2[4] = {1, 23, 49}; + uint16_t arrayU16NotCompNo1[] = {1, 23}; + uint16_t arrayU16NotCompNo2[] = {1, 23, 49}; + uint16_t arrayU16NotCompNo3[] = {1, 23, 456, 6789, 65535, 127}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); + uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU8No2(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, true)); + JSHandle handleEcmaStrU16NotCompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo2[0], + lengthEcmaStrU16NotCompNo2, true)); + JSHandle handleEcmaStrU16NotCompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo3[0], + lengthEcmaStrU16NotCompNo3, false)); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No1, handleEcmaStrU16NotCompNo1), 0); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo1, handleEcmaStrU8No1), 0); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No1, handleEcmaStrU16NotCompNo2), -1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo2, handleEcmaStrU8No1), 1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU8No2, handleEcmaStrU16NotCompNo3), 49 - 456); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo3, handleEcmaStrU8No2), 456 - 49); + } + + /* + * @tc.name: Compare_006 + * @tc.desc: Check whether the value returned through calling Compare function between EcmaString made by + * CreateFromUtf16( , , , true) and EcmaString made by CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Compare_006) + { + // Compare(). EcmaString made by CreateFromUtf16( , , , true) and EcmaString made by + // CreateFromUtf16( , , , false). + uint16_t arrayU16CompNo1[] = {1, 23}; + uint16_t arrayU16CompNo2[] = {1, 23, 49}; + uint16_t arrayU16NotCompNo1[] = {1, 23}; + uint16_t arrayU16NotCompNo2[] = {1, 23, 49}; + uint16_t arrayU16NotCompNo3[] = {1, 23, 456, 6789, 65535, 127}; + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); + uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, true)); + JSHandle handleEcmaStrU16NotCompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo2[0], + lengthEcmaStrU16NotCompNo2, true)); + JSHandle handleEcmaStrU16NotCompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo3[0], + lengthEcmaStrU16NotCompNo3, false)); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo1, handleEcmaStrU16NotCompNo1), 0); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo1, handleEcmaStrU16CompNo1), 0); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo1, handleEcmaStrU16NotCompNo2), -1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo2, handleEcmaStrU16CompNo1), 1); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16CompNo2, handleEcmaStrU16NotCompNo3), 49 - 456); + EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStrU16NotCompNo3, handleEcmaStrU16CompNo2), 456 - 49); + } + + /* + * @tc.name: Concat_001 + * @tc.desc: Check whether the EcmaString returned through calling Concat function between EcmaString made by + * CreateFromUtf8() and EcmaString made by CreateFromUtf8() is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Concat_001) + { + // Concat(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf8(). + uint8_t arrayFrontU8[] = {"abcdef"}; + uint8_t arrayBackU8[] = {"ABCDEF"}; + uint32_t lengthEcmaStrFrontU8 = sizeof(arrayFrontU8) - 1; + uint32_t lengthEcmaStrBackU8 = sizeof(arrayBackU8) - 1; + JSHandle handleEcmaStrFrontU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayFrontU8[0], lengthEcmaStrFrontU8, true)); + JSHandle handleEcmaStrBackU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayBackU8[0], lengthEcmaStrBackU8, true)); + JSHandle handleEcmaStrConcatU8(thread, + EcmaStringAccessor::Concat( + instance, handleEcmaStrFrontU8, handleEcmaStrBackU8)); + EXPECT_TRUE(handleEcmaStrConcatU8->ToBaseString()->IsUtf8()); + for (uint32_t i = 0; i < lengthEcmaStrFrontU8; i++) { + EXPECT_EQ(handleEcmaStrConcatU8->ToBaseString()->At(Barriers::GetTaggedObject, i), arrayFrontU8[i]); + } + for (uint32_t i = 0; i < lengthEcmaStrBackU8; i++) { + EXPECT_EQ(handleEcmaStrConcatU8->ToBaseString()->At(Barriers::GetTaggedObject, i + lengthEcmaStrFrontU8), + arrayBackU8[i]); + } + EXPECT_EQ(handleEcmaStrConcatU8->ToBaseString()->GetLength(), lengthEcmaStrFrontU8 + lengthEcmaStrBackU8); + } + + /* + * @tc.name: Concat_002 + * @tc.desc: Check whether the EcmaString returned through calling Concat function between EcmaString made by + * CreateFromUtf16( , , , false) and EcmaString made by CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Concat_002) + { + // Concat(). EcmaString made by CreateFromUtf16( , , , false) and EcmaString made by + // CreateFromUtf16( , , , false). + uint16_t arrayFrontU16NotComp[] = {128, 129, 256, 11100, 65535, 100}; + uint16_t arrayBackU16NotComp[] = {88, 768, 1, 270, 345, 333}; + uint32_t lengthEcmaStrFrontU16NotComp = sizeof(arrayFrontU16NotComp) / sizeof(arrayFrontU16NotComp[0]); + uint32_t lengthEcmaStrBackU16NotComp = sizeof(arrayBackU16NotComp) / sizeof(arrayBackU16NotComp[0]); + JSHandle handleEcmaStrFrontU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayFrontU16NotComp[0], + lengthEcmaStrFrontU16NotComp, false)); + JSHandle handleEcmaStrBackU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayBackU16NotComp[0], + lengthEcmaStrBackU16NotComp, false)); + JSHandle handleEcmaStrConcatU16NotComp(thread, + EcmaStringAccessor::Concat( + instance, handleEcmaStrFrontU16NotComp, + handleEcmaStrBackU16NotComp)); + EXPECT_TRUE(handleEcmaStrConcatU16NotComp->ToBaseString()->IsUtf16()); + for (uint32_t i = 0; i < lengthEcmaStrFrontU16NotComp; i++) { + EXPECT_EQ(handleEcmaStrConcatU16NotComp->ToBaseString()->At(Barriers::GetTaggedObject, i), + arrayFrontU16NotComp[i]); + } + for (uint32_t i = 0; i < lengthEcmaStrBackU16NotComp; i++) { + EXPECT_EQ( + handleEcmaStrConcatU16NotComp->ToBaseString()->At(Barriers::GetTaggedObject, i + + lengthEcmaStrFrontU16NotComp), arrayBackU16NotComp[i]); + } + EXPECT_EQ(handleEcmaStrConcatU16NotComp->ToBaseString()->GetLength(), + lengthEcmaStrFrontU16NotComp + lengthEcmaStrBackU16NotComp); + } + + /* + * @tc.name: Concat_003 + * @tc.desc: Check whether the EcmaString returned through calling Concat function between EcmaString made by + * CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, Concat_003) + { + // Concat(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false). + uint8_t arrayFrontU8[] = {"abcdef"}; + uint16_t arrayBackU16NotComp[] = {88, 768, 1, 270, 345, 333}; + uint32_t lengthEcmaStrFrontU8 = sizeof(arrayFrontU8) - 1; + uint32_t lengthEcmaStrBackU16NotComp = sizeof(arrayBackU16NotComp) / sizeof(arrayBackU16NotComp[0]); + JSHandle handleEcmaStrFrontU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayFrontU8[0], lengthEcmaStrFrontU8, true)); + JSHandle handleEcmaStrBackU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayBackU16NotComp[0], + lengthEcmaStrBackU16NotComp, false)); + JSHandle handleEcmaStrConcatU8U16NotComp(thread, + EcmaStringAccessor::Concat( + instance, handleEcmaStrFrontU8, + handleEcmaStrBackU16NotComp)); + EXPECT_TRUE(handleEcmaStrConcatU8U16NotComp->ToBaseString()->IsUtf16()); + for (uint32_t i = 0; i < lengthEcmaStrFrontU8; i++) { + EXPECT_EQ(handleEcmaStrConcatU8U16NotComp->ToBaseString()->At(Barriers::GetTaggedObject, i), + arrayFrontU8[i]); + } + for (uint32_t i = 0; i < lengthEcmaStrBackU16NotComp; i++) { + EXPECT_EQ( + handleEcmaStrConcatU8U16NotComp->ToBaseString()->At(Barriers::GetTaggedObject, i + lengthEcmaStrFrontU8), + arrayBackU16NotComp[i]); + } + EXPECT_EQ(handleEcmaStrConcatU8U16NotComp->ToBaseString()->GetLength(), + lengthEcmaStrFrontU8 + lengthEcmaStrBackU16NotComp); + } + + /* + * @tc.name: FastSubString_001 + * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString made by + * CreateFromUtf8() is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, FastSubString_001) + { + // FastSubString(). From EcmaString made by CreateFromUtf8(). + uint8_t arrayU8[6] = {3, 7, 19, 54, 99}; + uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + uint32_t indexStartSubU8 = 2; + uint32_t lengthSubU8 = 2; + JSHandle handleEcmaStrSubU8(thread, + EcmaStringAccessor::FastSubString( + instance, handleEcmaStrU8, indexStartSubU8, lengthSubU8)); + for (uint32_t i = 0; i < lengthSubU8; i++) { + EXPECT_EQ(handleEcmaStrSubU8->ToBaseString()->At(Barriers::GetTaggedObject, i), + handleEcmaStrU8->ToBaseString()->At(Barriers::GetTaggedObject, i + indexStartSubU8)); + } + EXPECT_EQ(handleEcmaStrSubU8->ToBaseString()->GetLength(), lengthSubU8); + } + + /* + * @tc.name: FastSubString_002 + * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString made by + * CreateFromUtf16( , , , true) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, FastSubString_002) + { + // FastSubString(). From EcmaString made by CreateFromUtf16( , , , true). + uint16_t arrayU16Comp[] = {1, 12, 34, 56, 127}; + uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + uint32_t indexStartSubU16Comp = 0; + uint32_t lengthSubU16Comp = 2; + JSHandle handleEcmaStrSubU16Comp(thread, + EcmaStringAccessor::FastSubString( + instance, handleEcmaStrU16Comp, indexStartSubU16Comp, + lengthSubU16Comp)); + for (uint32_t i = 0; i < lengthSubU16Comp; i++) { + EXPECT_EQ(handleEcmaStrSubU16Comp->ToBaseString()->At(Barriers::GetTaggedObject, i), + handleEcmaStrU16Comp->ToBaseString()->At(Barriers::GetTaggedObject, i + indexStartSubU16Comp)); + } + EXPECT_EQ(handleEcmaStrSubU16Comp->ToBaseString()->GetLength(), lengthSubU16Comp); + } + + /* + * @tc.name: FastSubString_003 + * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString made by + * CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, FastSubString_003) + { + // FastSubString(). From EcmaString made by CreateFromUtf16( , , , false). + uint16_t arrayU16NotComp[] = {19, 54, 256, 11100, 65535}; + uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, + false)); + uint32_t indexStartSubU16NotComp = 0; + uint32_t lengthSubU16NotComp = 2; + JSHandle handleEcmaStrSubU16NotComp(thread, + EcmaStringAccessor::FastSubString( + instance, handleEcmaStrU16NotComp, indexStartSubU16NotComp, + lengthSubU16NotComp)); + for (uint32_t i = 0; i < lengthSubU16NotComp; i++) { + EXPECT_EQ(handleEcmaStrSubU16NotComp->ToBaseString()->At(Barriers::GetTaggedObject, i), + handleEcmaStrU16NotComp->ToBaseString()->At(Barriers::GetTaggedObject, + i + indexStartSubU16NotComp)); + } + EXPECT_EQ(handleEcmaStrSubU16NotComp->ToBaseString()->GetLength(), lengthSubU16NotComp); + } + + /* + * @tc.name: FastSubString_004 + * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, FastSubString_004) + { + ObjectFactory* factory = instance->GetFactory(); + { + JSHandle sourceString = factory->NewFromUtf8("整数integer"); + JSHandle tmpString = factory->NewFromASCII("integer"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EcmaString* res = EcmaStringAccessor::FastSubString(instance, sourceString, 2, 7); + EXPECT_TRUE(res->ToBaseString()->IsUtf8()); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, res->ToBaseString(), tmpString->ToBaseString())); + } + { + JSHandle sourceString = factory->NewFromUtf8("整数integer"); + JSHandle tmpString = factory->NewFromUtf8("整数"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EcmaString* res = EcmaStringAccessor::FastSubString(instance, sourceString, 0, 2); + EXPECT_TRUE(res->ToBaseString()->IsUtf16()); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, res->ToBaseString(), tmpString->ToBaseString())); + } + { + JSHandle sourceString = factory->NewFromUtf8("整数integer"); + JSHandle tmpString = factory->NewFromUtf8("数intege"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EcmaString* res = EcmaStringAccessor::FastSubString(instance, sourceString, 1, 7); + EXPECT_TRUE(res->ToBaseString()->IsUtf16()); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, res->ToBaseString(), tmpString->ToBaseString())); + } + { + JSHandle sourceString = factory->NewFromASCII("integer123"); + JSHandle tmpString = factory->NewFromASCII("integer"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf8()); + EcmaString* res = EcmaStringAccessor::FastSubString(instance, sourceString, 0, 7); + EXPECT_TRUE(res->ToBaseString()->IsUtf8()); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject,res->ToBaseString(), tmpString->ToBaseString())); + } + } + + /* + * @tc.name: WriteData_001 + * @tc.desc: Check whether the target EcmaString made by CreateLineString( , true, ) changed through calling + * WriteData + * function with a source EcmaString made by CreateFromUtf8() is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, WriteData_001) + { + // WriteData(). From EcmaString made by CreateFromUtf8() to EcmaString made by CreateLineString( , true, ). + uint8_t arrayU8WriteFrom[6] = {1, 12, 34, 56, 127}; + uint32_t lengthEcmaStrU8WriteFrom = sizeof(arrayU8WriteFrom) - 1; + JSHandle handleEcmaStrU8WriteFrom(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8WriteFrom[0], lengthEcmaStrU8WriteFrom, + true)); + size_t sizeEcmaStrU8WriteTo = 5; + JSHandle handleEcmaStrAllocTrueWriteTo(thread, + EcmaStringAccessor::CreateLineString( + instance, sizeEcmaStrU8WriteTo, true)); + uint32_t indexStartWriteFromArrayU8 = 2; + uint32_t lengthWriteFromArrayU8 = 2; + handleEcmaStrAllocTrueWriteTo->ToBaseString()->WriteData(Barriers::GetTaggedObject, + handleEcmaStrU8WriteFrom->ToBaseString(), + indexStartWriteFromArrayU8, + sizeEcmaStrU8WriteTo, lengthWriteFromArrayU8); + for (uint32_t i = 0; i < lengthWriteFromArrayU8; i++) { + EXPECT_EQ( + handleEcmaStrAllocTrueWriteTo->ToBaseString()->At(Barriers::GetTaggedObject, i + + indexStartWriteFromArrayU8 + ), handleEcmaStrU8WriteFrom->ToBaseString()->At(Barriers::GetTaggedObject, i)); + } + } + + /* + * @tc.name: WriteData_002 + * @tc.desc: Check whether the target EcmaString made by CreateLineString( , true, ) changed through calling + * WriteData + * function from a source char is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, WriteData_002) + { + // WriteData(). From char to EcmaString made by CreateLineString( , true, ). + char u8Write = 'a'; + size_t sizeEcmaStrU8WriteTo = 5; + JSHandle handleEcmaStrAllocTrueWriteTo(thread, + EcmaStringAccessor::CreateLineString( + instance, sizeEcmaStrU8WriteTo, true)); + uint32_t indexAtWriteFromU8 = 4; + handleEcmaStrAllocTrueWriteTo->ToBaseString()->WriteData(indexAtWriteFromU8, u8Write); + EXPECT_EQ(handleEcmaStrAllocTrueWriteTo->ToBaseString()->At(Barriers::GetTaggedObject, indexAtWriteFromU8), + u8Write); + } + + /* + * @tc.name: WriteData_003 + * @tc.desc: Check whether the target EcmaString made by CreateLineString( , false, ) changed through calling + * WriteData function with a source EcmaString made by CreateFromUtf16( , , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, WriteData_003) + { + /* WriteData(). From EcmaString made by CreateFromUtf16( , , , false) to EcmaStringU16 made by + * CreateLineString( , false, ). + */ + uint16_t arrayU16WriteFrom[10] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; + uint32_t lengthEcmaStrU16WriteFrom = sizeof(arrayU16WriteFrom) / sizeof(arrayU16WriteFrom[0]); + JSHandle handleEcmaStrU16WriteFrom(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16WriteFrom[0], lengthEcmaStrU16WriteFrom, + false)); + size_t sizeEcmaStrU16WriteTo = 10; + JSHandle handleEcmaStrU16WriteTo(thread, + EcmaStringAccessor::CreateLineString( + instance, sizeEcmaStrU16WriteTo, false)); + uint32_t indexStartWriteFromArrayU16 = 3; + uint32_t numBytesWriteFromArrayU16 = 2 * 3; + handleEcmaStrU16WriteTo->ToBaseString()->WriteData(Barriers::GetTaggedObject, + handleEcmaStrU16WriteFrom->ToBaseString(), + indexStartWriteFromArrayU16, sizeEcmaStrU16WriteTo, + numBytesWriteFromArrayU16); + for (uint32_t i = 0; i < (numBytesWriteFromArrayU16 / 2); i++) { + EXPECT_EQ( + handleEcmaStrU16WriteTo->ToBaseString()->At(Barriers::GetTaggedObject, i + indexStartWriteFromArrayU16), + handleEcmaStrU16WriteFrom->ToBaseString()->At(Barriers::GetTaggedObject, i)); + } + } + + /* + * @tc.name: WriteData_004 + * @tc.desc: Check whether the target EcmaString made by CreateLineString( , false, ) changed through calling + * WriteData function with a source EcmaString made by CreateFromUtf8() is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, WriteData_004) + { + // WriteData(). From EcmaString made by CreateFromUtf8() to EcmaString made by CreateLineString( , false, ). + uint8_t arrayU8WriteFrom[6] = {1, 12, 34, 56, 127}; + uint32_t lengthEcmaStrU8WriteFrom = sizeof(arrayU8WriteFrom) - 1; + JSHandle handleEcmaStrU8WriteFrom(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8WriteFrom[0], lengthEcmaStrU8WriteFrom, + true)); + size_t sizeEcmaStrU16WriteTo = 10; + JSHandle handleEcmaStrU16WriteTo(thread, + EcmaStringAccessor::CreateLineString( + instance, sizeEcmaStrU16WriteTo, false)); + uint32_t indexStartWriteFromU8ToU16 = 1; + uint32_t numBytesWriteFromU8ToU16 = 4; + handleEcmaStrU16WriteTo->ToBaseString()->WriteData(Barriers::GetTaggedObject, + handleEcmaStrU8WriteFrom->ToBaseString(), + indexStartWriteFromU8ToU16, sizeEcmaStrU16WriteTo, + numBytesWriteFromU8ToU16); + for (uint32_t i = 0; i < numBytesWriteFromU8ToU16; i++) { + EXPECT_EQ( + handleEcmaStrU16WriteTo->ToBaseString()->At(Barriers::GetTaggedObject, i + indexStartWriteFromU8ToU16), + handleEcmaStrU8WriteFrom->ToBaseString()->At(Barriers::GetTaggedObject, i)); + } + } + + /* + * @tc.name: WriteData_005 + * @tc.desc: Check whether the target EcmaString made by CreateLineString( , false, ) changed through calling + * WriteData function with a source char is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, WriteData_005) + { + // WriteData(). From char to EcmaString made by CreateLineString( , false, ). + size_t sizeEcmaStrU16WriteTo = 10; + JSHandle handleEcmaStrU16WriteTo(thread, + EcmaStringAccessor::CreateLineString( + instance, sizeEcmaStrU16WriteTo, false)); + char u8Write = 'a'; + uint32_t indexAt = 4; + handleEcmaStrU16WriteTo->ToBaseString()->WriteData(indexAt, u8Write); + EXPECT_EQ(handleEcmaStrU16WriteTo->ToBaseString()->At(Barriers::GetTaggedObject, indexAt), u8Write); + } + + /* + * @tc.name: GetUtf8Length + * @tc.desc: Check whether the value returned through calling GetUtf8Length function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetUtf8Length) + { + uint8_t arrayU8[6] = {3, 7, 19, 54, 99}; + uint16_t arrayU16Comp[] = {1, 12, 34, 56, 127}; + uint16_t arrayU16NotComp[] = {19, 54, 256, 11100, 65535}; + uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, + false)); + EXPECT_EQ(handleEcmaStrU8->ToBaseString()->GetUtf8Length(Barriers::GetTaggedObject), lengthEcmaStrU8 + 1); + EXPECT_EQ(handleEcmaStrU16Comp->ToBaseString()->GetUtf8Length(Barriers::GetTaggedObject), + lengthEcmaStrU16Comp + 1); + EXPECT_EQ(handleEcmaStrU16NotComp->ToBaseString()->GetUtf8Length(Barriers::GetTaggedObject), + 2 * lengthEcmaStrU16NotComp + 1); + } + + /* + * @tc.name: GetDataUtf8 + * @tc.desc: Check whether the pointer returned through calling GetDataUtf8 function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetDataUtf8) + { + // From EcmaString made by CreateFromUtf8(). + uint8_t arrayU8[] = {"abcde"}; + uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { + EXPECT_EQ(*(handleEcmaStrU8->ToBaseString()->GetDataUtf8() + i), arrayU8[i]); + } + + // From EcmaString made by CreateFromUtf16( , , , true). + uint16_t arrayU16Comp[] = {3, 1, 34, 123, 127, 111, 42, 3, 20, 10}; + uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + for (uint32_t i = 0; i < sizeof(arrayU16Comp) / arrayU16Comp[0]; i++) { + EXPECT_EQ(*(handleEcmaStrU16Comp->ToBaseString()->GetDataUtf8() + i), arrayU16Comp[i]); + } + } + + /* + * @tc.name: GetDataUtf16 + * @tc.desc: Check whether the pointer returned through calling GetDataUtf16 function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetDataUtf16) + { + // From EcmaString made by CreateFromUtf16( , , , false). + uint16_t arrayU16NotComp[] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; + uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, + false)); + for (uint32_t i = 0; i < lengthEcmaStrU16NotComp; i++) { + EXPECT_EQ(*(handleEcmaStrU16NotComp->ToBaseString()->GetDataUtf16() + i), arrayU16NotComp[i]); + } + } + + /* + * @tc.name: CopyDataRegionUtf8 + * @tc.desc: Check whether the returned value and the changed array through a source EcmaString's calling + * CopyDataRegionUtf8 function are within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CopyDataRegionUtf8) + { + // CopyDataRegionUtf8(). From EcmaString made by CreateFromUtf8(). + uint8_t arrayU8CopyFrom[6] = {1, 12, 34, 56, 127}; + uint32_t lengthEcmaStrU8CopyFrom = sizeof(arrayU8CopyFrom) - 1; + JSHandle handleEcmaStrU8CopyFrom(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8CopyFrom[0], lengthEcmaStrU8CopyFrom, true)); + const size_t lengthArrayU8Target = 7; + uint8_t defaultByteForU8CopyTo = 1; + uint8_t arrayU8CopyTo[lengthArrayU8Target]; + int checkResUtf8 = memset_s(&arrayU8CopyTo[0], lengthArrayU8Target, defaultByteForU8CopyTo, + lengthArrayU8Target); + EXPECT_TRUE(checkResUtf8 == 0); + + size_t indexStartFromArrayU8 = 2; + size_t lengthCopyToEcmaStrU8 = 3; + size_t lengthReturnU8 = handleEcmaStrU8CopyFrom->ToBaseString()->CopyDataRegionUtf8( + Barriers::GetTaggedObject, arrayU8CopyTo, indexStartFromArrayU8, + lengthCopyToEcmaStrU8, lengthArrayU8Target); + + EXPECT_EQ(lengthReturnU8, lengthCopyToEcmaStrU8); + for (uint32_t i = 0; i < lengthCopyToEcmaStrU8; i++) { + EXPECT_EQ(arrayU8CopyTo[i], + handleEcmaStrU8CopyFrom->ToBaseString()->At(Barriers::GetTaggedObject, i + indexStartFromArrayU8)); + } + for (uint32_t i = lengthCopyToEcmaStrU8; i < lengthArrayU8Target; i++) { + EXPECT_EQ(arrayU8CopyTo[i], defaultByteForU8CopyTo); + } + + // CopyDataRegionUtf8(). From EcmaString made by CreateFromUtf16( , , , true). + uint16_t arrayU16CompCopyFrom[] = {1, 12, 34, 56, 127}; + uint32_t lengthEcmaStrU16CompCopyFrom = sizeof(arrayU16CompCopyFrom) / sizeof(arrayU16CompCopyFrom[0]); + JSHandle handleEcmaStrU16CompCopyFrom(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompCopyFrom[0], + lengthEcmaStrU16CompCopyFrom, true)); + const size_t lengthArrayU16Target = 8; + uint8_t defaultByteForU16CompCopyTo = 1; + uint8_t arrayU16CompCopyTo[lengthArrayU16Target]; + int checkResUtf16 = memset_s(&arrayU16CompCopyTo[0], lengthArrayU16Target, defaultByteForU16CompCopyTo, + lengthArrayU16Target); + EXPECT_TRUE(checkResUtf16 == 0); + + size_t indexStartFromArrayU16Comp = 2; + size_t lengthCopyToEcmaStrU16Comp = 3; + size_t lengthReturnU16Comp = handleEcmaStrU16CompCopyFrom->ToBaseString()->CopyDataRegionUtf8( + Barriers::GetTaggedObject, &arrayU16CompCopyTo[0], + indexStartFromArrayU16Comp, lengthCopyToEcmaStrU16Comp, lengthArrayU16Target); + + EXPECT_EQ(lengthReturnU16Comp, lengthCopyToEcmaStrU16Comp); + for (uint32_t i = 0; i < lengthReturnU16Comp; i++) { + EXPECT_EQ(arrayU16CompCopyTo[i], + handleEcmaStrU16CompCopyFrom->ToBaseString()->At(Barriers::GetTaggedObject, i + + indexStartFromArrayU16Comp)); + } + for (uint32_t i = lengthReturnU16Comp; i < lengthArrayU16Target; i++) { + EXPECT_EQ(arrayU16CompCopyTo[i], defaultByteForU16CompCopyTo); + } + } + + /* + * @tc.name: CopyDataUtf16 + * @tc.desc: Check whether the returned value and the changed array through a source EcmaString's calling + * CopyDataUtf16 function are within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, CopyDataUtf16) + { + // CopyDataUtf16(). From EcmaString made by CreateFromUtf16( , , , false). + uint16_t arrayU16NotCompCopyFrom[10] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; + uint32_t lengthEcmaStrU16NotCompCopyFrom = sizeof(arrayU16NotCompCopyFrom) / sizeof(arrayU16NotCompCopyFrom[0]); + JSHandle handleEcmaStrU16NotCompCopyFrom(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompCopyFrom[0], + lengthEcmaStrU16NotCompCopyFrom, false)); + const size_t lengthArrayU16Target = 13; + uint16_t arrayU16NotCompCopyTo[lengthArrayU16Target]; + uint8_t defaultOneByteValueOfArrayU16NotCompCopyTo = 244; + int checkResUtf16 = memset_s(&arrayU16NotCompCopyTo[0], sizeof(uint16_t) * lengthArrayU16Target, + defaultOneByteValueOfArrayU16NotCompCopyTo, + sizeof(uint16_t) * lengthArrayU16Target); + EXPECT_TRUE(checkResUtf16 == 0); + + size_t lengthReturnU16NotComp = handleEcmaStrU16NotCompCopyFrom->ToBaseString()->CopyDataUtf16( + Barriers::GetTaggedObject, &arrayU16NotCompCopyTo[0], + lengthArrayU16Target); + + EXPECT_EQ(lengthReturnU16NotComp, lengthEcmaStrU16NotCompCopyFrom); + for (uint32_t i = 0; i < lengthReturnU16NotComp; i++) { + EXPECT_EQ(arrayU16NotCompCopyTo[i], + handleEcmaStrU16NotCompCopyFrom->ToBaseString()->At(Barriers::GetTaggedObject, i)); + } + for (uint32_t i = lengthReturnU16NotComp; i < lengthArrayU16Target; i++) { + EXPECT_EQ(arrayU16NotCompCopyTo[i], + ((uint16_t)defaultOneByteValueOfArrayU16NotCompCopyTo) * (1 + (1 << 8))); + } + } + + /* + * @tc.name: StringsAreEqual_001 + * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with two EcmaStrings made by + * CreateFromUtf8() is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqual_001) + { + // StringsAreEqual(). + uint8_t arrayU8No1[4] = {45, 92, 78}; + uint8_t arrayU8No2[4] = {45, 92, 78}; + uint8_t arrayU8No3[5] = {45, 92, 78, 1}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; + uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU8No2(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); + JSHandle handleEcmaStrU8No3(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), + handleEcmaStrU8No2->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), + handleEcmaStrU8No3->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU8No3->ToBaseString(), + handleEcmaStrU8No1->ToBaseString())); + } + + /* + * @tc.name: StringsAreEqual_002 + * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with a EcmaString made by + * CreateFromUtf8() and a EcmaString made by CreateFromUtf16(, , , true) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqual_002) + { + // StringsAreEqual(). + uint8_t arrayU8No1[4] = {45, 92, 78}; + uint16_t arrayU16CompNo2[] = {45, 92, 78}; + uint16_t arrayU16CompNo3[] = {45, 92, 78, 1}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16CompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), + handleEcmaStrU16CompNo2->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), + handleEcmaStrU16CompNo3->ToBaseString())); + } + + /* + * @tc.name: StringsAreEqual_003 + * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with two EcmaStrings made by + * CreateFromUtf16(, , , true) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqual_003) + { + // StringsAreEqual(). + uint16_t arrayU16CompNo1[] = {45, 92, 78}; + uint16_t arrayU16CompNo2[] = {45, 92, 78}; + uint16_t arrayU16CompNo3[] = {45, 92, 78, 1}; + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16CompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16CompNo1->ToBaseString(), + handleEcmaStrU16CompNo2->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16CompNo1->ToBaseString(), + handleEcmaStrU16CompNo3->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16CompNo3->ToBaseString(), + handleEcmaStrU16CompNo1->ToBaseString())); + } + + /* + * @tc.name: StringsAreEqual_004 + * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with a EcmaString made by + * CreateFromUtf8() and a EcmaString made by CreateFromUtf16(, , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqual_004) + { + // StringsAreEqual(). + uint8_t arrayU8No1[4] = {45, 92, 78}; + uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, true)); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), + handleEcmaStrU16NotCompNo1->ToBaseString())); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo1->ToBaseString(), + handleEcmaStrU8No1->ToBaseString())); + } + + /* + * @tc.name: StringsAreEqual_005 + * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with a EcmaString made by + * CreateFromUtf16(, , , true) and a EcmaString made by CreateFromUtf16(, , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqual_005) + { + // StringsAreEqual(). + uint16_t arrayU16CompNo1[] = {45, 92, 78}; + uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, true)); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16CompNo1->ToBaseString(), + handleEcmaStrU16NotCompNo1->ToBaseString())); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo1->ToBaseString(), + handleEcmaStrU16CompNo1->ToBaseString())); + } + + /* + * @tc.name: StringsAreEqual_006 + * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with two EcmaStrings made by + * CreateFromUtf16(, , , false) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqual_006) + { + // StringsAreEqual(). + uint16_t arrayU16NotCompNo1[] = {234, 345, 127, 2345, 65535, 5}; + uint16_t arrayU16NotCompNo2[] = {234, 345, 127, 2345, 65535, 5}; + uint16_t arrayU16NotCompNo3[] = {1, 234, 345, 127, 2345, 65535, 5}; + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); + uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, false)); + JSHandle handleEcmaStrU16NotCompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo2[0], + lengthEcmaStrU16NotCompNo2, false)); + JSHandle handleEcmaStrU16NotCompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo3[0], + lengthEcmaStrU16NotCompNo3, false)); + EXPECT_TRUE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo1->ToBaseString(), + handleEcmaStrU16NotCompNo2->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo1->ToBaseString(), + handleEcmaStrU16NotCompNo3->ToBaseString())); + EXPECT_FALSE( + BaseString::StringsAreEqual(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo3->ToBaseString(), + handleEcmaStrU16NotCompNo1->ToBaseString())); + } + + /* + * @tc.name: StringsAreEqualUtf8_001 + * @tc.desc: Check whether the bool returned through calling StringIsEqualUint8Data function with an EcmaString made + * by CreateFromUtf8() and an Array(uint8_t) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqualUtf8_001) + { + // StringIsEqualUint8Data(). EcmaString made by CreateFromUtf8(), Array:U8. + uint8_t arrayU8No1[4] = {45, 92, 78}; + uint8_t arrayU8No2[5] = {45, 92, 78, 24}; + uint8_t arrayU8No3[3] = {45, 92}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; + uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU8No2(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); + JSHandle handleEcmaStrU8No3(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); + EXPECT_TRUE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), & + arrayU8No1[0], lengthEcmaStrU8No1, true)); + EXPECT_FALSE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), &arrayU8No1 + [0], lengthEcmaStrU8No1, false)); + EXPECT_FALSE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU8No2->ToBaseString(), &arrayU8No1 + [0], lengthEcmaStrU8No1, true)); + EXPECT_FALSE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU8No3->ToBaseString(), &arrayU8No1 + [0], lengthEcmaStrU8No1, true)); + } + + /* + * @tc.name: StringsAreEqualUtf8_002 + * @tc.desc: Check whether the bool returned through calling StringIsEqualUint8Data function with an EcmaString made + * by CreateFromUtf16( , , , true) and an Array(uint8_t) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqualUtf8_002) + { + // StringIsEqualUint8Data(). EcmaString made by CreateFromUtf16( , , , true), Array:U8. + uint8_t arrayU8No1[4] = {45, 92, 78}; + uint16_t arrayU16CompNo1[] = {45, 92, 78}; + uint16_t arrayU16CompNo2[] = {45, 92, 78, 24}; + uint16_t arrayU16CompNo3[] = {45, 92}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16CompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); + EXPECT_TRUE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU16CompNo1->ToBaseString(), + &arrayU8No1[0], lengthEcmaStrU8No1, true)); + EXPECT_FALSE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU16CompNo1->ToBaseString(), + &arrayU8No1[0], lengthEcmaStrU8No1, false)); + EXPECT_FALSE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU16CompNo2->ToBaseString(), + &arrayU8No1[0], lengthEcmaStrU8No1, true)); + EXPECT_FALSE( + BaseString::StringIsEqualUint8Data(Barriers::GetTaggedObject, handleEcmaStrU16CompNo3->ToBaseString(), + &arrayU8No1[0], lengthEcmaStrU8No1, true)); + } + + /* + * @tc.name: StringsAreEqualUtf8_003 + * @tc.desc: Check whether the bool returned through calling StringIsEqualUint8Data function with an EcmaString made + * by CreateFromUtf16( , , , false) and an Array(uint8_t) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqualUtf8_003) + { + // StringIsEqualUint8Data(). EcmaString made by CreateFromUtf16( , , , false), Array:U8. + EcmaTestCommon::StringIsEqualCommonCase(thread, instance, EcmaStringAccessor::StringIsEqualUint8Data); + } + + /* + * @tc.name: StringsAreEqualUtf16_001 + * @tc.desc: Check whether the bool returned through calling StringsAreEqualUtf16 function with an EcmaString made + * by CreateFromUtf8() and an Array(uint16_t) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqualUtf16_001) + { + // StringsAreEqualUtf16(). EcmaString made by CreateFromUtf8, Array:U16(1-127). + uint8_t arrayU8No1[4] = {45, 92, 78}; + uint8_t arrayU8No2[5] = {45, 92, 78, 24}; + uint8_t arrayU8No3[3] = {45, 92}; + uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; + uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; + uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; + uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + JSHandle handleEcmaStrU8No1(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); + JSHandle handleEcmaStrU8No2(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); + JSHandle handleEcmaStrU8No3(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); + EXPECT_TRUE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU8No1->ToBaseString(), & + arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU8No2->ToBaseString(), & + arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU8No3->ToBaseString(), & + arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1)); + } + + /* + * @tc.name: StringsAreEqualUtf16_002 + * @tc.desc: Check whether the bool returned through calling StringsAreEqualUtf16 function with an EcmaString made + * by CreateFromUtf16( , , , true) and an Array(uint16_t) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqualUtf16_002) + { + // StringsAreEqualUtf16(). EcmaString made by CreateFromUtf16( , , , true), Array:U16(1-127). + uint16_t arrayU16CompNo1[] = {45, 92, 78}; + uint16_t arrayU16CompNo2[] = {45, 92, 78, 24}; + uint16_t arrayU16CompNo3[] = {45, 92}; + uint16_t arrayU16CompNo4[] = {25645, 25692, 25678}; // 25645 % 256 == 45... + uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); + uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); + uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); + uint32_t lengthEcmaStrU16CompNo4 = sizeof(arrayU16CompNo4) / sizeof(arrayU16CompNo4[0]); + JSHandle handleEcmaStrU16CompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); + JSHandle handleEcmaStrU16CompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); + JSHandle handleEcmaStrU16CompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); + JSHandle handleEcmaStrU16CompNo4(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16CompNo4[0], lengthEcmaStrU16CompNo4, true)); + EXPECT_TRUE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16CompNo1->ToBaseString(), & + arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16CompNo2->ToBaseString(), & + arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16CompNo3->ToBaseString(), & + arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); + EXPECT_TRUE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16CompNo4->ToBaseString(), & + arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); + } + + /* + * @tc.name: StringsAreEqualUtf16_003 + * @tc.desc: Check whether the bool returned through calling StringsAreEqualUtf16 function with an EcmaString made + * by CreateFromUtf16( , , , false) and an Array(uint16_t) is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, StringsAreEqualUtf16_003) + { + uint16_t arrayU16NotCompNo1[] = {25645, 25692, 25678}; + uint16_t arrayU16NotCompNo2[] = {25645, 25692, 78}; // 25645 % 256 == 45... + uint16_t arrayU16NotCompNo3[] = {25645, 25692, 25678, 65535}; + uint16_t arrayU16NotCompNo4[] = {25645, 25692}; + uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); + uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); + uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); + uint32_t lengthEcmaStrU16NotCompNo4 = sizeof(arrayU16NotCompNo4) / sizeof(arrayU16NotCompNo4[0]); + JSHandle handleEcmaStrU16NotCompNo1(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1, false)); + JSHandle handleEcmaStrU16NotCompNo2(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo2[0], + lengthEcmaStrU16NotCompNo2, false)); + JSHandle handleEcmaStrU16NotCompNo3(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo3[0], + lengthEcmaStrU16NotCompNo3, false)); + JSHandle handleEcmaStrU16NotCompNo4(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotCompNo4[0], + lengthEcmaStrU16NotCompNo4, false)); + EXPECT_TRUE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo1->ToBaseString(), & + arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo1->ToBaseString(), & + arrayU16NotCompNo2[0], + lengthEcmaStrU16NotCompNo2)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo2->ToBaseString(), & + arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo3->ToBaseString(), & + arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1)); + EXPECT_FALSE( + BaseString::StringsAreEqualUtf16(Barriers::GetTaggedObject, handleEcmaStrU16NotCompNo4->ToBaseString(), & + arrayU16NotCompNo1[0], + lengthEcmaStrU16NotCompNo1)); + } + + /* + * @tc.name: ComputeHashcodeUtf8 + * @tc.desc: Check whether the value returned through calling ComputeHashcodeUtf8 function with an Array(uint8_t) is + * within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, ComputeHashcodeUtf8) + { + uint8_t arrayU8[] = {"abc"}; + uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + uint32_t hashExpect = 0; + for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { + hashExpect = hashExpect * 31 + arrayU8[i]; + } + EXPECT_EQ(BaseString::ComputeHashcodeUtf8(&arrayU8[0], lengthEcmaStrU8, true), hashExpect); + } + + /* + * @tc.name: ComputeHashcodeUtf16 + * @tc.desc: Check whether the value returned through calling ComputeHashcodeUtf16 function with an Array(uint16_t) + * is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, ComputeHashcodeUtf16) + { + uint16_t arrayU16[] = {199, 1, 256, 65535, 777}; + uint32_t lengthEcmaStrU16 = sizeof(arrayU16) / sizeof(arrayU16[0]); + uint32_t hashExpect = 0; + for (uint32_t i = 0; i < lengthEcmaStrU16; i++) { + hashExpect = hashExpect * 31 + arrayU16[i]; + } + EXPECT_EQ(BaseString::ComputeHashcodeUtf16(&arrayU16[0], lengthEcmaStrU16), hashExpect); + } + + /* + * @tc.name: GetHashcode_001 + * @tc.desc: Check whether the value returned through an EcmaString made by CreateFromUtf8() calling GetHashcode + * function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetHashcode_001) + { + // GetHashcode(). EcmaString made by CreateFromUtf8(). + uint8_t arrayU8[] = {"abc"}; + uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + uint32_t hashExpect = 0; + for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { + hashExpect = hashExpect * 31 + arrayU8[i]; + } + EXPECT_EQ(handleEcmaStrU8->ToBaseString()->GetHashcode(Barriers::GetTaggedObject), hashExpect); + } + + /* + * @tc.name: GetHashcode_002 + * @tc.desc: Check whether the value returned through an EcmaString made by CreateFromUtf16( , , , true) calling + * GetHashcode function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetHashcode_002) + { + // GetHashcode(). EcmaString made by CreateFromUtf16( , , , true). + uint16_t arrayU16Comp[] = {45, 92, 78, 24}; + uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + uint32_t hashExpect = 0; + for (uint32_t i = 0; i < lengthEcmaStrU16Comp; i++) { + hashExpect = hashExpect * 31 + arrayU16Comp[i]; + } + EXPECT_EQ(handleEcmaStrU16Comp->ToBaseString()->GetHashcode(Barriers::GetTaggedObject), hashExpect); + } + + /* + * @tc.name: GetHashcode_003 + * @tc.desc: Check whether the value returned through an EcmaString made by CreateFromUtf16( , , , false) calling + * GetHashcode function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetHashcode_003) + { + // GetHashcode(). EcmaString made by CreateFromUtf16( , , , false). + uint16_t arrayU16NotComp[] = {199, 1, 256, 65535, 777}; + uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, + false)); + uint32_t hashExpect = 0; + for (uint32_t i = 0; i < lengthEcmaStrU16NotComp; i++) { + hashExpect = hashExpect * 31 + arrayU16NotComp[i]; + } + EXPECT_EQ(handleEcmaStrU16NotComp->ToBaseString()->GetHashcode(Barriers::GetTaggedObject), hashExpect); + } + + /* + * @tc.name: GetHashcode_004 + * @tc.desc: Check whether the value returned through an EcmaString made by CreateEmptyString() calling GetHashcode + * function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetHashcode_004) + { + // GetHashcode(). EcmaString made by CreateEmptyString(). + JSHandle handleEcmaStrEmpty(thread, EcmaStringAccessor::CreateEmptyString(instance)); + EXPECT_EQ(handleEcmaStrEmpty->ToBaseString()->GetHashcode(Barriers::GetTaggedObject), 0U); + } + + /* + * @tc.name: GetHashcode_005 + * @tc.desc: Check whether the value returned through an EcmaString made by CreateLineString(, true/false, ) calling + * GetHashcode function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, GetHashcode_005) + { + // GetHashcode(). EcmaString made by CreateLineString(). + size_t sizeAlloc = 5; + JSHandle handleEcmaStrAllocComp( + thread, EcmaStringAccessor::CreateLineString(instance, sizeAlloc, true)); + JSHandle handleEcmaStrAllocNotComp( + thread, EcmaStringAccessor::CreateLineString(instance, sizeAlloc, false)); + EXPECT_EQ(handleEcmaStrAllocComp->ToBaseString()->GetRawHashcode(), 0U); + EXPECT_EQ(handleEcmaStrAllocNotComp->ToBaseString()->GetRawHashcode(), 0U); + } + + /* + * @tc.name: SetIsInternString + * @tc.desc: Call SetIsInternString function, check whether the bool returned through calling IsInternString + * function is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, SetIsInternString) + { + uint8_t arrayU8[] = {"abc"}; + uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; + JSHandle handleEcmaStrU8(thread, + EcmaStringAccessor::CreateFromUtf8( + instance, &arrayU8[0], lengthEcmaStrU8, true)); + EXPECT_FALSE(handleEcmaStrU8->ToBaseString()->IsInternString()); + handleEcmaStrU8->ToBaseString()->SetIsInternString(); + EXPECT_TRUE(handleEcmaStrU8->ToBaseString()->IsInternString()); + + uint16_t arrayU16Comp[] = {97, 98, 99}; + uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); + JSHandle handleEcmaStrU16Comp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); + EXPECT_FALSE(handleEcmaStrU16Comp->ToBaseString()->IsInternString()); + handleEcmaStrU16Comp->ToBaseString()->SetIsInternString(); + EXPECT_TRUE(handleEcmaStrU16Comp->ToBaseString()->IsInternString()); + + uint16_t arrayU16NotComp[] = {97, 98, 99}; + uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); + JSHandle handleEcmaStrU16NotComp(thread, + EcmaStringAccessor::CreateFromUtf16( + instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, true)); + EXPECT_FALSE(handleEcmaStrU16NotComp->ToBaseString()->IsInternString()); + handleEcmaStrU16NotComp->ToBaseString()->SetIsInternString(); + EXPECT_TRUE(handleEcmaStrU16NotComp->ToBaseString()->IsInternString()); + } + + /* + * @tc.name: EqualToSplicedString + * @tc.desc: Tests whether the source string is equal to the concatenated string. + * is within expectations. + * @tc.type: FUNC + * @tc.require: + */ + HWTEST_F_L0(BaseStringTest, EqualToSplicedString) + { + ObjectFactory* factory = instance->GetFactory(); + { + JSHandle sourceString = factory->NewFromUtf8("Start开始"); + JSHandle firstString = factory->NewFromASCII("Start"); + JSHandle secondString = factory->NewFromUtf8("开始"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf16()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Start开始"); + JSHandle firstString = factory->NewFromASCII("Start"); + JSHandle secondString = factory->NewFromASCII("start"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf8()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(!result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Start开始"); + JSHandle firstString = factory->NewFromUtf8("Start开"); + JSHandle secondString = factory->NewFromUtf8("始"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf16()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Startstart"); + JSHandle firstString = factory->NewFromASCII("Start"); + JSHandle secondString = factory->NewFromASCII("start"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf8()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Startstart"); + JSHandle firstString = factory->NewFromASCII("Start"); + JSHandle secondString = factory->NewFromUtf8("开始"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf16()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(!result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Startstat"); + JSHandle firstString = factory->NewFromASCII("Start"); + JSHandle secondString = factory->NewFromASCII("start"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf8()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(!result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Start开始"); + JSHandle firstString = factory->NewFromUtf8("Stat开"); + JSHandle secondString = factory->NewFromUtf8("始"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf16()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(!result); + } + + { + JSHandle sourceString = factory->NewFromUtf8("Start开始"); + JSHandle firstString = factory->NewFromASCII("Stat"); + JSHandle secondString = factory->NewFromUtf8("开始"); + EXPECT_TRUE(sourceString->ToBaseString()->IsUtf16()); + EXPECT_TRUE(firstString->ToBaseString()->IsUtf8()); + EXPECT_TRUE(secondString->ToBaseString()->IsUtf16()); + bool result = sourceString->ToBaseString()->EqualToSplicedString( + Barriers::GetTaggedObject, firstString->ToBaseString(), secondString->ToBaseString()); + EXPECT_TRUE(!result); + } + } + + HWTEST_F_L0(BaseStringTest, ConvertToString001) + { + ObjectFactory* factory = thread->GetEcmaVM()->GetFactory(); + JSHandle testString = factory->NewFromASCII("bar2bazJavaScriptbaz"); + CString str = ConvertToString(*testString, StringConvertedUsage::LOGICOPERATION, false); + EXPECT_EQ(str, CString("bar2bazJavaScriptbaz")); + } + + HWTEST_F_L0(BaseStringTest, ConvertToString002) + { + CString str = ConvertToString(nullptr, StringConvertedUsage::LOGICOPERATION, false); + EXPECT_EQ(str, CString("")); + } + + HWTEST_F_L0(BaseStringTest, ConvertToString003) + { + ObjectFactory* factory = thread->GetEcmaVM()->GetFactory(); + JSHandle testString = factory->NewFromASCII("test"); + CString str = ConvertToString(*testString); + EXPECT_EQ(str, CString("test")); + } +} // namespace panda::test diff --git a/ecmascript/tests/ecma_string_accessor_test.cpp b/ecmascript/tests/ecma_string_accessor_test.cpp index f8316b1804..555f01e310 100644 --- a/ecmascript/tests/ecma_string_accessor_test.cpp +++ b/ecmascript/tests/ecma_string_accessor_test.cpp @@ -32,9 +32,9 @@ class LineEcmaStringTest : public BaseTestWithScope { HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf8) { uint32_t scale = 3333; - for (uint32_t i = EcmaString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) { + for (uint32_t i = BaseString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) { uint32_t length = i; - EXPECT_EQ(LineEcmaString::ComputeSizeUtf8(length), length + LineEcmaString::SIZE); + EXPECT_EQ(LineEcmaString::ComputeSizeUtf8(length), length + LineString::SIZE); } } @@ -47,9 +47,9 @@ HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf8) HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf16) { uint32_t scale = 3333; - for (uint32_t i = EcmaString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) { + for (uint32_t i = BaseString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) { uint32_t length = i; - EXPECT_EQ(LineEcmaString::ComputeSizeUtf16(length), 2 * length + LineEcmaString::SIZE); + EXPECT_EQ(LineEcmaString::ComputeSizeUtf16(length), 2 * length + LineString::SIZE); } } @@ -360,25 +360,25 @@ HWTEST_F_L0(EcmaStringAccessorTest, GetUtf8Length) HWTEST_F_L0(EcmaStringAccessorTest, ObjectSize) { JSHandle handleEcmaStrEmpty(thread, EcmaStringAccessor::CreateEmptyString(instance)); - EXPECT_EQ(EcmaStringAccessor(handleEcmaStrEmpty).ObjectSize(), EcmaString::SIZE + 0); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrEmpty).ObjectSize(), BaseString::SIZE + 0); size_t lengthEcmaStrAllocComp = 5; JSHandle handleEcmaStrAllocComp(thread, EcmaStringAccessor::CreateLineString(instance, lengthEcmaStrAllocComp, true)); EXPECT_EQ(EcmaStringAccessor(handleEcmaStrAllocComp).ObjectSize(), - EcmaString::SIZE + sizeof(uint8_t) * lengthEcmaStrAllocComp); + BaseString::SIZE + sizeof(uint8_t) * lengthEcmaStrAllocComp); size_t lengthEcmaStrAllocNotComp = 5; JSHandle handleEcmaStrAllocNotComp(thread, EcmaStringAccessor::CreateLineString(instance, lengthEcmaStrAllocNotComp, false)); EXPECT_EQ(EcmaStringAccessor(handleEcmaStrAllocNotComp).ObjectSize(), - EcmaString::SIZE + sizeof(uint16_t) * lengthEcmaStrAllocNotComp); + BaseString::SIZE + sizeof(uint16_t) * lengthEcmaStrAllocNotComp); uint8_t arrayU8[] = {"abcde"}; size_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; JSHandle handleEcmaStrU8(thread, EcmaStringAccessor::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU8).ObjectSize(), EcmaString::SIZE + sizeof(uint8_t) * lengthEcmaStrU8); + EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU8).ObjectSize(), BaseString::SIZE + sizeof(uint8_t) * lengthEcmaStrU8); // ObjectSize(). EcmaString made by CreateFromUtf16( , , , true). uint16_t arrayU16Comp[] = {1, 23, 45, 67, 127}; @@ -386,7 +386,7 @@ HWTEST_F_L0(EcmaStringAccessorTest, ObjectSize) JSHandle handleEcmaStrU16Comp(thread, EcmaStringAccessor::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU16Comp).ObjectSize(), - EcmaString::SIZE + sizeof(uint8_t) * lengthEcmaStrU16Comp); + BaseString::SIZE + sizeof(uint8_t) * lengthEcmaStrU16Comp); // ObjectSize(). EcmaString made by CreateFromUtf16( , , , false). uint16_t arrayU16NotComp[] = {127, 128, 256, 11100, 65535}; @@ -394,7 +394,7 @@ HWTEST_F_L0(EcmaStringAccessorTest, ObjectSize) JSHandle handleEcmaStrU16NotComp(thread, EcmaStringAccessor::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); EXPECT_EQ(EcmaStringAccessor(handleEcmaStrU16NotComp).ObjectSize(), - EcmaString::SIZE + sizeof(uint16_t) * lengthEcmaStrU16NotComp); + BaseString::SIZE + sizeof(uint16_t) * lengthEcmaStrU16NotComp); } /* diff --git a/ecmascript/tests/ecma_string_equals_test.cpp b/ecmascript/tests/ecma_string_equals_test.cpp index e05301d239..a8ae4373d1 100644 --- a/ecmascript/tests/ecma_string_equals_test.cpp +++ b/ecmascript/tests/ecma_string_equals_test.cpp @@ -25,7 +25,7 @@ class EcmaStringEqualsTest : public BaseTestWithScope { static bool IsUtf8EqualsUtf16UT(const uint8_t *utf8Data, size_t utf8Len, const uint16_t *utf16Data, uint32_t utf16Len) { - return EcmaString::IsUtf8EqualsUtf16(utf8Data, utf8Len, utf16Data, utf16Len); + return BaseString::IsUtf8EqualsUtf16(utf8Data, utf8Len, utf16Data, utf16Len); } }; diff --git a/ecmascript/tests/ecma_string_hash_test.cpp b/ecmascript/tests/ecma_string_hash_test.cpp index 482c223571..4159406fef 100644 --- a/ecmascript/tests/ecma_string_hash_test.cpp +++ b/ecmascript/tests/ecma_string_hash_test.cpp @@ -16,6 +16,7 @@ #include "ecmascript/tests/test_helper.h" #include "ecmascript/ecma_string.h" +#include "ecmascript/platform/ecma_string_hash.h" using namespace panda::ecmascript; @@ -35,7 +36,7 @@ public: template static uint32_t ComputeHashOpt(const T *data, size_t size, uint32_t hashSeed) { - return EcmaString::ComputeHashForData(data, size, hashSeed); + return BaseString::ComputeHashForData(data, size, hashSeed); } static uint32_t ComputeConcatHash( diff --git a/ecmascript/tests/ecma_string_test.cpp b/ecmascript/tests/ecma_string_test.cpp deleted file mode 100644 index 298ed4cea8..0000000000 --- a/ecmascript/tests/ecma_string_test.cpp +++ /dev/null @@ -1,1788 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ecmascript/ecma_string-inl.h" -#include "ecmascript/object_factory.h" -#include "ecmascript/tests/ecma_test_common.h" - -using namespace panda::ecmascript; - -namespace panda::test { -class EcmaStringTest : public BaseTestWithScope { -public: - static void SetUpTestCase() - { - GTEST_LOG_(INFO) << "SetUpTestCase"; - uint8_t arrayU8[] = {12, 34, 77, 127, 99, 1}; - uint16_t arrayU16Comp[] = {1, 4, 37, 91, 127, 1}; - uint16_t arrayU16NotComp[] = {72, 43, 337, 961, 1317, 65535}; - EXPECT_TRUE(EcmaString::CanBeCompressed(arrayU8, sizeof(arrayU8) / sizeof(arrayU8[0]))); - EXPECT_TRUE(EcmaString::CanBeCompressed(arrayU16Comp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); - EXPECT_FALSE(EcmaString::CanBeCompressed(arrayU16NotComp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); - } -}; - -/* - * @tc.name: CanBeCompressed - * @tc.desc: Check whether the bool returned through calling CanBeCompressed function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CanBeCompressed) -{ - uint8_t arrayU8[] = {12, 34, 77, 127, 99, 1}; - uint16_t arrayU16Comp[] = {1, 4, 37, 91, 127, 1}; - uint16_t arrayU16NotComp[] = {72, 43, 337, 961, 1317, 65535}; - EXPECT_TRUE(EcmaString::CanBeCompressed(arrayU8, sizeof(arrayU8) / sizeof(arrayU8[0]))); - EXPECT_TRUE(EcmaString::CanBeCompressed(arrayU16Comp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); - EXPECT_FALSE(EcmaString::CanBeCompressed(arrayU16NotComp, sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]))); -} - -/* - * @tc.name: CreateEmptyString - * @tc.desc: Check whether the EcmaString created through calling CreateEmptyString function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CreateEmptyString) -{ - JSHandle handleEcmaStrEmpty(thread, EcmaString::CreateEmptyString(instance)); - EXPECT_EQ(handleEcmaStrEmpty->GetLength(), 0U); - EXPECT_TRUE(handleEcmaStrEmpty->IsUtf8()); - EXPECT_FALSE(handleEcmaStrEmpty->IsUtf16()); -} - -/* - * @tc.name: CreateLineString - * @tc.desc: Check whether the EcmaString created through calling CreateLineString function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CreateLineString) -{ - // CreateLineString( , true, ). - size_t sizeAllocComp = 5; - JSHandle handleEcmaStrAllocComp(thread, EcmaString::CreateLineString(instance, sizeAllocComp, true)); - for (uint32_t i = 0; i < sizeAllocComp; i++) { - EXPECT_EQ(handleEcmaStrAllocComp->At(i), 0U); - } - EXPECT_EQ(handleEcmaStrAllocComp->GetLength(), sizeAllocComp); - EXPECT_TRUE(handleEcmaStrAllocComp->IsUtf8()); - EXPECT_FALSE(handleEcmaStrAllocComp->IsUtf16()); - - // CreateLineString( , false, ). - size_t sizeAllocNotComp = 5; - JSHandle handleEcmaStrAllocNotComp(thread, - EcmaString::CreateLineString(instance, sizeAllocNotComp, false)); - for (uint32_t i = 0; i < sizeAllocNotComp; i++) { - EXPECT_EQ(handleEcmaStrAllocNotComp->At(i), 0U); - } - EXPECT_EQ(handleEcmaStrAllocNotComp->GetLength(), sizeAllocNotComp); - EXPECT_FALSE(handleEcmaStrAllocNotComp->IsUtf8()); - EXPECT_TRUE(handleEcmaStrAllocNotComp->IsUtf16()); -} - -/* - * @tc.name: CreateFromUtf8 - * @tc.desc: Check whether the EcmaString created through calling CreateFromUtf8 function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CreateFromUtf8) -{ - uint8_t arrayU8[] = {"xyz123!@#"}; - size_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { - EXPECT_EQ(arrayU8[i], handleEcmaStrU8->At(i)); - } - EXPECT_EQ(handleEcmaStrU8->GetLength(), lengthEcmaStrU8); - EXPECT_TRUE(handleEcmaStrU8->IsUtf8()); - EXPECT_FALSE(handleEcmaStrU8->IsUtf16()); -} - -/* - * @tc.name: CreateFromUtf16 - * @tc.desc: Check whether the EcmaString created through calling CreateFromUtf16 function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CreateFromUtf16) -{ - // CreateFromUtf16( , , , true). - uint16_t arrayU16Comp[] = {1, 23, 45, 67, 127}; - size_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - EXPECT_EQ(handleEcmaStrU16Comp->GetLength(), lengthEcmaStrU16Comp); - EXPECT_TRUE(handleEcmaStrU16Comp->IsUtf8()); - EXPECT_FALSE(handleEcmaStrU16Comp->IsUtf16()); - - // CreateFromUtf16( , , , false). - uint16_t arrayU16NotComp[] = {127, 33, 128, 12, 256, 11100, 65535}; - size_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); - EXPECT_EQ(handleEcmaStrU16NotComp->GetLength(), lengthEcmaStrU16NotComp); - EXPECT_FALSE(handleEcmaStrU16NotComp->IsUtf8()); - EXPECT_TRUE(handleEcmaStrU16NotComp->IsUtf16()); -} - -/* - * @tc.name: ObjectSize - * @tc.desc: Check whether the value returned through calling ObjectSize function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, ObjectSize) -{ - JSHandle handleEcmaStrEmpty(thread, EcmaString::CreateEmptyString(instance)); - EXPECT_EQ(handleEcmaStrEmpty->ObjectSize(), EcmaString::SIZE + 0); - - size_t lengthEcmaStrAllocComp = 5; - JSHandle handleEcmaStrAllocComp(thread, - EcmaString::CreateLineString(instance, lengthEcmaStrAllocComp, true)); - EXPECT_EQ(handleEcmaStrAllocComp->ObjectSize(), EcmaString::SIZE + sizeof(uint8_t) * lengthEcmaStrAllocComp); - - size_t lengthEcmaStrAllocNotComp = 5; - JSHandle handleEcmaStrAllocNotComp(thread, - EcmaString::CreateLineString(instance, lengthEcmaStrAllocNotComp, false)); - EXPECT_EQ(handleEcmaStrAllocNotComp->ObjectSize(), - EcmaString::SIZE + sizeof(uint16_t) * lengthEcmaStrAllocNotComp); - - uint8_t arrayU8[] = {"abcde"}; - size_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - EXPECT_EQ(handleEcmaStrU8->ObjectSize(), EcmaString::SIZE + sizeof(uint8_t) * lengthEcmaStrU8); - - // ObjectSize(). EcmaString made by CreateFromUtf16( , , , true). - uint16_t arrayU16Comp[] = {1, 23, 45, 67, 127}; - size_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - EXPECT_EQ(handleEcmaStrU16Comp->ObjectSize(), EcmaString::SIZE + sizeof(uint8_t) * lengthEcmaStrU16Comp); - - // ObjectSize(). EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotComp[] = {127, 128, 256, 11100, 65535}; - size_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); - EXPECT_EQ(handleEcmaStrU16NotComp->ObjectSize(), EcmaString::SIZE + sizeof(uint16_t) * lengthEcmaStrU16NotComp); -} - -/* - * @tc.name: Compare_001 - * @tc.desc: Check whether the value returned through calling Compare function between EcmaStrings made by - * CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Compare_001) -{ - // Compare(). Between EcmaStrings made by CreateFromUtf8(). - uint8_t arrayU8No1[3] = {1, 23}; - uint8_t arrayU8No2[4] = {1, 23, 49}; - uint8_t arrayU8No3[6] = {1, 23, 45, 97, 127}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; - uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU8No2(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); - JSHandle handleEcmaStrU8No3(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No1, *handleEcmaStrU8No2), -1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No2, *handleEcmaStrU8No1), 1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No2, *handleEcmaStrU8No3), 49 - 45); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No3, *handleEcmaStrU8No2), 45 - 49); -} - -/* - * @tc.name: Compare_002 - * @tc.desc: Check whether the value returned through calling Compare function between EcmaStrings made by - * CreateFromUtf16( , , , true) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Compare_002) -{ - // Compare(). Between EcmaStrings made by CreateFromUtf16( , , , true). - uint16_t arrayU16CompNo1[] = {1, 23}; - uint16_t arrayU16CompNo2[] = {1, 23, 49}; - uint16_t arrayU16CompNo3[] = {1, 23, 45, 97, 127}; - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16CompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo1, *handleEcmaStrU16CompNo2), -1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo2, *handleEcmaStrU16CompNo1), 1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo2, *handleEcmaStrU16CompNo3), 49 - 45); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo3, *handleEcmaStrU16CompNo2), 45 - 49); -} - -/* - * @tc.name: Compare_003 - * @tc.desc: Check whether the value returned through calling Compare function between EcmaString made by - * CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , true) made by CreateFromUtf16( , , , true) is within - * expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Compare_003) -{ - // Compare(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , true). - uint8_t arrayU8No1[3] = {1, 23}; - uint8_t arrayU8No2[4] = {1, 23, 49}; - uint16_t arrayU16CompNo1[] = {1, 23}; - uint16_t arrayU16CompNo2[] = {1, 23, 49}; - uint16_t arrayU16CompNo3[] = {1, 23, 45, 97, 127}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU8No2(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16CompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No1, *handleEcmaStrU16CompNo1), 0); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo1, *handleEcmaStrU8No1), 0); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No1, *handleEcmaStrU16CompNo2), -1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo2, *handleEcmaStrU8No1), 1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No2, *handleEcmaStrU16CompNo3), 49 - 45); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo3, *handleEcmaStrU8No2), 45 - 49); -} - -/* - * @tc.name: Compare_004 - * @tc.desc: Check whether the value returned through calling Compare function between EcmaStrings made by - * CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Compare_004) -{ - // Compare(). Between EcmaStrings made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotCompNo1[] = {1, 23}; - uint16_t arrayU16NotCompNo2[] = {1, 23, 49}; - uint16_t arrayU16NotCompNo3[] = {1, 23, 456, 6789, 65535, 127}; - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); - uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, true)); - JSHandle handleEcmaStrU16NotCompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo2[0], lengthEcmaStrU16NotCompNo2, true)); - JSHandle handleEcmaStrU16NotCompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo3[0], lengthEcmaStrU16NotCompNo3, false)); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU16NotCompNo2), -1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo2, *handleEcmaStrU16NotCompNo1), 1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo2, *handleEcmaStrU16NotCompNo3), 49 - 456); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo3, *handleEcmaStrU16NotCompNo2), 456 - 49); -} - -/* - * @tc.name: Compare_005 - * @tc.desc: Check whether the value returned through calling Compare function between EcmaString made by - * CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Compare_005) -{ - // Compare(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false). - uint8_t arrayU8No1[3] = {1, 23}; - uint8_t arrayU8No2[4] = {1, 23, 49}; - uint16_t arrayU16NotCompNo1[] = {1, 23}; - uint16_t arrayU16NotCompNo2[] = {1, 23, 49}; - uint16_t arrayU16NotCompNo3[] = {1, 23, 456, 6789, 65535, 127}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); - uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU8No2(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, true)); - JSHandle handleEcmaStrU16NotCompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo2[0], lengthEcmaStrU16NotCompNo2, true)); - JSHandle handleEcmaStrU16NotCompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo3[0], lengthEcmaStrU16NotCompNo3, false)); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No1, *handleEcmaStrU16NotCompNo1), 0); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU8No1), 0); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No1, *handleEcmaStrU16NotCompNo2), -1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo2, *handleEcmaStrU8No1), 1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU8No2, *handleEcmaStrU16NotCompNo3), 49 - 456); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo3, *handleEcmaStrU8No2), 456 - 49); -} - -/* - * @tc.name: Compare_006 - * @tc.desc: Check whether the value returned through calling Compare function between EcmaString made by - * CreateFromUtf16( , , , true) and EcmaString made by CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Compare_006) -{ - // Compare(). EcmaString made by CreateFromUtf16( , , , true) and EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16CompNo1[] = {1, 23}; - uint16_t arrayU16CompNo2[] = {1, 23, 49}; - uint16_t arrayU16NotCompNo1[] = {1, 23}; - uint16_t arrayU16NotCompNo2[] = {1, 23, 49}; - uint16_t arrayU16NotCompNo3[] = {1, 23, 456, 6789, 65535, 127}; - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); - uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, true)); - JSHandle handleEcmaStrU16NotCompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo2[0], lengthEcmaStrU16NotCompNo2, true)); - JSHandle handleEcmaStrU16NotCompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo3[0], lengthEcmaStrU16NotCompNo3, false)); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo1, *handleEcmaStrU16NotCompNo1), 0); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU16CompNo1), 0); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo1, *handleEcmaStrU16NotCompNo2), -1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo2, *handleEcmaStrU16CompNo1), 1); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16CompNo2, *handleEcmaStrU16NotCompNo3), 49 - 456); - EXPECT_EQ(EcmaString::Compare(*handleEcmaStrU16NotCompNo3, *handleEcmaStrU16CompNo2), 456 - 49); -} - -/* - * @tc.name: Concat_001 - * @tc.desc: Check whether the EcmaString returned through calling Concat function between EcmaString made by - * CreateFromUtf8() and EcmaString made by CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Concat_001) -{ - // Concat(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf8(). - uint8_t arrayFrontU8[] = {"abcdef"}; - uint8_t arrayBackU8[] = {"ABCDEF"}; - uint32_t lengthEcmaStrFrontU8 = sizeof(arrayFrontU8) - 1; - uint32_t lengthEcmaStrBackU8 = sizeof(arrayBackU8) - 1; - JSHandle handleEcmaStrFrontU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayFrontU8[0], lengthEcmaStrFrontU8, true)); - JSHandle handleEcmaStrBackU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayBackU8[0], lengthEcmaStrBackU8, true)); - JSHandle handleEcmaStrConcatU8(thread, - EcmaString::Concat(instance, handleEcmaStrFrontU8, handleEcmaStrBackU8)); - EXPECT_TRUE(handleEcmaStrConcatU8->IsUtf8()); - for (uint32_t i = 0; i < lengthEcmaStrFrontU8; i++) { - EXPECT_EQ(handleEcmaStrConcatU8->At(i), arrayFrontU8[i]); - } - for (uint32_t i = 0; i < lengthEcmaStrBackU8; i++) { - EXPECT_EQ(handleEcmaStrConcatU8->At(i + lengthEcmaStrFrontU8), arrayBackU8[i]); - } - EXPECT_EQ(handleEcmaStrConcatU8->GetLength(), lengthEcmaStrFrontU8 + lengthEcmaStrBackU8); -} - -/* - * @tc.name: Concat_002 - * @tc.desc: Check whether the EcmaString returned through calling Concat function between EcmaString made by - * CreateFromUtf16( , , , false) and EcmaString made by CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Concat_002) -{ - // Concat(). EcmaString made by CreateFromUtf16( , , , false) and EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayFrontU16NotComp[] = {128, 129, 256, 11100, 65535, 100}; - uint16_t arrayBackU16NotComp[] = {88, 768, 1, 270, 345, 333}; - uint32_t lengthEcmaStrFrontU16NotComp = sizeof(arrayFrontU16NotComp) / sizeof(arrayFrontU16NotComp[0]); - uint32_t lengthEcmaStrBackU16NotComp = sizeof(arrayBackU16NotComp) / sizeof(arrayBackU16NotComp[0]); - JSHandle handleEcmaStrFrontU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayFrontU16NotComp[0], lengthEcmaStrFrontU16NotComp, false)); - JSHandle handleEcmaStrBackU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayBackU16NotComp[0], lengthEcmaStrBackU16NotComp, false)); - JSHandle handleEcmaStrConcatU16NotComp(thread, - EcmaString::Concat(instance, handleEcmaStrFrontU16NotComp, handleEcmaStrBackU16NotComp)); - EXPECT_TRUE(handleEcmaStrConcatU16NotComp->IsUtf16()); - for (uint32_t i = 0; i < lengthEcmaStrFrontU16NotComp; i++) { - EXPECT_EQ(handleEcmaStrConcatU16NotComp->At(i), arrayFrontU16NotComp[i]); - } - for (uint32_t i = 0; i < lengthEcmaStrBackU16NotComp; i++) { - EXPECT_EQ(handleEcmaStrConcatU16NotComp->At(i + lengthEcmaStrFrontU16NotComp), arrayBackU16NotComp[i]); - } - EXPECT_EQ(handleEcmaStrConcatU16NotComp->GetLength(), lengthEcmaStrFrontU16NotComp + lengthEcmaStrBackU16NotComp); -} - -/* - * @tc.name: Concat_003 - * @tc.desc: Check whether the EcmaString returned through calling Concat function between EcmaString made by - * CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, Concat_003) -{ - // Concat(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , false). - uint8_t arrayFrontU8[] = {"abcdef"}; - uint16_t arrayBackU16NotComp[] = {88, 768, 1, 270, 345, 333}; - uint32_t lengthEcmaStrFrontU8 = sizeof(arrayFrontU8) - 1; - uint32_t lengthEcmaStrBackU16NotComp = sizeof(arrayBackU16NotComp) / sizeof(arrayBackU16NotComp[0]); - JSHandle handleEcmaStrFrontU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayFrontU8[0], lengthEcmaStrFrontU8, true)); - JSHandle handleEcmaStrBackU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayBackU16NotComp[0], lengthEcmaStrBackU16NotComp, false)); - JSHandle handleEcmaStrConcatU8U16NotComp(thread, - EcmaString::Concat(instance, handleEcmaStrFrontU8, handleEcmaStrBackU16NotComp)); - EXPECT_TRUE(handleEcmaStrConcatU8U16NotComp->IsUtf16()); - for (uint32_t i = 0; i < lengthEcmaStrFrontU8; i++) { - EXPECT_EQ(handleEcmaStrConcatU8U16NotComp->At(i), arrayFrontU8[i]); - } - for (uint32_t i = 0; i < lengthEcmaStrBackU16NotComp; i++) { - EXPECT_EQ(handleEcmaStrConcatU8U16NotComp->At(i + lengthEcmaStrFrontU8), arrayBackU16NotComp[i]); - } - EXPECT_EQ(handleEcmaStrConcatU8U16NotComp->GetLength(), lengthEcmaStrFrontU8 + lengthEcmaStrBackU16NotComp); -} - -/* - * @tc.name: FastSubString_001 - * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString made by - * CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, FastSubString_001) -{ - // FastSubString(). From EcmaString made by CreateFromUtf8(). - uint8_t arrayU8[6] = {3, 7, 19, 54, 99}; - uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - uint32_t indexStartSubU8 = 2; - uint32_t lengthSubU8 = 2; - JSHandle handleEcmaStrSubU8(thread, - EcmaString::FastSubString(instance, handleEcmaStrU8, indexStartSubU8, lengthSubU8)); - for (uint32_t i = 0; i < lengthSubU8; i++) { - EXPECT_EQ(handleEcmaStrSubU8->At(i), handleEcmaStrU8->At(i + indexStartSubU8)); - } - EXPECT_EQ(handleEcmaStrSubU8->GetLength(), lengthSubU8); -} - -/* - * @tc.name: FastSubString_002 - * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString made by - * CreateFromUtf16( , , , true) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, FastSubString_002) -{ - // FastSubString(). From EcmaString made by CreateFromUtf16( , , , true). - uint16_t arrayU16Comp[] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - uint32_t indexStartSubU16Comp = 0; - uint32_t lengthSubU16Comp = 2; - JSHandle handleEcmaStrSubU16Comp(thread, - EcmaString::FastSubString(instance, handleEcmaStrU16Comp, indexStartSubU16Comp, lengthSubU16Comp)); - for (uint32_t i = 0; i < lengthSubU16Comp; i++) { - EXPECT_EQ(handleEcmaStrSubU16Comp->At(i), handleEcmaStrU16Comp->At(i + indexStartSubU16Comp)); - } - EXPECT_EQ(handleEcmaStrSubU16Comp->GetLength(), lengthSubU16Comp); -} - -/* - * @tc.name: FastSubString_003 - * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString made by - * CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, FastSubString_003) -{ - // FastSubString(). From EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotComp[] = {19, 54, 256, 11100, 65535}; - uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); - uint32_t indexStartSubU16NotComp = 0; - uint32_t lengthSubU16NotComp = 2; - JSHandle handleEcmaStrSubU16NotComp(thread, - EcmaString::FastSubString(instance, handleEcmaStrU16NotComp, indexStartSubU16NotComp, lengthSubU16NotComp)); - for (uint32_t i = 0; i < lengthSubU16NotComp; i++) { - EXPECT_EQ(handleEcmaStrSubU16NotComp->At(i), handleEcmaStrU16NotComp->At(i + indexStartSubU16NotComp)); - } - EXPECT_EQ(handleEcmaStrSubU16NotComp->GetLength(), lengthSubU16NotComp); -} - -/* - * @tc.name: FastSubString_004 - * @tc.desc: Check whether the EcmaString returned through calling FastSubString function from EcmaString - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, FastSubString_004) -{ - ObjectFactory* factory = instance->GetFactory(); - { - JSHandle sourceString = factory->NewFromUtf8("整数integer"); - JSHandle tmpString = factory->NewFromASCII("integer"); - EXPECT_TRUE(sourceString->IsUtf16()); - EcmaString *res = EcmaString::FastSubString(instance, sourceString, 2, 7); - EXPECT_TRUE(res->IsUtf8()); - EXPECT_TRUE(EcmaString::StringsAreEqual(res, *tmpString)); - } - { - JSHandle sourceString = factory->NewFromUtf8("整数integer"); - JSHandle tmpString = factory->NewFromUtf8("整数"); - EXPECT_TRUE(sourceString->IsUtf16()); - EcmaString *res = EcmaString::FastSubString(instance, sourceString, 0, 2); - EXPECT_TRUE(res->IsUtf16()); - EXPECT_TRUE(EcmaString::StringsAreEqual(res, *tmpString)); - } - { - JSHandle sourceString = factory->NewFromUtf8("整数integer"); - JSHandle tmpString = factory->NewFromUtf8("数intege"); - EXPECT_TRUE(sourceString->IsUtf16()); - EcmaString *res = EcmaString::FastSubString(instance, sourceString, 1, 7); - EXPECT_TRUE(res->IsUtf16()); - EXPECT_TRUE(EcmaString::StringsAreEqual(res, *tmpString)); - } - { - JSHandle sourceString = factory->NewFromASCII("integer123"); - JSHandle tmpString = factory->NewFromASCII("integer"); - EXPECT_TRUE(sourceString->IsUtf8()); - EcmaString *res = EcmaString::FastSubString(instance, sourceString, 0, 7); - EXPECT_TRUE(res->IsUtf8()); - EXPECT_TRUE(EcmaString::StringsAreEqual(res, *tmpString)); - } -} - -/* - * @tc.name: WriteData_001 - * @tc.desc: Check whether the target EcmaString made by CreateLineString( , true, ) changed through calling WriteData - * function with a source EcmaString made by CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, WriteData_001) -{ - // WriteData(). From EcmaString made by CreateFromUtf8() to EcmaString made by CreateLineString( , true, ). - uint8_t arrayU8WriteFrom[6] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU8WriteFrom = sizeof(arrayU8WriteFrom) - 1; - JSHandle handleEcmaStrU8WriteFrom(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8WriteFrom[0], lengthEcmaStrU8WriteFrom, true)); - size_t sizeEcmaStrU8WriteTo = 5; - JSHandle handleEcmaStrAllocTrueWriteTo(thread, - EcmaString::CreateLineString(instance, sizeEcmaStrU8WriteTo, true)); - uint32_t indexStartWriteFromArrayU8 = 2; - uint32_t lengthWriteFromArrayU8 = 2; - handleEcmaStrAllocTrueWriteTo->WriteData(*handleEcmaStrU8WriteFrom, indexStartWriteFromArrayU8, - sizeEcmaStrU8WriteTo, lengthWriteFromArrayU8); - for (uint32_t i = 0; i < lengthWriteFromArrayU8; i++) { - EXPECT_EQ(handleEcmaStrAllocTrueWriteTo->At(i + indexStartWriteFromArrayU8), handleEcmaStrU8WriteFrom->At(i)); - } -} - -/* - * @tc.name: WriteData_002 - * @tc.desc: Check whether the target EcmaString made by CreateLineString( , true, ) changed through calling WriteData - * function from a source char is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, WriteData_002) -{ - // WriteData(). From char to EcmaString made by CreateLineString( , true, ). - char u8Write = 'a'; - size_t sizeEcmaStrU8WriteTo = 5; - JSHandle handleEcmaStrAllocTrueWriteTo(thread, - EcmaString::CreateLineString(instance, sizeEcmaStrU8WriteTo, true)); - uint32_t indexAtWriteFromU8 = 4; - handleEcmaStrAllocTrueWriteTo->WriteData(u8Write, indexAtWriteFromU8); - EXPECT_EQ(handleEcmaStrAllocTrueWriteTo->At(indexAtWriteFromU8), u8Write); -} - -/* - * @tc.name: WriteData_003 - * @tc.desc: Check whether the target EcmaString made by CreateLineString( , false, ) changed through calling - * WriteData function with a source EcmaString made by CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, WriteData_003) -{ - /* WriteData(). From EcmaString made by CreateFromUtf16( , , , false) to EcmaStringU16 made by - * CreateLineString( , false, ). - */ - uint16_t arrayU16WriteFrom[10] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; - uint32_t lengthEcmaStrU16WriteFrom = sizeof(arrayU16WriteFrom) / sizeof(arrayU16WriteFrom[0]); - JSHandle handleEcmaStrU16WriteFrom(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16WriteFrom[0], lengthEcmaStrU16WriteFrom, false)); - size_t sizeEcmaStrU16WriteTo = 10; - JSHandle handleEcmaStrU16WriteTo(thread, - EcmaString::CreateLineString(instance, sizeEcmaStrU16WriteTo, false)); - uint32_t indexStartWriteFromArrayU16 = 3; - uint32_t numBytesWriteFromArrayU16 = 2 * 3; - handleEcmaStrU16WriteTo->WriteData(*handleEcmaStrU16WriteFrom, indexStartWriteFromArrayU16, sizeEcmaStrU16WriteTo, - numBytesWriteFromArrayU16); - for (uint32_t i = 0; i < (numBytesWriteFromArrayU16 / 2); i++) { - EXPECT_EQ(handleEcmaStrU16WriteTo->At(i + indexStartWriteFromArrayU16), handleEcmaStrU16WriteFrom->At(i)); - } -} - -/* - * @tc.name: WriteData_004 - * @tc.desc: Check whether the target EcmaString made by CreateLineString( , false, ) changed through calling - * WriteData function with a source EcmaString made by CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, WriteData_004) -{ - // WriteData(). From EcmaString made by CreateFromUtf8() to EcmaString made by CreateLineString( , false, ). - uint8_t arrayU8WriteFrom[6] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU8WriteFrom = sizeof(arrayU8WriteFrom) - 1; - JSHandle handleEcmaStrU8WriteFrom(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8WriteFrom[0], lengthEcmaStrU8WriteFrom, true)); - size_t sizeEcmaStrU16WriteTo = 10; - JSHandle handleEcmaStrU16WriteTo(thread, - EcmaString::CreateLineString(instance, sizeEcmaStrU16WriteTo, false)); - uint32_t indexStartWriteFromU8ToU16 = 1; - uint32_t numBytesWriteFromU8ToU16 = 4; - handleEcmaStrU16WriteTo->WriteData(*handleEcmaStrU8WriteFrom, indexStartWriteFromU8ToU16, sizeEcmaStrU16WriteTo, - numBytesWriteFromU8ToU16); - for (uint32_t i = 0; i < numBytesWriteFromU8ToU16; i++) { - EXPECT_EQ(handleEcmaStrU16WriteTo->At(i + indexStartWriteFromU8ToU16), handleEcmaStrU8WriteFrom->At(i)); - } -} - -/* - * @tc.name: WriteData_005 - * @tc.desc: Check whether the target EcmaString made by CreateLineString( , false, ) changed through calling - * WriteData function with a source char is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, WriteData_005) -{ - // WriteData(). From char to EcmaString made by CreateLineString( , false, ). - size_t sizeEcmaStrU16WriteTo = 10; - JSHandle handleEcmaStrU16WriteTo(thread, - EcmaString::CreateLineString(instance, sizeEcmaStrU16WriteTo, false)); - char u8Write = 'a'; - uint32_t indexAt = 4; - handleEcmaStrU16WriteTo->WriteData(u8Write, indexAt); - EXPECT_EQ(handleEcmaStrU16WriteTo->At(indexAt), u8Write); -} - -/* - * @tc.name: GetUtf8Length - * @tc.desc: Check whether the value returned through calling GetUtf8Length function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetUtf8Length) -{ - uint8_t arrayU8[6] = {3, 7, 19, 54, 99}; - uint16_t arrayU16Comp[] = {1, 12, 34, 56, 127}; - uint16_t arrayU16NotComp[] = {19, 54, 256, 11100, 65535}; - uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); - EXPECT_EQ(handleEcmaStrU8->GetUtf8Length(), lengthEcmaStrU8 + 1); - EXPECT_EQ(handleEcmaStrU16Comp->GetUtf8Length(), lengthEcmaStrU16Comp + 1); - EXPECT_EQ(handleEcmaStrU16NotComp->GetUtf8Length(), 2 * lengthEcmaStrU16NotComp + 1); -} - -/* - * @tc.name: GetDataUtf8 - * @tc.desc: Check whether the pointer returned through calling GetDataUtf8 function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetDataUtf8) -{ - // From EcmaString made by CreateFromUtf8(). - uint8_t arrayU8[] = {"abcde"}; - uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { - EXPECT_EQ(*(handleEcmaStrU8->GetDataUtf8() + i), arrayU8[i]); - } - - // From EcmaString made by CreateFromUtf16( , , , true). - uint16_t arrayU16Comp[] = {3, 1, 34, 123, 127, 111, 42, 3, 20, 10}; - uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - for (uint32_t i = 0; i < sizeof(arrayU16Comp) / arrayU16Comp[0]; i++) { - EXPECT_EQ(*(handleEcmaStrU16Comp->GetDataUtf8() + i), arrayU16Comp[i]); - } -} - -/* - * @tc.name: GetDataUtf16 - * @tc.desc: Check whether the pointer returned through calling GetDataUtf16 function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetDataUtf16) -{ - // From EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotComp[] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; - uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); - for (uint32_t i = 0; i < lengthEcmaStrU16NotComp; i++) { - EXPECT_EQ(*(handleEcmaStrU16NotComp->GetDataUtf16() + i), arrayU16NotComp[i]); - } -} - -/* - * @tc.name: CopyDataRegionUtf8 - * @tc.desc: Check whether the returned value and the changed array through a source EcmaString's calling - * CopyDataRegionUtf8 function are within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CopyDataRegionUtf8) -{ - // CopyDataRegionUtf8(). From EcmaString made by CreateFromUtf8(). - uint8_t arrayU8CopyFrom[6] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU8CopyFrom = sizeof(arrayU8CopyFrom) - 1; - JSHandle handleEcmaStrU8CopyFrom(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8CopyFrom[0], lengthEcmaStrU8CopyFrom, true)); - const size_t lengthArrayU8Target = 7; - uint8_t defaultByteForU8CopyTo = 1; - uint8_t arrayU8CopyTo[lengthArrayU8Target]; - int checkResUtf8 = memset_s(&arrayU8CopyTo[0], lengthArrayU8Target, defaultByteForU8CopyTo, lengthArrayU8Target); - EXPECT_TRUE(checkResUtf8 == 0); - - size_t indexStartFromArrayU8 = 2; - size_t lengthCopyToEcmaStrU8 = 3; - size_t lengthReturnU8 = handleEcmaStrU8CopyFrom->CopyDataRegionUtf8(arrayU8CopyTo, indexStartFromArrayU8, - lengthCopyToEcmaStrU8, lengthArrayU8Target); - - EXPECT_EQ(lengthReturnU8, lengthCopyToEcmaStrU8); - for (uint32_t i = 0; i < lengthCopyToEcmaStrU8; i++) { - EXPECT_EQ(arrayU8CopyTo[i], handleEcmaStrU8CopyFrom->At(i + indexStartFromArrayU8)); - } - for (uint32_t i = lengthCopyToEcmaStrU8; i < lengthArrayU8Target; i++) { - EXPECT_EQ(arrayU8CopyTo[i], defaultByteForU8CopyTo); - } - - // CopyDataRegionUtf8(). From EcmaString made by CreateFromUtf16( , , , true). - uint16_t arrayU16CompCopyFrom[] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU16CompCopyFrom = sizeof(arrayU16CompCopyFrom) / sizeof(arrayU16CompCopyFrom[0]); - JSHandle handleEcmaStrU16CompCopyFrom(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompCopyFrom[0], lengthEcmaStrU16CompCopyFrom, true)); - const size_t lengthArrayU16Target = 8; - uint8_t defaultByteForU16CompCopyTo = 1; - uint8_t arrayU16CompCopyTo[lengthArrayU16Target]; - int checkResUtf16 = memset_s(&arrayU16CompCopyTo[0], lengthArrayU16Target, defaultByteForU16CompCopyTo, - lengthArrayU16Target); - EXPECT_TRUE(checkResUtf16 == 0); - - size_t indexStartFromArrayU16Comp = 2; - size_t lengthCopyToEcmaStrU16Comp = 3; - size_t lengthReturnU16Comp = handleEcmaStrU16CompCopyFrom->CopyDataRegionUtf8(&arrayU16CompCopyTo[0], - indexStartFromArrayU16Comp, lengthCopyToEcmaStrU16Comp, lengthArrayU16Target); - - EXPECT_EQ(lengthReturnU16Comp, lengthCopyToEcmaStrU16Comp); - for (uint32_t i = 0; i < lengthReturnU16Comp; i++) { - EXPECT_EQ(arrayU16CompCopyTo[i], handleEcmaStrU16CompCopyFrom->At(i + indexStartFromArrayU16Comp)); - } - for (uint32_t i = lengthReturnU16Comp; i < lengthArrayU16Target; i++) { - EXPECT_EQ(arrayU16CompCopyTo[i], defaultByteForU16CompCopyTo); - } -} - -/* - * @tc.name: CopyDataUtf8 - * @tc.desc: Check whether the returned value and the changed array through a source EcmaString's calling - * CopyDataUtf8 function are within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CopyDataUtf8) -{ - // CopyDataUtf8(). From EcmaString made by CreateFromUtf8(). - uint8_t arrayU8CopyFrom[6] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU8CopyFrom = sizeof(arrayU8CopyFrom) - 1; - JSHandle handleEcmaStrU8CopyFrom(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8CopyFrom[0], lengthEcmaStrU8CopyFrom, true)); - const size_t lengthArrayU8Target = 6; - uint8_t arrayU8CopyTo[lengthArrayU8Target]; - - size_t lengthReturnU8 = handleEcmaStrU8CopyFrom->CopyDataUtf8(&arrayU8CopyTo[0], lengthArrayU8Target); - - EXPECT_EQ(lengthReturnU8, lengthArrayU8Target); - for (uint32_t i = 0; i < lengthReturnU8 - 1; i++) { - EXPECT_EQ(arrayU8CopyTo[i], arrayU8CopyFrom[i]); - } - EXPECT_EQ(arrayU8CopyTo[lengthReturnU8 - 1], 0); - - // CopyDataUtf8(). From EcmaString made by CreateFromUtf16( , , , true). - uint16_t arrayU16CompCopyFrom[] = {1, 12, 34, 56, 127}; - uint32_t lengthEcmaStrU16CompCopyFrom = sizeof(arrayU16CompCopyFrom) / sizeof(arrayU16CompCopyFrom[0]); - JSHandle handleEcmaStrU16CompCopyFrom(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompCopyFrom[0], lengthEcmaStrU16CompCopyFrom, true)); - const size_t lengthArrayU16Target = 6; - uint8_t arrayU8CompCopyTo[lengthArrayU16Target]; - - size_t lengthReturnU16Comp = handleEcmaStrU16CompCopyFrom->CopyDataUtf8(&arrayU8CompCopyTo[0], - lengthArrayU16Target); - - EXPECT_EQ(lengthReturnU16Comp, lengthArrayU16Target); - for (uint32_t i = 0; i < lengthReturnU16Comp - 1; i++) { - EXPECT_EQ(arrayU8CompCopyTo[i], arrayU16CompCopyFrom[i]); - } - EXPECT_EQ(arrayU8CompCopyTo[lengthReturnU16Comp - 1], 0U); -} - -/* - * @tc.name: CopyDataRegionUtf16 - * @tc.desc: Check whether the returned value and the changed array through a source EcmaString's calling - * CopyDataRegionUtf16 function are within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CopyDataRegionUtf16) -{ - // CopyDataRegionUtf16(). From EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotCompCopyFrom[10] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; - uint32_t lengthEcmaStrU16NotCompCopyFrom = sizeof(arrayU16NotCompCopyFrom) / sizeof(arrayU16NotCompCopyFrom[0]); - JSHandle handleEcmaStrU16NotCompCopyFrom(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompCopyFrom[0], lengthEcmaStrU16NotCompCopyFrom, false)); - const size_t lengthArrayU16Target = 13; - uint16_t arrayU16NotCompCopyTo[lengthArrayU16Target]; - uint8_t defaultOneByteValueOfArrayU16NotCompCopyTo = 244; - int checkResUtf16 = memset_s(&arrayU16NotCompCopyTo[0], sizeof(uint16_t) * lengthArrayU16Target, - defaultOneByteValueOfArrayU16NotCompCopyTo, sizeof(uint16_t) * lengthArrayU16Target); - EXPECT_TRUE(checkResUtf16 == 0); - - size_t startIndexFromArrayU16NotComp = 2; - size_t lengthCopyFromArrayU16NotComp = 3; - size_t lengthReturnU16NotComp = handleEcmaStrU16NotCompCopyFrom->CopyDataRegionUtf16(&arrayU16NotCompCopyTo[0], - startIndexFromArrayU16NotComp, lengthCopyFromArrayU16NotComp, lengthArrayU16Target); - - EXPECT_EQ(lengthReturnU16NotComp, lengthCopyFromArrayU16NotComp); - for (uint32_t i = 0; i < lengthReturnU16NotComp; i++) { - EXPECT_EQ(arrayU16NotCompCopyTo[i], handleEcmaStrU16NotCompCopyFrom->At(i + startIndexFromArrayU16NotComp)); - } - for (uint32_t i = lengthReturnU16NotComp; i < lengthArrayU16Target; i++) { - EXPECT_EQ(arrayU16NotCompCopyTo[i], ((uint16_t)defaultOneByteValueOfArrayU16NotCompCopyTo) * (1 + (1 << 8))); - } -} - -/* - * @tc.name: CopyDataUtf16 - * @tc.desc: Check whether the returned value and the changed array through a source EcmaString's calling - * CopyDataUtf16 function are within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, CopyDataUtf16) -{ - // CopyDataUtf16(). From EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotCompCopyFrom[10] = {67, 777, 1999, 1, 45, 66, 23456, 65535, 127, 333}; - uint32_t lengthEcmaStrU16NotCompCopyFrom = sizeof(arrayU16NotCompCopyFrom) / sizeof(arrayU16NotCompCopyFrom[0]); - JSHandle handleEcmaStrU16NotCompCopyFrom(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompCopyFrom[0], lengthEcmaStrU16NotCompCopyFrom, false)); - const size_t lengthArrayU16Target = 13; - uint16_t arrayU16NotCompCopyTo[lengthArrayU16Target]; - uint8_t defaultOneByteValueOfArrayU16NotCompCopyTo = 244; - int checkResUtf16 = memset_s(&arrayU16NotCompCopyTo[0], sizeof(uint16_t) * lengthArrayU16Target, - defaultOneByteValueOfArrayU16NotCompCopyTo, sizeof(uint16_t) * lengthArrayU16Target); - EXPECT_TRUE(checkResUtf16 == 0); - - size_t lengthReturnU16NotComp = handleEcmaStrU16NotCompCopyFrom->CopyDataUtf16(&arrayU16NotCompCopyTo[0], - lengthArrayU16Target); - - EXPECT_EQ(lengthReturnU16NotComp, lengthEcmaStrU16NotCompCopyFrom); - for (uint32_t i = 0; i < lengthReturnU16NotComp; i++) { - EXPECT_EQ(arrayU16NotCompCopyTo[i], handleEcmaStrU16NotCompCopyFrom->At(i)); - } - for (uint32_t i = lengthReturnU16NotComp; i < lengthArrayU16Target; i++) { - EXPECT_EQ(arrayU16NotCompCopyTo[i], ((uint16_t)defaultOneByteValueOfArrayU16NotCompCopyTo) * (1 + (1 << 8))); - } -} - -/* - * @tc.name: IndexOf_001 - * @tc.desc: Check whether the value returned through a source EcmaString made by CreateFromUtf8() calling IndexOf - * function with a target EcmaString made by CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, IndexOf_001) -{ - // IndexOf(). Find EcmaString made by CreateFromUtf8() From EcmaString made by CreateFromUtf8(). - uint8_t arrayU8From[7] = {23, 25, 1, 3, 39, 80}; - uint8_t arrayU8Target[4] = {1, 3, 39}; - uint32_t lengthEcmaStrU8From = sizeof(arrayU8From) - 1; - uint32_t lengthEcmaStrU8Target = sizeof(arrayU8Target) - 1; - JSHandle handleEcmaStr(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8From[0], lengthEcmaStrU8From, true)); - JSHandle handleEcmaStr1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8Target[0], lengthEcmaStrU8Target, true)); - int32_t posStart = 0; - EXPECT_EQ(handleEcmaStr->IndexOf(*handleEcmaStr1, posStart), 2); - EXPECT_EQ(handleEcmaStr1->IndexOf(*handleEcmaStr, posStart), -1); - posStart = -1; - EXPECT_EQ(handleEcmaStr->IndexOf(*handleEcmaStr1, posStart), 2); - posStart = 1; - EXPECT_EQ(handleEcmaStr->IndexOf(*handleEcmaStr1, posStart), 2); - posStart = 2; - EXPECT_EQ(handleEcmaStr->IndexOf(*handleEcmaStr1, posStart), 2); - posStart = 3; - EXPECT_EQ(handleEcmaStr->IndexOf(*handleEcmaStr1, posStart), -1); -} - -/* - * @tc.name: IndexOf_002 - * @tc.desc: Check whether the value returned through a source EcmaString made by CreateFromUtf16( , , , false) calling - * IndexOf function with a target EcmaString made by CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, IndexOf_002) -{ - // IndexOf(). Find EcmaString made by CreateFromUtf8() From EcmaString made by CreateFromUtf16( , , , false). - uint8_t arrayU8Target[4] = {1, 3, 39}; - uint16_t arrayU16NotCompFromNo1[] = {67, 65535, 127, 777, 1453, 44, 1, 3, 39, 80, 333}; - uint32_t lengthEcmaStrU8Target = sizeof(arrayU8Target) - 1; - uint32_t lengthEcmaStrU16NotCompFromNo1 = sizeof(arrayU16NotCompFromNo1) / sizeof(arrayU16NotCompFromNo1[0]); - JSHandle handleEcmaStr(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8Target[0], lengthEcmaStrU8Target, true)); - JSHandle handleEcmaStr1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompFromNo1[0], lengthEcmaStrU16NotCompFromNo1, false)); - int32_t posStart = 0; - EXPECT_EQ(handleEcmaStr1->IndexOf(*handleEcmaStr, posStart), 6); - EXPECT_EQ(handleEcmaStr->IndexOf(*handleEcmaStr1, posStart), -1); - posStart = -1; - EXPECT_EQ(handleEcmaStr1->IndexOf(*handleEcmaStr, posStart), 6); - posStart = 1; - EXPECT_EQ(handleEcmaStr1->IndexOf(*handleEcmaStr, posStart), 6); - posStart = 6; - EXPECT_EQ(handleEcmaStr1->IndexOf(*handleEcmaStr, posStart), 6); - posStart = 7; - EXPECT_EQ(handleEcmaStr1->IndexOf(*handleEcmaStr, posStart), -1); -} - -/* - * @tc.name: IndexOf_003 - * @tc.desc: Check whether the value returned through a source EcmaString made by CreateFromUtf16( , , , false) calling - * IndexOf function with a target EcmaString made by CreateFromUtf16( , , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, IndexOf_003) -{ - /* IndexOf(). Find EcmaString made by CreateFromUtf16( , , , false) From EcmaString made by - * CreateFromUtf16( , , , false). - */ - uint16_t arrayU16NotCompTarget[] = {1453, 44}; - uint16_t arrayU16NotCompFrom[] = {67, 65535, 127, 777, 1453, 44, 1, 3, 39, 80, 333}; - uint32_t lengthEcmaStrU16NotCompTarget = sizeof(arrayU16NotCompTarget) / sizeof(arrayU16NotCompTarget[0]); - uint32_t lengthEcmaStrU16NotCompFrom = sizeof(arrayU16NotCompFrom) / sizeof(arrayU16NotCompFrom[0]); - JSHandle handleEcmaStrU16NotCompTarget(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompTarget[0], lengthEcmaStrU16NotCompTarget, false)); - JSHandle handleEcmaStrU16NotCompFrom(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompFrom[0], lengthEcmaStrU16NotCompFrom, false)); - int32_t posStart = 0; - EXPECT_EQ(handleEcmaStrU16NotCompFrom->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 4); - EXPECT_EQ(handleEcmaStrU16NotCompTarget->IndexOf(*handleEcmaStrU16NotCompFrom, posStart), -1); - posStart = -1; - EXPECT_EQ(handleEcmaStrU16NotCompFrom->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 4); - posStart = 1; - EXPECT_EQ(handleEcmaStrU16NotCompFrom->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 4); - posStart = 4; - EXPECT_EQ(handleEcmaStrU16NotCompFrom->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 4); - posStart = 5; - EXPECT_EQ(handleEcmaStrU16NotCompFrom->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), -1); -} - -/* - * @tc.name: IndexOf_004 - * @tc.desc: Check whether the value returned through a source EcmaString made by CreateFromUtf8() calling IndexOf - * function with a target EcmaString made by CreateFromUtf16() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, IndexOf_004) -{ - // IndexOf(). Find EcmaString made by CreateFromUtf16() From EcmaString made by CreateFromUtf8(). - uint16_t ecmaStrU16NotCompTarget[] = {3, 39, 80}; - uint8_t arrayU8From[7] = {23, 25, 1, 3, 39, 80}; - uint32_t lengthEcmaStrU16NotCompTarget = sizeof(ecmaStrU16NotCompTarget) / sizeof(ecmaStrU16NotCompTarget[0]); - uint32_t lengthEcmaStrU8From = sizeof(arrayU8From) - 1; - JSHandle handleEcmaStrU16NotCompTarget(thread, - EcmaString::CreateFromUtf16(instance, &ecmaStrU16NotCompTarget[0], lengthEcmaStrU16NotCompTarget, true)); - JSHandle handleEcmaStrU8From(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8From[0], lengthEcmaStrU8From, true)); - int32_t posStart = 0; - EXPECT_EQ(handleEcmaStrU8From->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 3); - EXPECT_EQ(handleEcmaStrU16NotCompTarget->IndexOf(*handleEcmaStrU8From, posStart), -1); - posStart = -1; - EXPECT_EQ(handleEcmaStrU8From->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 3); - posStart = 1; - EXPECT_EQ(handleEcmaStrU8From->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 3); - posStart = 3; - EXPECT_EQ(handleEcmaStrU8From->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), 3); - posStart = 4; - EXPECT_EQ(handleEcmaStrU8From->IndexOf(*handleEcmaStrU16NotCompTarget, posStart), -1); -} - -/* - * @tc.name: StringsAreEqual_001 - * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with two EcmaStrings made by - * CreateFromUtf8() is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqual_001) -{ - // StringsAreEqual(). - uint8_t arrayU8No1[4] = {45, 92, 78}; - uint8_t arrayU8No2[4] = {45, 92, 78}; - uint8_t arrayU8No3[5] = {45, 92, 78, 1}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; - uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU8No2(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); - JSHandle handleEcmaStrU8No3(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU8No1, *handleEcmaStrU8No2)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU8No1, *handleEcmaStrU8No3)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU8No3, *handleEcmaStrU8No1)); -} - -/* - * @tc.name: StringsAreEqual_002 - * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with a EcmaString made by - * CreateFromUtf8() and a EcmaString made by CreateFromUtf16(, , , true) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqual_002) -{ - // StringsAreEqual(). - uint8_t arrayU8No1[4] = {45, 92, 78}; - uint16_t arrayU16CompNo2[] = {45, 92, 78}; - uint16_t arrayU16CompNo3[] = {45, 92, 78, 1}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16CompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU8No1, *handleEcmaStrU16CompNo2)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU8No1, *handleEcmaStrU16CompNo3)); -} - -/* - * @tc.name: StringsAreEqual_003 - * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with two EcmaStrings made by - * CreateFromUtf16(, , , true) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqual_003) -{ - // StringsAreEqual(). - uint16_t arrayU16CompNo1[] = {45, 92, 78}; - uint16_t arrayU16CompNo2[] = {45, 92, 78}; - uint16_t arrayU16CompNo3[] = {45, 92, 78, 1}; - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16CompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU16CompNo1, *handleEcmaStrU16CompNo2)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU16CompNo1, *handleEcmaStrU16CompNo3)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU16CompNo3, *handleEcmaStrU16CompNo1)); -} - -/* - * @tc.name: StringsAreEqual_004 - * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with a EcmaString made by - * CreateFromUtf8() and a EcmaString made by CreateFromUtf16(, , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqual_004) -{ - // StringsAreEqual(). - uint8_t arrayU8No1[4] = {45, 92, 78}; - uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, true)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU8No1, *handleEcmaStrU16NotCompNo1)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU8No1)); -} - -/* - * @tc.name: StringsAreEqual_005 - * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with a EcmaString made by - * CreateFromUtf16(, , , true) and a EcmaString made by CreateFromUtf16(, , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqual_005) -{ - // StringsAreEqual(). - uint16_t arrayU16CompNo1[] = {45, 92, 78}; - uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, true)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU16CompNo1, *handleEcmaStrU16NotCompNo1)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU16CompNo1)); -} - -/* - * @tc.name: StringsAreEqual_006 - * @tc.desc: Check whether the bool returned through calling StringsAreEqual function with two EcmaStrings made by - * CreateFromUtf16(, , , false) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqual_006) -{ - // StringsAreEqual(). - uint16_t arrayU16NotCompNo1[] = {234, 345, 127, 2345, 65535, 5}; - uint16_t arrayU16NotCompNo2[] = {234, 345, 127, 2345, 65535, 5}; - uint16_t arrayU16NotCompNo3[] = {1, 234, 345, 127, 2345, 65535, 5}; - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); - uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, false)); - JSHandle handleEcmaStrU16NotCompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo2[0], lengthEcmaStrU16NotCompNo2, false)); - JSHandle handleEcmaStrU16NotCompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo3[0], lengthEcmaStrU16NotCompNo3, false)); - EXPECT_TRUE(EcmaString::StringsAreEqual(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU16NotCompNo2)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU16NotCompNo1, *handleEcmaStrU16NotCompNo3)); - EXPECT_FALSE(EcmaString::StringsAreEqual(*handleEcmaStrU16NotCompNo3, *handleEcmaStrU16NotCompNo1)); -} - -/* - * @tc.name: StringsAreEqualUtf8_001 - * @tc.desc: Check whether the bool returned through calling StringIsEqualUint8Data function with an EcmaString made by - * CreateFromUtf8() and an Array(uint8_t) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqualUtf8_001) -{ - // StringIsEqualUint8Data(). EcmaString made by CreateFromUtf8(), Array:U8. - uint8_t arrayU8No1[4] = {45, 92, 78}; - uint8_t arrayU8No2[5] = {45, 92, 78, 24}; - uint8_t arrayU8No3[3] = {45, 92}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; - uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU8No2(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); - JSHandle handleEcmaStrU8No3(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); - EXPECT_TRUE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU8No1, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - EXPECT_FALSE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU8No1, &arrayU8No1[0], lengthEcmaStrU8No1, false)); - EXPECT_FALSE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU8No2, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - EXPECT_FALSE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU8No3, &arrayU8No1[0], lengthEcmaStrU8No1, true)); -} - -/* - * @tc.name: StringsAreEqualUtf8_002 - * @tc.desc: Check whether the bool returned through calling StringIsEqualUint8Data function with an EcmaString made by - * CreateFromUtf16( , , , true) and an Array(uint8_t) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqualUtf8_002) -{ - // StringIsEqualUint8Data(). EcmaString made by CreateFromUtf16( , , , true), Array:U8. - uint8_t arrayU8No1[4] = {45, 92, 78}; - uint16_t arrayU16CompNo1[] = {45, 92, 78}; - uint16_t arrayU16CompNo2[] = {45, 92, 78, 24}; - uint16_t arrayU16CompNo3[] = {45, 92}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16CompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); - EXPECT_TRUE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU16CompNo1, - &arrayU8No1[0], lengthEcmaStrU8No1, true)); - EXPECT_FALSE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU16CompNo1, - &arrayU8No1[0], lengthEcmaStrU8No1, false)); - EXPECT_FALSE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU16CompNo2, - &arrayU8No1[0], lengthEcmaStrU8No1, true)); - EXPECT_FALSE(EcmaString::StringIsEqualUint8Data(*handleEcmaStrU16CompNo3, - &arrayU8No1[0], lengthEcmaStrU8No1, true)); -} - -/* - * @tc.name: StringsAreEqualUtf8_003 - * @tc.desc: Check whether the bool returned through calling StringIsEqualUint8Data function with an EcmaString made by - * CreateFromUtf16( , , , false) and an Array(uint8_t) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqualUtf8_003) -{ - // StringIsEqualUint8Data(). EcmaString made by CreateFromUtf16( , , , false), Array:U8. - EcmaTestCommon::StringIsEqualCommonCase(thread, instance, EcmaString::StringIsEqualUint8Data); -} - -/* - * @tc.name: StringsAreEqualUtf16_001 - * @tc.desc: Check whether the bool returned through calling StringsAreEqualUtf16 function with an EcmaString made by - * CreateFromUtf8() and an Array(uint16_t) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqualUtf16_001) -{ - // StringsAreEqualUtf16(). EcmaString made by CreateFromUtf8, Array:U16(1-127). - uint8_t arrayU8No1[4] = {45, 92, 78}; - uint8_t arrayU8No2[5] = {45, 92, 78, 24}; - uint8_t arrayU8No3[3] = {45, 92}; - uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; - uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; - uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; - uint32_t lengthEcmaStrU8No3 = sizeof(arrayU8No3) - 1; - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - JSHandle handleEcmaStrU8No1(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); - JSHandle handleEcmaStrU8No2(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); - JSHandle handleEcmaStrU8No3(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8No3[0], lengthEcmaStrU8No3, true)); - EXPECT_TRUE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU8No1, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1)); - EXPECT_FALSE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU8No2, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1)); - EXPECT_FALSE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU8No3, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1)); -} - -/* - * @tc.name: StringsAreEqualUtf16_002 - * @tc.desc: Check whether the bool returned through calling StringsAreEqualUtf16 function with an EcmaString made by - * CreateFromUtf16( , , , true) and an Array(uint16_t) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqualUtf16_002) -{ - // StringsAreEqualUtf16(). EcmaString made by CreateFromUtf16( , , , true), Array:U16(1-127). - uint16_t arrayU16CompNo1[] = {45, 92, 78}; - uint16_t arrayU16CompNo2[] = {45, 92, 78, 24}; - uint16_t arrayU16CompNo3[] = {45, 92}; - uint16_t arrayU16CompNo4[] = {25645, 25692, 25678}; // 25645 % 256 == 45... - uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); - uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); - uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); - uint32_t lengthEcmaStrU16CompNo4 = sizeof(arrayU16CompNo4) / sizeof(arrayU16CompNo4[0]); - JSHandle handleEcmaStrU16CompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); - JSHandle handleEcmaStrU16CompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); - JSHandle handleEcmaStrU16CompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); - JSHandle handleEcmaStrU16CompNo4(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16CompNo4[0], lengthEcmaStrU16CompNo4, true)); - EXPECT_TRUE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16CompNo1, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); - EXPECT_FALSE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16CompNo2, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); - EXPECT_FALSE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16CompNo3, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); - EXPECT_TRUE( - EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16CompNo4, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1)); -} - -/* - * @tc.name: StringsAreEqualUtf16_003 - * @tc.desc: Check whether the bool returned through calling StringsAreEqualUtf16 function with an EcmaString made by - * CreateFromUtf16( , , , false) and an Array(uint16_t) is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, StringsAreEqualUtf16_003) -{ - uint16_t arrayU16NotCompNo1[] = {25645, 25692, 25678}; - uint16_t arrayU16NotCompNo2[] = {25645, 25692, 78}; // 25645 % 256 == 45... - uint16_t arrayU16NotCompNo3[] = {25645, 25692, 25678, 65535}; - uint16_t arrayU16NotCompNo4[] = {25645, 25692}; - uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); - uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); - uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); - uint32_t lengthEcmaStrU16NotCompNo4 = sizeof(arrayU16NotCompNo4) / sizeof(arrayU16NotCompNo4[0]); - JSHandle handleEcmaStrU16NotCompNo1(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, false)); - JSHandle handleEcmaStrU16NotCompNo2(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo2[0], lengthEcmaStrU16NotCompNo2, false)); - JSHandle handleEcmaStrU16NotCompNo3(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo3[0], lengthEcmaStrU16NotCompNo3, false)); - JSHandle handleEcmaStrU16NotCompNo4(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotCompNo4[0], lengthEcmaStrU16NotCompNo4, false)); - EXPECT_TRUE(EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16NotCompNo1, &arrayU16NotCompNo1[0], - lengthEcmaStrU16NotCompNo1)); - EXPECT_FALSE(EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16NotCompNo1, &arrayU16NotCompNo2[0], - lengthEcmaStrU16NotCompNo2)); - EXPECT_FALSE(EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16NotCompNo2, &arrayU16NotCompNo1[0], - lengthEcmaStrU16NotCompNo1)); - EXPECT_FALSE(EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16NotCompNo3, &arrayU16NotCompNo1[0], - lengthEcmaStrU16NotCompNo1)); - EXPECT_FALSE(EcmaString::StringsAreEqualUtf16(*handleEcmaStrU16NotCompNo4, &arrayU16NotCompNo1[0], - lengthEcmaStrU16NotCompNo1)); -} - -/* - * @tc.name: ComputeHashcodeUtf8 - * @tc.desc: Check whether the value returned through calling ComputeHashcodeUtf8 function with an Array(uint8_t) is - * within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, ComputeHashcodeUtf8) -{ - uint8_t arrayU8[] = {"abc"}; - uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - uint32_t hashExpect = 0; - for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { - hashExpect = hashExpect * 31 + arrayU8[i]; - } - EXPECT_EQ(EcmaString::ComputeHashcodeUtf8(&arrayU8[0], lengthEcmaStrU8, true), hashExpect); -} - -/* - * @tc.name: ComputeHashcodeUtf16 - * @tc.desc: Check whether the value returned through calling ComputeHashcodeUtf16 function with an Array(uint16_t) is - * within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, ComputeHashcodeUtf16) -{ - uint16_t arrayU16[] = {199, 1, 256, 65535, 777}; - uint32_t lengthEcmaStrU16 = sizeof(arrayU16) / sizeof(arrayU16[0]); - uint32_t hashExpect = 0; - for (uint32_t i = 0; i < lengthEcmaStrU16; i++) { - hashExpect = hashExpect * 31 + arrayU16[i]; - } - EXPECT_EQ(EcmaString::ComputeHashcodeUtf16(&arrayU16[0], lengthEcmaStrU16), hashExpect); -} - -/* - * @tc.name: GetHashcode_001 - * @tc.desc: Check whether the value returned through an EcmaString made by CreateFromUtf8() calling GetHashcode - * function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetHashcode_001) -{ - // GetHashcode(). EcmaString made by CreateFromUtf8(). - uint8_t arrayU8[] = {"abc"}; - uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - uint32_t hashExpect = 0; - for (uint32_t i = 0; i < lengthEcmaStrU8; i++) { - hashExpect = hashExpect * 31 + arrayU8[i]; - } - EXPECT_EQ(handleEcmaStrU8->GetHashcode(), hashExpect); -} - -/* - * @tc.name: GetHashcode_002 - * @tc.desc: Check whether the value returned through an EcmaString made by CreateFromUtf16( , , , true) calling - * GetHashcode function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetHashcode_002) -{ - // GetHashcode(). EcmaString made by CreateFromUtf16( , , , true). - uint16_t arrayU16Comp[] = {45, 92, 78, 24}; - uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - uint32_t hashExpect = 0; - for (uint32_t i = 0; i < lengthEcmaStrU16Comp; i++) { - hashExpect = hashExpect * 31 + arrayU16Comp[i]; - } - EXPECT_EQ(handleEcmaStrU16Comp->GetHashcode(), hashExpect); -} - -/* - * @tc.name: GetHashcode_003 - * @tc.desc: Check whether the value returned through an EcmaString made by CreateFromUtf16( , , , false) calling - * GetHashcode function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetHashcode_003) -{ - // GetHashcode(). EcmaString made by CreateFromUtf16( , , , false). - uint16_t arrayU16NotComp[] = {199, 1, 256, 65535, 777}; - uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, false)); - uint32_t hashExpect = 0; - for (uint32_t i = 0; i < lengthEcmaStrU16NotComp; i++) { - hashExpect = hashExpect * 31 + arrayU16NotComp[i]; - } - EXPECT_EQ(handleEcmaStrU16NotComp->GetHashcode(), hashExpect); -} - -/* - * @tc.name: GetHashcode_004 - * @tc.desc: Check whether the value returned through an EcmaString made by CreateEmptyString() calling GetHashcode - * function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetHashcode_004) -{ - // GetHashcode(). EcmaString made by CreateEmptyString(). - JSHandle handleEcmaStrEmpty(thread, EcmaString::CreateEmptyString(instance)); - EXPECT_EQ(handleEcmaStrEmpty->GetHashcode(), 0U); -} - -/* - * @tc.name: GetHashcode_005 - * @tc.desc: Check whether the value returned through an EcmaString made by CreateLineString(, true/false, ) calling - * GetHashcode function is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, GetHashcode_005) -{ - // GetHashcode(). EcmaString made by CreateLineString(). - size_t sizeAlloc = 5; - JSHandle handleEcmaStrAllocComp(thread, EcmaString::CreateLineString(instance, sizeAlloc, true)); - JSHandle handleEcmaStrAllocNotComp(thread, EcmaString::CreateLineString(instance, sizeAlloc, false)); - EXPECT_EQ(handleEcmaStrAllocComp->GetHashcode(), 0U); - EXPECT_EQ(handleEcmaStrAllocNotComp->GetHashcode(), 0U); -} - -/* - * @tc.name: SetIsInternString - * @tc.desc: Call SetIsInternString function, check whether the bool returned through calling IsInternString function - * is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, SetIsInternString) -{ - uint8_t arrayU8[] = {"abc"}; - uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; - JSHandle handleEcmaStrU8(thread, - EcmaString::CreateFromUtf8(instance, &arrayU8[0], lengthEcmaStrU8, true)); - EXPECT_FALSE(handleEcmaStrU8->IsInternString()); - handleEcmaStrU8->SetIsInternString(); - EXPECT_TRUE(handleEcmaStrU8->IsInternString()); - - uint16_t arrayU16Comp[] = {97, 98, 99}; - uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); - JSHandle handleEcmaStrU16Comp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16Comp[0], lengthEcmaStrU16Comp, true)); - EXPECT_FALSE(handleEcmaStrU16Comp->IsInternString()); - handleEcmaStrU16Comp->SetIsInternString(); - EXPECT_TRUE(handleEcmaStrU16Comp->IsInternString()); - - uint16_t arrayU16NotComp[] = {97, 98, 99}; - uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); - JSHandle handleEcmaStrU16NotComp(thread, - EcmaString::CreateFromUtf16(instance, &arrayU16NotComp[0], lengthEcmaStrU16NotComp, true)); - EXPECT_FALSE(handleEcmaStrU16NotComp->IsInternString()); - handleEcmaStrU16NotComp->SetIsInternString(); - EXPECT_TRUE(handleEcmaStrU16NotComp->IsInternString()); -} - -/* - * @tc.name: EqualToSplicedString - * @tc.desc: Tests whether the source string is equal to the concatenated string. - * is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, EqualToSplicedString) -{ - ObjectFactory* factory = instance->GetFactory(); - { - JSHandle sourceString = factory->NewFromUtf8("Start开始"); - JSHandle firstString = factory->NewFromASCII("Start"); - JSHandle secondString = factory->NewFromUtf8("开始"); - EXPECT_TRUE(sourceString->IsUtf16()); - EXPECT_TRUE(firstString->IsUtf8()); - EXPECT_TRUE(secondString->IsUtf16()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Start开始"); - JSHandle firstString = factory->NewFromASCII("Start"); - JSHandle secondString = factory->NewFromASCII("start"); - EXPECT_TRUE(sourceString->IsUtf16()); - EXPECT_TRUE(firstString->IsUtf8()); - EXPECT_TRUE(secondString->IsUtf8()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(!result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Start开始"); - JSHandle firstString = factory->NewFromUtf8("Start开"); - JSHandle secondString = factory->NewFromUtf8("始"); - EXPECT_TRUE(sourceString->IsUtf16()); - EXPECT_TRUE(firstString->IsUtf16()); - EXPECT_TRUE(secondString->IsUtf16()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Startstart"); - JSHandle firstString = factory->NewFromASCII("Start"); - JSHandle secondString = factory->NewFromASCII("start"); - EXPECT_TRUE(sourceString->IsUtf8()); - EXPECT_TRUE(firstString->IsUtf8()); - EXPECT_TRUE(secondString->IsUtf8()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Startstart"); - JSHandle firstString = factory->NewFromASCII("Start"); - JSHandle secondString = factory->NewFromUtf8("开始"); - EXPECT_TRUE(sourceString->IsUtf8()); - EXPECT_TRUE(firstString->IsUtf8()); - EXPECT_TRUE(secondString->IsUtf16()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(!result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Startstat"); - JSHandle firstString = factory->NewFromASCII("Start"); - JSHandle secondString = factory->NewFromASCII("start"); - EXPECT_TRUE(sourceString->IsUtf8()); - EXPECT_TRUE(firstString->IsUtf8()); - EXPECT_TRUE(secondString->IsUtf8()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(!result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Start开始"); - JSHandle firstString = factory->NewFromUtf8("Stat开"); - JSHandle secondString = factory->NewFromUtf8("始"); - EXPECT_TRUE(sourceString->IsUtf16()); - EXPECT_TRUE(firstString->IsUtf16()); - EXPECT_TRUE(secondString->IsUtf16()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(!result); - } - - { - JSHandle sourceString = factory->NewFromUtf8("Start开始"); - JSHandle firstString = factory->NewFromASCII("Stat"); - JSHandle secondString = factory->NewFromUtf8("开始"); - EXPECT_TRUE(sourceString->IsUtf16()); - EXPECT_TRUE(firstString->IsUtf8()); - EXPECT_TRUE(secondString->IsUtf16()); - bool result = sourceString->EqualToSplicedString(*firstString, *secondString); - EXPECT_TRUE(!result); - } -} - -/* - * @tc.name: ConvertUtf8ToLowerOrUpper - * @tc.desc: Check whether the EcmaString created through calling ConvertUtf8ToLowerOrUpper is within expectations. - * is within expectations. - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F_L0(EcmaStringTest, ConvertUtf8ToLowerOrUpper) -{ - ObjectFactory* factory = instance->GetFactory(); - JSHandle lowerStr = factory->NewFromASCII("aaabbbcccddd"); - JSHandle upperStr = factory->NewFromASCII("AAABBBCCCDDD"); - JSHandle testStr1 = factory->NewFromASCII("aaaBBBcccDDD"); - JSHandle testStr2 = factory->NewFromASCII("AAAbbbcccDDD"); - { - auto testStrFlat = JSHandle(instance->GetJSThread(), Flatten(instance, testStr1)); - JSHandle testEcmaString(thread, ConvertUtf8ToLowerOrUpper(instance, testStrFlat, true)); - EXPECT_TRUE(JSTaggedValue::SameValue(lowerStr.GetTaggedValue(), testEcmaString.GetTaggedValue())); - EXPECT_EQ(lowerStr->GetLength(), testEcmaString->GetLength()); - EXPECT_TRUE(testEcmaString->IsUtf8()); - EXPECT_FALSE(testEcmaString->IsUtf16()); - } - - { - auto testStrFlat = JSHandle(instance->GetJSThread(), Flatten(instance, testStr1)); - JSHandle testEcmaString(thread, ConvertUtf8ToLowerOrUpper(instance, testStrFlat, false)); - EXPECT_TRUE(JSTaggedValue::SameValue(upperStr.GetTaggedValue(), testEcmaString.GetTaggedValue())); - EXPECT_EQ(upperStr->GetLength(), testEcmaString->GetLength()); - EXPECT_TRUE(testEcmaString->IsUtf8()); - EXPECT_FALSE(testEcmaString->IsUtf16()); - } - - { - auto testStrFlat = JSHandle(instance->GetJSThread(), Flatten(instance, testStr2)); - JSHandle testEcmaString(thread, ConvertUtf8ToLowerOrUpper(instance, testStrFlat, true)); - EXPECT_TRUE(JSTaggedValue::SameValue(lowerStr.GetTaggedValue(), testEcmaString.GetTaggedValue())); - EXPECT_EQ(lowerStr->GetLength(), testEcmaString->GetLength()); - EXPECT_TRUE(testEcmaString->IsUtf8()); - EXPECT_FALSE(testEcmaString->IsUtf16()); - } - - { - auto testStrFlat = JSHandle(instance->GetJSThread(), Flatten(instance, testStr2)); - JSHandle testEcmaString(thread, ConvertUtf8ToLowerOrUpper(instance, testStrFlat, false)); - EXPECT_TRUE(JSTaggedValue::SameValue(upperStr.GetTaggedValue(), testEcmaString.GetTaggedValue())); - EXPECT_EQ(upperStr->GetLength(), testEcmaString->GetLength()); - EXPECT_TRUE(testEcmaString->IsUtf8()); - EXPECT_FALSE(testEcmaString->IsUtf16()); - } -} - -/* - * @tc.name: TryToLower - * @tc.desc: Check whether the EcmaString created through calling TryToLower function is within expectations. - * is within expectations. - * @tc.type: FUNC - * @tc.require:upperStr - */ -HWTEST_F_L0(EcmaStringTest, TryToLower) -{ - ObjectFactory* factory = instance->GetFactory(); - JSHandle lowerStr = factory->NewFromASCII("aaabbbcccddd"); - JSHandle upperStr = factory->NewFromASCII("AAABBBCCCDDD"); - JSHandle testStr1 = factory->NewFromASCII("aaaBBBcccDDD"); - JSHandle testStr2 = factory->NewFromASCII("AAAbbbcccDDD"); - { - JSHandle lowerEcmaString(thread, TryToLower(instance, lowerStr)); - EXPECT_TRUE(JSTaggedValue::SameValue(lowerStr.GetTaggedValue(), lowerEcmaString.GetTaggedValue())); - EXPECT_EQ(lowerStr->GetLength(), lowerEcmaString->GetLength()); - EXPECT_TRUE(lowerEcmaString->IsUtf8()); - EXPECT_FALSE(lowerEcmaString->IsUtf16()); - } - - { - JSHandle lowerEcmaString(thread, TryToLower(instance, upperStr)); - EXPECT_TRUE(JSTaggedValue::SameValue(lowerStr.GetTaggedValue(), lowerEcmaString.GetTaggedValue())); - EXPECT_EQ(lowerStr->GetLength(), lowerEcmaString->GetLength()); - EXPECT_TRUE(lowerEcmaString->IsUtf8()); - EXPECT_FALSE(lowerEcmaString->IsUtf16()); - } - - { - JSHandle testEcmaString(thread, TryToLower(instance, testStr1)); - EXPECT_TRUE(JSTaggedValue::SameValue(lowerStr.GetTaggedValue(), testEcmaString.GetTaggedValue())); - EXPECT_EQ(lowerStr->GetLength(), testEcmaString->GetLength()); - EXPECT_TRUE(testEcmaString->IsUtf8()); - EXPECT_FALSE(testEcmaString->IsUtf16()); - } - - { - JSHandle testEcmaString(thread, TryToLower(instance, testStr2)); - EXPECT_TRUE(JSTaggedValue::SameValue(lowerStr.GetTaggedValue(), testEcmaString.GetTaggedValue())); - EXPECT_EQ(lowerStr->GetLength(), testEcmaString->GetLength()); - EXPECT_TRUE(testEcmaString->IsUtf8()); - EXPECT_FALSE(testEcmaString->IsUtf16()); - } -} - -HWTEST_F_L0(EcmaStringTest, ConvertToString001) -{ - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle testString = factory->NewFromASCII("bar2bazJavaScriptbaz"); - CString str = ConvertToString(*testString, StringConvertedUsage::LOGICOPERATION, false); - EXPECT_EQ(str, CString("bar2bazJavaScriptbaz")); -} - -HWTEST_F_L0(EcmaStringTest, ConvertToString002) -{ - CString str = ConvertToString(nullptr, StringConvertedUsage::LOGICOPERATION, false); - EXPECT_EQ(str, CString("")); -} - -HWTEST_F_L0(EcmaStringTest, ConvertToString003) -{ - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle testString = factory->NewFromASCII("test"); - CString str = ConvertToString(*testString); - EXPECT_EQ(str, CString("test")); -} -} // namespace panda::test \ No newline at end of file diff --git a/ecmascript/tests/js_thread_state_test.cpp b/ecmascript/tests/js_thread_state_test.cpp index 75eb09c785..a8be8146e2 100644 --- a/ecmascript/tests/js_thread_state_test.cpp +++ b/ecmascript/tests/js_thread_state_test.cpp @@ -78,7 +78,7 @@ public: size_t oldCount = activeThreadCount; // This case isn't a really fork which causes JSThread::GetCurrentThread() equals nullptr in worker_thread. // So reset the threadState as CREATED to skip the check. - newVm->GetAssociatedJSThread()->UpdateState(ThreadState::CREATED); + newVm->GetAssociatedJSThread()->UpdateState(ecmascript::ThreadState::CREATED); std::thread *worker_thread = new std::thread(StateTransitioningTest::NewVMThreadEntry, newVm, nativeState, &changeToRunning, &isTestEnded, &activeThreadCount); threads.push_back(worker_thread); @@ -105,7 +105,7 @@ public: return result; } - bool CheckAllThreadsState(ThreadState expectedState) + bool CheckAllThreadsState(ecmascript::ThreadState expectedState) { bool result = true; for (auto i: vms) { @@ -144,89 +144,89 @@ public: HWTEST_F_L0(StateTransitioningTest, ThreadStateTransitionScopeTest) { - ThreadState mainState = thread->GetState(); + ecmascript::ThreadState mainState = thread->GetState(); { - ThreadStateTransitionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::CREATED); + ThreadStateTransitionScope scope(thread); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::CREATED); } EXPECT_TRUE(thread->GetState() == mainState); { - ThreadStateTransitionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::RUNNING); + ThreadStateTransitionScope scope(thread); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::RUNNING); } EXPECT_TRUE(thread->GetState() == mainState); { - ThreadStateTransitionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::NATIVE); + ThreadStateTransitionScope scope(thread); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::NATIVE); } EXPECT_TRUE(thread->GetState() == mainState); { - ThreadStateTransitionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::WAIT); + ThreadStateTransitionScope scope(thread); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::WAIT); } EXPECT_TRUE(thread->GetState() == mainState); { - ThreadStateTransitionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::IS_SUSPENDED); + ThreadStateTransitionScope scope(thread); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::IS_SUSPENDED); } EXPECT_TRUE(thread->GetState() == mainState); { - ThreadStateTransitionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::TERMINATED); + ThreadStateTransitionScope scope(thread); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::TERMINATED); } EXPECT_TRUE(thread->GetState() == mainState); } HWTEST_F_L0(StateTransitioningTest, ThreadManagedScopeTest) { - ThreadState mainState = thread->GetState(); + ecmascript::ThreadState mainState = thread->GetState(); { ThreadManagedScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::RUNNING); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::RUNNING); } - if (mainState == ThreadState::RUNNING) { - ThreadStateTransitionScope tempScope(thread); + if (mainState == ecmascript::ThreadState::RUNNING) { + ThreadStateTransitionScope tempScope(thread); { ThreadManagedScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::RUNNING); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::RUNNING); } - EXPECT_TRUE(thread->GetState() == ThreadState::WAIT); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::WAIT); } EXPECT_TRUE(thread->GetState() == mainState); } HWTEST_F_L0(StateTransitioningTest, ThreadNativeScopeTest) { - ThreadState mainState = thread->GetState(); + ecmascript::ThreadState mainState = thread->GetState(); { ThreadNativeScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::NATIVE); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::NATIVE); } - if (mainState == ThreadState::NATIVE) { - ThreadStateTransitionScope tempScope(thread); + if (mainState == ecmascript::ThreadState::NATIVE) { + ThreadStateTransitionScope tempScope(thread); { ThreadNativeScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::NATIVE); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::NATIVE); } - EXPECT_TRUE(thread->GetState() == ThreadState::WAIT); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::WAIT); } EXPECT_TRUE(thread->GetState() == mainState); } HWTEST_F_L0(StateTransitioningTest, ThreadSuspensionScopeTest) { - ThreadState mainState = thread->GetState(); + ecmascript::ThreadState mainState = thread->GetState(); { ThreadSuspensionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::IS_SUSPENDED); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::IS_SUSPENDED); } - if (mainState == ThreadState::IS_SUSPENDED) { - ThreadStateTransitionScope tempScope(thread); + if (mainState == ecmascript::ThreadState::IS_SUSPENDED) { + ThreadStateTransitionScope tempScope(thread); { ThreadSuspensionScope scope(thread); - EXPECT_TRUE(thread->GetState() == ThreadState::IS_SUSPENDED); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::IS_SUSPENDED); } - EXPECT_TRUE(thread->GetState() == ThreadState::WAIT); + EXPECT_TRUE(thread->GetState() == ecmascript::ThreadState::WAIT); } EXPECT_TRUE(thread->GetState() == mainState); } @@ -262,56 +262,56 @@ HWTEST_F_L0(StateTransitioningTest, SuspendResumeRunningThreadVMTest) EXPECT_FALSE(CheckAllThreadsSuspended()); { SuspendOrResumeAllThreads(true); - while (!CheckAllThreadsState(ThreadState::IS_SUSPENDED)) {} + while (!CheckAllThreadsState(ecmascript::ThreadState::IS_SUSPENDED)) {} EXPECT_TRUE(CheckAllThreadsSuspended()); - EXPECT_TRUE(CheckAllThreadsState(ThreadState::IS_SUSPENDED)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::IS_SUSPENDED)); } SuspendOrResumeAllThreads(false); - while (CheckAllThreadsState(ThreadState::IS_SUSPENDED)) {} + while (CheckAllThreadsState(ecmascript::ThreadState::IS_SUSPENDED)) {} EXPECT_FALSE(CheckAllThreadsSuspended()); - EXPECT_FALSE(CheckAllThreadsState(ThreadState::IS_SUSPENDED)); + EXPECT_FALSE(CheckAllThreadsState(ecmascript::ThreadState::IS_SUSPENDED)); DestroyAllVMs(); } HWTEST_F_L0(StateTransitioningTest, SuspendAllManagedTest) { CreateNewVMInSeparateThread(false); - EXPECT_TRUE(CheckAllThreadsState(ThreadState::RUNNING)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::RUNNING)); { SuspendAllScope suspendScope(JSThread::GetCurrent()); EXPECT_TRUE(CheckAllThreadsSuspended()); } - while (CheckAllThreadsState(ThreadState::IS_SUSPENDED)) {} - EXPECT_TRUE(CheckAllThreadsState(ThreadState::RUNNING)); + while (CheckAllThreadsState(ecmascript::ThreadState::IS_SUSPENDED)) {} + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::RUNNING)); DestroyAllVMs(); } HWTEST_F_L0(StateTransitioningTest, SuspendAllNativeTest) { CreateNewVMInSeparateThread(true); - EXPECT_TRUE(CheckAllThreadsState(ThreadState::NATIVE)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::NATIVE)); { SuspendAllScope suspendScope(JSThread::GetCurrent()); - EXPECT_TRUE(CheckAllThreadsState(ThreadState::NATIVE)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::NATIVE)); } - EXPECT_TRUE(CheckAllThreadsState(ThreadState::NATIVE)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::NATIVE)); DestroyAllVMs(); } HWTEST_F_L0(StateTransitioningTest, SuspendAllNativeTransferToRunningTest) { CreateNewVMInSeparateThread(true); - EXPECT_TRUE(CheckAllThreadsState(ThreadState::NATIVE)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::NATIVE)); { SuspendAllScope suspendScope(JSThread::GetCurrent()); - EXPECT_TRUE(CheckAllThreadsState(ThreadState::NATIVE)); + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::NATIVE)); ChangeAllThreadsToRunning(); - while (!CheckAllThreadsState(ThreadState::NATIVE)) {} - EXPECT_TRUE(CheckAllThreadsState(ThreadState::NATIVE)); + while (!CheckAllThreadsState(ecmascript::ThreadState::NATIVE)) {} + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::NATIVE)); } - while (CheckAllThreadsState(ThreadState::IS_SUSPENDED)) {} - while (CheckAllThreadsState(ThreadState::NATIVE)) {} - EXPECT_TRUE(CheckAllThreadsState(ThreadState::RUNNING)); + while (CheckAllThreadsState(ecmascript::ThreadState::IS_SUSPENDED)) {} + while (CheckAllThreadsState(ecmascript::ThreadState::NATIVE)) {} + EXPECT_TRUE(CheckAllThreadsState(ecmascript::ThreadState::RUNNING)); DestroyAllVMs(); } } // namespace panda::test diff --git a/test/resource/js_runtime/ohos_test.xml b/test/resource/js_runtime/ohos_test.xml index c3495348e7..876c04f820 100755 --- a/test/resource/js_runtime/ohos_test.xml +++ b/test/resource/js_runtime/ohos_test.xml @@ -901,7 +901,7 @@