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