mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
!9178 修改Hash策略以及修复HashConcat Bug
Merge pull request !9178 from yinwuxiao/ywxhash
This commit is contained in:
commit
66f0c60deb
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
59
ecmascript/platform/arm64/ecma_string_hash_internal.h
Normal file
59
ecmascript/platform/arm64/ecma_string_hash_internal.h
Normal 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
|
52
ecmascript/platform/common/ecma_string_hash_internal.h
Normal file
52
ecmascript/platform/common/ecma_string_hash_internal.h
Normal 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
|
29
ecmascript/platform/ecma_string_hash.h
Normal file
29
ecmascript/platform/ecma_string_hash.h
Normal 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
|
38
ecmascript/platform/ecma_string_hash_helper.h
Normal file
38
ecmascript/platform/ecma_string_hash_helper.h
Normal 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
|
@ -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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user