mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
Bugfix on EcmaString::CreateTreeString create long ecmaString
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7R95U Signed-off-by: quiet-thought <chenjingxiang1@huawei.com> Change-Id: Iaebdd8f8fa998b10124894e61a304b6957b11f57
This commit is contained in:
parent
a9538dd60f
commit
8e3717baf4
@ -927,8 +927,12 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv)
|
||||
auto thisLen = EcmaStringAccessor(thisString).GetLength();
|
||||
JSHandle<EcmaString> suffixString(thread,
|
||||
EcmaStringAccessor::FastSubString(ecmaVm, thisString, tailPos, thisLen - tailPos));
|
||||
JSHandle<EcmaString> tempString(thread, EcmaStringAccessor::Concat(ecmaVm, prefixString, realReplaceStr));
|
||||
return JSTaggedValue(EcmaStringAccessor::Concat(ecmaVm, tempString, suffixString));
|
||||
EcmaString *tempStr = EcmaStringAccessor::Concat(ecmaVm, prefixString, realReplaceStr);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<EcmaString> tempString(thread, tempStr);
|
||||
EcmaString *resultStr = EcmaStringAccessor::Concat(ecmaVm, tempString, suffixString);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(resultStr);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsString::ReplaceAll(EcmaRuntimeCallInfo *argv)
|
||||
|
@ -154,6 +154,7 @@ inline EcmaString *EcmaString::CreateConstantString(const EcmaVM *vm, const uint
|
||||
inline EcmaString *EcmaString::CreateTreeString(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right, uint32_t length, bool compressed)
|
||||
{
|
||||
ECMA_STRING_CHECK_LENGTH_AND_TRHOW(vm, length);
|
||||
auto thread = vm->GetJSThread();
|
||||
auto string = TreeEcmaString::Cast(vm->GetFactory()->AllocTreeStringObject());
|
||||
string->SetLength(length, compressed);
|
||||
|
@ -43,12 +43,19 @@ class LineEcmaString;
|
||||
class ConstantString;
|
||||
class TreeEcmaString;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ECMA_STRING_CHECK_LENGTH_AND_TRHOW(vm, length) \
|
||||
if ((length) >= MAX_STRING_LENGTH) { \
|
||||
THROW_RANGE_ERROR_AND_RETURN((vm)->GetJSThread(), "Invalid string length", nullptr); \
|
||||
}
|
||||
|
||||
class EcmaString : public TaggedObject {
|
||||
public:
|
||||
CAST_CHECK(EcmaString, IsString);
|
||||
|
||||
static constexpr uint32_t STRING_COMPRESSED_BIT = 0x1;
|
||||
static constexpr uint32_t STRING_INTERN_BIT = 0x2;
|
||||
static constexpr size_t MAX_STRING_LENGTH = 0x40000000U; // 30 bits for string length, 2 bits for special meaning
|
||||
|
||||
static constexpr size_t MIX_LENGTH_OFFSET = TaggedObjectSize();
|
||||
// In last bit of mix_length we store if this string is compressed or not.
|
||||
@ -130,7 +137,7 @@ private:
|
||||
|
||||
void SetLength(uint32_t length, bool compressed = false)
|
||||
{
|
||||
ASSERT(length < 0x40000000U);
|
||||
ASSERT(length < MAX_STRING_LENGTH);
|
||||
// Use 0u for compressed/utf8 expression
|
||||
SetMixLength((length << 2U) | (compressed ? STRING_COMPRESSED : STRING_UNCOMPRESSED));
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
JSHandle<EcmaString> stringA0 = JSHandle<EcmaString>(JSHandle<JSTaggedValue>(thread, left));
|
||||
JSHandle<EcmaString> stringA1 = JSHandle<EcmaString>(JSHandle<JSTaggedValue>(thread, right));
|
||||
EcmaString *ret = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(ret);
|
||||
}
|
||||
// Support cases, such as: string + null, string + object, string + boolean, string + number, etc.
|
||||
@ -79,12 +80,14 @@ public:
|
||||
JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, rightValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
EcmaString *ret = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(ret);
|
||||
} else {
|
||||
JSHandle<EcmaString> stringA0 = JSTaggedValue::ToString(thread, leftValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<EcmaString> stringA1 = JSHandle<EcmaString>(rightValue);
|
||||
EcmaString *ret = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(ret);
|
||||
}
|
||||
}
|
||||
|
@ -1466,8 +1466,10 @@ JSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTagge
|
||||
const JSHandle<JSTaggedValue> &right)
|
||||
{
|
||||
if (left->IsString() && right->IsString()) {
|
||||
return JSTaggedValue(EcmaStringAccessor::Concat(
|
||||
thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right)));
|
||||
EcmaString *resultStr = EcmaStringAccessor::Concat(
|
||||
thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(resultStr);
|
||||
}
|
||||
JSHandle<JSTaggedValue> primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, left));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -1479,7 +1481,9 @@ JSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTagge
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, primitiveA1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1));
|
||||
EcmaString *resultStr = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return JSTaggedValue(resultStr);
|
||||
}
|
||||
JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, primitiveA0);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf8)
|
||||
{
|
||||
uint32_t scale = 3333;
|
||||
for (uint32_t i = 0x40000000U - 1; i > scale; i = i - scale) {
|
||||
for (uint32_t i = EcmaString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) {
|
||||
uint32_t length = i;
|
||||
EXPECT_EQ(LineEcmaString::ComputeSizeUtf8(length), length + LineEcmaString::SIZE);
|
||||
}
|
||||
@ -71,7 +71,7 @@ HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf8)
|
||||
HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf16)
|
||||
{
|
||||
uint32_t scale = 3333;
|
||||
for (uint32_t i = 0x40000000U - 1; i > scale; i = i - scale) {
|
||||
for (uint32_t i = EcmaString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) {
|
||||
uint32_t length = i;
|
||||
EXPECT_EQ(LineEcmaString::ComputeSizeUtf16(length), 2 * length + LineEcmaString::SIZE);
|
||||
}
|
||||
|
@ -16,3 +16,4 @@ false
|
||||
true
|
||||
true
|
||||
false
|
||||
Invalid string length
|
||||
|
@ -34,4 +34,15 @@ let utf81 = '1231246334765963428744656876534423435679865345567889986574643532345
|
||||
let utf82 = utf81.substring(0, 169) + '8';
|
||||
let utf83 = utf81.substring(0, 169) + '0';
|
||||
print((utf81 === utf82).toString());
|
||||
print((utf81 === utf83).toString());
|
||||
print((utf81 === utf83).toString());
|
||||
|
||||
function foo(a) {
|
||||
return a;
|
||||
}
|
||||
try {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
foo += foo;
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.message);
|
||||
}
|
Loading…
Reference in New Issue
Block a user