1/* 2 * Copyright (c) 2021-2022 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 16#include <thread> 17 18#include "libpandabase/utils/utf.h" 19#include "libpandafile/class_data_accessor-inl.h" 20 21#include "ecmascript/builtins/builtins_arraybuffer.h" 22#include "ecmascript/ecma_vm.h" 23#include "ecmascript/global_env.h" 24#include "ecmascript/js_array.h" 25#include "ecmascript/js_arraybuffer.h" 26#include "ecmascript/js_hclass.h" 27#include "ecmascript/js_regexp.h" 28#include "ecmascript/js_set.h" 29#include "ecmascript/js_thread.h" 30#include "ecmascript/js_typed_array.h" 31#include "ecmascript/jspandafile/js_pandafile.h" 32#include "ecmascript/jspandafile/js_pandafile_manager.h" 33#include "ecmascript/linked_hash_table.h" 34#include "ecmascript/mem/c_containers.h" 35#include "ecmascript/object_factory.h" 36#include "ecmascript/tests/test_helper.h" 37 38#include "ecmascript/serializer/value_serializer.h" 39#include "ecmascript/serializer/base_deserializer.h" 40 41using namespace panda::ecmascript; 42using namespace testing::ext; 43using namespace panda::ecmascript::builtins; 44 45namespace panda::test { 46using DeserializeFunc = void (*)(SerializeData* data); 47using Clock = std::chrono::high_resolution_clock; 48using Duration = std::chrono::duration<uint64_t, std::nano>; 49 50constexpr int32_t INITIALIZE_SIZE = 100; 51 52class JSDeserializerTest { 53public: 54 JSDeserializerTest() : ecmaVm(nullptr), scope(nullptr), thread(nullptr) {} 55 void Init() 56 { 57 JSRuntimeOptions options; 58 options.SetEnableForceGC(true); 59 ecmaVm = JSNApi::CreateEcmaVM(options); 60 ecmaVm->SetEnableForceGC(true); 61 EXPECT_TRUE(ecmaVm != nullptr) << "Cannot create Runtime"; 62 thread = ecmaVm->GetJSThread(); 63 scope = new EcmaHandleScope(thread); 64 thread->ManagedCodeBegin(); 65 } 66 void Destroy() 67 { 68 thread->ManagedCodeEnd(); 69 delete scope; 70 scope = nullptr; 71 ecmaVm->SetEnableForceGC(false); 72 thread->ClearException(); 73 JSNApi::DestroyJSVM(ecmaVm); 74 } 75 76 void JSSpecialValueTest(SerializeData* data) 77 { 78 Init(); 79 JSHandle<JSTaggedValue> jsTrue(thread, JSTaggedValue::True()); 80 JSHandle<JSTaggedValue> jsFalse(thread, JSTaggedValue::False()); 81 JSHandle<JSTaggedValue> jsUndefined(thread, JSTaggedValue::Undefined()); 82 JSHandle<JSTaggedValue> jsNull(thread, JSTaggedValue::Null()); 83 JSHandle<JSTaggedValue> jsHole(thread, JSTaggedValue::Hole()); 84 85 BaseDeserializer deserializer(thread, data); 86 JSHandle<JSTaggedValue> retTrue = deserializer.ReadValue(); 87 EXPECT_TRUE(JSTaggedValue::SameValue(jsTrue, retTrue)) << "Not same value for JS_TRUE"; 88 JSHandle<JSTaggedValue> retFalse = deserializer.ReadValue(); 89 EXPECT_TRUE(JSTaggedValue::SameValue(jsFalse, retFalse)) << "Not same value for JS_FALSE"; 90 JSHandle<JSTaggedValue> retUndefined = deserializer.ReadValue(); 91 JSHandle<JSTaggedValue> retNull = deserializer.ReadValue(); 92 JSHandle<JSTaggedValue> retHole = deserializer.ReadValue(); 93 94 EXPECT_TRUE(JSTaggedValue::SameValue(jsUndefined, retUndefined)) << "Not same value for JS_UNDEFINED"; 95 EXPECT_TRUE(JSTaggedValue::SameValue(jsNull, retNull)) << "Not same value for JS_NULL"; 96 EXPECT_TRUE(JSTaggedValue::SameValue(jsHole, retHole)) << "Not same value for JS_HOLE"; 97 Destroy(); 98 } 99 100 void LineStringTest(SerializeData* data) 101 { 102 Init(); 103 BaseDeserializer deserializer(thread, data); 104 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 105 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 106 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 107 108 EXPECT_FALSE(res.IsEmpty()); 109 EXPECT_TRUE(res->IsLineString()); 110 111 Destroy(); 112 } 113 114 void TreeStringTest(SerializeData* data) 115 { 116 Init(); 117 BaseDeserializer deserializer(thread, data); 118 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 119 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 120 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 121 122 EXPECT_FALSE(res.IsEmpty()); 123 EXPECT_TRUE(res->IsTreeString()); 124 125 Destroy(); 126 } 127 128 void SlicedStringTest(SerializeData* data) 129 { 130 Init(); 131 BaseDeserializer deserializer(thread, data); 132 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 133 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 134 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 135 136 EXPECT_FALSE(res.IsEmpty()); 137 EXPECT_TRUE(res->IsSlicedString()); 138 139 Destroy(); 140 } 141 142 void JSPlainObjectTest1(SerializeData* data) 143 { 144 Init(); 145 BaseDeserializer deserializer(thread, data); 146 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 147 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 148 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 149 150 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 151 EXPECT_FALSE(retObj.IsEmpty()); 152 153 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 154 uint32_t length = array->GetLength(); 155 EXPECT_EQ(length, 4U); // 4 : test case 156 double sum = 0.0; 157 for (uint32_t i = 0; i < length; i++) { 158 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 159 double a = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue()->GetNumber(); 160 sum += a; 161 } 162 EXPECT_EQ(sum, 10); // 10 : test case 163 164 Destroy(); 165 } 166 167 void JSPlainObjectTest2(SerializeData* data) 168 { 169 Init(); 170 BaseDeserializer deserializer(thread, data); 171 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 172 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 173 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 174 175 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 176 EXPECT_FALSE(retObj.IsEmpty()); 177 178 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 179 uint32_t length = array->GetLength(); 180 EXPECT_EQ(length, 10U); 181 for (uint32_t i = 0; i < length; i++) { 182 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 183 JSHandle<JSTaggedValue> value = 184 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 185 EXPECT_TRUE(value->GetTaggedObject()->GetClass()->IsJSObject()); 186 } 187 188 Destroy(); 189 } 190 191 void JSPlainObjectTest3(SerializeData* data) 192 { 193 Init(); 194 BaseDeserializer deserializer(thread, data); 195 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 196 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 197 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 198 199 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 200 EXPECT_FALSE(retObj.IsEmpty()); 201 EXPECT_TRUE(retObj->GetClass()->IsDictionaryMode()); 202 203 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 204 uint32_t length = array->GetLength(); 205 EXPECT_EQ(length, 1030U); 206 for (uint32_t i = 0; i < length; i++) { 207 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 208 JSHandle<JSTaggedValue> value = 209 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 210 EXPECT_TRUE(value->IsInt()); 211 } 212 213 Destroy(); 214 } 215 216 void JSPlainObjectTest4(SerializeData* data) 217 { 218 Init(); 219 ObjectFactory *factory = ecmaVm->GetFactory(); 220 JSHandle<JSTaggedValue> key(factory->NewFromASCII("str1")); 221 222 BaseDeserializer deserializer(thread, data); 223 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 224 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 225 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 226 227 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 228 EXPECT_FALSE(retObj.IsEmpty()); 229 230 JSHandle<JSTaggedValue> value = 231 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 232 EXPECT_TRUE(value->IsTaggedArray()); 233 TaggedArray *array = reinterpret_cast<TaggedArray *>(value->GetTaggedObject()); 234 size_t length = array->GetLength(); 235 EXPECT_EQ(length, 102400U); // 102400: array length 236 for (uint32_t i = 0; i < length; i++) { 237 EXPECT_TRUE(array->Get(i).IsHole()); 238 } 239 240 Destroy(); 241 } 242 243 void JSErrorTest1(SerializeData* data) 244 { 245 Init(); 246 247 BaseDeserializer deserializer(thread, data); 248 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 249 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 250 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 251 252 EXPECT_FALSE(objValue.IsEmpty()); 253 EXPECT_TRUE(objValue->IsJSError()); 254 255 Destroy(); 256 } 257 258 void JSErrorTest2(SerializeData* data) 259 { 260 Init(); 261 262 BaseDeserializer deserializer(thread, data); 263 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 264 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 265 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 266 267 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 268 EXPECT_FALSE(retObj.IsEmpty()); 269 270 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 271 uint32_t length = array->GetLength(); 272 EXPECT_EQ(length, 2U); 273 for (uint32_t i = 0; i < length; i++) { 274 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 275 JSHandle<JSTaggedValue> value = 276 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 277 EXPECT_TRUE(value->IsJSError()); 278 } 279 280 Destroy(); 281 } 282 283 void JSErrorTest3(SerializeData *data) 284 { 285 Init(); 286 287 BaseDeserializer deserializer(thread, data); 288 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 289 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 290 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 291 292 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 293 EXPECT_FALSE(retObj.IsEmpty()); 294 295 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 296 uint32_t length = array->GetLength(); 297 EXPECT_EQ(length, 7U); // 7 : test case 298 for (uint32_t i = 0; i < length; i++) { 299 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 300 JSHandle<JSTaggedValue> value = 301 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 302 EXPECT_TRUE(value->IsJSError()); 303 } 304 305 Destroy(); 306 } 307 308 void BigIntTest(SerializeData* data) 309 { 310 Init(); 311 BaseDeserializer deserializer(thread, data); 312 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 313 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 314 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 315 316 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 317 EXPECT_FALSE(retObj.IsEmpty()); 318 319 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 320 uint32_t length = array->GetLength(); 321 EXPECT_EQ(length, 2U); 322 for (uint32_t i = 0; i < length; i++) { 323 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 324 JSHandle<JSTaggedValue> value = 325 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 326 EXPECT_TRUE(value->GetTaggedObject()->GetClass()->IsBigInt()); 327 } 328 329 Destroy(); 330 } 331 332 void NativeBindingObjectTest1(SerializeData* data) 333 { 334 Init(); 335 BaseDeserializer deserializer(thread, data); 336 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 337 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 338 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 339 EXPECT_TRUE(objValue->IsUndefined()); 340 Destroy(); 341 } 342 343 void NativeBindingObjectTest2(SerializeData* data) 344 { 345 Init(); 346 BaseDeserializer deserializer(thread, data); 347 JSHandle<JSTaggedValue> objValue = deserializer.ReadValue(); 348 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 349 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 350 EXPECT_TRUE(objValue->IsJSObject()); 351 352 JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue); 353 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj); 354 uint32_t length = array->GetLength(); 355 EXPECT_EQ(length, 2U); 356 JSHandle<JSTaggedValue> key(thread, array->Get(0)); 357 JSHandle<JSTaggedValue> value = 358 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue(); 359 EXPECT_TRUE(value->IsUndefined()); 360 361 Destroy(); 362 } 363 364 void JSSetTest(SerializeData* data) 365 { 366 Init(); 367 ObjectFactory *factory = ecmaVm->GetFactory(); 368 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7)); // 7 : test case 369 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9)); // 9 : test case 370 JSHandle<JSTaggedValue> value3(factory->NewFromASCII("x")); 371 JSHandle<JSTaggedValue> value4(factory->NewFromASCII("y")); 372 373 BaseDeserializer deserializer(thread, data); 374 JSHandle<JSTaggedValue> setValue = deserializer.ReadValue(); 375 EXPECT_TRUE(!setValue.IsEmpty()); 376 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 377 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 378 379 JSHandle<JSSet> retSet = JSHandle<JSSet>::Cast(setValue); 380 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>::Cast(retSet)); 381 uint32_t propertyLength = array->GetLength(); 382 EXPECT_EQ(propertyLength, 2U); // 2 : test case 383 int sum = 0; 384 for (uint32_t i = 0; i < propertyLength; i++) { 385 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 386 double a = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retSet), key).GetValue()->GetNumber(); 387 sum += a; 388 } 389 EXPECT_EQ(sum, 16); // 16 : test case 390 391 EXPECT_EQ(retSet->GetSize(), 4); // 4 : test case 392 EXPECT_TRUE(retSet->Has(thread, value1.GetTaggedValue())); 393 EXPECT_TRUE(retSet->Has(thread, value2.GetTaggedValue())); 394 EXPECT_TRUE(retSet->Has(thread, value3.GetTaggedValue())); 395 EXPECT_TRUE(retSet->Has(thread, value4.GetTaggedValue())); 396 Destroy(); 397 } 398 399 void JSArrayTest(SerializeData* data) 400 { 401 Init(); 402 BaseDeserializer deserializer(thread, data); 403 JSHandle<JSTaggedValue> arrayValue = deserializer.ReadValue(); 404 EXPECT_TRUE(!arrayValue.IsEmpty()); 405 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 406 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 407 408 JSHandle<JSArray> retArray = JSHandle<JSArray>::Cast(arrayValue); 409 410 JSHandle<TaggedArray> keyArray = JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>(retArray)); 411 uint32_t propertyLength = keyArray->GetLength(); 412 EXPECT_EQ(propertyLength, 23U); // 23 : test case 413 int sum = 0; 414 for (uint32_t i = 0; i < propertyLength; i++) { 415 JSHandle<JSTaggedValue> key(thread, keyArray->Get(i)); 416 double a = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retArray), key).GetValue()->GetNumber(); 417 sum += a; 418 } 419 EXPECT_EQ(sum, 226); // 226 : test case 420 421 // test get value from array 422 for (int i = 0; i < 20; i++) { // 20 : test case 423 JSHandle<JSTaggedValue> value = JSArray::FastGetPropertyByValue(thread, arrayValue, i); 424 EXPECT_EQ(i, value.GetTaggedValue().GetInt()); 425 } 426 Destroy(); 427 } 428 429 void EcmaStringTest1(SerializeData* data) 430 { 431 Init(); 432 const char *rawStr = "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\ 433 "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\ 434 "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\ 435 "ssssss"; 436 JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(rawStr); 437 438 BaseDeserializer deserializer(thread, data); 439 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 440 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ecmaString fail"; 441 EXPECT_TRUE(res->IsString()) << "[NotString] Deserialize ecmaString fail"; 442 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 443 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 444 445 JSHandle<EcmaString> resEcmaString = JSHandle<EcmaString>::Cast(res); 446 auto ecmaStringCode = EcmaStringAccessor(ecmaString).GetHashcode(); 447 auto resEcmaStringCode = EcmaStringAccessor(resEcmaString).GetHashcode(); 448 EXPECT_TRUE(ecmaStringCode == resEcmaStringCode) << "Not same HashCode"; 449 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*ecmaString, *resEcmaString)) << "Not same EcmaString"; 450 Destroy(); 451 } 452 453 void EcmaStringTest2(SerializeData* data) 454 { 455 Init(); 456 JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromStdString("你好,世界"); 457 JSHandle<EcmaString> ecmaString1 = thread->GetEcmaVM()->GetFactory()->NewFromStdString("你好,世界"); 458 auto ecmaStringCode1 = EcmaStringAccessor(ecmaString).GetHashcode(); 459 auto ecmaString1Code = EcmaStringAccessor(ecmaString1).GetHashcode(); 460 EXPECT_TRUE(ecmaStringCode1 == ecmaString1Code) << "Not same HashCode"; 461 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*ecmaString, *ecmaString1)) << "Not same EcmaString"; 462 463 BaseDeserializer deserializer(thread, data); 464 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 465 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ecmaString fail"; 466 EXPECT_TRUE(res->IsString()) << "[NotString] Deserialize ecmaString fail"; 467 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 468 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 469 470 JSHandle<EcmaString> resEcmaString = JSHandle<EcmaString>::Cast(res); 471 auto ecmaStringCode2 = EcmaStringAccessor(ecmaString).GetHashcode(); 472 auto resEcmaStringCode = EcmaStringAccessor(resEcmaString).GetHashcode(); 473 EXPECT_TRUE(ecmaStringCode2 == resEcmaStringCode) << "Not same HashCode"; 474 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*ecmaString, *resEcmaString)) << "Not same EcmaString"; 475 Destroy(); 476 } 477 478 void Int32Test(SerializeData* data) 479 { 480 Init(); 481 int32_t a = 64; 482 int32_t min = -2147483648; 483 int32_t b = -63; 484 BaseDeserializer deserializer(thread, data); 485 JSHandle<JSTaggedValue> resA = deserializer.ReadValue(); 486 JSHandle<JSTaggedValue> resMin = deserializer.ReadValue(); 487 JSHandle<JSTaggedValue> resB = deserializer.ReadValue(); 488 EXPECT_TRUE(!resA.IsEmpty() && !resMin.IsEmpty() && !resB.IsEmpty()) << "[Empty] Deserialize Int32 fail"; 489 EXPECT_TRUE(resA->IsInt() && resMin->IsInt() && resB->IsInt()) << "[NotInt] Deserialize Int32 fail"; 490 EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resA) == a) << "Not Same Value"; 491 EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resMin) == min) << "Not Same Value"; 492 EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resB) == b) << "Not Same Value"; 493 Destroy(); 494 } 495 496 void DoubleTest(SerializeData* data) 497 { 498 Init(); 499 double a = 3.1415926535; 500 double b = -3.1415926535; 501 BaseDeserializer deserializer(thread, data); 502 JSHandle<JSTaggedValue> resA = deserializer.ReadValue(); 503 JSHandle<JSTaggedValue> resB = deserializer.ReadValue(); 504 EXPECT_TRUE(!resA.IsEmpty() && !resB.IsEmpty()) << "[Empty] Deserialize double fail"; 505 EXPECT_TRUE(resA->IsDouble() && resB->IsDouble()) << "[NotInt] Deserialize double fail"; 506 EXPECT_TRUE(resA->GetDouble() == a) << "Not Same Value"; 507 EXPECT_TRUE(resB->GetDouble() == b) << "Not Same Value"; 508 Destroy(); 509 } 510 511 void JSDateTest(SerializeData* data) 512 { 513 Init(); 514 double tm = 28 * 60 * 60 * 1000; // 28 * 60 * 60 * 1000 : test case 515 BaseDeserializer deserializer(thread, data); 516 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 517 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSDate fail"; 518 EXPECT_TRUE(res->IsDate()) << "[NotJSDate] Deserialize JSDate fail"; 519 JSHandle<JSDate> resDate = JSHandle<JSDate>(res); 520 EXPECT_TRUE(resDate->GetTimeValue() == JSTaggedValue(tm)) << "Not Same Time Value"; 521 Destroy(); 522 } 523 524 void JSMapTest(SerializeData* data, const JSHandle<JSMap> &originMap) 525 { 526 Init(); 527 BaseDeserializer deserializer(thread, data); 528 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 529 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSMap fail"; 530 EXPECT_TRUE(res->IsJSMap()) << "[NotJSMap] Deserialize JSMap fail"; 531 JSHandle<JSMap> resMap = JSHandle<JSMap>::Cast(res); 532 EXPECT_TRUE(originMap->GetSize() == resMap->GetSize()) << "the map size Not equal"; 533 uint32_t resSize = static_cast<uint32_t>(resMap->GetSize()); 534 for (uint32_t i = 0; i < resSize; i++) { 535 JSHandle<JSTaggedValue> resKey(thread, resMap->GetKey(i)); 536 JSHandle<JSTaggedValue> resValue(thread, resMap->GetValue(i)); 537 JSHandle<JSTaggedValue> key(thread, originMap->GetKey(i)); 538 JSHandle<JSTaggedValue> value(thread, originMap->GetValue(i)); 539 540 JSHandle<EcmaString> resKeyStr = JSHandle<EcmaString>::Cast(resKey); 541 JSHandle<EcmaString> keyStr = JSHandle<EcmaString>::Cast(key); 542 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*resKeyStr, *keyStr)) << "Not same map key"; 543 EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resValue) == JSTaggedValue::ToInt32(thread, value)) 544 << "Not same map value"; 545 } 546 Destroy(); 547 } 548 549 void JSSharedArrayBufferTest(SerializeData *data, int32_t byteLength, const char *msg) 550 { 551 Init(); 552 BaseDeserializer deserializer(thread, data); 553 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 554 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSArrayBuffer fail"; 555 EXPECT_TRUE(res->IsSharedArrayBuffer()) << "[NotJSArrayBuffer] Deserialize JSArrayBuffer fail"; 556 JSHandle<JSArrayBuffer> resJSArrayBuffer = JSHandle<JSArrayBuffer>::Cast(res); 557 int32_t resByteLength = static_cast<int32_t>(resJSArrayBuffer->GetArrayBufferByteLength()); 558 EXPECT_TRUE(resByteLength == byteLength) << "Not Same ByteLength"; 559 JSHandle<JSTaggedValue> resBufferData(thread, resJSArrayBuffer->GetArrayBufferData()); 560 JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(resBufferData); 561 void *resBuffer = resNp->GetExternalPointer(); 562 ASSERT_NE(resBuffer, nullptr); 563 564 if (msg != nullptr) { 565 if (memcpy_s(resBuffer, byteLength, msg, byteLength) != EOK) { 566 EXPECT_TRUE(false) << " memcpy error!"; 567 } 568 } 569 Destroy(); 570 } 571 572 void SerializeMultiSharedRegionTest(SerializeData *data) 573 { 574 Init(); 575 BaseDeserializer deserializer(thread, data); 576 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 577 EXPECT_TRUE(!res.IsEmpty()); 578 EXPECT_TRUE(res->IsJSObject()); 579 JSTaggedValue elements = JSHandle<JSObject>(res)->GetElements(); 580 EXPECT_TRUE(elements.IsTaggedArray()); 581 EXPECT_EQ(JSHandle<TaggedArray>(thread, elements)->GetLength(), 10 * 1024); // 10 * 1024: array length 582 JSTaggedValue value = JSHandle<TaggedArray>(thread, elements)->Get(0); 583 EXPECT_TRUE(value.IsTaggedArray()); 584 uint32_t length = JSHandle<TaggedArray>(thread, value)->GetLength(); 585 EXPECT_EQ(length, 11 * 1024); // 11 * 1024: array length 586 Destroy(); 587 } 588 589 void JSSharedSetBasicTest1(SerializeData *data) 590 { 591 Init(); 592 BaseDeserializer deserializer(thread, data); 593 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 594 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSSharedSet failed"; 595 EXPECT_TRUE(res->IsJSSharedSet()) << "[NotJSSharedSet] Deserialize JSSharedSet failed"; 596 JSHandle<JSSharedSet> jsSet = JSHandle<JSSharedSet>::Cast(res); 597 auto size = JSSharedSet::GetSize(thread, jsSet); 598 EXPECT_TRUE(size == INITIALIZE_SIZE); 599 JSSharedSet::Clear(thread, jsSet); 600 Destroy(); 601 } 602 603 void JSSharedSetBasicTest2(SerializeData *data) 604 { 605 Init(); 606 BaseDeserializer deserializer(thread, data); 607 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 608 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSSharedSet failed"; 609 EXPECT_TRUE(res->IsJSSharedSet()) << "[NotJSSharedSet] Deserialize JSSharedSet failed"; 610 JSHandle<JSSharedSet> jsSet = JSHandle<JSSharedSet>::Cast(res); 611 612 auto size = JSSharedSet::GetSize(thread, jsSet); 613 EXPECT_TRUE(size == INITIALIZE_SIZE); 614 for (int32_t i = 0; i < size; i++) { 615 EXPECT_TRUE(JSSharedSet::Has(thread, jsSet, JSTaggedValue(i))); 616 } 617 JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(INITIALIZE_SIZE))); 618 bool result = JSSharedSet::Delete(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0))); 619 EXPECT_TRUE(result) << "Delete failed"; 620 Destroy(); 621 } 622 623 void JSSharedSetMultiThreadTest1(SerializeData *data) 624 { 625 EXPECT_TRUE(data != nullptr); 626 Init(); 627 BaseDeserializer deserializer(thread, data); 628 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 629 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSSharedSet fail"; 630 EXPECT_TRUE(res->IsJSSharedSet()) << "[NotJSSharedSet] Deserialize JSSharedSet fail"; 631 JSHandle<JSSharedSet> jsSet = JSHandle<JSSharedSet>::Cast(res); 632 EXPECT_TRUE(JSSharedSet::GetSize(thread, jsSet) == INITIALIZE_SIZE); 633 for (int i = 0; i < INITIALIZE_SIZE; i++) { 634 EXPECT_TRUE(JSSharedSet::Has(thread, jsSet, JSTaggedValue(i))); 635 } 636 Destroy(); 637 } 638 639 void JSSharedMapBasicTest1(SerializeData *data) 640 { 641 Init(); 642 BaseDeserializer deserializer(thread, data); 643 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 644 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSSharedMap failed"; 645 EXPECT_TRUE(res->IsJSSharedMap()) << "[NotJSSharedMap] Deserialize JSSharedMap failed"; 646 JSHandle<JSSharedMap> jsMap = JSHandle<JSSharedMap>::Cast(res); 647 auto size = JSSharedMap::GetSize(thread, jsMap); 648 EXPECT_TRUE(size == INITIALIZE_SIZE); 649 JSSharedMap::Clear(thread, jsMap); 650 Destroy(); 651 } 652 653 void JSSharedMapBasicTest2(SerializeData *data) 654 { 655 Init(); 656 BaseDeserializer deserializer(thread, data); 657 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 658 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSSharedMap failed"; 659 EXPECT_TRUE(res->IsJSSharedMap()) << "[NotJSSharedMap] Deserialize JSSharedMap failed"; 660 JSHandle<JSSharedMap> jsMap = JSHandle<JSSharedMap>::Cast(res); 661 662 auto size = JSSharedMap::GetSize(thread, jsMap); 663 EXPECT_TRUE(size == INITIALIZE_SIZE); 664 for (int32_t i = 0; i < size; i++) { 665 EXPECT_TRUE(JSSharedMap::Has(thread, jsMap, JSTaggedValue(i))); 666 } 667 JSSharedMap::Set(thread, jsMap, JSHandle<JSTaggedValue>(thread, JSTaggedValue(INITIALIZE_SIZE)), 668 JSHandle<JSTaggedValue>(thread, JSTaggedValue(INITIALIZE_SIZE))); 669 bool result = JSSharedMap::Delete(thread, jsMap, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0))); 670 EXPECT_TRUE(result) << "Delete failed"; 671 Destroy(); 672 } 673 674 void JSRegexpTest(SerializeData *data) 675 { 676 Init(); 677 JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"); 678 JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 679 char buffer[] = "1234567"; // use char buffer to simulate byteCodeBuffer 680 uint32_t bufferSize = 7; 681 682 BaseDeserializer deserializer(thread, data); 683 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 684 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSRegExp fail"; 685 EXPECT_TRUE(res->IsJSRegExp()) << "[NotJSRegexp] Deserialize JSRegExp fail"; 686 JSHandle<JSRegExp> resJSRegexp(res); 687 688 uint32_t resBufferSize = resJSRegexp->GetLength(); 689 EXPECT_TRUE(resBufferSize == bufferSize) << "Not Same Length"; 690 JSHandle<JSTaggedValue> originalSource(thread, resJSRegexp->GetOriginalSource()); 691 EXPECT_TRUE(originalSource->IsString()); 692 JSHandle<JSTaggedValue> originalFlags(thread, resJSRegexp->GetOriginalFlags()); 693 EXPECT_TRUE(originalFlags->IsString()); 694 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(originalSource), *pattern)); 695 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(originalFlags), *flags)); 696 JSHandle<JSTaggedValue> resBufferData(thread, resJSRegexp->GetByteCodeBuffer()); 697 JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(resBufferData); 698 void *resBuffer = resNp->GetExternalPointer(); 699 ASSERT_NE(resBuffer, nullptr); 700 701 for (uint32_t i = 0; i < resBufferSize; i++) { 702 EXPECT_TRUE(static_cast<char *>(resBuffer)[i] == buffer[i]) << "Not Same ByteCode"; 703 } 704 705 Destroy(); 706 } 707 708 void TypedArrayTest1(SerializeData *data) 709 { 710 Init(); 711 JSHandle<JSTaggedValue> originTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString()); 712 BaseDeserializer deserializer(thread, data); 713 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 714 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TypedArray fail"; 715 EXPECT_TRUE(res->IsJSInt8Array()) << "[NotJSInt8Array] Deserialize TypedArray fail"; 716 JSHandle<JSTypedArray> resJSInt8Array = JSHandle<JSTypedArray>::Cast(res); 717 718 JSHandle<JSTaggedValue> typedArrayName(thread, resJSInt8Array->GetTypedArrayName()); 719 uint32_t byteLength = resJSInt8Array->GetByteLength(); 720 uint32_t byteOffset = resJSInt8Array->GetByteOffset(); 721 uint32_t arrayLength = resJSInt8Array->GetArrayLength(); 722 ContentType contentType = resJSInt8Array->GetContentType(); 723 JSHandle<JSTaggedValue> viewedArrayBuffer(thread, resJSInt8Array->GetViewedArrayBufferOrByteArray()); 724 725 EXPECT_TRUE(typedArrayName->IsString()); 726 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(typedArrayName), 727 *JSHandle<EcmaString>(originTypedArrayName))); 728 EXPECT_EQ(byteLength, 10) << "Not Same ByteLength"; // 10: bufferLength 729 EXPECT_EQ(byteOffset, 0) << "Not Same ByteOffset"; 730 EXPECT_EQ(arrayLength, 10) << "Not Same ArrayLength"; // 10: arrayLength 731 EXPECT_TRUE(contentType == ContentType::Number) << "Not Same ContentType"; 732 733 // check arrayBuffer 734 EXPECT_TRUE(viewedArrayBuffer->IsArrayBuffer()); 735 JSHandle<JSArrayBuffer> resJSArrayBuffer(viewedArrayBuffer); 736 uint32_t resTaggedLength = resJSArrayBuffer->GetArrayBufferByteLength(); 737 EXPECT_EQ(resTaggedLength, 10) << "Not same viewedBuffer length"; // 10: bufferLength 738 JSHandle<JSTaggedValue> resBufferData(thread, resJSArrayBuffer->GetArrayBufferData()); 739 JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(resBufferData); 740 void *resBuffer = resNp->GetExternalPointer(); 741 for (uint32_t i = 0; i < resTaggedLength; i++) { 742 EXPECT_EQ(static_cast<uint8_t *>(resBuffer)[i], i) << "Not same viewedBuffer"; 743 } 744 Destroy(); 745 } 746 747 void TypedArrayTest2(SerializeData *data) 748 { 749 Init(); 750 JSHandle<JSTaggedValue> originTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString()); 751 BaseDeserializer deserializer(thread, data); 752 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 753 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TypedArray fail"; 754 EXPECT_TRUE(res->IsJSInt8Array()) << "[NotJSInt8Array] Deserialize TypedArray fail"; 755 JSHandle<JSTypedArray> resJSInt8Array = JSHandle<JSTypedArray>::Cast(res); 756 757 JSHandle<JSTaggedValue> typedArrayName(thread, resJSInt8Array->GetTypedArrayName()); 758 uint32_t byteLength = resJSInt8Array->GetByteLength(); 759 uint32_t byteOffset = resJSInt8Array->GetByteOffset(); 760 uint32_t arrayLength = resJSInt8Array->GetArrayLength(); 761 ContentType contentType = resJSInt8Array->GetContentType(); 762 JSHandle<JSTaggedValue> byteArray(thread, resJSInt8Array->GetViewedArrayBufferOrByteArray()); 763 764 EXPECT_TRUE(typedArrayName->IsString()); 765 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(typedArrayName), 766 *JSHandle<EcmaString>(originTypedArrayName))); 767 EXPECT_EQ(byteLength, 10) << "Not Same ByteLength"; // 10: bufferLength 768 EXPECT_EQ(byteOffset, 0) << "Not Same ByteOffset"; 769 EXPECT_EQ(arrayLength, 10) << "Not Same ArrayLength"; // 10: arrayLength 770 EXPECT_TRUE(contentType == ContentType::Number) << "Not Same ContentType"; 771 772 // check byteArray 773 EXPECT_TRUE(byteArray->IsByteArray()); 774 JSHandle<ByteArray> resByteArray(byteArray); 775 uint32_t resTaggedLength = resByteArray->GetArrayLength(); 776 EXPECT_EQ(resTaggedLength, 10) << "Not same viewedBuffer length"; // 10: bufferLength 777 uint32_t resElementSize = resByteArray->GetByteLength(); 778 EXPECT_EQ(resElementSize, 1) << "Not same byteArray size"; 779 for (uint32_t i = 0; i < resTaggedLength; i++) { 780 JSHandle<JSTaggedValue> taggedVal(thread, resByteArray->Get(thread, i, DataViewType::UINT8)); 781 int32_t byteArrayVal = JSTaggedValue::ToInt32(thread, taggedVal); 782 EXPECT_EQ(byteArrayVal, 255) << "Not same byteArray value"; // 255: value in byteArray 783 } 784 Destroy(); 785 } 786 787 void SharedObjectTest4(SerializeData* data) 788 { 789 Init(); 790 BaseDeserializer deserializer(thread, data); 791 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 792 EXPECT_FALSE(res.IsEmpty()); 793 EXPECT_TRUE(res->IsJSSharedObject()) << "[NotJSSharedObject] Deserialize SharedObject fail"; 794 795 JSHandle<JSObject> sObj = JSHandle<JSObject>::Cast(res); 796 JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, sObj); 797 uint32_t length = array->GetLength(); 798 EXPECT_EQ(length, 512U); 799 for (uint32_t i = 0; i < length; i++) { 800 JSHandle<JSTaggedValue> key(thread, array->Get(i)); 801 JSHandle<JSTaggedValue> value = 802 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(sObj), key).GetValue(); 803 EXPECT_TRUE(value->IsInt()); 804 } 805 806 Destroy(); 807 } 808 809 void SerializeSharedFunctionTest(SerializeData *data) 810 { 811 Init(); 812 BaseDeserializer deserializer(thread, data); 813 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 814 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize SharedFunction fail"; 815 EXPECT_TRUE(res->IsJSSharedFunction()) << "[NotJSSharedFunction] Deserialize SharedFunction fail"; 816 JSHandle<JSSharedFunction> sFunc = JSHandle<JSSharedFunction>::Cast(res); 817 818 EXPECT_TRUE(sFunc->IsCallable()); 819 EXPECT_FALSE(sFunc->GetProtoOrHClass().IsHole()); 820 EXPECT_TRUE(sFunc->GetLexicalEnv().IsTaggedArray()); 821 EXPECT_TRUE(sFunc->GetHomeObject().IsJSSharedObject()); 822 JSHandle<JSSharedObject> sObj(thread, sFunc->GetHomeObject()); 823 Destroy(); 824 } 825 826 void SerializeSharedFunctionTest1(SerializeData *data) 827 { 828 Init(); 829 BaseDeserializer deserializer(thread, data); 830 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 831 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize SharedFunction fail"; 832 EXPECT_TRUE(res->IsJSSharedFunction()) << "[NotJSSharedFunction] Deserialize SharedFunction fail"; 833 Destroy(); 834 } 835 836 void ObjectWithConcurrentFunctionTest(SerializeData* data) 837 { 838 Init(); 839 ObjectFactory *factory = ecmaVm->GetFactory(); 840 BaseDeserializer deserializer(thread, data); 841 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 842 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 843 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 844 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ObjectWithConcurrentFunction fail"; 845 846 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("abc")); 847 OperationResult result1 = JSObject::GetProperty(thread, res, key1); 848 JSHandle<JSTaggedValue> value1 = result1.GetRawValue(); 849 EXPECT_TRUE(value1->IsString()); 850 851 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("2")); 852 OperationResult result2 = JSObject::GetProperty(thread, res, key2); 853 JSHandle<JSTaggedValue> value2 = result2.GetRawValue(); 854 EXPECT_TRUE(value2->IsJSFunction()); 855 EXPECT_TRUE(JSHandle<JSFunction>::Cast(value2)->GetWorkNodePointer() == reinterpret_cast<uintptr_t>(nullptr)); 856 JSHandle<JSTaggedValue> key3(factory->NewFromASCII("key")); 857 OperationResult result3 = JSObject::GetProperty(thread, res, key3); 858 JSHandle<JSTaggedValue> value3 = result3.GetRawValue(); 859 EXPECT_TRUE(value3->IsJSFunction()); 860 EXPECT_TRUE(JSHandle<JSFunction>::Cast(value3)->GetWorkNodePointer() == reinterpret_cast<uintptr_t>(nullptr)); 861 862 Destroy(); 863 } 864 865 void TransferJSArrayBufferTest1(SerializeData *data, uintptr_t bufferAddrCheck) 866 { 867 Init(); 868 BaseDeserializer deserializer(thread, data); 869 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 870 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 871 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 872 873 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer1 fail"; 874 EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer1 fail"; 875 876 JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res); 877 EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 5); // 5: bufferLength 878 JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData()); 879 EXPECT_TRUE(nativePtr->IsJSNativePointer()) << "[NotJSNativePointer] Deserialize TransferJSArrayBuffer1 fail"; 880 JSHandle<JSNativePointer> np = JSHandle<JSNativePointer>::Cast(nativePtr); 881 uintptr_t bufferAddr = reinterpret_cast<uintptr_t>(np->GetExternalPointer()); 882 // The deserialized C buffer pointer shall be same to the original one 883 EXPECT_EQ(static_cast<uint64_t>(bufferAddr), static_cast<uint64_t>(bufferAddrCheck)); 884 Destroy(); 885 } 886 887 void TransferJSArrayBufferTest2(SerializeData *data, uintptr_t bufferAddrCheck) 888 { 889 Init(); 890 BaseDeserializer deserializer(thread, data); 891 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 892 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 893 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 894 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer2 fail"; 895 EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer2 fail"; 896 897 JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res); 898 EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 5); // 5: bufferLength 899 JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData()); 900 EXPECT_TRUE(nativePtr->IsJSNativePointer()) << "[NotJSNativePointer] Deserialize TransferJSArrayBuffer2 fail"; 901 JSHandle<JSNativePointer> np = JSHandle<JSNativePointer>::Cast(nativePtr); 902 uintptr_t bufferAddr = reinterpret_cast<uintptr_t>(np->GetExternalPointer()); 903 // The deserialized C buffer pointer shall be different to the original one 904 EXPECT_NE(static_cast<uint64_t>(bufferAddr), static_cast<uint64_t>(bufferAddrCheck)); 905 Destroy(); 906 } 907 908 void TransferJSArrayBufferTest3(SerializeData *data) 909 { 910 Init(); 911 BaseDeserializer deserializer(thread, data); 912 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 913 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 914 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 915 916 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer3 fail"; 917 EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer3 fail"; 918 919 JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res); 920 EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 0); 921 JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData()); 922 EXPECT_TRUE(nativePtr->IsUndefined()) << "[NotJSNativePointer] Deserialize TransferJSArrayBuffer3 fail"; 923 Destroy(); 924 } 925 926 void TransferJSArrayBufferTest5(SerializeData *data) 927 { 928 Init(); 929 BaseDeserializer deserializer(thread, data); 930 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 931 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 932 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 933 934 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer5 fail"; 935 EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer5 fail"; 936 937 JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res); 938 EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 5); // 5: bufferLength 939 JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData()); 940 EXPECT_TRUE(reinterpret_cast<JSNativePointer *>(nativePtr->GetTaggedObject())->GetDeleter()); 941 Destroy(); 942 } 943 944 void SerializeCloneListTest1(SerializeData *data) 945 { 946 Init(); 947 BaseDeserializer deserializer(thread, data); 948 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 949 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 950 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 951 952 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize CloneListTest1 fail"; 953 Region *region = Region::ObjectAddressToRange(res->GetTaggedObject()); 954 EXPECT_TRUE(region->InSharedHeap()); 955 JSType resType = res->GetTaggedObject()->GetClass()->GetObjectType(); 956 EXPECT_EQ(resType, JSType::JS_SHARED_OBJECT); 957 958 ObjectFactory *factory = ecmaVm->GetFactory(); 959 JSHandle<JSTaggedValue> key(factory->NewFromASCII("str2str1")); 960 JSHandle<JSTaggedValue> shareObj = 961 JSObject::GetProperty(thread, JSHandle<JSObject>(res), key).GetValue(); 962 Region *region1 = Region::ObjectAddressToRange(shareObj->GetTaggedObject()); 963 EXPECT_TRUE(region1->InSharedHeap()); 964 Destroy(); 965 } 966 967 void SerializeCloneListTest2(SerializeData *data) 968 { 969 Init(); 970 BaseDeserializer deserializer(thread, data); 971 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 972 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 973 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 974 975 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize CloneListTest2 fail"; 976 ObjectFactory *factory = ecmaVm->GetFactory(); 977 JSHandle<JSTaggedValue> key(factory->NewFromASCII("shareObj")); 978 JSHandle<JSTaggedValue> shareObj = 979 JSObject::GetProperty(thread, JSHandle<JSObject>(res), key).GetValue(); 980 Region *region = Region::ObjectAddressToRange(shareObj->GetTaggedObject()); 981 EXPECT_TRUE(region->InSharedHeap()); 982 Destroy(); 983 } 984 985 void SerializeCloneListTest4(SerializeData *data) 986 { 987 Init(); 988 BaseDeserializer deserializer(thread, data); 989 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 990 ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC); 991 ecmaVm->CollectGarbage(TriggerGCType::OLD_GC); 992 993 EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize CloneListTest4 fail"; 994 Destroy(); 995 } 996 997private: 998 EcmaVM *ecmaVm = nullptr; 999 EcmaHandleScope *scope = nullptr; 1000 JSThread *thread = nullptr; 1001}; 1002 1003class JSSerializerTest : public testing::Test { 1004public: 1005 static void SetUpTestCase() 1006 { 1007 GTEST_LOG_(INFO) << "SetUpTestCase"; 1008 } 1009 1010 static void TearDownTestCase() 1011 { 1012 GTEST_LOG_(INFO) << "TearDownCase"; 1013 } 1014 1015 void SetUp() override 1016 { 1017 TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope); 1018 } 1019 1020 void TearDown() override 1021 { 1022 TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope); 1023 } 1024 1025 JSThread *thread {nullptr}; 1026 EcmaVM *ecmaVm {nullptr}; 1027 EcmaHandleScope *scope {nullptr}; 1028}; 1029 1030HWTEST_F_L0(JSSerializerTest, SerializeJSSpecialValue) 1031{ 1032 ValueSerializer *serializer = new ValueSerializer(thread); 1033 serializer->SerializeJSTaggedValue(JSTaggedValue::True()); 1034 serializer->SerializeJSTaggedValue(JSTaggedValue::False()); 1035 serializer->SerializeJSTaggedValue(JSTaggedValue::Undefined()); 1036 serializer->SerializeJSTaggedValue(JSTaggedValue::Null()); 1037 serializer->SerializeJSTaggedValue(JSTaggedValue::Hole()); 1038 std::unique_ptr<SerializeData> data = serializer->Release(); 1039 1040 JSDeserializerTest jsDeserializerTest; 1041 std::thread t1(&JSDeserializerTest::JSSpecialValueTest, jsDeserializerTest, data.release()); 1042 ThreadSuspensionScope scope(thread); 1043 t1.join(); 1044 delete serializer; 1045}; 1046 1047HWTEST_F_L0(JSSerializerTest, SerializeLineString) 1048{ 1049 ObjectFactory *factory = ecmaVm->GetFactory(); 1050 JSHandle<EcmaString> str(factory->NewFromASCII("123")); 1051 1052 ValueSerializer *serializer = new ValueSerializer(thread); 1053 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str), 1054 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1055 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1056 std::unique_ptr<SerializeData> data = serializer->Release(); 1057 JSDeserializerTest jsDeserializerTest; 1058 std::thread t1(&JSDeserializerTest::LineStringTest, jsDeserializerTest, data.release()); 1059 { 1060 ThreadSuspensionScope suspensionScope(thread); 1061 t1.join(); 1062 } 1063 delete serializer; 1064}; 1065 1066HWTEST_F_L0(JSSerializerTest, SerializeTreeString) 1067{ 1068 ObjectFactory *factory = ecmaVm->GetFactory(); 1069 JSHandle<EcmaString> str1(factory->NewFromASCII("123456789")); 1070 JSHandle<EcmaString> str2(factory->NewFromASCII("abcdefghi")); 1071 1072 JSHandle<EcmaString> str3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, str1, str2)); 1073 EXPECT_TRUE(str3.GetTaggedValue().IsTreeString()); 1074 1075 ValueSerializer *serializer = new ValueSerializer(thread); 1076 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str3), 1077 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1078 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1079 std::unique_ptr<SerializeData> data = serializer->Release(); 1080 JSDeserializerTest jsDeserializerTest; 1081 std::thread t1(&JSDeserializerTest::TreeStringTest, jsDeserializerTest, data.release()); 1082 { 1083 ThreadSuspensionScope suspensionScope(thread); 1084 t1.join(); 1085 } 1086 delete serializer; 1087}; 1088 1089HWTEST_F_L0(JSSerializerTest, SerializeSlicedString) 1090{ 1091 ObjectFactory *factory = ecmaVm->GetFactory(); 1092 JSHandle<EcmaString> str1(factory->NewFromASCII("123456789abcedfghijk")); 1093 1094 JSHandle<EcmaString> str2 = 1095 JSHandle<EcmaString>(thread, EcmaStringAccessor::GetSubString(ecmaVm, str1, 2, 13)); // 2: start, 3: len 1096 EXPECT_TRUE(str2.GetTaggedValue().IsSlicedString()); 1097 1098 ValueSerializer *serializer = new ValueSerializer(thread); 1099 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str2), 1100 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1101 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1102 std::unique_ptr<SerializeData> data = serializer->Release(); 1103 JSDeserializerTest jsDeserializerTest; 1104 std::thread t1(&JSDeserializerTest::SlicedStringTest, jsDeserializerTest, data.release()); 1105 { 1106 ThreadSuspensionScope suspensionScope(thread); 1107 t1.join(); 1108 } 1109 delete serializer; 1110}; 1111 1112HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject1) 1113{ 1114 ObjectFactory *factory = ecmaVm->GetFactory(); 1115 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1116 1117 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("2")); 1118 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("3")); 1119 JSHandle<JSTaggedValue> key3(factory->NewFromASCII("x")); 1120 JSHandle<JSTaggedValue> key4(factory->NewFromASCII("y")); 1121 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1)); 1122 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2)); 1123 JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3)); 1124 JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4)); 1125 1126 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1); 1127 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2); 1128 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3); 1129 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4); 1130 1131 ValueSerializer *serializer = new ValueSerializer(thread); 1132 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1133 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1134 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1135 std::unique_ptr<SerializeData> data = serializer->Release(); 1136 JSDeserializerTest jsDeserializerTest; 1137 std::thread t1(&JSDeserializerTest::JSPlainObjectTest1, jsDeserializerTest, data.release()); 1138 ThreadSuspensionScope scope(thread); 1139 t1.join(); 1140 delete serializer; 1141}; 1142 1143HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject2) 1144{ 1145 ObjectFactory *factory = ecmaVm->GetFactory(); 1146 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1147 JSHandle<EcmaString> key1(factory->NewFromASCII("str1")); 1148 JSHandle<EcmaString> key2(factory->NewFromASCII("str2")); 1149 for (int i = 0; i < 10; i++) { 1150 JSHandle<JSObject> obj1 = factory->NewEmptyJSObject(); 1151 JSHandle<EcmaString> key3(factory->NewFromASCII("str3")); 1152 for (int j = 0; j < 10; j++) { 1153 key3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key3, key1)); 1154 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), JSHandle<JSTaggedValue>(key3), 1155 JSHandle<JSTaggedValue>(factory->NewEmptyJSObject())); 1156 } 1157 key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1)); 1158 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), 1159 JSHandle<JSTaggedValue>(obj1)); 1160 } 1161 1162 ValueSerializer *serializer = new ValueSerializer(thread); 1163 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1164 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1165 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1166 std::unique_ptr<SerializeData> data = serializer->Release(); 1167 JSDeserializerTest jsDeserializerTest; 1168 std::thread t1(&JSDeserializerTest::JSPlainObjectTest2, jsDeserializerTest, data.release()); 1169 ThreadSuspensionScope scope(thread); 1170 t1.join(); 1171 delete serializer; 1172}; 1173 1174// test dictionary mode 1175HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject3) 1176{ 1177 ObjectFactory *factory = ecmaVm->GetFactory(); 1178 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1179 JSHandle<EcmaString> key1(factory->NewFromASCII("str1")); 1180 JSHandle<EcmaString> key2(factory->NewFromASCII("str2")); 1181 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1)); 1182 for (int i = 0; i < 1030; i++) { 1183 key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1)); 1184 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), value1); 1185 } 1186 1187 EXPECT_TRUE(obj->GetClass()->IsDictionaryMode()); 1188 1189 ValueSerializer *serializer = new ValueSerializer(thread); 1190 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1191 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1192 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1193 std::unique_ptr<SerializeData> data = serializer->Release(); 1194 JSDeserializerTest jsDeserializerTest; 1195 std::thread t1(&JSDeserializerTest::JSPlainObjectTest3, jsDeserializerTest, data.release()); 1196 ThreadSuspensionScope scope(thread); 1197 t1.join(); 1198 delete serializer; 1199}; 1200 1201// test huge object serialize 1202HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject4) 1203{ 1204 ObjectFactory *factory = ecmaVm->GetFactory(); 1205 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1206 JSHandle<EcmaString> key1(factory->NewFromASCII("str1")); 1207 // new huge tagged array 1208 JSHandle<TaggedArray> taggedArray = 1209 factory->NewTaggedArray(1024 * 100, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE); 1210 1211 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), 1212 JSHandle<JSTaggedValue>(taggedArray)); 1213 1214 ValueSerializer *serializer = new ValueSerializer(thread); 1215 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1216 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1217 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1218 std::unique_ptr<SerializeData> data = serializer->Release(); 1219 JSDeserializerTest jsDeserializerTest; 1220 std::thread t1(&JSDeserializerTest::JSPlainObjectTest4, jsDeserializerTest, data.release()); 1221 ThreadSuspensionScope scope(thread); 1222 t1.join(); 1223 delete serializer; 1224}; 1225 1226HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject5) 1227{ 1228 ObjectFactory *factory = ecmaVm->GetFactory(); 1229 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1230 1231 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("2")); 1232 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("3")); 1233 JSHandle<JSTaggedValue> key3(factory->NewFromASCII("x")); 1234 JSHandle<JSTaggedValue> key4(factory->NewFromASCII("y")); 1235 JSHandle<JSTaggedValue> key5(factory->NewFromASCII("func")); 1236 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1)); 1237 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2)); 1238 JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3)); 1239 JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4)); 1240 JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 1241 JSHandle<JSFunction> function = factory->NewJSFunction(env, nullptr, FunctionKind::NORMAL_FUNCTION); 1242 EXPECT_TRUE(function->IsJSFunction()); 1243 JSHandle<JSTaggedValue> value5 = JSHandle<JSTaggedValue>::Cast(function); 1244 1245 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1); 1246 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2); 1247 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3); 1248 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4); 1249 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key5, value5); 1250 1251 ValueSerializer *serializer = new ValueSerializer(thread); 1252 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1253 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1254 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1255 EXPECT_FALSE(success); 1256 std::unique_ptr<SerializeData> data = serializer->Release(); 1257 BaseDeserializer deserializer(thread, data.release()); 1258 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 1259 EXPECT_TRUE(res.IsEmpty()); 1260 delete serializer; 1261}; 1262 1263HWTEST_F_L0(JSSerializerTest, SerializeJSError1) 1264{ 1265 ObjectFactory *factory = ecmaVm->GetFactory(); 1266 JSHandle<EcmaString> msg(factory->NewFromASCII("this is error")); 1267 JSHandle<JSTaggedValue> errorTag = 1268 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::ERROR, msg, StackCheck::NO)); 1269 1270 ValueSerializer *serializer = new ValueSerializer(thread); 1271 serializer->WriteValue(thread, errorTag, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1272 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1273 std::unique_ptr<SerializeData> data = serializer->Release(); 1274 JSDeserializerTest jsDeserializerTest; 1275 std::thread t1(&JSDeserializerTest::JSErrorTest1, jsDeserializerTest, data.release()); 1276 ThreadSuspensionScope scope(thread); 1277 t1.join(); 1278 delete serializer; 1279}; 1280 1281HWTEST_F_L0(JSSerializerTest, SerializeJSError2) 1282{ 1283 ObjectFactory *factory = ecmaVm->GetFactory(); 1284 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1285 JSHandle<EcmaString> key1(factory->NewFromASCII("error1")); 1286 JSHandle<EcmaString> key2(factory->NewFromASCII("error2")); 1287 JSHandle<EcmaString> msg(factory->NewFromASCII("this is error")); 1288 JSHandle<JSTaggedValue> errorTag = 1289 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::ERROR, msg, StackCheck::NO)); 1290 1291 1292 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), errorTag); 1293 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), errorTag); 1294 1295 ValueSerializer *serializer = new ValueSerializer(thread); 1296 serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1297 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1298 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1299 std::unique_ptr<SerializeData> data = serializer->Release(); 1300 JSDeserializerTest jsDeserializerTest; 1301 std::thread t1(&JSDeserializerTest::JSErrorTest2, jsDeserializerTest, data.release()); 1302 ThreadSuspensionScope scope(thread); 1303 t1.join(); 1304 delete serializer; 1305}; 1306 1307HWTEST_F_L0(JSSerializerTest, SerializeJSError3) 1308{ 1309 ObjectFactory *factory = ecmaVm->GetFactory(); 1310 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1311 JSHandle<EcmaString> key1(factory->NewFromASCII("error1")); 1312 JSHandle<EcmaString> key2(factory->NewFromASCII("error2")); 1313 JSHandle<EcmaString> key3(factory->NewFromASCII("error3")); 1314 JSHandle<EcmaString> key4(factory->NewFromASCII("error4")); 1315 JSHandle<EcmaString> key5(factory->NewFromASCII("error5")); 1316 JSHandle<EcmaString> key6(factory->NewFromASCII("error6")); 1317 JSHandle<EcmaString> key7(factory->NewFromASCII("error7")); 1318 JSHandle<EcmaString> msg(factory->NewFromASCII("this is error")); 1319 JSHandle<JSTaggedValue> error1 = 1320 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::RANGE_ERROR, msg, StackCheck::NO)); 1321 JSHandle<JSTaggedValue> error2 = 1322 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg, StackCheck::NO)); 1323 JSHandle<JSTaggedValue> error3 = 1324 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::TYPE_ERROR, msg, StackCheck::NO)); 1325 JSHandle<JSTaggedValue> error4 = 1326 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::URI_ERROR, msg, StackCheck::NO)); 1327 JSHandle<JSTaggedValue> error5 = 1328 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::SYNTAX_ERROR, msg, StackCheck::NO)); 1329 JSHandle<JSTaggedValue> error6 = 1330 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::OOM_ERROR, msg, StackCheck::NO)); 1331 JSHandle<JSTaggedValue> error7 = 1332 JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::TERMINATION_ERROR, msg, StackCheck::NO)); 1333 1334 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), error1); 1335 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), error2); 1336 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key3), error3); 1337 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key4), error4); 1338 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key5), error5); 1339 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key6), error6); 1340 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key7), error7); 1341 1342 ValueSerializer *serializer = new ValueSerializer(thread); 1343 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1344 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1345 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1346 EXPECT_TRUE(success); 1347 std::unique_ptr<SerializeData> data = serializer->Release(); 1348 JSDeserializerTest jsDeserializerTest; 1349 std::thread t1(&JSDeserializerTest::JSErrorTest3, jsDeserializerTest, data.release()); 1350 ThreadSuspensionScope scope(thread); 1351 t1.join(); 1352 delete serializer; 1353} 1354 1355HWTEST_F_L0(JSSerializerTest, SerializeBigInt) 1356{ 1357 ObjectFactory *factory = ecmaVm->GetFactory(); 1358 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1359 JSHandle<EcmaString> key1(factory->NewFromASCII("pss")); 1360 JSHandle<EcmaString> key2(factory->NewFromASCII("nativeHeap")); 1361 CString value1 = "365769"; 1362 CString value2 = "139900"; 1363 JSHandle<BigInt> bigInt1 = BigIntHelper::SetBigInt(thread, value1); 1364 JSHandle<BigInt> bigInt2 = BigIntHelper::SetBigInt(thread, value1); 1365 1366 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), 1367 JSHandle<JSTaggedValue>(bigInt1)); 1368 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), 1369 JSHandle<JSTaggedValue>(bigInt2)); 1370 1371 1372 ValueSerializer *serializer = new ValueSerializer(thread); 1373 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1374 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1375 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1376 EXPECT_TRUE(success) << "Serialize bigInt fail"; 1377 std::unique_ptr<SerializeData> data = serializer->Release(); 1378 JSDeserializerTest jsDeserializerTest; 1379 std::thread t1(&JSDeserializerTest::BigIntTest, jsDeserializerTest, data.release()); 1380 ThreadSuspensionScope scope(thread); 1381 t1.join(); 1382 delete serializer; 1383}; 1384 1385static void* Detach(void *param1, void *param2, void *hint, void *detachData) 1386{ 1387 GTEST_LOG_(INFO) << "detach is running"; 1388 if (param1 == nullptr && param2 == nullptr) { 1389 GTEST_LOG_(INFO) << "detach: two params is nullptr"; 1390 } 1391 if (hint == nullptr && detachData) { 1392 GTEST_LOG_(INFO) << "detach: hint is nullptr"; 1393 } 1394 return nullptr; 1395} 1396 1397static void* Attach([[maybe_unused]] void *enginePointer, [[maybe_unused]] void *buffer, [[maybe_unused]] void *hint, 1398 [[maybe_unused]] void *attachData) 1399{ 1400 GTEST_LOG_(INFO) << "attach is running"; 1401 return nullptr; 1402} 1403 1404static panda::JSNApi::NativeBindingInfo* CreateNativeBindingInfo(void* attach, void* detach) 1405{ 1406 GTEST_LOG_(INFO) << "CreateNativeBindingInfo"; 1407 auto info = panda::JSNApi::NativeBindingInfo::CreateNewInstance(); 1408 info->attachFunc = attach; 1409 info->detachFunc = detach; 1410 return info; 1411} 1412 1413HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject1) 1414{ 1415 ObjectFactory *factory = ecmaVm->GetFactory(); 1416 JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 1417 JSHandle<JSObject> obj1 = factory->NewEmptyJSObject(); 1418 1419 JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol(); 1420 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x")); 1421 auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach)); 1422 JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info))); 1423 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1)); 1424 1425 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1); 1426 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2); 1427 obj1->GetClass()->SetIsNativeBindingObject(true); 1428 1429 ValueSerializer *serializer = new ValueSerializer(thread); 1430 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj1), 1431 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1432 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1433 EXPECT_TRUE(success) << "Serialize fail"; 1434 std::unique_ptr<SerializeData> data = serializer->Release(); 1435 JSDeserializerTest jsDeserializerTest; 1436 std::thread t1(&JSDeserializerTest::NativeBindingObjectTest1, jsDeserializerTest, data.release()); 1437 ThreadSuspensionScope scope(thread); 1438 t1.join(); 1439 delete serializer; 1440} 1441 1442HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject2) 1443{ 1444 ObjectFactory *factory = ecmaVm->GetFactory(); 1445 JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 1446 JSHandle<JSObject> obj1 = factory->NewEmptyJSObject(); 1447 JSHandle<JSObject> obj2 = factory->NewEmptyJSObject(); 1448 1449 JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol(); 1450 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x")); 1451 JSHandle<JSTaggedValue> key3(factory->NewFromASCII("xx")); 1452 auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach)); 1453 JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info))); 1454 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1)); 1455 JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(2)); 1456 1457 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1); 1458 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2); 1459 obj1->GetClass()->SetIsNativeBindingObject(true); 1460 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2, JSHandle<JSTaggedValue>(obj1)); 1461 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key3, value3); 1462 1463 ValueSerializer *serializer = new ValueSerializer(thread); 1464 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj2), 1465 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1466 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1467 EXPECT_TRUE(success) << "Serialize fail"; 1468 std::unique_ptr<SerializeData> data = serializer->Release(); 1469 JSDeserializerTest jsDeserializerTest; 1470 std::thread t1(&JSDeserializerTest::NativeBindingObjectTest2, jsDeserializerTest, data.release()); 1471 ThreadSuspensionScope scope(thread); 1472 t1.join(); 1473 delete serializer; 1474} 1475 1476HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject3) 1477{ 1478 ObjectFactory *factory = ecmaVm->GetFactory(); 1479 JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 1480 JSHandle<JSObject> obj1 = factory->NewEmptyJSObject(); 1481 1482 JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol(); 1483 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x")); 1484 auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), nullptr); 1485 JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info))); 1486 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1)); 1487 1488 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1); 1489 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2); 1490 obj1->GetClass()->SetIsNativeBindingObject(true); 1491 1492 ValueSerializer *serializer = new ValueSerializer(thread); 1493 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj1), 1494 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1495 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1496 EXPECT_FALSE(success); 1497 std::unique_ptr<SerializeData> data = serializer->Release(); 1498 BaseDeserializer deserializer(thread, data.release()); 1499 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 1500 EXPECT_TRUE(res.IsEmpty()); 1501 delete serializer; 1502} 1503 1504HWTEST_F_L0(JSSerializerTest, TestSerializeJSSet) 1505{ 1506 ObjectFactory *factory = ecmaVm->GetFactory(); 1507 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1508 1509 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsSetFunction(); 1510 JSHandle<JSSet> set = 1511 JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor)); 1512 JSHandle<LinkedHashSet> linkedSet = LinkedHashSet::Create(thread); 1513 set->SetLinkedSet(thread, linkedSet); 1514 // set property to set 1515 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7)); 1516 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9)); 1517 JSHandle<JSTaggedValue> value3(factory->NewFromASCII("x")); 1518 JSHandle<JSTaggedValue> value4(factory->NewFromASCII("y")); 1519 1520 JSSet::Add(thread, set, value1); 1521 JSSet::Add(thread, set, value2); 1522 JSSet::Add(thread, set, value3); 1523 JSSet::Add(thread, set, value4); 1524 1525 // set property to object 1526 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("5")); 1527 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("6")); 1528 1529 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(set), key1, value1); 1530 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(set), key2, value2); 1531 1532 ValueSerializer *serializer = new ValueSerializer(thread); 1533 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(set), 1534 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1535 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1536 EXPECT_TRUE(success) << "Serialize JSSet fail"; 1537 std::unique_ptr<SerializeData> data = serializer->Release(); 1538 JSDeserializerTest jsDeserializerTest; 1539 std::thread t1(&JSDeserializerTest::JSSetTest, jsDeserializerTest, data.release()); 1540 ThreadSuspensionScope scope(thread); 1541 t1.join(); 1542 delete serializer; 1543}; 1544 1545JSDate *JSDateCreate(EcmaVM *ecmaVM) 1546{ 1547 ObjectFactory *factory = ecmaVM->GetFactory(); 1548 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv(); 1549 JSHandle<JSTaggedValue> dateFunction = globalEnv->GetDateFunction(); 1550 JSHandle<JSDate> dateObject = 1551 JSHandle<JSDate>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dateFunction), dateFunction)); 1552 return *dateObject; 1553} 1554 1555HWTEST_F_L0(JSSerializerTest, SerializeDate) 1556{ 1557 double tm = 28 * 60 * 60 * 1000; 1558 JSHandle<JSDate> jsDate(thread, JSDateCreate(ecmaVm)); 1559 jsDate->SetTimeValue(thread, JSTaggedValue(tm)); 1560 1561 ValueSerializer *serializer = new ValueSerializer(thread); 1562 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsDate), 1563 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1564 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1565 EXPECT_TRUE(success) << "Serialize JSDate fail"; 1566 std::unique_ptr<SerializeData> data = serializer->Release(); 1567 JSDeserializerTest jsDeserializerTest; 1568 std::thread t1(&JSDeserializerTest::JSDateTest, jsDeserializerTest, data.release()); 1569 ThreadSuspensionScope scope(thread); 1570 t1.join(); 1571 delete serializer; 1572}; 1573 1574JSMap *CreateMap(JSThread *thread) 1575{ 1576 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1577 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1578 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsMapFunction(); 1579 JSHandle<JSMap> map = 1580 JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor)); 1581 JSHandle<LinkedHashMap> linkedMap = LinkedHashMap::Create(thread); 1582 map->SetLinkedMap(thread, linkedMap); 1583 return *map; 1584} 1585 1586HWTEST_F_L0(JSSerializerTest, SerializeJSMap) 1587{ 1588 JSHandle<JSMap> map(thread, CreateMap(thread)); 1589 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1590 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("3")); 1591 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(12345)); 1592 JSMap::Set(thread, map, key1, value1); 1593 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key1")); 1594 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(34567)); 1595 JSMap::Set(thread, map, key2, value2); 1596 1597 ValueSerializer *serializer = new ValueSerializer(thread); 1598 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(map), 1599 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1600 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1601 EXPECT_TRUE(success) << "Serialize JSMap fail"; 1602 std::unique_ptr<SerializeData> data = serializer->Release(); 1603 JSDeserializerTest jsDeserializerTest; 1604 std::thread t1(&JSDeserializerTest::JSMapTest, jsDeserializerTest, data.release(), map); 1605 ThreadSuspensionScope scope(thread); 1606 t1.join(); 1607 delete serializer; 1608}; 1609 1610HWTEST_F_L0(JSSerializerTest, SerializeJSRegExp) 1611{ 1612 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1613 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1614 JSHandle<JSTaggedValue> target = env->GetRegExpFunction(); 1615 JSHandle<JSRegExp> jsRegexp = 1616 JSHandle<JSRegExp>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target)); 1617 JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"); 1618 JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i"); 1619 char buffer[] = "1234567"; // use char to simulate bytecode 1620 uint32_t bufferSize = 7; 1621 factory->NewJSRegExpByteCodeData(jsRegexp, static_cast<void *>(buffer), bufferSize); 1622 jsRegexp->SetOriginalSource(thread, JSHandle<JSTaggedValue>(pattern)); 1623 jsRegexp->SetOriginalFlags(thread, JSHandle<JSTaggedValue>(flags)); 1624 1625 ValueSerializer *serializer = new ValueSerializer(thread); 1626 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsRegexp), 1627 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1628 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1629 EXPECT_TRUE(success) << "Serialize JSRegExp fail"; 1630 std::unique_ptr<SerializeData> data = serializer->Release(); 1631 JSDeserializerTest jsDeserializerTest; 1632 std::thread t1(&JSDeserializerTest::JSRegexpTest, jsDeserializerTest, data.release()); 1633 ThreadSuspensionScope scope(thread); 1634 t1.join(); 1635 delete serializer; 1636}; 1637 1638HWTEST_F_L0(JSSerializerTest, TestSerializeJSArray) 1639{ 1640 ObjectFactory *factory = ecmaVm->GetFactory(); 1641 JSHandle<JSArray> array = factory->NewJSArray(); 1642 1643 // set property to object 1644 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("abasd")); 1645 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("qweqwedasd")); 1646 1647 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7)); 1648 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9)); 1649 1650 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(array), key1, value1); 1651 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(array), key2, value2); 1652 1653 // set value to array 1654 array->SetArrayLength(thread, 20); 1655 for (int i = 0; i < 20; i++) { 1656 JSHandle<JSTaggedValue> data(thread, JSTaggedValue(i)); 1657 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>::Cast(array), i, data); 1658 } 1659 1660 ValueSerializer *serializer = new ValueSerializer(thread); 1661 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(array), 1662 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1663 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1664 EXPECT_TRUE(success) << "Serialize JSArray fail"; 1665 std::unique_ptr<SerializeData> data = serializer->Release(); 1666 JSDeserializerTest jsDeserializerTest; 1667 std::thread t1(&JSDeserializerTest::JSArrayTest, jsDeserializerTest, data.release()); 1668 ThreadSuspensionScope scope(thread); 1669 t1.join(); 1670 delete serializer; 1671}; 1672 1673HWTEST_F_L0(JSSerializerTest, SerializeEcmaString1) 1674{ 1675 const char *rawStr = "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\ 1676 "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\ 1677 "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\ 1678 "ssssss"; 1679 JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(rawStr); 1680 1681 ValueSerializer *serializer = new ValueSerializer(thread); 1682 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(ecmaString), 1683 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1684 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1685 EXPECT_TRUE(success) << "Serialize EcmaString fail"; 1686 std::unique_ptr<SerializeData> data = serializer->Release(); 1687 JSDeserializerTest jsDeserializerTest; 1688 std::thread t1(&JSDeserializerTest::EcmaStringTest1, jsDeserializerTest, data.release()); 1689 ThreadSuspensionScope scope(thread); 1690 t1.join(); 1691 delete serializer; 1692}; 1693 1694// Test EcmaString contains Chinese Text 1695HWTEST_F_L0(JSSerializerTest, SerializeEcmaString2) 1696{ 1697 std::string rawStr = "你好,世界"; 1698 JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromStdString(rawStr); 1699 1700 ValueSerializer *serializer = new ValueSerializer(thread); 1701 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(ecmaString), 1702 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1703 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1704 EXPECT_TRUE(success) << "Serialize EcmaString fail"; 1705 std::unique_ptr<SerializeData> data = serializer->Release(); 1706 JSDeserializerTest jsDeserializerTest; 1707 std::thread t1(&JSDeserializerTest::EcmaStringTest2, jsDeserializerTest, data.release()); 1708 ThreadSuspensionScope scope(thread); 1709 t1.join(); 1710 delete serializer; 1711}; 1712 1713HWTEST_F_L0(JSSerializerTest, SerializeInt32_t) 1714{ 1715 int32_t a = 64, min = -2147483648, b = -63; 1716 JSTaggedValue aTag(a), minTag(min), bTag(b); 1717 1718 ValueSerializer *serializer = new ValueSerializer(thread); 1719 serializer->SerializeJSTaggedValue(aTag); 1720 serializer->SerializeJSTaggedValue(minTag); 1721 serializer->SerializeJSTaggedValue(bTag); 1722 std::unique_ptr<SerializeData> data = serializer->Release(); 1723 1724 JSDeserializerTest jsDeserializerTest; 1725 std::thread t1(&JSDeserializerTest::Int32Test, jsDeserializerTest, data.release()); 1726 ThreadSuspensionScope scope(thread); 1727 t1.join(); 1728 delete serializer; 1729}; 1730 1731HWTEST_F_L0(JSSerializerTest, SerializeDouble) 1732{ 1733 double a = 3.1415926535, b = -3.1415926535; 1734 JSTaggedValue aTag(a), bTag(b); 1735 1736 ValueSerializer *serializer = new ValueSerializer(thread); 1737 serializer->SerializeJSTaggedValue(aTag); 1738 serializer->SerializeJSTaggedValue(bTag); 1739 std::unique_ptr<SerializeData> data = serializer->Release(); 1740 1741 JSDeserializerTest jsDeserializerTest; 1742 std::thread t1(&JSDeserializerTest::DoubleTest, jsDeserializerTest, data.release()); 1743 ThreadSuspensionScope scope(thread); 1744 t1.join(); 1745 delete serializer; 1746}; 1747 1748JSArrayBuffer *CreateJSArrayBuffer(JSThread *thread) 1749{ 1750 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1751 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1752 JSHandle<JSTaggedValue> target = env->GetArrayBufferFunction(); 1753 JSHandle<JSArrayBuffer> jsArrayBuffer = 1754 JSHandle<JSArrayBuffer>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target)); 1755 return *jsArrayBuffer; 1756} 1757 1758HWTEST_F_L0(JSSerializerTest, SerializeObjectWithConcurrentFunction) 1759{ 1760 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1761 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1762 JSHandle<JSFunction> concurrentFunction1 = factory->NewJSFunction(env, nullptr, FunctionKind::CONCURRENT_FUNCTION); 1763 EXPECT_TRUE(concurrentFunction1->IsJSFunction()); 1764 EXPECT_TRUE(concurrentFunction1->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION); 1765 JSHandle<JSFunction> concurrentFunction2 = factory->NewJSFunction(env, nullptr, FunctionKind::CONCURRENT_FUNCTION); 1766 EXPECT_TRUE(concurrentFunction2->IsJSFunction()); 1767 EXPECT_TRUE(concurrentFunction2->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION); 1768 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("1")); 1769 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("2")); 1770 JSHandle<JSTaggedValue> key3(factory->NewFromASCII("abc")); 1771 JSHandle<JSTaggedValue> key4(factory->NewFromASCII("4")); 1772 JSHandle<JSTaggedValue> key5(factory->NewFromASCII("key")); 1773 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(12345)); 1774 JSHandle<JSTaggedValue> value2(factory->NewFromASCII("def")); 1775 JSHandle<JSTaggedValue> value3(factory->NewFromASCII("value")); 1776 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1777 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1); 1778 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, JSHandle<JSTaggedValue>(concurrentFunction1)); 1779 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value2); 1780 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value1); 1781 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key5, JSHandle<JSTaggedValue>(concurrentFunction2)); 1782 1783 ValueSerializer *serializer = new ValueSerializer(thread); 1784 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1785 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1786 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1787 EXPECT_TRUE(success) << "Serialize concurrent function fail"; 1788 std::unique_ptr<SerializeData> data = serializer->Release(); 1789 JSDeserializerTest jsDeserializerTest; 1790 1791 std::thread t1(&JSDeserializerTest::ObjectWithConcurrentFunctionTest, jsDeserializerTest, data.release()); 1792 ThreadSuspensionScope scope(thread); 1793 t1.join(); 1794 delete serializer; 1795}; 1796 1797// not support most function except concurrent function 1798HWTEST_F_L0(JSSerializerTest, SerializeFunction) 1799{ 1800 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1801 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1802 JSHandle<JSFunction> function = factory->NewJSFunction(env, nullptr, FunctionKind::NORMAL_FUNCTION); 1803 EXPECT_TRUE(function->IsJSFunction()); 1804 1805 ValueSerializer *serializer = new ValueSerializer(thread); 1806 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(function), 1807 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1808 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1809 EXPECT_FALSE(success); 1810 std::unique_ptr<SerializeData> data = serializer->Release(); 1811 BaseDeserializer deserializer(thread, data.release()); 1812 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 1813 EXPECT_TRUE(res.IsEmpty()); 1814 delete serializer; 1815} 1816 1817// Test transfer JSArrayBuffer 1818HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer1) 1819{ 1820 ObjectFactory *factory = ecmaVm->GetFactory(); 1821 1822 // create a JSArrayBuffer 1823 size_t length = 5; 1824 uint8_t value = 100; 1825 void *buffer = ecmaVm->GetNativeAreaAllocator()->AllocateBuffer(length); 1826 if (memset_s(buffer, length, value, length) != EOK) { 1827 LOG_ECMA(FATAL) << "this branch is unreachable"; 1828 UNREACHABLE(); 1829 } 1830 JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer, 1831 length, NativeAreaAllocator::FreeBufferFunc, ecmaVm->GetNativeAreaAllocator()); 1832 JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>(arrBuf); 1833 1834 JSHandle<JSArray> array = factory->NewJSArray(); 1835 1836 // set value to array 1837 array->SetArrayLength(thread, 1); 1838 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, arrBufTag); 1839 1840 ValueSerializer *serializer = new ValueSerializer(thread); 1841 bool success = serializer->WriteValue(thread, arrBufTag, JSHandle<JSTaggedValue>(array), 1842 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1843 EXPECT_TRUE(success) << "Serialize transfer JSArrayBuffer fail"; 1844 std::unique_ptr<SerializeData> data = serializer->Release(); 1845 JSDeserializerTest jsDeserializerTest; 1846 std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest1, 1847 jsDeserializerTest, 1848 data.release(), 1849 reinterpret_cast<uintptr_t>(buffer)); 1850 ThreadSuspensionScope scope(thread); 1851 t1.join(); 1852 delete serializer; 1853 // test if detached 1854 EXPECT_TRUE(arrBuf->IsDetach()); 1855}; 1856 1857// Test serialize JSArrayBuffer that not transfer 1858HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer2) 1859{ 1860 ObjectFactory *factory = ecmaVm->GetFactory(); 1861 1862 // create a JSArrayBuffer 1863 size_t length = 5; 1864 uint8_t value = 100; 1865 void *buffer = ecmaVm->GetNativeAreaAllocator()->AllocateBuffer(length); 1866 if (memset_s(buffer, length, value, length) != EOK) { 1867 LOG_ECMA(FATAL) << "this branch is unreachable"; 1868 UNREACHABLE(); 1869 } 1870 JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer, 1871 length, NativeAreaAllocator::FreeBufferFunc, ecmaVm->GetNativeAreaAllocator()); 1872 JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf); 1873 1874 ValueSerializer *serializer = new ValueSerializer(thread); 1875 bool success = serializer->WriteValue(thread, arrBufTag, 1876 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1877 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1878 EXPECT_TRUE(success) << "Serialize not transfer JSArrayBuffer fail"; 1879 std::unique_ptr<SerializeData> data = serializer->Release(); 1880 JSDeserializerTest jsDeserializerTest; 1881 std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest2, 1882 jsDeserializerTest, 1883 data.release(), 1884 reinterpret_cast<uintptr_t>(buffer)); 1885 ThreadSuspensionScope scope(thread); 1886 t1.join(); 1887 delete serializer; 1888 // test if detached 1889 EXPECT_FALSE(arrBuf->IsDetach()); 1890}; 1891 1892// Test serialize an empty JSArrayBuffer 1893HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer3) 1894{ 1895 ObjectFactory *factory = ecmaVm->GetFactory(); 1896 1897 // create a JSArrayBuffer 1898 JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(0); 1899 JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf); 1900 1901 ValueSerializer *serializer = new ValueSerializer(thread); 1902 bool success = serializer->WriteValue(thread, arrBufTag, 1903 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1904 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1905 EXPECT_TRUE(success) << "Serialize empty JSArrayBuffer fail"; 1906 std::unique_ptr<SerializeData> data = serializer->Release(); 1907 JSDeserializerTest jsDeserializerTest; 1908 std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest3, jsDeserializerTest, data.release()); 1909 ThreadSuspensionScope scope(thread); 1910 t1.join(); 1911 delete serializer; 1912 // test if detached 1913 EXPECT_FALSE(arrBuf->IsDetach()); 1914}; 1915 1916// Test serialize JSArrayBuffer with external native buffer that not transfer 1917HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer4) 1918{ 1919 ObjectFactory *factory = ecmaVm->GetFactory(); 1920 1921 // create a JSArrayBuffer 1922 size_t length = 5; 1923 uint8_t value = 100; 1924 void *buffer = reinterpret_cast<void *>(malloc(length)); 1925 if (memset_s(buffer, length, value, length) != EOK) { 1926 LOG_ECMA(FATAL) << "this branch is unreachable"; 1927 UNREACHABLE(); 1928 } 1929 JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer, length, nullptr, nullptr); 1930 JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf); 1931 1932 ValueSerializer *serializer = new ValueSerializer(thread); 1933 bool res = serializer->WriteValue(thread, arrBufTag, 1934 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1935 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1936 EXPECT_FALSE(res) << "serialize JSArrayBuffer with external native shall not clone it"; 1937 free(buffer); 1938}; 1939 1940void ArrayBufferDeleter([[maybe_unused]] void *env, void *buf, [[maybe_unused]] void *data) 1941{ 1942 free(buf); 1943} 1944 1945// Test serialize JSArrayBuffer with external native buffer that transfer 1946HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer5) 1947{ 1948 ObjectFactory *factory = ecmaVm->GetFactory(); 1949 1950 // create a JSArrayBuffer 1951 size_t length = 5; 1952 uint8_t value = 100; 1953 void *buffer = reinterpret_cast<void *>(malloc(length)); 1954 if (memset_s(buffer, length, value, length) != EOK) { 1955 LOG_ECMA(FATAL) << "this branch is unreachable"; 1956 UNREACHABLE(); 1957 } 1958 JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer, length, ArrayBufferDeleter, nullptr); 1959 JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf); 1960 1961 ValueSerializer *serializer = new ValueSerializer(thread, true); 1962 bool res = serializer->WriteValue(thread, arrBufTag, 1963 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 1964 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1965 EXPECT_TRUE(res) << "serialize JSArrayBuffer with external pointer fail"; 1966 EXPECT_TRUE(arrBuf->IsDetach()); 1967 std::unique_ptr<SerializeData> data = serializer->Release(); 1968 JSDeserializerTest jsDeserializerTest; 1969 std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest5, jsDeserializerTest, data.release()); 1970 ThreadSuspensionScope scope(thread); 1971 t1.join(); 1972 delete serializer; 1973}; 1974 1975HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer6) 1976{ 1977 ObjectFactory *factory = ecmaVm->GetFactory(); 1978 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1979 JSHandle<EcmaString> transfer(factory->NewFromASCII("transfer")); 1980 ValueSerializer *serializer = new ValueSerializer(thread); 1981 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 1982 JSHandle<JSTaggedValue>(transfer), 1983 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 1984 EXPECT_FALSE(success); 1985 std::unique_ptr<SerializeData> data = serializer->Release(); 1986 BaseDeserializer deserializer(thread, data.release()); 1987 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 1988 EXPECT_TRUE(res.IsEmpty()); 1989 delete serializer; 1990}; 1991 1992HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer7) 1993{ 1994 ObjectFactory *factory = ecmaVm->GetFactory(); 1995 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 1996 JSHandle<EcmaString> transfer(factory->NewFromASCII("transfer")); 1997 JSHandle<JSArray> array = factory->NewJSArray(); 1998 // set value to array 1999 array->SetArrayLength(thread, 1); 2000 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(transfer)); 2001 ValueSerializer *serializer = new ValueSerializer(thread); 2002 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 2003 JSHandle<JSTaggedValue>(array), 2004 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2005 EXPECT_FALSE(success); 2006 std::unique_ptr<SerializeData> data = serializer->Release(); 2007 BaseDeserializer deserializer(thread, data.release()); 2008 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 2009 EXPECT_TRUE(res.IsEmpty()); 2010 delete serializer; 2011}; 2012 2013HWTEST_F_L0(JSSerializerTest, SerializeJSArrayBufferShared2) 2014{ 2015 std::string msg = "hello world"; 2016 int msgBufferLen = static_cast<int>(msg.length()) + 1; 2017 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2018 JSHandle<JSArrayBuffer> jsArrayBuffer = factory->NewJSSharedArrayBuffer(msgBufferLen); 2019 JSHandle<JSTaggedValue> BufferData(thread, jsArrayBuffer->GetArrayBufferData()); 2020 JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(BufferData); 2021 void *buffer = resNp->GetExternalPointer(); 2022 if (memcpy_s(buffer, msgBufferLen, msg.c_str(), msgBufferLen) != EOK) { 2023 EXPECT_TRUE(false) << " memcpy error"; 2024 } 2025 2026 ValueSerializer *serializer = new ValueSerializer(thread); 2027 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsArrayBuffer), 2028 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2029 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2030 EXPECT_TRUE(success) << "Serialize JSSharedArrayBuffer fail"; 2031 std::unique_ptr<SerializeData> data = serializer->Release(); 2032 JSDeserializerTest jsDeserializerTest; 2033 std::string changeStr = "world hello"; 2034 std::thread t1(&JSDeserializerTest::JSSharedArrayBufferTest, 2035 jsDeserializerTest, data.release(), 12, changeStr.c_str()); 2036 ThreadSuspensionScope scope(thread); 2037 t1.join(); 2038 EXPECT_TRUE(strcmp((char *)buffer, "world hello") == 0) << "Serialize JSArrayBuffer fail"; 2039 delete serializer; 2040}; 2041 2042HWTEST_F_L0(JSSerializerTest, SerializeJSArrayBufferShared3) 2043{ 2044 std::string msg = "hello world"; 2045 int msgBufferLen = static_cast<int>(msg.length()) + 1; 2046 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2047 JSHandle<JSArrayBuffer> jsArrayBuffer = factory->NewJSSharedArrayBuffer(msgBufferLen); 2048 JSHandle<JSTaggedValue> BufferData(thread, jsArrayBuffer->GetArrayBufferData()); 2049 JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(BufferData); 2050 void *buffer = resNp->GetExternalPointer(); 2051 if (memcpy_s(buffer, msgBufferLen, msg.c_str(), msgBufferLen) != EOK) { 2052 EXPECT_TRUE(false) << " memcpy error"; 2053 } 2054 2055 ValueSerializer *serializer = new ValueSerializer(thread); 2056 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsArrayBuffer), 2057 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2058 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2059 EXPECT_TRUE(success) << "Serialize JSSharedArrayBuffer fail"; 2060 std::unique_ptr<SerializeData> data = serializer->Release(); 2061 JSDeserializerTest jsDeserializerTest; 2062 std::string changeStr = "world hello"; 2063 std::thread t1(&JSDeserializerTest::JSSharedArrayBufferTest, 2064 jsDeserializerTest, data.get(), 12, changeStr.c_str()); 2065 { 2066 ThreadSuspensionScope scope(thread); 2067 t1.join(); 2068 EXPECT_TRUE(strcmp((char *)buffer, "world hello") == 0) << "Serialize JSArrayBuffer fail"; 2069 changeStr = "world hella"; 2070 JSDeserializerTest jsDeserializerTest1; 2071 std::thread t2(&JSDeserializerTest::JSSharedArrayBufferTest, 2072 jsDeserializerTest1, data.get(), 12, changeStr.c_str()); 2073 t2.join(); 2074 EXPECT_TRUE(strcmp((char *)buffer, "world hella") == 0) << "Serialize JSArrayBuffer fail"; 2075 changeStr = "world hellb"; 2076 JSDeserializerTest jsDeserializerTest2; 2077 std::thread t3(&JSDeserializerTest::JSSharedArrayBufferTest, 2078 jsDeserializerTest2, data.get(), 12, changeStr.c_str()); 2079 t3.join(); 2080 EXPECT_TRUE(strcmp((char *)buffer, "world hellb") == 0) << "Serialize JSArrayBuffer fail"; 2081 } 2082 delete serializer; 2083 data.reset(); 2084 EXPECT_TRUE(JSHandle<JSTaggedValue>(jsArrayBuffer)->IsSharedArrayBuffer()); 2085}; 2086 2087HWTEST_F_L0(JSSerializerTest, SerializeJSNativePointer) 2088{ 2089 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2090 JSHandle<JSNativePointer> np = factory->NewJSNativePointer(nullptr); 2091 ValueSerializer *serializer = new ValueSerializer(thread); 2092 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(np), 2093 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2094 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2095 // Don't support serialize JSNativePointer directly 2096 EXPECT_TRUE(!success); 2097 std::unique_ptr<SerializeData> data = serializer->Release(); 2098 EXPECT_TRUE(data->IsIncompleteData()); 2099 delete serializer; 2100} 2101 2102JSArrayBuffer *CreateTestJSArrayBuffer(JSThread *thread) 2103{ 2104 JSHandle<JSArrayBuffer> jsArrayBuffer(thread, CreateJSArrayBuffer(thread)); 2105 int32_t byteLength = 10; 2106 thread->GetEcmaVM()->GetFactory()->NewJSArrayBufferData(jsArrayBuffer, byteLength); 2107 jsArrayBuffer->SetArrayBufferByteLength(byteLength); 2108 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(jsArrayBuffer); 2109 JSMutableHandle<JSTaggedValue> number(thread, JSTaggedValue::Undefined()); 2110 for (int i = 0; i < 10; i++) { // 10: arrayLength 2111 number.Update(JSTaggedValue(i)); 2112 BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), i, DataViewType::UINT8, 2113 number, true); 2114 } 2115 return *jsArrayBuffer; 2116} 2117 2118HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray1) 2119{ 2120 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2121 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 2122 JSHandle<JSTaggedValue> target = env->GetInt8ArrayFunction(); 2123 JSHandle<JSTypedArray> int8Array = 2124 JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target)); 2125 JSHandle<JSTaggedValue> viewedArrayBuffer(thread, CreateTestJSArrayBuffer(thread)); 2126 int8Array->SetViewedArrayBufferOrByteArray(thread, viewedArrayBuffer); 2127 int byteLength = 10; 2128 int byteOffset = 0; 2129 int arrayLength = (byteLength - byteOffset) / (sizeof(int8_t)); 2130 int8Array->SetByteLength(byteLength); 2131 int8Array->SetByteOffset(byteOffset); 2132 int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString()); 2133 int8Array->SetArrayLength(arrayLength); 2134 int8Array->SetContentType(ContentType::Number); 2135 2136 ValueSerializer *serializer = new ValueSerializer(thread); 2137 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(int8Array), 2138 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2139 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2140 EXPECT_TRUE(success) << "Serialize type array fail"; 2141 std::unique_ptr<SerializeData> data = serializer->Release(); 2142 JSDeserializerTest jsDeserializerTest; 2143 std::thread t1(&JSDeserializerTest::TypedArrayTest1, jsDeserializerTest, data.release()); 2144 ThreadSuspensionScope scope(thread); 2145 t1.join(); 2146 delete serializer; 2147}; 2148 2149HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray2) 2150{ 2151 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2152 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 2153 JSHandle<JSTaggedValue> target = env->GetInt8ArrayFunction(); 2154 JSHandle<JSTypedArray> int8Array = 2155 JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target)); 2156 uint8_t value = 255; // 255 : test case 2157 JSTaggedType val = JSTaggedValue(value).GetRawData(); 2158 int byteArrayLength = 10; // 10: arrayLength 2159 JSHandle<ByteArray> byteArray = factory->NewByteArray(byteArrayLength, sizeof(value)); 2160 for (int i = 0; i < byteArrayLength; i++) { 2161 byteArray->Set(thread, i, DataViewType::UINT8, val); 2162 } 2163 int8Array->SetViewedArrayBufferOrByteArray(thread, byteArray); 2164 int byteLength = 10; 2165 int byteOffset = 0; 2166 int arrayLength = (byteLength - byteOffset) / (sizeof(int8_t)); 2167 int8Array->SetByteLength(byteLength); 2168 int8Array->SetByteOffset(byteOffset); 2169 int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString()); 2170 int8Array->SetArrayLength(arrayLength); 2171 int8Array->SetContentType(ContentType::Number); 2172 2173 ValueSerializer *serializer = new ValueSerializer(thread); 2174 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(int8Array), 2175 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2176 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2177 EXPECT_TRUE(success) << "Serialize type array fail"; 2178 std::unique_ptr<SerializeData> data = serializer->Release(); 2179 JSDeserializerTest jsDeserializerTest; 2180 std::thread t1(&JSDeserializerTest::TypedArrayTest2, jsDeserializerTest, data.release()); 2181 ThreadSuspensionScope scope(thread); 2182 t1.join(); 2183 delete serializer; 2184}; 2185 2186JSHandle<JSObject> CreateEmptySObject(JSThread *thread) 2187{ 2188 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2189 const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 2190 JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull(); 2191 JSHandle<LayoutInfo> emptyLayout = factory->CreateSLayoutInfo(0); 2192 JSHandle<JSHClass> hclass = factory->NewSEcmaHClass(JSSharedObject::SIZE, 0, JSType::JS_SHARED_OBJECT, nullHandle, 2193 JSHandle<JSTaggedValue>(emptyLayout)); 2194 return factory->NewSharedOldSpaceJSObject(hclass); 2195} 2196 2197JSHandle<JSObject> CreateSObject(JSThread *thread) 2198{ 2199 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2200 const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 2201 JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull(); 2202 2203 uint32_t index = 0; 2204 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false); 2205 attributes.SetIsInlinedProps(true); 2206 attributes.SetRepresentation(Representation::TAGGED); 2207 uint32_t length = 4; 2208 JSHandle<LayoutInfo> layout = factory->CreateSLayoutInfo(length); 2209 2210 JSHandle<EcmaString> key1(factory->NewFromASCII("str1")); 2211 JSHandle<EcmaString> key2(factory->NewFromASCII("str2")); 2212 2213 while (index < length) { 2214 attributes.SetOffset(index); 2215 attributes.SetIsAccessor(false); 2216 key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(thread->GetEcmaVM(), key2, key1)); 2217 auto stringTable = thread->GetEcmaVM()->GetEcmaStringTable(); 2218 stringTable->GetOrInternString(thread->GetEcmaVM(), *key2); 2219 layout->AddKey(thread, index++, key2.GetTaggedValue(), attributes); 2220 } 2221 2222 JSHandle<JSHClass> hclass = factory->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT, 2223 nullHandle, JSHandle<JSTaggedValue>(layout)); 2224 JSHandle<JSObject> object = factory->NewSharedOldSpaceJSObject(hclass); 2225 uint32_t fieldIndex = 0; 2226 while (fieldIndex < length) { 2227 JSHandle<JSObject> emptyObject = CreateEmptySObject(thread); 2228 object->SetPropertyInlinedProps(thread, fieldIndex++, emptyObject.GetTaggedValue()); 2229 } 2230 return object; 2231} 2232 2233JSHandle<JSSharedSet> CreateSSet(JSThread *thread) 2234{ 2235 auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 2236 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2237 JSHandle<JSTaggedValue> proto = globalEnv->GetSharedSetPrototype(); 2238 auto emptySLayout = thread->GlobalConstants()->GetHandledEmptySLayoutInfo(); 2239 JSHandle<JSHClass> setClass = factory->NewSEcmaHClass(JSSharedSet::SIZE, 0, 2240 JSType::JS_SHARED_SET, proto, emptySLayout); 2241 JSHandle<JSSharedSet> jsSet = JSHandle<JSSharedSet>::Cast(factory->NewSharedOldSpaceJSObjectWithInit(setClass)); 2242 JSHandle<LinkedHashSet> linkedSet( 2243 LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED)); 2244 jsSet->SetLinkedSet(thread, linkedSet); 2245 jsSet->SetModRecord(0); 2246 return jsSet; 2247} 2248 2249JSHandle<JSSharedMap> CreateSMap(JSThread *thread) 2250{ 2251 auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 2252 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2253 JSHandle<JSTaggedValue> proto = globalEnv->GetSharedMapPrototype(); 2254 auto emptySLayout = thread->GlobalConstants()->GetHandledEmptySLayoutInfo(); 2255 JSHandle<JSHClass> mapClass = factory->NewSEcmaHClass(JSSharedMap::SIZE, 0, 2256 JSType::JS_SHARED_MAP, proto, emptySLayout); 2257 JSHandle<JSSharedMap> jsMap = JSHandle<JSSharedMap>::Cast(factory->NewSharedOldSpaceJSObjectWithInit(mapClass)); 2258 JSHandle<LinkedHashMap> linkedMap( 2259 LinkedHashMap::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED)); 2260 jsMap->SetLinkedMap(thread, linkedMap); 2261 jsMap->SetModRecord(0); 2262 return jsMap; 2263} 2264 2265HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest1) 2266{ 2267 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2268 JSHandle<JSObject> shareObj = CreateSObject(thread); 2269 Region *region = Region::ObjectAddressToRange(*shareObj); 2270 EXPECT_TRUE(region->InSharedHeap()); 2271 2272 JSHandle<EcmaString> key(factory->NewFromASCII("str2str1")); 2273 JSHandle<JSTaggedValue> shareObj1 = 2274 JSObject::GetProperty(thread, JSHandle<JSObject>(shareObj), JSHandle<JSTaggedValue>(key)).GetValue(); 2275 Region *region1 = Region::ObjectAddressToRange(shareObj1->GetTaggedObject()); 2276 EXPECT_TRUE(region1->InSharedHeap()); 2277 2278 JSHandle<JSArray> array = factory->NewJSArray(); 2279 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(shareObj)); 2280 2281 ValueSerializer *serializer = new ValueSerializer(thread); 2282 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(shareObj), 2283 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2284 JSHandle<JSTaggedValue>(array)); 2285 EXPECT_TRUE(success) << "SerializeCloneListTest1: Serialize shared obj fail"; 2286 std::unique_ptr<SerializeData> data = serializer->Release(); 2287 JSDeserializerTest jsDeserializerTest; 2288 std::thread t1(&JSDeserializerTest::SerializeCloneListTest1, jsDeserializerTest, data.release()); 2289 ThreadSuspensionScope scope(thread); 2290 t1.join(); 2291 delete serializer; 2292}; 2293 2294HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest2) 2295{ 2296 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2297 JSHandle<JSObject> rootObj = factory->NewEmptyJSObject(); 2298 JSHandle<JSObject> shareObj = CreateSObject(thread); 2299 JSHandle<JSObject> noShareObj = CreateSObject(thread); 2300 2301 JSHandle<JSTaggedValue> key1(factory->NewFromASCII("shareObj")); 2302 JSHandle<JSTaggedValue> key2(factory->NewFromASCII("noShareObj")); 2303 2304 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(rootObj), key1, JSHandle<JSTaggedValue>(shareObj)); 2305 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(rootObj), key2, JSHandle<JSTaggedValue>(noShareObj)); 2306 2307 JSHandle<JSArray> array = factory->NewJSArray(); 2308 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(shareObj)); 2309 2310 ValueSerializer *serializer = new ValueSerializer(thread); 2311 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(rootObj), 2312 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2313 JSHandle<JSTaggedValue>(array)); 2314 EXPECT_TRUE(success) << "SerializeCloneListTest2: Serialize shared obj fail"; 2315 std::unique_ptr<SerializeData> data = serializer->Release(); 2316 JSDeserializerTest jsDeserializerTest; 2317 std::thread t1(&JSDeserializerTest::SerializeCloneListTest2, jsDeserializerTest, data.release()); 2318 ThreadSuspensionScope scope(thread); 2319 t1.join(); 2320 delete serializer; 2321}; 2322 2323HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest3) 2324{ 2325 ObjectFactory *factory = ecmaVm->GetFactory(); 2326 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 2327 JSHandle<EcmaString> cloneList(factory->NewFromASCII("cloneList")); 2328 ValueSerializer *serializer = new ValueSerializer(thread); 2329 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 2330 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2331 JSHandle<JSTaggedValue>(cloneList)); 2332 EXPECT_FALSE(success); 2333 std::unique_ptr<SerializeData> data = serializer->Release(); 2334 BaseDeserializer deserializer(thread, data.release()); 2335 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 2336 EXPECT_TRUE(res.IsEmpty()); 2337 delete serializer; 2338}; 2339 2340HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest4) 2341{ 2342 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2343 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 2344 2345 JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(0); 2346 JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf); 2347 JSHandle<JSArray> array = factory->NewJSArray(); 2348 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, arrBufTag); 2349 2350 ValueSerializer *serializer = new ValueSerializer(thread); 2351 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 2352 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2353 JSHandle<JSTaggedValue>(array)); 2354 EXPECT_TRUE(success) << "SerializeCloneListTest4: Serialize shared obj fail"; 2355 std::unique_ptr<SerializeData> data = serializer->Release(); 2356 JSDeserializerTest jsDeserializerTest; 2357 std::thread t1(&JSDeserializerTest::SerializeCloneListTest4, jsDeserializerTest, data.release()); 2358 ThreadSuspensionScope scope(thread); 2359 t1.join(); 2360 delete serializer; 2361}; 2362 2363HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest5) 2364{ 2365 ObjectFactory *factory = ecmaVm->GetFactory(); 2366 JSHandle<JSObject> obj = factory->NewEmptyJSObject(); 2367 JSHandle<JSObject> obj1 = factory->NewEmptyJSObject(); 2368 JSHandle<JSArray> array = factory->NewJSArray(); 2369 // set value to array 2370 array->SetArrayLength(thread, 1); 2371 JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(obj1)); 2372 ValueSerializer *serializer = new ValueSerializer(thread); 2373 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj), 2374 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2375 JSHandle<JSTaggedValue>(array)); 2376 EXPECT_FALSE(success); 2377 std::unique_ptr<SerializeData> data = serializer->Release(); 2378 BaseDeserializer deserializer(thread, data.release()); 2379 JSHandle<JSTaggedValue> res = deserializer.ReadValue(); 2380 EXPECT_TRUE(res.IsEmpty()); 2381 delete serializer; 2382}; 2383 2384HWTEST_F_L0(JSSerializerTest, SerializeJSSharedSetBasic1) 2385{ 2386 JSHandle<JSSharedSet> jsSet = CreateSSet(thread); 2387 ValueSerializer *serializer = new ValueSerializer(thread); 2388 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsSet), 2389 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2390 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2391 EXPECT_TRUE(success) << "Serialize JSSharedSet failed"; 2392 std::unique_ptr<SerializeData> data = serializer->Release(); 2393 { 2394 for (int i = 0; i < INITIALIZE_SIZE; i++) { 2395 JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i))); 2396 } 2397 JSDeserializerTest jsDeserializerTest; 2398 // The Deserializer thread will clear the shared set 2399 std::thread t1(&JSDeserializerTest::JSSharedSetBasicTest1, 2400 jsDeserializerTest, data.get()); 2401 ThreadSuspensionScope scope(thread); 2402 t1.join(); 2403 EXPECT_TRUE(JSSharedSet::GetSize(thread, jsSet) == 0); 2404 } 2405 { 2406 for (int i = 0; i < INITIALIZE_SIZE; i++) { 2407 JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i))); 2408 } 2409 EXPECT_TRUE(!JSSharedSet::Has(thread, jsSet, JSTaggedValue(INITIALIZE_SIZE))); 2410 JSDeserializerTest jsDeserializerTest; 2411 // The Deserializer thread will add and delete a element 2412 std::thread t1(&JSDeserializerTest::JSSharedSetBasicTest2, 2413 jsDeserializerTest, data.get()); 2414 ThreadSuspensionScope scope(thread); 2415 t1.join(); 2416 EXPECT_TRUE(!JSSharedSet::Has(thread, jsSet, JSTaggedValue(0))); 2417 EXPECT_TRUE(JSSharedSet::Has(thread, jsSet, JSTaggedValue(INITIALIZE_SIZE))); 2418 } 2419 delete serializer; 2420}; 2421 2422HWTEST_F_L0(JSSerializerTest, SerializeMultiThreadJSSharedSet) 2423{ 2424 JSHandle<JSSharedSet> jsSet = CreateSSet(thread); 2425 ValueSerializer *serializer = new ValueSerializer(thread); 2426 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsSet), 2427 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2428 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2429 EXPECT_TRUE(success) << "Serialize JSSharedSet fail"; 2430 std::unique_ptr<SerializeData> data = serializer->Release(); 2431 for (int i = 0; i < INITIALIZE_SIZE; i++) { 2432 JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i))); 2433 } 2434 constexpr uint32_t maxNumDeserializers = 10; 2435 JSDeserializerTest jsDeserializerTests[maxNumDeserializers]; 2436 std::thread threads[maxNumDeserializers]; 2437 for (int32_t i = 0; i < maxNumDeserializers; i++) { 2438 threads[i] = std::thread(&JSDeserializerTest::JSSharedSetMultiThreadTest1, 2439 jsDeserializerTests[i], data.get()); 2440 } 2441 ThreadSuspensionScope scope(thread); 2442 for (int i = 0; i < maxNumDeserializers; i++) { 2443 threads[i].join(); 2444 } 2445 EXPECT_TRUE(jsSet->GetModRecord() == 0); 2446 delete serializer; 2447}; 2448 2449HWTEST_F_L0(JSSerializerTest, SerializeJSSharedMapBasic) 2450{ 2451 JSHandle<JSSharedMap> jsMap = CreateSMap(thread); 2452 ValueSerializer *serializer = new ValueSerializer(thread); 2453 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsMap), 2454 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2455 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2456 EXPECT_TRUE(success) << "Serialize JSSharedMap failed"; 2457 std::unique_ptr<SerializeData> data = serializer->Release(); 2458 { 2459 for (int i = 0; i < INITIALIZE_SIZE; i++) { 2460 JSSharedMap::Set(thread, jsMap, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)), 2461 JSHandle<JSTaggedValue>(thread, JSTaggedValue(i))); 2462 } 2463 JSDeserializerTest jsDeserializerTest; 2464 // The Deserializer thread will clear the shared map 2465 std::thread t1(&JSDeserializerTest::JSSharedMapBasicTest1, 2466 jsDeserializerTest, data.get()); 2467 ThreadSuspensionScope scope(thread); 2468 t1.join(); 2469 EXPECT_TRUE(JSSharedMap::GetSize(thread, jsMap) == 0); 2470 } 2471 { 2472 for (int i = 0; i < INITIALIZE_SIZE; i++) { 2473 JSSharedMap::Set(thread, jsMap, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)), 2474 JSHandle<JSTaggedValue>(thread, JSTaggedValue(i))); 2475 } 2476 EXPECT_TRUE(!JSSharedMap::Has(thread, jsMap, JSTaggedValue(INITIALIZE_SIZE))); 2477 JSDeserializerTest jsDeserializerTest; 2478 // The Deserializer thread will add and delete a element 2479 std::thread t1(&JSDeserializerTest::JSSharedMapBasicTest2, 2480 jsDeserializerTest, data.get()); 2481 ThreadSuspensionScope scope(thread); 2482 t1.join(); 2483 EXPECT_TRUE(!JSSharedMap::Has(thread, jsMap, JSTaggedValue(0))); 2484 EXPECT_TRUE(JSSharedMap::Has(thread, jsMap, JSTaggedValue(INITIALIZE_SIZE))); 2485 } 2486 delete serializer; 2487}; 2488 2489HWTEST_F_L0(JSSerializerTest, SerializeMultiSharedRegion) 2490{ 2491 ObjectFactory *factory = ecmaVm->GetFactory(); 2492 JSHandle<TaggedArray> array = factory->NewSTaggedArray(10 * 1024, JSTaggedValue::Hole()); // 10 * 1024: array length 2493 for (int i = 0; i < 5; i++) { 2494 JSHandle<TaggedArray> element = factory->NewSTaggedArray((11 + i) * 1024, JSTaggedValue::Hole()); 2495 array->Set(thread, i, element); 2496 } 2497 JSHandle<JSObject> sobj = CreateEmptySObject(thread); 2498 sobj->SetElements(thread, array); 2499 ValueSerializer *serializer = new ValueSerializer(thread, false, true); 2500 bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(sobj), 2501 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 2502 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 2503 EXPECT_TRUE(success); 2504 std::unique_ptr<SerializeData> data = serializer->Release(); 2505 JSDeserializerTest jsDeserializerTest; 2506 std::thread t1(&JSDeserializerTest::SerializeMultiSharedRegionTest, jsDeserializerTest, data.release()); 2507 ThreadSuspensionScope scope(thread); 2508 t1.join(); 2509 delete serializer; 2510}; 2511} // namespace panda::test 2512