1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef ECMA_TEST_COMMON_H 16 #define ECMA_TEST_COMMON_H 17 #include <functional> 18 #include "ecmascript/containers/containers_private.h" 19 #include "ecmascript/ecma_string-inl.h" 20 #include "ecmascript/global_env.h" 21 #include "ecmascript/js_date_time_format.h" 22 #include "ecmascript/js_tagged_value.h" 23 #include "ecmascript/object_factory.h" 24 #include "ecmascript/tagged_tree.h" 25 #include "ecmascript/tests/ecma_container_common.h" 26 #include "ecmascript/tests/test_common.h" 27 28 namespace panda::test { 29 30 using namespace panda; 31 using namespace panda::ecmascript; 32 using ecmascript::base::BuiltinsBase; 33 34 constexpr uint32_t g_numberFive = 5; 35 constexpr uint32_t g_numberNine = 9; 36 constexpr uint32_t g_nintyNine = 99; 37 constexpr uint32_t g_hundred = 100; 38 constexpr uint32_t g_hundredAndOne = 101; 39 static uint8_t g_arrayFrontU8[] = {"abcdef"}; 40 static uint32_t g_lenFrontU8 = sizeof(g_arrayFrontU8) - 1; 41 42 class EcmaTestCommon { 43 public: 44 using CreateStringFunc = 45 std::function<EcmaString *(const EcmaVM *vm, const uint8_t *utf8Data, size_t length, bool canBeCompress)>; 46 using CreateStringUtf16Func = 47 std::function<EcmaString *(const EcmaVM *vm, const uint16_t *utf8Data, size_t length, bool canBeCompress)>; 48 using StringAreEqualUtf16Func = 49 std::function<bool(JSThread*, const EcmaString *str1, const uint16_t *utf16Data, uint32_t utf16Len)>; 50 using StringIsEqualUint8Func = 51 std::function<bool(JSThread*, const EcmaString *str1, const uint8_t *dataAddr, 52 uint32_t dataLen, bool canBeCompress)>; 53 using Compare = 54 std::function<int32_t(const EcmaVM *vm, const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right)>; 55 ConcatCommonCase2(JSThread * thread,const EcmaVM * instance)56 static void ConcatCommonCase2(JSThread *thread, const EcmaVM *instance) 57 { 58 uint16_t arrayBackU16NotComp[] = {88, 768, 1, 270, 345, 333}; 59 uint32_t lengthEcmaStrBackU16NotComp = sizeof(arrayBackU16NotComp) / sizeof(arrayBackU16NotComp[0]); 60 61 EcmaString *ecmaFrontU8 = EcmaStringAccessor::CreateFromUtf8(instance, &g_arrayFrontU8[0], g_lenFrontU8, true); 62 JSHandle<EcmaString> handleEcmaStrFrontU8(thread, ecmaFrontU8); 63 JSHandle<EcmaString> handleEcmaStrBackU16NotComp( 64 thread, 65 EcmaStringAccessor::CreateFromUtf16(instance, &arrayBackU16NotComp[0], lengthEcmaStrBackU16NotComp, false)); 66 JSHandle<EcmaString> handleEcmaStrConcatU8U16NotComp( 67 thread, EcmaStringAccessor::Concat(instance, handleEcmaStrFrontU8, handleEcmaStrBackU16NotComp)); 68 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrConcatU8U16NotComp).IsUtf16()); 69 for (uint32_t i = 0; i < g_lenFrontU8; i++) { 70 EXPECT_EQ(EcmaStringAccessor(handleEcmaStrConcatU8U16NotComp).Get(thread, i), g_arrayFrontU8[i]); 71 } 72 for (uint32_t i = 0; i < lengthEcmaStrBackU16NotComp; i++) { 73 EXPECT_EQ(EcmaStringAccessor(handleEcmaStrConcatU8U16NotComp).Get(thread, i + g_lenFrontU8), 74 arrayBackU16NotComp[i]); 75 } 76 EXPECT_EQ(EcmaStringAccessor(handleEcmaStrConcatU8U16NotComp).GetLength(), 77 g_lenFrontU8 + lengthEcmaStrBackU16NotComp); 78 } 79 FastSubStringCommonCase(JSThread * thread,const EcmaVM * instance,std::vector<uint8_t> & data,CreateStringFunc createStringFunc)80 static void FastSubStringCommonCase(JSThread *thread, const EcmaVM *instance, std::vector<uint8_t> &data, 81 CreateStringFunc createStringFunc) 82 { 83 EcmaString *frontEcmaStr = createStringFunc(instance, data.data(), data.size(), true); 84 JSHandle<EcmaString> handleEcmaStrU8(thread, frontEcmaStr); 85 uint32_t indexStartSubU8 = 2; // 2: sub index 86 uint32_t lengthSubU8 = 2; // 2: length 87 JSHandle<EcmaString> handleEcmaStrSubU8( 88 thread, EcmaStringAccessor::FastSubString(instance, handleEcmaStrU8, indexStartSubU8, lengthSubU8)); 89 for (uint32_t i = 0; i < lengthSubU8; i++) { 90 EXPECT_EQ(EcmaStringAccessor(handleEcmaStrSubU8).Get(thread, i), 91 EcmaStringAccessor(handleEcmaStrU8).Get(thread, i + indexStartSubU8)); 92 } 93 EXPECT_EQ(EcmaStringAccessor(handleEcmaStrSubU8).GetLength(), lengthSubU8); 94 } 95 IndexOfCommonCase(JSThread * thread,const EcmaVM * instance,std::vector<uint16_t> & dataU16,std::vector<uint8_t> & dataU8,CreateStringFunc createStringFunc)96 static void IndexOfCommonCase(JSThread *thread, const EcmaVM *instance, std::vector<uint16_t> &dataU16, 97 std::vector<uint8_t> &dataU8, CreateStringFunc createStringFunc) 98 { 99 JSHandle<EcmaString> ecmaU16( 100 thread, EcmaStringAccessor::CreateFromUtf16(instance, dataU16.data(), dataU16.size(), true)); 101 102 EcmaString *ecmaStr = createStringFunc(instance, dataU8.data(), dataU8.size(), true); 103 JSHandle<EcmaString> ecmaU8(thread, ecmaStr); 104 105 int32_t posStart = 0; 106 EXPECT_EQ(EcmaStringAccessor::IndexOf(instance, ecmaU8, ecmaU16, posStart), 3); // 3: value 107 EXPECT_EQ(EcmaStringAccessor::IndexOf(instance, ecmaU16, ecmaU8, posStart), -1); 108 posStart = -1; 109 EXPECT_EQ(EcmaStringAccessor::IndexOf(instance, ecmaU8, ecmaU16, posStart), 3); // 3: value 110 posStart = 1; 111 EXPECT_EQ(EcmaStringAccessor::IndexOf(instance, ecmaU8, ecmaU16, posStart), 3); // 3: value 112 posStart = 3; // 3: pos start 113 EXPECT_EQ(EcmaStringAccessor::IndexOf(instance, ecmaU8, ecmaU16, posStart), 3); // 3: value 114 posStart = 4; // 4: pos start 115 EXPECT_EQ(EcmaStringAccessor::IndexOf(instance, ecmaU8, ecmaU16, posStart), -1); 116 } 117 StringIsEqualCommonCase(JSThread * thread,const EcmaVM * instance,StringIsEqualUint8Func stringIsEqualFunc)118 static void StringIsEqualCommonCase(JSThread *thread, const EcmaVM *instance, 119 StringIsEqualUint8Func stringIsEqualFunc) 120 { 121 uint8_t arrayU8No1[4] = {45, 92, 78}; 122 uint16_t arrayU16NotCompNo1[] = {45, 92, 78}; 123 uint16_t arrayU16NotCompNo2[] = {45, 92, 78, 24}; 124 uint16_t arrayU16NotCompNo3[] = {45, 92}; 125 uint16_t arrayU16NotCompNo4[] = {25645, 25692, 25678}; 126 uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; 127 uint32_t lengthEcmaStrU16NotCompNo1 = sizeof(arrayU16NotCompNo1) / sizeof(arrayU16NotCompNo1[0]); 128 uint32_t lengthEcmaStrU16NotCompNo2 = sizeof(arrayU16NotCompNo2) / sizeof(arrayU16NotCompNo2[0]); 129 uint32_t lengthEcmaStrU16NotCompNo3 = sizeof(arrayU16NotCompNo3) / sizeof(arrayU16NotCompNo3[0]); 130 uint32_t lengthEcmaStrU16NotCompNo4 = sizeof(arrayU16NotCompNo4) / sizeof(arrayU16NotCompNo4[0]); 131 JSHandle<EcmaString> handleEcmaStrU16NotCompNo1( 132 thread, 133 EcmaStringAccessor::CreateFromUtf16(instance, &arrayU16NotCompNo1[0], lengthEcmaStrU16NotCompNo1, true)); 134 JSHandle<EcmaString> handleEcmaStrU16NotCompNo2( 135 thread, 136 EcmaStringAccessor::CreateFromUtf16(instance, &arrayU16NotCompNo2[0], lengthEcmaStrU16NotCompNo2, true)); 137 JSHandle<EcmaString> handleEcmaStrU16NotCompNo3( 138 thread, 139 EcmaStringAccessor::CreateFromUtf16(instance, &arrayU16NotCompNo3[0], lengthEcmaStrU16NotCompNo3, true)); 140 JSHandle<EcmaString> handleEcmaStrU16NotCompNo4( 141 thread, 142 EcmaStringAccessor::CreateFromUtf16(instance, &arrayU16NotCompNo4[0], lengthEcmaStrU16NotCompNo4, false)); 143 EXPECT_FALSE(stringIsEqualFunc(thread, *handleEcmaStrU16NotCompNo1, &arrayU8No1[0], lengthEcmaStrU8No1, false)); 144 EXPECT_TRUE(stringIsEqualFunc(thread, *handleEcmaStrU16NotCompNo1, &arrayU8No1[0], lengthEcmaStrU8No1, true)); 145 EXPECT_FALSE(stringIsEqualFunc(thread, *handleEcmaStrU16NotCompNo2, &arrayU8No1[0], lengthEcmaStrU8No1, false)); 146 EXPECT_FALSE(stringIsEqualFunc(thread, *handleEcmaStrU16NotCompNo3, &arrayU8No1[0], lengthEcmaStrU8No1, false)); 147 EXPECT_FALSE(stringIsEqualFunc(thread, *handleEcmaStrU16NotCompNo4, &arrayU8No1[0], lengthEcmaStrU8No1, false)); 148 } 149 TryLowerCommonCase(JSThread * thread,const EcmaVM * instance,JSHandle<EcmaString> & lowerStr,std::vector<JSHandle<EcmaString>> caseStrings)150 static void TryLowerCommonCase(JSThread *thread, const EcmaVM *instance, JSHandle<EcmaString> &lowerStr, 151 std::vector<JSHandle<EcmaString>> caseStrings) 152 { 153 { 154 JSHandle<EcmaString> lowerEcmaString(thread, EcmaStringAccessor::TryToLower(instance, lowerStr)); 155 EXPECT_TRUE(JSTaggedValue::SameValue(thread, lowerStr.GetTaggedValue(), lowerEcmaString.GetTaggedValue())); 156 EXPECT_EQ(EcmaStringAccessor(lowerStr).GetLength(), EcmaStringAccessor(lowerEcmaString).GetLength()); 157 EXPECT_TRUE(EcmaStringAccessor(lowerEcmaString).IsUtf8()); 158 EXPECT_FALSE(EcmaStringAccessor(lowerEcmaString).IsUtf16()); 159 } 160 161 for (size_t i = 0; i < caseStrings.size(); i++) { 162 JSHandle<EcmaString> lowerEcmaString(thread, EcmaStringAccessor::TryToLower(instance, caseStrings[i])); 163 EXPECT_TRUE(JSTaggedValue::SameValue(thread, lowerStr.GetTaggedValue(), lowerEcmaString.GetTaggedValue())); 164 EXPECT_EQ(EcmaStringAccessor(lowerStr).GetLength(), EcmaStringAccessor(lowerEcmaString).GetLength()); 165 EXPECT_TRUE(EcmaStringAccessor(lowerEcmaString).IsUtf8()); 166 EXPECT_FALSE(EcmaStringAccessor(lowerEcmaString).IsUtf16()); 167 } 168 } 169 CompareCommonCase(JSThread * thread,const EcmaVM * instance,CreateStringFunc createUtf8,CreateStringUtf16Func createUtf16,Compare compare)170 static void CompareCommonCase(JSThread *thread, const EcmaVM *instance, CreateStringFunc createUtf8, 171 CreateStringUtf16Func createUtf16, Compare compare) 172 { 173 // Compare(). EcmaString made by CreateFromUtf8() and EcmaString made by CreateFromUtf16( , , , true). 174 uint8_t arrayU8No1[3] = {1, 23}; 175 uint8_t arrayU8No2[4] = {1, 23, 49}; 176 uint16_t arrayU16CompNo1[] = {1, 23}; 177 uint16_t arrayU16CompNo2[] = {1, 23, 49}; 178 uint16_t arrayU16CompNo3[] = {1, 23, 45, 97, 127}; 179 uint32_t lengthEcmaStrU8No1 = sizeof(arrayU8No1) - 1; 180 uint32_t lengthEcmaStrU8No2 = sizeof(arrayU8No2) - 1; 181 uint32_t lengthEcmaStrU16CompNo1 = sizeof(arrayU16CompNo1) / sizeof(arrayU16CompNo1[0]); 182 uint32_t lengthEcmaStrU16CompNo2 = sizeof(arrayU16CompNo2) / sizeof(arrayU16CompNo2[0]); 183 uint32_t lengthEcmaStrU16CompNo3 = sizeof(arrayU16CompNo3) / sizeof(arrayU16CompNo3[0]); 184 JSHandle<EcmaString> handleEcmaStrU8No1(thread, createUtf8(instance, &arrayU8No1[0], lengthEcmaStrU8No1, true)); 185 JSHandle<EcmaString> handleEcmaStrU8No2(thread, createUtf8(instance, &arrayU8No2[0], lengthEcmaStrU8No2, true)); 186 JSHandle<EcmaString> handleEcmaStrU16CompNo1( 187 thread, createUtf16(instance, &arrayU16CompNo1[0], lengthEcmaStrU16CompNo1, true)); 188 JSHandle<EcmaString> handleEcmaStrU16CompNo2( 189 thread, createUtf16(instance, &arrayU16CompNo2[0], lengthEcmaStrU16CompNo2, true)); 190 JSHandle<EcmaString> handleEcmaStrU16CompNo3( 191 thread, createUtf16(instance, &arrayU16CompNo3[0], lengthEcmaStrU16CompNo3, true)); 192 EXPECT_EQ(compare(instance, handleEcmaStrU8No1, handleEcmaStrU16CompNo1), 0); 193 EXPECT_EQ(compare(instance, handleEcmaStrU16CompNo1, handleEcmaStrU8No1), 0); 194 EXPECT_EQ(compare(instance, handleEcmaStrU8No1, handleEcmaStrU16CompNo2), -1); 195 EXPECT_EQ(compare(instance, handleEcmaStrU16CompNo2, handleEcmaStrU8No1), 1); 196 EXPECT_EQ(compare(instance, handleEcmaStrU8No2, handleEcmaStrU16CompNo3), 49 - 45); // 49: value, 45: value 197 EXPECT_EQ(compare(instance, handleEcmaStrU16CompNo3, handleEcmaStrU8No2), 45 - 49); // 49: value, 45: value 198 } 199 200 static void GcCommonCase(JSThread *thread, Heap *heap, bool nonMovable = true) 201 { 202 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 203 size_t oldNativeSize = heap->GetNativeBindingSize(); 204 size_t newNativeSize = heap->GetNativeBindingSize(); 205 constexpr int32_t nums = 1024; 206 { 207 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 208 auto newData = thread->GetEcmaVM()->GetNativeAreaAllocator()->AllocateBuffer(1 * nums * nums); 209 [[maybe_unused]] JSHandle<JSNativePointer> obj = factory->NewJSNativePointer( 210 newData, NativeAreaAllocator::FreeBufferFunc, nullptr, nonMovable, 1 * nums * nums); 211 newNativeSize = heap->GetNativeBindingSize(); 212 EXPECT_EQ(newNativeSize - oldNativeSize, 1UL * nums * nums); 213 auto newData1 = thread->GetEcmaVM()->GetNativeAreaAllocator()->AllocateBuffer(1 * nums * nums); 214 [[maybe_unused]] JSHandle<JSNativePointer> obj2 = factory->NewJSNativePointer( 215 newData1, NativeAreaAllocator::FreeBufferFunc, nullptr, false, 1 * nums * nums); 216 217 EXPECT_TRUE(newNativeSize - oldNativeSize > 0); 218 EXPECT_TRUE(newNativeSize - oldNativeSize <= 2 * nums * nums); // 2: value 219 for (int i = 0; i < 2048; i++) { // 2048: loop count 220 [[maybe_unused]] ecmascript::EcmaHandleScope baseScopeForeach(thread); 221 auto newData2 = thread->GetEcmaVM()->GetNativeAreaAllocator()->AllocateBuffer(1 * nums); 222 // malloc size is smaller to avoid test fail in the small devices. 223 [[maybe_unused]] JSHandle<JSNativePointer> obj3 = factory->NewJSNativePointer( 224 newData2, NativeAreaAllocator::FreeBufferFunc, nullptr, true, 1 * nums * nums); 225 } 226 newNativeSize = heap->GetNativeBindingSize(); 227 // Old GC should be trigger here, so the size should be reduced. 228 EXPECT_TRUE(newNativeSize - oldNativeSize < 2048 * nums * nums); // 2048: value 229 } 230 } 231 GcCommonCase(JSThread * thread)232 static size_t GcCommonCase(JSThread *thread) 233 { 234 { 235 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); 236 for (int i = 0; i < g_hundred; i++) { // g_hundred: run count 237 [[maybe_unused]] JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray( 238 10 * 1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE); // 10: value, 1024: value 239 } 240 } 241 return thread->GetEcmaVM()->GetHeap()->GetCommittedSize(); 242 } 243 244 template <class T> ListAddHasCommon(JSThread * thread,JSHandle<T> & toor,JSMutableHandle<JSTaggedValue> & value,std::string myValue,int32_t numbers)245 static void ListAddHasCommon(JSThread *thread, JSHandle<T> &toor, JSMutableHandle<JSTaggedValue> &value, 246 std::string myValue, int32_t numbers) 247 { 248 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 249 for (int32_t i = 0; i < numbers; i++) { 250 std::string ivalue = myValue + std::to_string(i); 251 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 252 253 JSTaggedValue gValue = toor->Get(thread, i); 254 EXPECT_EQ(gValue, value.GetTaggedValue()); 255 } 256 JSTaggedValue gValue = toor->Get(thread, 10); // 10: index 257 EXPECT_EQ(gValue, JSTaggedValue::Undefined()); 258 259 std::string ivalue = myValue + std::to_string(1); 260 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 261 EXPECT_TRUE(toor->Has(thread, value.GetTaggedValue())); 262 } 263 264 template <class T> ListGetLastCommon(JSThread * thread,JSHandle<T> & toor)265 static JSMutableHandle<JSTaggedValue> ListGetLastCommon(JSThread *thread, JSHandle<T> &toor) 266 { 267 constexpr uint32_t NODE_NUMBERS = 9; 268 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 269 EXPECT_EQ(toor->GetLast(thread), JSTaggedValue::Undefined()); 270 EXPECT_EQ(toor->GetFirst(thread), JSTaggedValue::Undefined()); 271 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 272 value.Update(JSTaggedValue(i + 1)); 273 T::Add(thread, toor, value); 274 } 275 EXPECT_EQ(toor->GetLast(thread).GetInt(), g_numberNine); 276 EXPECT_EQ(toor->GetFirst(thread).GetInt(), 1); 277 278 value.Update(JSTaggedValue(g_nintyNine)); 279 int len = toor->Length(thread); 280 toor->Insert(thread, toor, value, len); 281 return value; 282 } 283 284 template <class T> GetIndexOfAndGetLastIndexOfCommon(JSThread * thread,JSHandle<T> & toor)285 static void GetIndexOfAndGetLastIndexOfCommon(JSThread *thread, JSHandle<T> &toor) 286 { 287 auto value = ListGetLastCommon<T>(thread, toor); 288 EXPECT_EQ(toor->GetIndexOf(thread, value.GetTaggedValue()).GetInt(), g_numberNine); 289 EXPECT_EQ(toor->GetLastIndexOf(thread, value.GetTaggedValue()).GetInt(), g_numberNine); 290 EXPECT_EQ(toor->Length(thread), 10); // 10: len 291 292 value.Update(JSTaggedValue(g_hundred)); 293 toor->Insert(thread, toor, value, 0); 294 EXPECT_EQ(toor->GetIndexOf(thread, value.GetTaggedValue()).GetInt(), 0); 295 EXPECT_EQ(toor->GetLastIndexOf(thread, value.GetTaggedValue()).GetInt(), 0); 296 EXPECT_EQ(toor->Length(thread), 11); // 11: len 297 298 value.Update(JSTaggedValue(g_hundredAndOne)); 299 toor->Insert(thread, toor, value, g_numberFive); 300 EXPECT_EQ(toor->GetIndexOf(thread, value.GetTaggedValue()).GetInt(), g_numberFive); 301 EXPECT_EQ(toor->GetLastIndexOf(thread, value.GetTaggedValue()).GetInt(), g_numberFive); 302 EXPECT_EQ(toor->Length(thread), 12); // 12: len 303 304 toor->Dump(thread); 305 } 306 307 template <class T> InsertAndGetLastCommon(JSThread * thread,JSHandle<T> & toor)308 static void InsertAndGetLastCommon(JSThread *thread, JSHandle<T> &toor) 309 { 310 auto value = ListGetLastCommon<T>(thread, toor); 311 EXPECT_EQ(toor->GetLast(thread).GetInt(), g_nintyNine); 312 EXPECT_EQ(toor->Length(thread), 10); // 10: len 313 314 value.Update(JSTaggedValue(g_hundred)); 315 toor->Insert(thread, toor, value, 0); 316 EXPECT_EQ(toor->GetFirst(thread).GetInt(), g_hundred); 317 EXPECT_EQ(toor->Length(thread), 11); // 11: len 318 319 toor->Dump(thread); 320 321 value.Update(JSTaggedValue(g_hundredAndOne)); 322 toor->Insert(thread, toor, value, g_numberFive); 323 EXPECT_EQ(toor->Length(thread), 12); // 12: len 324 toor->Dump(thread); 325 EXPECT_EQ(toor->Get(thread, g_numberFive).GetInt(), g_hundredAndOne); 326 } 327 328 template <class T> ListRemoveCommon(JSThread * thread,JSHandle<T> & toor,JSMutableHandle<JSTaggedValue> & value)329 static void ListRemoveCommon(JSThread *thread, JSHandle<T> &toor, JSMutableHandle<JSTaggedValue> &value) 330 { 331 constexpr uint32_t NODE_NUMBERS = 20; 332 EXPECT_EQ(toor->GetLast(thread), JSTaggedValue::Undefined()); 333 EXPECT_EQ(toor->GetFirst(thread), JSTaggedValue::Undefined()); 334 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 335 value.Update(JSTaggedValue(i)); 336 T::Add(thread, toor, value); 337 } 338 EXPECT_EQ(toor->Length(thread), NODE_NUMBERS); 339 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 340 value.Update(JSTaggedValue(i)); 341 JSTaggedValue gValue = toor->Get(thread, i); 342 EXPECT_EQ(gValue, value.GetTaggedValue()); 343 } 344 } 345 SetDateOptionsTest(JSThread * thread,JSHandle<JSObject> & optionsObj,std::map<std::string,std::string> & dateOptions)346 static void SetDateOptionsTest(JSThread *thread, JSHandle<JSObject> &optionsObj, 347 std::map<std::string, std::string> &dateOptions) 348 { 349 auto factory = thread->GetEcmaVM()->GetFactory(); 350 auto globalConst = thread->GlobalConstants(); 351 // Date options keys. 352 JSHandle<JSTaggedValue> weekdayKey = globalConst->GetHandledWeekdayString(); 353 JSHandle<JSTaggedValue> yearKey = globalConst->GetHandledYearString(); 354 JSHandle<JSTaggedValue> monthKey = globalConst->GetHandledMonthString(); 355 JSHandle<JSTaggedValue> dayKey = globalConst->GetHandledDayString(); 356 // Date options values. 357 JSHandle<JSTaggedValue> weekdayValue(factory->NewFromASCII(dateOptions["weekday"].c_str())); 358 JSHandle<JSTaggedValue> yearValue(factory->NewFromASCII(dateOptions["year"].c_str())); 359 JSHandle<JSTaggedValue> monthValue(factory->NewFromASCII(dateOptions["month"].c_str())); 360 JSHandle<JSTaggedValue> dayValue(factory->NewFromASCII(dateOptions["day"].c_str())); 361 // Set date options. 362 JSObject::SetProperty(thread, optionsObj, weekdayKey, weekdayValue); 363 JSObject::SetProperty(thread, optionsObj, yearKey, yearValue); 364 JSObject::SetProperty(thread, optionsObj, monthKey, monthValue); 365 JSObject::SetProperty(thread, optionsObj, dayKey, dayValue); 366 } 367 SetTimeOptionsTest(JSThread * thread,JSHandle<JSObject> & optionsObj,std::map<std::string,std::string> & timeOptionsMap)368 static void SetTimeOptionsTest(JSThread *thread, JSHandle<JSObject> &optionsObj, 369 std::map<std::string, std::string> &timeOptionsMap) 370 { 371 auto factory = thread->GetEcmaVM()->GetFactory(); 372 auto globalConst = thread->GlobalConstants(); 373 // Time options keys. 374 JSHandle<JSTaggedValue> dayPeriodKey = globalConst->GetHandledDayPeriodString(); 375 JSHandle<JSTaggedValue> hourKey = globalConst->GetHandledHourString(); 376 JSHandle<JSTaggedValue> minuteKey = globalConst->GetHandledMinuteString(); 377 JSHandle<JSTaggedValue> secondKey = globalConst->GetHandledSecondString(); 378 JSHandle<JSTaggedValue> fractionalSecondDigitsKey = globalConst->GetHandledFractionalSecondDigitsString(); 379 // Time options values. 380 JSHandle<JSTaggedValue> dayPeriodValue(factory->NewFromASCII(timeOptionsMap["dayPeriod"].c_str())); 381 JSHandle<JSTaggedValue> hourValue(factory->NewFromASCII(timeOptionsMap["hour"].c_str())); 382 JSHandle<JSTaggedValue> minuteValue(factory->NewFromASCII(timeOptionsMap["minute"].c_str())); 383 JSHandle<JSTaggedValue> secondValue(factory->NewFromASCII(timeOptionsMap["second"].c_str())); 384 JSHandle<JSTaggedValue> fractionalSecondDigitsValue( 385 factory->NewFromASCII(timeOptionsMap["fractionalSecond"].c_str())); 386 // Set time options. 387 JSObject::SetProperty(thread, optionsObj, dayPeriodKey, dayPeriodValue); 388 JSObject::SetProperty(thread, optionsObj, hourKey, hourValue); 389 JSObject::SetProperty(thread, optionsObj, minuteKey, minuteValue); 390 JSObject::SetProperty(thread, optionsObj, secondKey, secondValue); 391 JSObject::SetProperty(thread, optionsObj, fractionalSecondDigitsKey, fractionalSecondDigitsValue); 392 } 393 CreateDateTimeFormatTest(JSThread * thread,icu::Locale icuLocale,JSHandle<JSObject> options)394 static JSHandle<JSDateTimeFormat> CreateDateTimeFormatTest(JSThread *thread, icu::Locale icuLocale, 395 JSHandle<JSObject> options) 396 { 397 auto factory = thread->GetEcmaVM()->GetFactory(); 398 399 JSHandle<JSTaggedValue> localeCtor = thread->GetEcmaVM()->GetGlobalEnv()->GetLocaleFunction(); 400 JSHandle<JSTaggedValue> dtfCtor = thread->GetEcmaVM()->GetGlobalEnv()->GetDateTimeFormatFunction(); 401 JSHandle<JSLocale> locales = 402 JSHandle<JSLocale>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(localeCtor), localeCtor)); 403 JSHandle<JSDateTimeFormat> dtf = 404 JSHandle<JSDateTimeFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dtfCtor), dtfCtor)); 405 406 JSHandle<JSTaggedValue> optionsVal = JSHandle<JSTaggedValue>::Cast(options); 407 factory->NewJSIntlIcuData(locales, icuLocale, JSLocale::FreeIcuLocale); 408 dtf = 409 JSDateTimeFormat::InitializeDateTimeFormat(thread, dtf, JSHandle<JSTaggedValue>::Cast(locales), optionsVal); 410 return dtf; 411 } 412 SetHourCycleKeyValue(JSThread * thread,std::string & cycle,std::string & zone)413 static JSHandle<JSObject> SetHourCycleKeyValue(JSThread *thread, std::string &cycle, std::string &zone) 414 { 415 auto factory = thread->GetEcmaVM()->GetFactory(); 416 JSHandle<JSTaggedValue> objFun = thread->GetEcmaVM()->GetGlobalEnv()->GetObjectFunction(); 417 JSHandle<JSObject> options = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun); 418 JSHandle<JSTaggedValue> hourCycleKey = thread->GlobalConstants()->GetHandledHourCycleString(); 419 JSHandle<JSTaggedValue> hourCycleValue(factory->NewFromASCII(cycle)); 420 JSHandle<JSTaggedValue> timeZoneKey = thread->GlobalConstants()->GetHandledTimeZoneString(); 421 JSHandle<JSTaggedValue> timeZoneValue(factory->NewFromASCII(zone)); 422 JSObject::SetProperty(thread, options, timeZoneKey, timeZoneValue); 423 JSObject::SetProperty(thread, options, hourCycleKey, hourCycleValue); 424 return options; 425 } 426 ArrayUndefinedGcCommon(JSThread * thread,TriggerGCType type)427 static void ArrayUndefinedGcCommon(JSThread *thread, TriggerGCType type) 428 { 429 EcmaVM *ecmaVM = thread->GetEcmaVM(); 430 JSHandle<TaggedArray> array = ecmaVM->GetFactory()->NewTaggedArray(2); // 2: len 431 EXPECT_TRUE(*array != nullptr); 432 JSHandle<JSObject> newObj1(thread, EcmaContainerCommon::JSObjectTestCreate(thread)); 433 array->Set(thread, 0, newObj1.GetTaggedValue()); 434 435 JSObject *newObj2 = EcmaContainerCommon::JSObjectTestCreate(thread); 436 JSTaggedValue value(newObj2); 437 value.CreateWeakRef(); 438 array->Set(thread, 1, value); 439 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(thread, 0)); 440 EXPECT_EQ(value, array->Get(thread, 1)); 441 ecmaVM->CollectGarbage(type); 442 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(thread, 0)); 443 EXPECT_EQ(JSTaggedValue::Undefined(), array->Get(thread, 1)); // 1 : index 444 } 445 ArrayKeepGcCommon(JSThread * thread,TriggerGCType type)446 static void ArrayKeepGcCommon(JSThread *thread, TriggerGCType type) 447 { 448 EcmaVM *ecmaVM = thread->GetEcmaVM(); 449 JSHandle<TaggedArray> array = ecmaVM->GetFactory()->NewTaggedArray(2); // 2: len 450 EXPECT_TRUE(*array != nullptr); 451 JSHandle<JSObject> newObj1(thread, EcmaContainerCommon::JSObjectTestCreate(thread)); 452 array->Set(thread, 0, newObj1.GetTaggedValue()); 453 454 JSHandle<JSObject> newObj2(thread, EcmaContainerCommon::JSObjectTestCreate(thread)); 455 JSTaggedValue value(newObj2.GetTaggedValue()); 456 value.CreateWeakRef(); 457 array->Set(thread, 1, value); 458 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(thread, 0)); 459 EXPECT_EQ(value, array->Get(thread, 1)); 460 ecmaVM->CollectGarbage(type); 461 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(thread, 0)); 462 EXPECT_EQ(true, array->Get(thread, 1).IsWeak()); 463 value = newObj2.GetTaggedValue(); 464 value.CreateWeakRef(); 465 EXPECT_EQ(value, array->Get(thread, 1)); 466 } 467 }; 468 }; // namespace panda::test 469 470 #endif 471