Reason:Fix bug for slicedString

Description:Fix bug for slicedString
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7ZHTB?from=project-issue

Signed-off-by: wupengyong <wupengyong@huawei.com>
Change-Id: If18961f4910af5800d8deb722532cc8e66ce75b8
This commit is contained in:
wupengyong 2023-09-10 19:00:35 +08:00
parent ffb1206169
commit cb258789b8
6 changed files with 96 additions and 75 deletions

View File

@ -3990,18 +3990,11 @@ GateRef StubBuilder::FastStringEqual(GateRef glue, GateRef left, GateRef right)
env->SubCfgEntry(&entry);
DEFVARIABLE(result, VariableType::BOOL(), False());
Label exit(env);
Label lengthCompare(env);
Label hashcodeCompare(env);
Label contentsCompare(env);
Label lenEqualOneCheck(env);
Label lenIsOne(env);
Branch(Int32Equal(ZExtInt1ToInt32(IsUtf16String(left)), ZExtInt1ToInt32(IsUtf16String(right))),
&lengthCompare, &exit);
Bind(&lengthCompare);
Branch(Int32Equal(GetLengthFromString(left), GetLengthFromString(right)), &lenEqualOneCheck, &exit);
Bind(&lenEqualOneCheck);
Branch(Int32Equal(GetLengthFromString(left), Int32(1)), &lenIsOne, &hashcodeCompare);
Bind(&lenIsOne);

View File

