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