!9178 修改Hash策略以及修复HashConcat Bug

Merge pull request !9178 from yinwuxiao/ywxhash
This commit is contained in:
openharmony_ci 2024-09-19 12:51:57 +00:00 committed by Gitee
commit 66f0c60deb
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 603 additions and 14 deletions

View File

@ -16,6 +16,7 @@
#include "ecmascript/ecma_string-inl.h"
#include "ecmascript/ecma_string_table.h"
#include "ecmascript/platform/ecma_string_hash.h"
namespace panda::ecmascript {
@ -502,6 +503,127 @@ std::u16string EcmaString::ToU16String(uint32_t len)
return result;
}
//static
uint32_t EcmaString::CalculateAllConcatHashCode(const JSHandle<EcmaString> &firstString,
const JSHandle<EcmaString> &secondString)
{
uint32_t hashCode;
uint32_t firstLength = firstString->GetLength();
uint32_t secondLength = secondString->GetLength();
if ((firstLength + secondLength < MAX_ELEMENT_INDEX_LEN) &&
firstString->IsUtf8() && secondString->IsUtf8() &&
firstString->IsInteger() && secondString->IsInteger()) {
firstString->HashIntegerString(firstLength, &hashCode, 0);
secondString->HashIntegerString(secondLength, &hashCode, hashCode);
return hashCode;
}
hashCode = EcmaString::CalculateConcatHashCode(firstString, secondString);
hashCode = MixHashcode(hashCode, NOT_INTEGER);
return hashCode;
}
// static
template<typename T1, typename T2>
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<uint32_t>(EcmaStringHash::HASH_SHIFT);
constexpr uint32_t blockSize = static_cast<size_t>(EcmaStringHash::BLOCK_SIZE);
// The concatenated length of the two strings is less than MIN_SIZE_FOR_UNROLLING.
if (sizeFirst + sizeSecond <= static_cast<size_t>(EcmaStringHash::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;
}
// Process the entire block of the first string.
uint32_t hash[blockSize] = {0};
uint32_t index = 0;
for (; index + blockSize <= sizeFirst; index += blockSize) {
hash[0] = (hash[0] << hashShift) - hash[0] + dataFirst[index];
hash[1] = (hash[1] << hashShift) - hash[1] + dataFirst[index + 1]; // 1: the second element
hash[2] = (hash[2] << hashShift) - hash[2] + dataFirst[index + 2]; // 2: the third element
hash[3] = (hash[3] << hashShift) - hash[3] + dataFirst[index + 3]; // 3: the fourth element
}
// The remaining total string length is less than a whole block.
if ((sizeFirst % blockSize) + sizeSecond < blockSize) {
for (; index < sizeFirst; ++index) {
hash[0] = (hash[0] << hashShift) - hash[0] + dataFirst[index];
}
index = 0;
} else {
//Calculate the non-integral block portion at the end of the first string.
for (; index < sizeFirst; ++index) {
hash[index % blockSize] = (hash[index % blockSize] << hashShift) -
hash[index % blockSize] + dataFirst[index];
}
//Calculate the portion of the second string
//that starts and aligns with an integral block at the end of the first string.
uint32_t wholeBlockRemain = (blockSize - sizeFirst % blockSize) % blockSize;
index = 0;
for (; index < wholeBlockRemain && index < sizeSecond; ++index) {
uint32_t nowHashIndex = sizeFirst % blockSize + index;
hash[nowHashIndex] = (hash[nowHashIndex] << hashShift) - hash[nowHashIndex] + dataSecond[index];
}
// Process the entire block of the Second string.
for (; index + blockSize <= sizeSecond; index += blockSize) {
hash[0] = (hash[0] << hashShift) - hash[0] + dataSecond[index];
hash[1] = (hash[1] << hashShift) - hash[1] + dataSecond[index + 1]; // 1: the second element
hash[2] = (hash[2] << hashShift) - hash[2] + dataSecond[index + 2]; // 2: the third element
hash[3] = (hash[3] << hashShift) - hash[3] + dataSecond[index + 3]; // 3: the fourth element
}
}
for (; index < sizeSecond; ++index) {
hash[0] = (hash[0] << hashShift) - hash[0] + dataSecond[index];
}
for (uint32_t i = 0; i < blockSize; ++i) {
totalHash = (totalHash << hashShift) - totalHash + hash[i];
}
return totalHash;
}
// static
uint32_t EcmaString::CalculateConcatHashCode(const JSHandle<EcmaString> &firstString,
const JSHandle<EcmaString> &secondString)
{
bool isFirstStringUtf8 = EcmaStringAccessor(firstString).IsUtf8();
bool isSecondStringUtf8 = EcmaStringAccessor(secondString).IsUtf8();
EcmaString *firstStr = *firstString;
EcmaString *secondStr = *secondString;
CVector<uint8_t> bufFirstUint8;
CVector<uint8_t> bufSecondUint8;
CVector<uint16_t> bufFirstUint16;
CVector<uint16_t> bufSecondUint16;
if (isFirstStringUtf8 && isSecondStringUtf8) {
const uint8_t *dataFirst = EcmaString::GetUtf8DataFlat(firstStr, bufFirstUint8);
const uint8_t *dataSecond = EcmaString::GetUtf8DataFlat(secondStr, bufSecondUint8);
return CalculateDataConcatHashCode(dataFirst, firstStr->GetLength(),
dataSecond, secondStr->GetLength());
}
if (!isFirstStringUtf8 && isSecondStringUtf8) {
const uint16_t *dataFirst = EcmaString::GetUtf16DataFlat(firstStr, bufFirstUint16);
const uint8_t *dataSecond = EcmaString::GetUtf8DataFlat(secondStr, bufSecondUint8);
return CalculateDataConcatHashCode(dataFirst, firstStr->GetLength(),
dataSecond, secondStr->GetLength());
}
if (isFirstStringUtf8 && !isSecondStringUtf8) {
const uint8_t *dataFirst = EcmaString::GetUtf8DataFlat(firstStr, bufFirstUint8);
const uint16_t *dataSecond = EcmaString::GetUtf16DataFlat(secondStr, bufSecondUint16);
return CalculateDataConcatHashCode(dataFirst, firstStr->GetLength(),
dataSecond, secondStr->GetLength());
}
{
const uint16_t *dataFirst = EcmaString::GetUtf16DataFlat(firstStr, bufFirstUint16);
const uint16_t *dataSecond = EcmaString::GetUtf16DataFlat(secondStr, bufSecondUint16);
return CalculateDataConcatHashCode(dataFirst, firstStr->GetLength(),
dataSecond, secondStr->GetLength());
}
}
// static
bool EcmaString::CanBeCompressed(const EcmaString *string)
{

View File

@ -28,6 +28,7 @@
#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 "libpandabase/macros.h"
#include "securec.h"
@ -111,7 +112,6 @@ private:
friend class panda::test::EcmaStringEqualsTest;
static constexpr int SMALL_STRING_SIZE = 128;
static constexpr size_t HASH_SHIFT = 5;
static EcmaString *CreateEmptyString(const EcmaVM *vm);
static EcmaString *CreateFromUtf8(const EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
bool canBeCompress, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, bool isConstantString = false,
@ -133,6 +133,13 @@ private:
size_t length, bool compressed, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, uint32_t idOffset = 0);
static EcmaString *Concat(const EcmaVM *vm, const JSHandle<EcmaString> &left,
const JSHandle<EcmaString> &right, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
template<typename T1, typename T2>
static uint32_t CalculateDataConcatHashCode(const T1 *dataFirst, size_t sizeFirst,
const T2 *dataSecond, size_t sizeSecond);
static uint32_t CalculateAllConcatHashCode(const JSHandle<EcmaString> &firstString,
const JSHandle<EcmaString> &secondString);
static uint32_t CalculateConcatHashCode(const JSHandle<EcmaString> &firstString,
const JSHandle<EcmaString> &secondString);
static EcmaString *CopyStringToOldSpace(const EcmaVM *vm, const JSHandle<EcmaString> &original,
uint32_t length, bool compressed);
static EcmaString *FastSubString(const EcmaVM *vm,
@ -646,15 +653,20 @@ private:
template<typename T>
static bool MemCopyChars(Span<T> &dst, size_t dstMax, Span<const T> &src, size_t count);
template<typename T>
static uint32_t ComputeHashForData(const T *data, size_t size, uint32_t hashSeed)
// To change the hash algorithm of EcmaString, please modify EcmaString::CalculateConcatHashCode
// and EcmaStringHashHelper::ComputeHashForDataPlatform simultaneously!!
template <typename T>
static uint32_t ComputeHashForData(const T *data, size_t size,
uint32_t hashSeed)
{
uint32_t hash = hashSeed;
Span<const T> sp(data, size);
for (auto c : sp) {
hash = (hash << HASH_SHIFT) - hash + c;
if (size <= static_cast<size_t>(EcmaStringHash::MIN_SIZE_FOR_UNROLLING)) {
uint32_t hash = hashSeed;
for (uint32_t i = 0; i < size ; i++) {
hash = (hash << static_cast<uint32_t>(EcmaStringHash::HASH_SHIFT)) - hash + data[i];
}
return hash;
}
return hash;
return EcmaStringHashHelper::ComputeHashForDataPlatform(data, size, hashSeed);
}
static bool IsASCIICharacter(uint16_t data)
@ -1070,6 +1082,12 @@ public:
explicit EcmaStringAccessor(const JSHandle<EcmaString> &strHandle);
static uint32_t CalculateAllConcatHashCode(const JSHandle<EcmaString> &firstString,
const JSHandle<EcmaString> &secondString)
{
return EcmaString::CalculateAllConcatHashCode(firstString, secondString);
}
static EcmaString *CreateLineString(const EcmaVM *vm, size_t length, bool compressed);
static EcmaString *CreateEmptyString(const EcmaVM *vm)

View File

@ -183,8 +183,7 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const JSHandle<EcmaSt
thread = signalState ? vm->GetJSThreadNoCheck() : vm->GetJSThread();
auto firstFlat = JSHandle<EcmaString>(thread, EcmaStringAccessor::Flatten(vm, firstString));
auto secondFlat = JSHandle<EcmaString>(thread, EcmaStringAccessor::Flatten(vm, secondString));
auto [hashcode, isInteger] = EcmaStringAccessor(firstFlat).ComputeRawHashcode();
hashcode = EcmaStringAccessor(secondFlat).ComputeHashcode(hashcode, isInteger);
uint32_t hashcode = EcmaStringAccessor::CalculateAllConcatHashCode(firstFlat, secondFlat);
if (signalState) {
return GetOrInternStringWithoutLock(thread, firstString, secondString, hashcode);
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2022 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.
*/
#ifndef ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_ARM64_H
#define ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_ARM64_H
#include <cstdint>
#include <arm_neon.h>
#include "ecmascript/platform/ecma_string_hash.h"
namespace panda::ecmascript {
class EcmaStringHashInternal {
friend class EcmaStringHashHelper;
private:
template <typename T>
static uint32_t ComputeHashForDataOfLongString(const T *data, size_t size,
uint32_t hashSeed)
{
constexpr uint32_t hashShift = static_cast<uint32_t>(EcmaStringHash::HASH_SHIFT);
constexpr uint32_t blockSize = static_cast<size_t>(EcmaStringHash::BLOCK_SIZE);
uint32_t hash[blockSize] = {0};
uint32_t index = 0;
uint32x4_t hashVec = vld1q_u32(hash);
uint32x4_t multiplier_vec = vdupq_n_u32(static_cast<uint32_t>(EcmaStringHash::HASH_MULTIPLY));
uint32x4_t dataVec;
for (; index + blockSize <= size; index += blockSize) {
dataVec[0] = data[index];
dataVec[1] = data[index + 1]; // 1: the second element of the block
dataVec[2] = data[index + 2]; // 2: the third element of the block
dataVec[3] = data[index + 3]; // 3: the fourth element of the block
hashVec = vaddq_u32(vmulq_u32(hashVec, multiplier_vec), dataVec);
}
vst1q_u32(hash, hashVec);
for (; index < size; ++index) {
hash[0] = (hash[0] << hashShift) - hash[0] + data[index];
}
uint32_t totalHash = hashSeed;
for (uint32_t i = 0; i < blockSize; ++i) {
totalHash = (totalHash << hashShift) - totalHash + hash[i];
}
return totalHash;
}
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_ARM64_H

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2022 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.
*/
#ifndef ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_COMMON_H
#define ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_COMMON_H
#include <cstdint>
#include "ecmascript/platform/ecma_string_hash.h"
namespace panda::ecmascript {
class EcmaStringHashInternal {
friend class EcmaStringHashHelper;
private:
template <typename T>
static uint32_t ComputeHashForDataOfLongString(const T *data, size_t size,
uint32_t hashSeed)
{
constexpr uint32_t hashShift = static_cast<uint32_t>(EcmaStringHash::HASH_SHIFT);
constexpr uint32_t blockSize = static_cast<size_t>(EcmaStringHash::BLOCK_SIZE);
uint32_t hash[blockSize] = {0};
uint32_t index = 0;
for (; index + blockSize <= size; index += blockSize) {
hash[0] = (hash[0] << hashShift) - hash[0] + data[index];
hash[1] = (hash[1] << hashShift) - hash[1] + data[index + 1]; // 1: the second element of the block
hash[2] = (hash[2] << hashShift) - hash[2] + data[index + 2]; // 2: the third element of the block
hash[3] = (hash[3] << hashShift) - hash[3] + data[index + 3]; // 3: the fourth element of the block
}
for (; index < size; ++index) {
hash[0] = (hash[0] << hashShift) - hash[0] + data[index];
}
uint32_t totalHash = hashSeed;
for (uint32_t i = 0; i < blockSize; ++i) {
totalHash = (totalHash << hashShift) - totalHash + hash[i];
}
return totalHash;
}
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_COMMON_H

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2022 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.
*/
#ifndef ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_H
#define ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_H
#include <cstdint>
namespace panda::ecmascript {
enum class EcmaStringHash : uint32_t {
BLOCK_SIZE = 4,
HASH_SHIFT = 5,
HASH_MULTIPLY = 31,
MIN_SIZE_FOR_UNROLLING = 16,
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_H

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 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.
*/
#ifndef ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_HELPER_H
#define ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_HELPER_H
#include <cstdint>
#include "ecmascript/platform/ecma_string_hash.h"
#ifdef PANDA_TARGET_ARM64
#include "ecmascript/platform/arm64/ecma_string_hash_internal.h"
#else
#include "ecmascript/platform/common/ecma_string_hash_internal.h"
#endif
namespace panda::ecmascript {
class EcmaStringHashHelper {
public:
template <typename T>
static uint32_t ComputeHashForDataPlatform(const T *data, size_t size,
uint32_t hashSeed)
{
return EcmaStringHashInternal::ComputeHashForDataOfLongString(data, size, hashSeed);
}
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_HELPER_H

View File

@ -1436,13 +1436,13 @@ HWTEST_F_L0(EcmaStringAccessorTest, StringsAreEqualUtf16_003)
}
/*
* @tc.name: EqualToSplicedString
* @tc.name: EqualToSplicedString_001
* @tc.desc: Tests whether the source string is equal to the concatenated string.
* is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString)
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString_001)
{
ObjectFactory* factory = instance->GetFactory();
{
@ -1534,6 +1534,278 @@ HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString)
}
}
/*
* @tc.name: EqualToSplicedString_002
* @tc.desc: Tests whether the source string is equal to the concatenated string.
* is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString_002)
{
ObjectFactory* factory = instance->GetFactory();
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("123A");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("123");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("A");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("A123");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("A");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("123");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("123456789A");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("123456789");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("A");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("123456789011A");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("123456789011");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("A");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
}
/*
* @tc.name: EqualToSplicedString_003
* @tc.desc: Tests whether the source string is equal to the concatenated string.
* is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString_003)
{
ObjectFactory* factory = instance->GetFactory();
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("12345678901");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("123456789");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("01");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("12345678901");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("1234567890");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("1");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("12345678901");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("123456789");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("01");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("12345678901");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("12345678");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("901");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("12345678901");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("1234567");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("8901");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("123456789");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("12345");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("6789");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("123456789");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("1234");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("56789");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
}
/*
* @tc.name: EqualToSplicedString_004
* @tc.desc: Tests whether the source string is equal to the concatenated string.
* is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString_004)
{
ObjectFactory* factory = instance->GetFactory();
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你好在干嘛");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("在干嘛");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你吃饭了么");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你吃");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("饭了么");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你你你你你你你你你我我我我我我我我我");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你你你你你你你你你");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("我我我我我我我我我");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
}
/*
* @tc.name: EqualToSplicedString_005
* @tc.desc: Tests whether the source string is equal to the concatenated string.
* is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString_005)
{
ObjectFactory* factory = instance->GetFactory();
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你好233");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("好233");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你好abc");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("abc");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("233你好");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("233");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("abc你好");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("abc");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你吃饭了么abc");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你吃");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("饭了么abc");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你吃饭了么abc");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你吃饭了么");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("abc");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
}
/*
* @tc.name: EqualToSplicedString_006
* @tc.desc: Tests whether the source string is equal to the concatenated string.
* is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(EcmaStringAccessorTest, EqualToSplicedString_006)
{
ObjectFactory* factory = instance->GetFactory();
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("你好");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("233");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("233");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
{
JSHandle<EcmaString> allString = factory->NewFromUtf8("233");
JSHandle<EcmaString> firstString = factory->NewFromUtf8("");
JSHandle<EcmaString> secondString = factory->NewFromUtf8("233");
JSHandle<EcmaString> ans = factory->ConcatFromString(firstString, secondString);
bool result = EcmaStringAccessor::StringsAreEqual(*allString, *ans);
EXPECT_TRUE(result);
}
}
/*
* @tc.name: CanBeCompressed
* @tc.desc: Check whether the bool returned through calling CanBeCompressed function is within expectations.

View File

@ -310,8 +310,8 @@ HWTEST_F_L0(JSHClassTest, TransitionExtension)
// find key
std::vector<JSTaggedValue> keyVector;
dictionary->GetAllKeysIntoVector(keyVector);
EXPECT_EQ(keyVector[0], keyHandle0.GetTaggedValue());
EXPECT_EQ(keyVector[1], preExtensionsKey.GetTaggedValue());
EXPECT_TRUE((keyVector[0] == keyHandle0.GetTaggedValue()) || (keyVector[0] == preExtensionsKey.GetTaggedValue()));
EXPECT_TRUE((keyVector[1] == keyHandle0.GetTaggedValue()) || (keyVector[1] == preExtensionsKey.GetTaggedValue()));
}
HWTEST_F_L0(JSHClassTest, TransitionProto)