@ -386,7 +386,9 @@ int32_t EcmaString::LastIndexOf(const EcmaVM *vm,
}
FlatStringInfo lhs = FlattenAllString(vm, receiver);
JSHandle<EcmaString> string(vm->GetJSThread(), lhs.GetString());
FlatStringInfo rhs = FlattenAllString(vm, search);
lhs.SetString(*string);
if (rhs.IsUtf8() && lhs.IsUtf8()) {
Span<const uint8_t> lhsSp(lhs.GetDataUtf8(), lhsCount);
Span<const uint8_t> rhsSp(rhs.GetDataUtf8(), rhsCount);
@ -469,68 +471,78 @@ bool EcmaString::EqualToSplicedString(const EcmaString *str1, const EcmaString *
return false;
}
if (IsUtf16()) {
if (str1->IsUtf8() && str2->IsUtf8()) {
return false;
}
CVector<uint16_t> 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 {
if (str1->IsUtf16() || str2->IsUtf16()) {
return false;
}
CVector<uint8_t> buf;
const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf);
CVector<uint8_t> bufStr1;
const uint8_t *dataStr1 = EcmaString::GetUtf8DataFlat(str1, bufStr1);
Span<const uint8_t> concatData(data, str1->GetLength());
Span<const uint8_t> data1(dataStr1, str1->GetLength());
if (EcmaString::StringsAreEquals(concatData, data1)) {
concatData = Span<const uint8_t>(data + str1->GetLength(), str2->GetLength());
CVector<uint8_t> bufStr2;
const uint8_t *dataStr2 = EcmaString::GetUtf8DataFlat(str2, bufStr2);
Span<const uint8_t> data2(dataStr2, str2->GetLength());
return EcmaString::StringsAreEquals(concatData, data2);
if (EcmaString::StringsAreEqualUtf8(str1, data, str1->GetLength(), this->IsUtf8())) {
return EcmaString::StringsAreEqualUtf8(str2, data + str1->GetLength(), str2->GetLength(), this->IsUtf8());
}
}
return false;
}
/* static */
bool EcmaString::StringsAreEqualSameUtfEncoding(EcmaString *str1, EcmaString *str2)
bool EcmaString::StringsAreEqualDiffUtfEncoding(EcmaString *left, EcmaString *right)
{
if (str1->IsUtf16()) {
CVector<uint16_t> buf1;
CVector<uint16_t> buf2;
const uint16_t *data1 = EcmaString::GetUtf16DataFlat(str1, buf1);
const uint16_t *data2 = EcmaString::GetUtf16DataFlat(str2, buf2);
Span<const uint16_t> sp1(data1, str1->GetLength());
Span<const uint16_t> sp2(data2, str2->GetLength());
return EcmaString::StringsAreEquals(sp1, sp2);
} else { // NOLINT(readability-else-after-return)
CVector<uint8_t> buf1;
CVector<uint8_t> buf2;
const uint8_t *data1 = EcmaString::GetUtf8DataFlat(str1, buf1);
const uint8_t *data2 = EcmaString::GetUtf8DataFlat(str2, buf2);
Span<const uint8_t> sp1(data1, str1->GetLength());
Span<const uint8_t> sp2(data2, str2->GetLength());
return EcmaString::StringsAreEquals(sp1, sp2);
CVector<uint16_t> bufLeftUft16;
CVector<uint16_t> bufRightUft16;
CVector<uint8_t> bufLeftUft8;
CVector<uint8_t> bufRightUft8;
int32_t lhsCount = static_cast<int32_t>(left->GetLength());
int32_t rhsCount = static_cast<int32_t>(right->GetLength());
if (!left->IsUtf16() && !right->IsUtf16()) {
const uint8_t *data1 = EcmaString::GetUtf8DataFlat(left, bufLeftUft8);
const uint8_t *data2 = EcmaString::GetUtf8DataFlat(right, bufRightUft8);
Span<const uint8_t> lhsSp(data1, lhsCount);
Span<const uint8_t> 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<const uint8_t> lhsSp(data1, lhsCount);
Span<const uint16_t> 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<const uint16_t> lhsSp(data1, lhsCount);
Span<const uint8_t> 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<const uint16_t> lhsSp(data1, lhsCount);
Span<const uint16_t> rhsSp(data2, rhsCount);
return EcmaString::StringsAreEquals(lhsSp, rhsSp);
}
}
/* static */
bool EcmaString::StringsAreEqualSameUtfEncoding(const FlatStringInfo &str1, const FlatStringInfo &str2)
bool EcmaString::StringsAreEqualDiffUtfEncoding(const FlatStringInfo &left, const FlatStringInfo &right)
{
if (str1.IsUtf16()) {
Span<const uint16_t> sp1(str1.GetDataUtf16(), str1.GetLength());
Span<const uint16_t> sp2(str2.GetDataUtf16(), str2.GetLength());
return EcmaString::StringsAreEquals(sp1, sp2);
} else { // NOLINT(readability-else-after-return)
Span<const uint8_t> sp1(str1.GetDataUtf8(), str1.GetLength());
Span<const uint8_t> sp2(str2.GetDataUtf8(), str2.GetLength());
return EcmaString::StringsAreEquals(sp1, sp2);
int32_t lhsCount = static_cast<int32_t>(left.GetLength());
int32_t rhsCount = static_cast<int32_t>(right.GetLength());
if (!left.IsUtf16() && !right.IsUtf16()) {
Span<const uint8_t> lhsSp(left.GetDataUtf8(), lhsCount);
Span<const uint8_t> rhsSp(right.GetDataUtf8(), rhsCount);
return EcmaString::StringsAreEquals(lhsSp, rhsSp);
} else if (!left.IsUtf16()) {
Span<const uint8_t> lhsSp(left.GetDataUtf8(), lhsCount);
Span<const uint16_t> rhsSp(right.GetDataUtf16(), rhsCount);
return EcmaString::StringsAreEquals(lhsSp, rhsSp);
} else if (!right.IsUtf16()) {
Span<const uint16_t> lhsSp(left.GetDataUtf16(), rhsCount);
Span<const uint8_t> rhsSp(right.GetDataUtf8(), lhsCount);
return EcmaString::StringsAreEquals(lhsSp, rhsSp);
} else {
Span<const uint16_t> lhsSp(left.GetDataUtf16(), lhsCount);
Span<const uint16_t> rhsSp(right.GetDataUtf16(), rhsCount);
return EcmaString::StringsAreEquals(lhsSp, rhsSp);
}
}
@ -539,9 +551,6 @@ bool EcmaString::StringsAreEqual(const EcmaVM *vm, const JSHandle<EcmaString> &s
if (str1 == str2) {
return true;
}
if (str1->IsUtf16() != str2->IsUtf16()) {
return false;
}
uint32_t str1Len = str1->GetLength();
if (str1Len != str2->GetLength()) {
return false;
@ -561,7 +570,7 @@ bool EcmaString::StringsAreEqual(const EcmaVM *vm, const JSHandle<EcmaString> &s
JSHandle<EcmaString> string(vm->GetJSThread(), str1Flat.GetString());
FlatStringInfo str2Flat = FlattenAllString(vm, str2);
str1Flat.SetString(*string);
return StringsAreEqualSameUtfEncoding(str1Flat, str2Flat);
return StringsAreEqualDiffUtfEncoding(str1Flat, str2Flat);
}
/* static */
@ -570,9 +579,6 @@ bool EcmaString::StringsAreEqual(EcmaString *str1, EcmaString *str2)
if (str1 == str2) {
return true;
}
if (str1->IsUtf16() != str2->IsUtf16()) {
return false;
}
uint32_t str1Len = str1->GetLength();
if (str1Len != str2->GetLength()) {
return false;
@ -588,20 +594,20 @@ bool EcmaString::StringsAreEqual(EcmaString *str1, EcmaString *str2)
return false;
}
}
return StringsAreEqualSameUtfEncoding(str1, str2);
return StringsAreEqualDiffUtfEncoding(str1, str2);
}
/* static */
bool EcmaString::StringsAreEqualUtf8(const EcmaString *str1, const uint8_t *utf8Data, uint32_t utf8Len,
bool canBeCompress)
{
if (canBeCompress != str1->IsUtf8()) {
if (!str1->IsSlicedString() && canBeCompress != str1->IsUtf8()) {
return false;
}
if (canBeCompress && str1->GetLength() != utf8Len) {
return false;
}
if (canBeCompress) {
if (str1->IsUtf8()) {
CVector<uint8_t> buf;
Span<const uint8_t> data1(EcmaString::GetUtf8DataFlat(str1, buf), utf8Len);
Span<const uint8_t> data2(utf8Data, utf8Len);

View File

@ -207,14 +207,16 @@ private:
// Check that two spans are equal. Should have the same length.
/* static */
template<typename T>
static bool StringsAreEquals(Span<const T> &str1, Span<const T> &str2)
template<typename T, typename T1>
static bool StringsAreEquals(Span<const T> &str1, Span<const T1> &str2)
{
ASSERT(str1.Size() <= str2.Size());
size_t size = str1.Size();
if (size < SMALL_STRING_SIZE) {
if (size < SMALL_STRING_SIZE || !std::is_same_v<T, T1>) {
for (size_t i = 0; i < size; i++) {
if (str1[i] != str2[i]) {
auto left = static_cast<int32_t>(str1[i]);
auto right = static_cast<int32_t>(str2[i]);
if (left != right) {
return false;
}
}
@ -233,8 +235,8 @@ private:
// Compares strings by bytes, It doesn't check canonical unicode equivalence.
static bool StringsAreEqual(EcmaString *str1, EcmaString *str2);
// Two strings have the same type of utf encoding format.
static bool StringsAreEqualSameUtfEncoding(EcmaString *str1, EcmaString *str2);
static bool StringsAreEqualSameUtfEncoding(const FlatStringInfo &str1, const FlatStringInfo &str2);
static bool StringsAreEqualDiffUtfEncoding(EcmaString *str1, EcmaString *str2);
static bool StringsAreEqualDiffUtfEncoding(const FlatStringInfo &str1, const FlatStringInfo &str2);
// Compares strings by bytes, It doesn't check canonical unicode equivalence.
// not change str1 data structure.
// if str1 is not flat, this func has low efficiency.
@ -1101,9 +1103,9 @@ public:
// not change str1 and str2 data structure.
// if str1 or str2 is not flat, this func has low efficiency.
static bool StringsAreEqualSameUtfEncoding(EcmaString *str1, EcmaString *str2)
static bool StringsAreEqualDiffUtfEncoding(EcmaString *str1, EcmaString *str2)
{
return EcmaString::StringsAreEqualSameUtfEncoding(str1, str2);
return EcmaString::StringsAreEqualDiffUtfEncoding(str1, str2);
}
// not change str1 data structure.

View File

@ -2075,7 +2075,7 @@ DEF_RUNTIME_STUBS(StringEqual)
EcmaVM *vm = thread->GetEcmaVM();
left = JSHandle<EcmaString>(thread, EcmaStringAccessor::Flatten(vm, left));
right = JSHandle<EcmaString>(thread, EcmaStringAccessor::Flatten(vm, right));
if (EcmaStringAccessor::StringsAreEqualSameUtfEncoding(*left, *right)) {
if (EcmaStringAccessor::StringsAreEqualDiffUtfEncoding(*left, *right)) {
return JSTaggedValue::VALUE_TRUE;
}
return JSTaggedValue::VALUE_FALSE;
@ -2298,7 +2298,7 @@ void RuntimeStubs::StoreBarrier([[maybe_unused]] uintptr_t argGlue,
bool RuntimeStubs::StringsAreEquals(EcmaString *str1, EcmaString *str2)
{
return EcmaStringAccessor::StringsAreEqualSameUtfEncoding(str1, str2);
return EcmaStringAccessor::StringsAreEqualDiffUtfEncoding(str1, str2);
}
bool RuntimeStubs::BigIntEquals(JSTaggedType left, JSTaggedType right)

View File

@ -17,7 +17,11 @@ true
true
false
Invalid string length
19981
肯访华:
20170
吃什么:
djdjsajkdfalddgetg
wode
wode1
true
true

View File

@ -19,8 +19,8 @@
* @tc.type: FUNC
* @tc.require: issueI5NO8G
*/
let tmp = '不林肯访华:习近平会晤美国国务卿促让中美关系稳下来好起来美国国务卿安东尼于6月1日于北京与习近平会大杂烩中国都五年来首位访华\
美国国务卿王刚说,你吵的菜安倍晋三吃了赞不绝口,但是王毅不喜欢,他接到一个快递单号为#nsExpress3SF#123456789的包裹';
let tmp = '今天吃什么:告诉了会晤今天吃什么促让今天吃什么下来好起来今天吃今天吃什么于6月1日于北京今天吃什么大杂烩中国都五年来首位访华\
今天吃什么王刚说,你吵的菜今天吃什么了赞不绝口,但是今天吃什么,他接到一个快递单号为#nsExpress3SF#123456789的包裹';
let flag = tmp;
let str1 = tmp.substring(0, 111) + ',,,,,,,,,,,,,,,,,,,,,,,' + tmp.substring(111 + 23);
let str2 = tmp.substring(0, 111) + 'nsExpress3SF#123456789的' + tmp.substring(111 + 23,111 + 24) + '需';
@ -51,4 +51,20 @@ let string2 = string1.substring(1);
print(str1.charAt());
print(str2.charCodeAt());
print(str1.substr(2, 4));
print(string2.toLowerCase(2, 4));
print(string2.toLowerCase(2, 4));
let tmp1 = '今天吃什么:哈哈哈会晤美国phonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatform国务卿促让今天吃什么下来好起来今天吃今天吃什么于6月1日于北京今天吃什么面大杂烩中国都五年来首位访华\
的今天吃什么王刚说,你吵的菜今天吃什么了赞不绝口,但是今天吃什么吃,他接到一个快递单号为#nsExpress3SF#123456789的包裹';
let flag1 = tmp1;
let str = tmp1.substring(13, 143);
let str4 = tmp1.substring(13, 26);
let str5 = "phonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatform";
let str6 = "phonePlatform";
var obj = {phonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatformphonePlatform: "wode",
phonePlatform: "wode1"};
print(obj[str]);
print(obj[str4]);
print((str === str5).toString());
print((str4 == str6).toString());