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