• 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->IsLineString());
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 
Reset()1040     void Reset()
1041     {
1042         TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
1043         thread = nullptr;
1044         ecmaVm = nullptr;
1045         scope = nullptr;
1046         TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
1047     }
1048 
1049     JSThread *thread {nullptr};
1050     EcmaVM *ecmaVm {nullptr};
1051     EcmaHandleScope *scope {nullptr};
1052 };
1053 
HWTEST_F_L0(JSSerializerTest,SerializeJSSpecialValue)1054 HWTEST_F_L0(JSSerializerTest, SerializeJSSpecialValue)
1055 {
1056     ValueSerializer *serializer = new ValueSerializer(thread);
1057     serializer->SerializeJSTaggedValue(JSTaggedValue::True());
1058     serializer->SerializeJSTaggedValue(JSTaggedValue::False());
1059     serializer->SerializeJSTaggedValue(JSTaggedValue::Undefined());
1060     serializer->SerializeJSTaggedValue(JSTaggedValue::Null());
1061     serializer->SerializeJSTaggedValue(JSTaggedValue::Hole());
1062     std::unique_ptr<SerializeData> data = serializer->Release();
1063 
1064     JSDeserializerTest jsDeserializerTest;
1065     std::thread t1(&JSDeserializerTest::JSSpecialValueTest, jsDeserializerTest, data.release());
1066     ThreadSuspensionScope scope(thread);
1067     t1.join();
1068     delete serializer;
1069 };
1070 
HWTEST_F_L0(JSSerializerTest,SerializeLineString)1071 HWTEST_F_L0(JSSerializerTest, SerializeLineString)
1072 {
1073     ObjectFactory *factory = ecmaVm->GetFactory();
1074     JSHandle<EcmaString> str(factory->NewFromASCII("123"));
1075 
1076     ValueSerializer *serializer = new ValueSerializer(thread);
1077     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str),
1078                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1079                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1080     std::unique_ptr<SerializeData> data = serializer->Release();
1081     JSDeserializerTest jsDeserializerTest;
1082     std::thread t1(&JSDeserializerTest::LineStringTest, jsDeserializerTest, data.release());
1083     {
1084         ThreadSuspensionScope suspensionScope(thread);
1085         t1.join();
1086     }
1087     delete serializer;
1088 };
1089 
HWTEST_F_L0(JSSerializerTest,SerializeTreeString)1090 HWTEST_F_L0(JSSerializerTest, SerializeTreeString)
1091 {
1092     ObjectFactory *factory = ecmaVm->GetFactory();
1093     JSHandle<EcmaString> str1(factory->NewFromASCII("123456789"));
1094     JSHandle<EcmaString> str2(factory->NewFromASCII("abcdefghi"));
1095 
1096     JSHandle<EcmaString> str3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, str1, str2));
1097     EXPECT_TRUE(str3.GetTaggedValue().IsTreeString());
1098 
1099     ValueSerializer *serializer = new ValueSerializer(thread);
1100     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str3),
1101                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1102                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1103     std::unique_ptr<SerializeData> data = serializer->Release();
1104     JSDeserializerTest jsDeserializerTest;
1105     std::thread t1(&JSDeserializerTest::TreeStringTest, jsDeserializerTest, data.release());
1106     {
1107         ThreadSuspensionScope suspensionScope(thread);
1108         t1.join();
1109     }
1110     delete serializer;
1111 };
1112 
HWTEST_F_L0(JSSerializerTest,SerializeSlicedString)1113 HWTEST_F_L0(JSSerializerTest, SerializeSlicedString)
1114 {
1115     ObjectFactory *factory = ecmaVm->GetFactory();
1116     JSHandle<EcmaString> str1(factory->NewFromASCII("123456789abcedfghijk"));
1117 
1118     JSHandle<EcmaString> str2 =
1119         JSHandle<EcmaString>(thread, EcmaStringAccessor::GetSubString(ecmaVm, str1, 2, 13)); // 2: start, 3: len
1120     EXPECT_TRUE(str2.GetTaggedValue().IsSlicedString());
1121 
1122     ValueSerializer *serializer = new ValueSerializer(thread);
1123     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str2),
1124                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1125                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1126     std::unique_ptr<SerializeData> data = serializer->Release();
1127     JSDeserializerTest jsDeserializerTest;
1128     std::thread t1(&JSDeserializerTest::SlicedStringTest, jsDeserializerTest, data.release());
1129     {
1130         ThreadSuspensionScope suspensionScope(thread);
1131         t1.join();
1132     }
1133     delete serializer;
1134 };
1135 
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject1)1136 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject1)
1137 {
1138     ObjectFactory *factory = ecmaVm->GetFactory();
1139     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1140 
1141     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("2"));
1142     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("3"));
1143     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("x"));
1144     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("y"));
1145     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1146     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
1147     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3));
1148     JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4));
1149 
1150     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
1151     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
1152     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3);
1153     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4);
1154 
1155     ValueSerializer *serializer = new ValueSerializer(thread);
1156     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1157                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1158                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1159     std::unique_ptr<SerializeData> data = serializer->Release();
1160     JSDeserializerTest jsDeserializerTest;
1161     std::thread t1(&JSDeserializerTest::JSPlainObjectTest1, jsDeserializerTest, data.release());
1162     ThreadSuspensionScope scope(thread);
1163     t1.join();
1164     delete serializer;
1165 };
1166 
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject2)1167 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject2)
1168 {
1169     ObjectFactory *factory = ecmaVm->GetFactory();
1170     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1171     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1172     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
1173     for (int i = 0; i < 10; i++) {
1174         JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1175         JSHandle<EcmaString> key3(factory->NewFromASCII("str3"));
1176         for (int j = 0; j < 10; j++) {
1177             key3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key3, key1));
1178             JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), JSHandle<JSTaggedValue>(key3),
1179                                   JSHandle<JSTaggedValue>(factory->NewEmptyJSObject()));
1180         }
1181         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1));
1182         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2),
1183                               JSHandle<JSTaggedValue>(obj1));
1184     }
1185 
1186     ValueSerializer *serializer = new ValueSerializer(thread);
1187     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1188                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1189                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1190     std::unique_ptr<SerializeData> data = serializer->Release();
1191     JSDeserializerTest jsDeserializerTest;
1192     std::thread t1(&JSDeserializerTest::JSPlainObjectTest2, jsDeserializerTest, data.release());
1193     ThreadSuspensionScope scope(thread);
1194     t1.join();
1195     delete serializer;
1196 };
1197 
1198 // test dictionary mode
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject3)1199 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject3)
1200 {
1201     ObjectFactory *factory = ecmaVm->GetFactory();
1202     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1203     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1204     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
1205     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1206     for (int i = 0; i < 1030; i++) {
1207         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1));
1208         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), value1);
1209     }
1210 
1211     EXPECT_TRUE(obj->GetClass()->IsDictionaryMode());
1212 
1213     ValueSerializer *serializer = new ValueSerializer(thread);
1214     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1215                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1216                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1217     std::unique_ptr<SerializeData> data = serializer->Release();
1218     JSDeserializerTest jsDeserializerTest;
1219     std::thread t1(&JSDeserializerTest::JSPlainObjectTest3, jsDeserializerTest, data.release());
1220     ThreadSuspensionScope scope(thread);
1221     t1.join();
1222     delete serializer;
1223 };
1224 
1225 // test huge object serialize
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject4)1226 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject4)
1227 {
1228     ObjectFactory *factory = ecmaVm->GetFactory();
1229     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1230     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1231     // new huge tagged array
1232     JSHandle<TaggedArray> taggedArray =
1233         factory->NewTaggedArray(1024 * 100, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
1234 
1235     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1),
1236                           JSHandle<JSTaggedValue>(taggedArray));
1237 
1238     ValueSerializer *serializer = new ValueSerializer(thread);
1239     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1240                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1241                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1242     std::unique_ptr<SerializeData> data = serializer->Release();
1243     JSDeserializerTest jsDeserializerTest;
1244     std::thread t1(&JSDeserializerTest::JSPlainObjectTest4, jsDeserializerTest, data.release());
1245     ThreadSuspensionScope scope(thread);
1246     t1.join();
1247     delete serializer;
1248 };
1249 
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject5)1250 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject5)
1251 {
1252     ObjectFactory *factory = ecmaVm->GetFactory();
1253     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1254 
1255     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("2"));
1256     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("3"));
1257     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("x"));
1258     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("y"));
1259     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("func"));
1260     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1261     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
1262     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3));
1263     JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4));
1264     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1265     JSHandle<JSFunction> function = factory->NewJSFunction(env, nullptr, FunctionKind::NORMAL_FUNCTION);
1266     EXPECT_TRUE(function->IsJSFunction());
1267     JSHandle<JSTaggedValue> value5 = JSHandle<JSTaggedValue>::Cast(function);
1268 
1269     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
1270     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
1271     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3);
1272     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4);
1273     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key5, value5);
1274 
1275     ValueSerializer *serializer = new ValueSerializer(thread);
1276     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1277                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1278                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1279     EXPECT_FALSE(success);
1280     std::unique_ptr<SerializeData> data = serializer->Release();
1281     BaseDeserializer deserializer(thread, data.release());
1282     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
1283     EXPECT_TRUE(res.IsEmpty());
1284     delete serializer;
1285 };
1286 
HWTEST_F_L0(JSSerializerTest,SerializeJSError1)1287 HWTEST_F_L0(JSSerializerTest, SerializeJSError1)
1288 {
1289     ObjectFactory *factory = ecmaVm->GetFactory();
1290     JSHandle<EcmaString> msg(factory->NewFromASCII("this is error"));
1291     JSHandle<JSTaggedValue> errorTag =
1292         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::ERROR, msg, StackCheck::NO));
1293 
1294     ValueSerializer *serializer = new ValueSerializer(thread);
1295     serializer->WriteValue(thread, errorTag, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1296                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1297     std::unique_ptr<SerializeData> data = serializer->Release();
1298     JSDeserializerTest jsDeserializerTest;
1299     std::thread t1(&JSDeserializerTest::JSErrorTest1, jsDeserializerTest, data.release());
1300     ThreadSuspensionScope scope(thread);
1301     t1.join();
1302     delete serializer;
1303 };
1304 
HWTEST_F_L0(JSSerializerTest,SerializeJSError2)1305 HWTEST_F_L0(JSSerializerTest, SerializeJSError2)
1306 {
1307     ObjectFactory *factory = ecmaVm->GetFactory();
1308     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1309     JSHandle<EcmaString> key1(factory->NewFromASCII("error1"));
1310     JSHandle<EcmaString> key2(factory->NewFromASCII("error2"));
1311     JSHandle<EcmaString> msg(factory->NewFromASCII("this is error"));
1312     JSHandle<JSTaggedValue> errorTag =
1313         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::ERROR, msg, StackCheck::NO));
1314 
1315 
1316     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), errorTag);
1317     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), errorTag);
1318 
1319     ValueSerializer *serializer = new ValueSerializer(thread);
1320     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1321                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1322                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1323     std::unique_ptr<SerializeData> data = serializer->Release();
1324     JSDeserializerTest jsDeserializerTest;
1325     std::thread t1(&JSDeserializerTest::JSErrorTest2, jsDeserializerTest, data.release());
1326     ThreadSuspensionScope scope(thread);
1327     t1.join();
1328     delete serializer;
1329 };
1330 
HWTEST_F_L0(JSSerializerTest,SerializeJSError3)1331 HWTEST_F_L0(JSSerializerTest, SerializeJSError3)
1332 {
1333     ObjectFactory *factory = ecmaVm->GetFactory();
1334     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1335     JSHandle<EcmaString> key1(factory->NewFromASCII("error1"));
1336     JSHandle<EcmaString> key2(factory->NewFromASCII("error2"));
1337     JSHandle<EcmaString> key3(factory->NewFromASCII("error3"));
1338     JSHandle<EcmaString> key4(factory->NewFromASCII("error4"));
1339     JSHandle<EcmaString> key5(factory->NewFromASCII("error5"));
1340     JSHandle<EcmaString> key6(factory->NewFromASCII("error6"));
1341     JSHandle<EcmaString> key7(factory->NewFromASCII("error7"));
1342     JSHandle<EcmaString> msg(factory->NewFromASCII("this is error"));
1343     JSHandle<JSTaggedValue> error1 =
1344         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::RANGE_ERROR, msg, StackCheck::NO));
1345     JSHandle<JSTaggedValue> error2 =
1346         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg, StackCheck::NO));
1347     JSHandle<JSTaggedValue> error3 =
1348         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::TYPE_ERROR, msg, StackCheck::NO));
1349     JSHandle<JSTaggedValue> error4 =
1350         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::URI_ERROR, msg, StackCheck::NO));
1351     JSHandle<JSTaggedValue> error5 =
1352         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::SYNTAX_ERROR, msg, StackCheck::NO));
1353     JSHandle<JSTaggedValue> error6 =
1354         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::OOM_ERROR, msg, StackCheck::NO));
1355     JSHandle<JSTaggedValue> error7 =
1356         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::TERMINATION_ERROR, msg, StackCheck::NO));
1357 
1358     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), error1);
1359     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), error2);
1360     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key3), error3);
1361     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key4), error4);
1362     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key5), error5);
1363     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key6), error6);
1364     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key7), error7);
1365 
1366     ValueSerializer *serializer = new ValueSerializer(thread);
1367     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1368                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1369                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1370     EXPECT_TRUE(success);
1371     std::unique_ptr<SerializeData> data = serializer->Release();
1372     JSDeserializerTest jsDeserializerTest;
1373     std::thread t1(&JSDeserializerTest::JSErrorTest3, jsDeserializerTest, data.release());
1374     ThreadSuspensionScope scope(thread);
1375     t1.join();
1376     delete serializer;
1377 }
1378 
HWTEST_F_L0(JSSerializerTest,SerializeBigInt)1379 HWTEST_F_L0(JSSerializerTest, SerializeBigInt)
1380 {
1381     ObjectFactory *factory = ecmaVm->GetFactory();
1382     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1383     JSHandle<EcmaString> key1(factory->NewFromASCII("pss"));
1384     JSHandle<EcmaString> key2(factory->NewFromASCII("nativeHeap"));
1385     CString value1 = "365769";
1386     CString value2 = "139900";
1387     JSHandle<BigInt> bigInt1 = BigIntHelper::SetBigInt(thread, value1);
1388     JSHandle<BigInt> bigInt2 = BigIntHelper::SetBigInt(thread, value1);
1389 
1390     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1),
1391                           JSHandle<JSTaggedValue>(bigInt1));
1392     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2),
1393                           JSHandle<JSTaggedValue>(bigInt2));
1394 
1395     ValueSerializer *serializer = new ValueSerializer(thread);
1396     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1397                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1398                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1399     EXPECT_TRUE(success) << "Serialize bigInt fail";
1400     std::unique_ptr<SerializeData> data = serializer->Release();
1401     JSDeserializerTest jsDeserializerTest;
1402     std::thread t1(&JSDeserializerTest::BigIntTest, jsDeserializerTest, data.release());
1403     ThreadSuspensionScope scope(thread);
1404     t1.join();
1405     delete serializer;
1406 };
1407 
HWTEST_F_L0(JSSerializerTest,SerializePrimitive)1408 HWTEST_F_L0(JSSerializerTest, SerializePrimitive)
1409 {
1410     ObjectFactory *factory = ecmaVm->GetFactory();
1411     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1412     JSHandle<EcmaString> keyInt(factory->NewFromASCII("int"));
1413     JSHandle<EcmaString> keyDouble(factory->NewFromASCII("double"));
1414     JSHandle<EcmaString> keyBoolean(factory->NewFromASCII("boolean"));
1415     JSHandle<EcmaString> keyString(factory->NewFromASCII("string"));
1416 
1417     int32_t intValue = 42;
1418     double doubleValue = 3.14159;
1419     bool booleanValue = true;
1420     JSHandle<EcmaString> stringValue(factory->NewFromASCII("Hello World"));
1421 
1422     JSHandle<JSPrimitiveRef> intPrimitive = factory->NewJSPrimitiveRef(
1423         PrimitiveType::PRIMITIVE_NUMBER, JSHandle<JSTaggedValue>(thread, JSTaggedValue(intValue)));
1424     JSHandle<JSPrimitiveRef> doublePrimitive = factory->NewJSPrimitiveRef(
1425         PrimitiveType::PRIMITIVE_NUMBER, JSHandle<JSTaggedValue>(thread, JSTaggedValue(doubleValue)));
1426     JSHandle<JSPrimitiveRef> booleanPrimitive = factory->NewJSPrimitiveRef(
1427         PrimitiveType::PRIMITIVE_BOOLEAN, JSHandle<JSTaggedValue>(thread, JSTaggedValue(booleanValue)));
1428     JSHandle<JSPrimitiveRef> stringPrimitive = factory->NewJSPrimitiveRef(
1429         PrimitiveType::PRIMITIVE_STRING, JSHandle<JSTaggedValue>(stringValue));
1430 
1431     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(keyInt),
1432                         JSHandle<JSTaggedValue>(intPrimitive));
1433     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(keyDouble),
1434                         JSHandle<JSTaggedValue>(doublePrimitive));
1435     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(keyBoolean),
1436                         JSHandle<JSTaggedValue>(booleanPrimitive));
1437     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(keyString),
1438                         JSHandle<JSTaggedValue>(stringPrimitive));
1439 
1440     ValueSerializer *serializer = new ValueSerializer(thread);
1441     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1442                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1443                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1444     EXPECT_TRUE(success) << "Serialize primitive types failed";
1445     std::unique_ptr<SerializeData> data = serializer->Release();
1446     JSDeserializerTest jsDeserializerTest;
1447     std::thread t1(&JSDeserializerTest::PrimitiveTest, jsDeserializerTest, data.release());
1448     ThreadSuspensionScope scope(thread);
1449     t1.join();
1450     delete serializer;
1451 }
1452 
Detach(void * param1,void * param2,void * hint,void * detachData)1453 static void* Detach(void *param1, void *param2, void *hint, void *detachData)
1454 {
1455     GTEST_LOG_(INFO) << "detach is running";
1456     if (param1 == nullptr && param2 == nullptr) {
1457         GTEST_LOG_(INFO) << "detach: two params is nullptr";
1458     }
1459     if (hint == nullptr && detachData) {
1460         GTEST_LOG_(INFO) << "detach: hint is nullptr";
1461     }
1462     return nullptr;
1463 }
1464 
Attach(void * enginePointer,void * buffer,void * hint,void * attachData)1465 static void* Attach([[maybe_unused]] void *enginePointer, [[maybe_unused]] void *buffer, [[maybe_unused]] void *hint,
1466                     [[maybe_unused]] void *attachData)
1467 {
1468     GTEST_LOG_(INFO) << "attach is running";
1469     return nullptr;
1470 }
1471 
CreateNativeBindingInfo(void * attach,void * detach)1472 static panda::JSNApi::NativeBindingInfo* CreateNativeBindingInfo(void* attach, void* detach)
1473 {
1474     GTEST_LOG_(INFO) << "CreateNativeBindingInfo";
1475     auto info = panda::JSNApi::NativeBindingInfo::CreateNewInstance();
1476     info->attachFunc = attach;
1477     info->detachFunc = detach;
1478     return info;
1479 }
1480 
HWTEST_F_L0(JSSerializerTest,SerializeNativeBindingObject1)1481 HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject1)
1482 {
1483     ObjectFactory *factory = ecmaVm->GetFactory();
1484     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1485     JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1486 
1487     JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol();
1488     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x"));
1489     auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach));
1490     JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info)));
1491     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1));
1492 
1493     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
1494     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2);
1495     obj1->GetClass()->SetIsNativeBindingObject(true);
1496 
1497     ValueSerializer *serializer = new ValueSerializer(thread);
1498     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj1),
1499                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1500                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1501     EXPECT_TRUE(success) << "Serialize fail";
1502     std::unique_ptr<SerializeData> data = serializer->Release();
1503     JSDeserializerTest jsDeserializerTest;
1504     std::thread t1(&JSDeserializerTest::NativeBindingObjectTest1, jsDeserializerTest, data.release());
1505     ThreadSuspensionScope scope(thread);
1506     t1.join();
1507     delete serializer;
1508 }
1509 
HWTEST_F_L0(JSSerializerTest,SerializeNativeBindingObject2)1510 HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject2)
1511 {
1512     ObjectFactory *factory = ecmaVm->GetFactory();
1513     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1514     JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1515     JSHandle<JSObject> obj2 = factory->NewEmptyJSObject();
1516 
1517     JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol();
1518     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x"));
1519     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("xx"));
1520     auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach));
1521     JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info)));
1522     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1));
1523     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(2));
1524 
1525     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
1526     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2);
1527     obj1->GetClass()->SetIsNativeBindingObject(true);
1528     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2, JSHandle<JSTaggedValue>(obj1));
1529     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key3, value3);
1530 
1531     ValueSerializer *serializer = new ValueSerializer(thread);
1532     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj2),
1533                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1534                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1535     EXPECT_TRUE(success) << "Serialize fail";
1536     std::unique_ptr<SerializeData> data = serializer->Release();
1537     JSDeserializerTest jsDeserializerTest;
1538     std::thread t1(&JSDeserializerTest::NativeBindingObjectTest2, jsDeserializerTest, data.release());
1539     ThreadSuspensionScope scope(thread);
1540     t1.join();
1541     delete serializer;
1542 }
1543 
HWTEST_F_L0(JSSerializerTest,SerializeNativeBindingObject3)1544 HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject3)
1545 {
1546     ObjectFactory *factory = ecmaVm->GetFactory();
1547     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1548     JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1549 
1550     JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol();
1551     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x"));
1552     auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), nullptr);
1553     JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info)));
1554     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1));
1555 
1556     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
1557     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2);
1558     obj1->GetClass()->SetIsNativeBindingObject(true);
1559 
1560     ValueSerializer *serializer = new ValueSerializer(thread);
1561     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj1),
1562                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1563                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1564     EXPECT_FALSE(success);
1565     std::unique_ptr<SerializeData> data = serializer->Release();
1566     BaseDeserializer deserializer(thread, data.release());
1567     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
1568     EXPECT_TRUE(res.IsEmpty());
1569     delete serializer;
1570 }
1571 
HWTEST_F_L0(JSSerializerTest,TestSerializeJSSet)1572 HWTEST_F_L0(JSSerializerTest, TestSerializeJSSet)
1573 {
1574     ObjectFactory *factory = ecmaVm->GetFactory();
1575     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1576 
1577     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsSetFunction();
1578     JSHandle<JSSet> set =
1579         JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1580     JSHandle<LinkedHashSet> linkedSet = LinkedHashSet::Create(thread);
1581     set->SetLinkedSet(thread, linkedSet);
1582     // set property to set
1583     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7));
1584     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9));
1585     JSHandle<JSTaggedValue> value3(factory->NewFromASCII("x"));
1586     JSHandle<JSTaggedValue> value4(factory->NewFromASCII("y"));
1587 
1588     JSSet::Add(thread, set, value1);
1589     JSSet::Add(thread, set, value2);
1590     JSSet::Add(thread, set, value3);
1591     JSSet::Add(thread, set, value4);
1592 
1593     // set property to object
1594     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("5"));
1595     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("6"));
1596 
1597     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(set), key1, value1);
1598     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(set), key2, value2);
1599 
1600     ValueSerializer *serializer = new ValueSerializer(thread);
1601     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(set),
1602                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1603                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1604     EXPECT_TRUE(success) << "Serialize JSSet fail";
1605     std::unique_ptr<SerializeData> data = serializer->Release();
1606     JSDeserializerTest jsDeserializerTest;
1607     std::thread t1(&JSDeserializerTest::JSSetTest, jsDeserializerTest, data.release());
1608     ThreadSuspensionScope scope(thread);
1609     t1.join();
1610     delete serializer;
1611 };
1612 
JSDateCreate(EcmaVM * ecmaVM)1613 JSDate *JSDateCreate(EcmaVM *ecmaVM)
1614 {
1615     ObjectFactory *factory = ecmaVM->GetFactory();
1616     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
1617     JSHandle<JSTaggedValue> dateFunction = globalEnv->GetDateFunction();
1618     JSHandle<JSDate> dateObject =
1619         JSHandle<JSDate>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dateFunction), dateFunction));
1620     return *dateObject;
1621 }
1622 
HWTEST_F_L0(JSSerializerTest,SerializeDate)1623 HWTEST_F_L0(JSSerializerTest, SerializeDate)
1624 {
1625     double tm = 28 * 60 * 60 * 1000;
1626     JSHandle<JSDate> jsDate(thread, JSDateCreate(ecmaVm));
1627     jsDate->SetTimeValue(thread, JSTaggedValue(tm));
1628 
1629     ValueSerializer *serializer = new ValueSerializer(thread);
1630     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsDate),
1631                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1632                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1633     EXPECT_TRUE(success) << "Serialize JSDate fail";
1634     std::unique_ptr<SerializeData> data = serializer->Release();
1635     JSDeserializerTest jsDeserializerTest;
1636     std::thread t1(&JSDeserializerTest::JSDateTest, jsDeserializerTest, data.release());
1637     ThreadSuspensionScope scope(thread);
1638     t1.join();
1639     delete serializer;
1640 };
1641 
CreateMap(JSThread * thread)1642 JSMap *CreateMap(JSThread *thread)
1643 {
1644     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1645     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1646     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsMapFunction();
1647     JSHandle<JSMap> map =
1648         JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1649     JSHandle<LinkedHashMap> linkedMap = LinkedHashMap::Create(thread);
1650     map->SetLinkedMap(thread, linkedMap);
1651     return *map;
1652 }
1653 
HWTEST_F_L0(JSSerializerTest,SerializeJSMap)1654 HWTEST_F_L0(JSSerializerTest, SerializeJSMap)
1655 {
1656     JSHandle<JSMap> map(thread, CreateMap(thread));
1657     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1658     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("3"));
1659     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(12345));
1660     JSMap::Set(thread, map, key1, value1);
1661     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key1"));
1662     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(34567));
1663     JSMap::Set(thread, map, key2, value2);
1664 
1665     ValueSerializer *serializer = new ValueSerializer(thread);
1666     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(map),
1667                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1668                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1669     EXPECT_TRUE(success) << "Serialize JSMap fail";
1670     std::unique_ptr<SerializeData> data = serializer->Release();
1671     JSDeserializerTest jsDeserializerTest;
1672     std::thread t1(&JSDeserializerTest::JSMapTest, jsDeserializerTest, data.release(), map);
1673     ThreadSuspensionScope scope(thread);
1674     t1.join();
1675     delete serializer;
1676 };
1677 
HWTEST_F_L0(JSSerializerTest,SerializeJSRegExp)1678 HWTEST_F_L0(JSSerializerTest, SerializeJSRegExp)
1679 {
1680     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1681     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1682     JSHandle<JSTaggedValue> target = env->GetRegExpFunction();
1683     JSHandle<JSRegExp> jsRegexp =
1684         JSHandle<JSRegExp>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
1685     JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2");
1686     JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i");
1687     char buffer[] = "1234567";  // use char to simulate bytecode
1688     uint32_t bufferSize = 7;
1689     factory->NewJSRegExpByteCodeData(jsRegexp, static_cast<void *>(buffer), bufferSize);
1690     jsRegexp->SetOriginalSource(thread, JSHandle<JSTaggedValue>(pattern));
1691     jsRegexp->SetOriginalFlags(thread, JSHandle<JSTaggedValue>(flags));
1692 
1693     ValueSerializer *serializer = new ValueSerializer(thread);
1694     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsRegexp),
1695                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1696                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1697     EXPECT_TRUE(success) << "Serialize JSRegExp fail";
1698     std::unique_ptr<SerializeData> data = serializer->Release();
1699     JSDeserializerTest jsDeserializerTest;
1700     std::thread t1(&JSDeserializerTest::JSRegexpTest, jsDeserializerTest, data.release());
1701     ThreadSuspensionScope scope(thread);
1702     t1.join();
1703     delete serializer;
1704 };
1705 
HWTEST_F_L0(JSSerializerTest,TestSerializeJSArray)1706 HWTEST_F_L0(JSSerializerTest, TestSerializeJSArray)
1707 {
1708     ObjectFactory *factory = ecmaVm->GetFactory();
1709     JSHandle<JSArray> array = factory->NewJSArray();
1710 
1711     // set property to object
1712     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("abasd"));
1713     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("qweqwedasd"));
1714 
1715     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7));
1716     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9));
1717 
1718     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(array), key1, value1);
1719     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(array), key2, value2);
1720 
1721     // set value to array
1722     array->SetArrayLength(thread, 20);
1723     for (int i = 0; i < 20; i++) {
1724         JSHandle<JSTaggedValue> data(thread, JSTaggedValue(i));
1725         JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>::Cast(array), i, data);
1726     }
1727 
1728     ValueSerializer *serializer = new ValueSerializer(thread);
1729     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(array),
1730                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1731                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1732     EXPECT_TRUE(success) << "Serialize JSArray fail";
1733     std::unique_ptr<SerializeData> data = serializer->Release();
1734     JSDeserializerTest jsDeserializerTest;
1735     std::thread t1(&JSDeserializerTest::JSArrayTest, jsDeserializerTest, data.release());
1736     ThreadSuspensionScope scope(thread);
1737     t1.join();
1738     delete serializer;
1739 };
1740 
HWTEST_F_L0(JSSerializerTest,SerializeEcmaString1)1741 HWTEST_F_L0(JSSerializerTest, SerializeEcmaString1)
1742 {
1743     const char *rawStr = "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
1744     "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
1745     "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
1746     "ssssss";
1747     JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(rawStr);
1748 
1749     ValueSerializer *serializer = new ValueSerializer(thread);
1750     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(ecmaString),
1751                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1752                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1753     EXPECT_TRUE(success) << "Serialize EcmaString fail";
1754     std::unique_ptr<SerializeData> data = serializer->Release();
1755     JSDeserializerTest jsDeserializerTest;
1756     std::thread t1(&JSDeserializerTest::EcmaStringTest1, jsDeserializerTest, data.release());
1757     ThreadSuspensionScope scope(thread);
1758     t1.join();
1759     delete serializer;
1760 };
1761 
1762 // Test EcmaString contains Chinese Text
HWTEST_F_L0(JSSerializerTest,SerializeEcmaString2)1763 HWTEST_F_L0(JSSerializerTest, SerializeEcmaString2)
1764 {
1765     std::string rawStr = "你好,世界";
1766     JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromStdString(rawStr);
1767 
1768     ValueSerializer *serializer = new ValueSerializer(thread);
1769     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(ecmaString),
1770                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1771                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1772     EXPECT_TRUE(success) << "Serialize EcmaString fail";
1773     std::unique_ptr<SerializeData> data = serializer->Release();
1774     JSDeserializerTest jsDeserializerTest;
1775     std::thread t1(&JSDeserializerTest::EcmaStringTest2, jsDeserializerTest, data.release());
1776     ThreadSuspensionScope scope(thread);
1777     t1.join();
1778     delete serializer;
1779 };
1780 
HWTEST_F_L0(JSSerializerTest,SerializeInt32_t)1781 HWTEST_F_L0(JSSerializerTest, SerializeInt32_t)
1782 {
1783     int32_t a = 64, min = -2147483648, b = -63;
1784     JSTaggedValue aTag(a), minTag(min), bTag(b);
1785 
1786     ValueSerializer *serializer = new ValueSerializer(thread);
1787     serializer->SerializeJSTaggedValue(aTag);
1788     serializer->SerializeJSTaggedValue(minTag);
1789     serializer->SerializeJSTaggedValue(bTag);
1790     std::unique_ptr<SerializeData> data = serializer->Release();
1791 
1792     JSDeserializerTest jsDeserializerTest;
1793     std::thread t1(&JSDeserializerTest::Int32Test, jsDeserializerTest, data.release());
1794     ThreadSuspensionScope scope(thread);
1795     t1.join();
1796     delete serializer;
1797 };
1798 
HWTEST_F_L0(JSSerializerTest,SerializeDouble)1799 HWTEST_F_L0(JSSerializerTest, SerializeDouble)
1800 {
1801     double a = 3.1415926535, b = -3.1415926535;
1802     JSTaggedValue aTag(a), bTag(b);
1803 
1804     ValueSerializer *serializer = new ValueSerializer(thread);
1805     serializer->SerializeJSTaggedValue(aTag);
1806     serializer->SerializeJSTaggedValue(bTag);
1807     std::unique_ptr<SerializeData> data = serializer->Release();
1808 
1809     JSDeserializerTest jsDeserializerTest;
1810     std::thread t1(&JSDeserializerTest::DoubleTest, jsDeserializerTest, data.release());
1811     ThreadSuspensionScope scope(thread);
1812     t1.join();
1813     delete serializer;
1814 };
1815 
CreateJSArrayBuffer(JSThread * thread)1816 JSArrayBuffer *CreateJSArrayBuffer(JSThread *thread)
1817 {
1818     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1819     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1820     JSHandle<JSTaggedValue> target = env->GetArrayBufferFunction();
1821     JSHandle<JSArrayBuffer> jsArrayBuffer =
1822         JSHandle<JSArrayBuffer>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
1823     return *jsArrayBuffer;
1824 }
1825 
HWTEST_F_L0(JSSerializerTest,SerializeObjectWithConcurrentFunction)1826 HWTEST_F_L0(JSSerializerTest, SerializeObjectWithConcurrentFunction)
1827 {
1828     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1829     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1830     JSHandle<JSFunction> concurrentFunction1 = factory->NewJSFunction(env, nullptr, FunctionKind::CONCURRENT_FUNCTION);
1831     EXPECT_TRUE(concurrentFunction1->IsJSFunction());
1832     EXPECT_TRUE(concurrentFunction1->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION);
1833     JSHandle<JSFunction> concurrentFunction2 = factory->NewJSFunction(env, nullptr, FunctionKind::CONCURRENT_FUNCTION);
1834     EXPECT_TRUE(concurrentFunction2->IsJSFunction());
1835     EXPECT_TRUE(concurrentFunction2->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION);
1836     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("1"));
1837     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("2"));
1838     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("abc"));
1839     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("4"));
1840     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("key"));
1841     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(12345));
1842     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("def"));
1843     JSHandle<JSTaggedValue> value3(factory->NewFromASCII("value"));
1844     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1845     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
1846     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, JSHandle<JSTaggedValue>(concurrentFunction1));
1847     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value2);
1848     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value1);
1849     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key5, JSHandle<JSTaggedValue>(concurrentFunction2));
1850 
1851     ValueSerializer *serializer = new ValueSerializer(thread);
1852     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1853                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1854                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1855     EXPECT_TRUE(success) << "Serialize concurrent function fail";
1856     std::unique_ptr<SerializeData> data = serializer->Release();
1857     JSDeserializerTest jsDeserializerTest;
1858 
1859     std::thread t1(&JSDeserializerTest::ObjectWithConcurrentFunctionTest, jsDeserializerTest, data.release());
1860     ThreadSuspensionScope scope(thread);
1861     t1.join();
1862     delete serializer;
1863 };
1864 
1865 // not support most function except concurrent function
HWTEST_F_L0(JSSerializerTest,SerializeFunction)1866 HWTEST_F_L0(JSSerializerTest, SerializeFunction)
1867 {
1868     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1869     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1870     JSHandle<JSFunction> function = factory->NewJSFunction(env, nullptr, FunctionKind::NORMAL_FUNCTION);
1871     EXPECT_TRUE(function->IsJSFunction());
1872 
1873     ValueSerializer *serializer = new ValueSerializer(thread);
1874     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(function),
1875                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1876                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1877     EXPECT_FALSE(success);
1878     std::unique_ptr<SerializeData> data = serializer->Release();
1879     BaseDeserializer deserializer(thread, data.release());
1880     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
1881     EXPECT_TRUE(res.IsEmpty());
1882     delete serializer;
1883 }
1884 
1885 // Test transfer JSArrayBuffer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer1)1886 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer1)
1887 {
1888     ObjectFactory *factory = ecmaVm->GetFactory();
1889 
1890     // create a JSArrayBuffer
1891     size_t length = 5;
1892     uint8_t value = 100;
1893     void *buffer = ecmaVm->GetNativeAreaAllocator()->AllocateBuffer(length);
1894     if (memset_s(buffer, length, value, length) != EOK) {
1895         LOG_ECMA(FATAL) << "this branch is unreachable";
1896         UNREACHABLE();
1897     }
1898     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer,
1899         length, NativeAreaAllocator::FreeBufferFunc, ecmaVm->GetNativeAreaAllocator());
1900     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>(arrBuf);
1901 
1902     JSHandle<JSArray> array = factory->NewJSArray();
1903 
1904     // set value to array
1905     array->SetArrayLength(thread, 1);
1906     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, arrBufTag);
1907 
1908     ValueSerializer *serializer = new ValueSerializer(thread);
1909     bool success = serializer->WriteValue(thread, arrBufTag, JSHandle<JSTaggedValue>(array),
1910                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1911     EXPECT_TRUE(success) << "Serialize transfer JSArrayBuffer fail";
1912     std::unique_ptr<SerializeData> data = serializer->Release();
1913     JSDeserializerTest jsDeserializerTest;
1914     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest1,
1915                    jsDeserializerTest,
1916                    data.release(),
1917                    reinterpret_cast<uintptr_t>(buffer));
1918     ThreadSuspensionScope scope(thread);
1919     t1.join();
1920     delete serializer;
1921     // test if detached
1922     EXPECT_TRUE(arrBuf->IsDetach());
1923 };
1924 
1925 // Test serialize JSArrayBuffer that not transfer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer2)1926 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer2)
1927 {
1928     ObjectFactory *factory = ecmaVm->GetFactory();
1929 
1930     // create a JSArrayBuffer
1931     size_t length = 5;
1932     uint8_t value = 100;
1933     void *buffer = ecmaVm->GetNativeAreaAllocator()->AllocateBuffer(length);
1934     if (memset_s(buffer, length, value, length) != EOK) {
1935         LOG_ECMA(FATAL) << "this branch is unreachable";
1936         UNREACHABLE();
1937     }
1938     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer,
1939         length, NativeAreaAllocator::FreeBufferFunc, ecmaVm->GetNativeAreaAllocator());
1940     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
1941 
1942     ValueSerializer *serializer = new ValueSerializer(thread);
1943     bool success = serializer->WriteValue(thread, arrBufTag,
1944                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1945                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1946     EXPECT_TRUE(success) << "Serialize not transfer JSArrayBuffer fail";
1947     std::unique_ptr<SerializeData> data = serializer->Release();
1948     JSDeserializerTest jsDeserializerTest;
1949     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest2,
1950                    jsDeserializerTest,
1951                    data.release(),
1952                    reinterpret_cast<uintptr_t>(buffer));
1953     ThreadSuspensionScope scope(thread);
1954     t1.join();
1955     delete serializer;
1956     // test if detached
1957     EXPECT_FALSE(arrBuf->IsDetach());
1958 };
1959 
1960 // Test serialize an empty JSArrayBuffer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer3)1961 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer3)
1962 {
1963     ObjectFactory *factory = ecmaVm->GetFactory();
1964 
1965     // create a JSArrayBuffer
1966     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(0);
1967     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
1968 
1969     ValueSerializer *serializer = new ValueSerializer(thread);
1970     bool success = serializer->WriteValue(thread, arrBufTag,
1971                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1972                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1973     EXPECT_TRUE(success) << "Serialize empty JSArrayBuffer fail";
1974     std::unique_ptr<SerializeData> data = serializer->Release();
1975     JSDeserializerTest jsDeserializerTest;
1976     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest3, jsDeserializerTest, data.release());
1977     ThreadSuspensionScope scope(thread);
1978     t1.join();
1979     delete serializer;
1980     // test if detached
1981     EXPECT_FALSE(arrBuf->IsDetach());
1982 };
1983 
1984 // Test serialize JSArrayBuffer with external native buffer that not transfer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer4)1985 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer4)
1986 {
1987     ObjectFactory *factory = ecmaVm->GetFactory();
1988 
1989     // create a JSArrayBuffer
1990     size_t length = 5;
1991     uint8_t value = 100;
1992     void *buffer = reinterpret_cast<void *>(malloc(length));
1993     if (memset_s(buffer, length, value, length) != EOK) {
1994         LOG_ECMA(FATAL) << "this branch is unreachable";
1995         UNREACHABLE();
1996     }
1997     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer, length, nullptr, nullptr);
1998     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
1999 
2000     ValueSerializer *serializer = new ValueSerializer(thread);
2001     bool res = serializer->WriteValue(thread, arrBufTag,
2002                                       JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2003                                       JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2004     EXPECT_FALSE(res) << "serialize JSArrayBuffer with external native shall not clone it";
2005     free(buffer);
2006 };
2007 
ArrayBufferDeleter(void * env,void * buf,void * data)2008 void ArrayBufferDeleter([[maybe_unused]] void *env, void *buf, [[maybe_unused]] void *data)
2009 {
2010     free(buf);
2011 }
2012 
2013 // Test serialize JSArrayBuffer with external native buffer that transfer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer5)2014 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer5)
2015 {
2016     ObjectFactory *factory = ecmaVm->GetFactory();
2017 
2018     // create a JSArrayBuffer
2019     size_t length = 5;
2020     uint8_t value = 100;
2021     void *buffer = reinterpret_cast<void *>(malloc(length));
2022     if (memset_s(buffer, length, value, length) != EOK) {
2023         LOG_ECMA(FATAL) << "this branch is unreachable";
2024         UNREACHABLE();
2025     }
2026     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer, length, ArrayBufferDeleter, nullptr);
2027     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
2028 
2029     ValueSerializer *serializer = new ValueSerializer(thread, true);
2030     bool res = serializer->WriteValue(thread, arrBufTag,
2031                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2032                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2033     EXPECT_TRUE(res) << "serialize JSArrayBuffer with external pointer fail";
2034     EXPECT_TRUE(arrBuf->IsDetach());
2035     std::unique_ptr<SerializeData> data = serializer->Release();
2036     JSDeserializerTest jsDeserializerTest;
2037     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest5, jsDeserializerTest, data.release());
2038     ThreadSuspensionScope scope(thread);
2039     t1.join();
2040     delete serializer;
2041 };
2042 
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer6)2043 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer6)
2044 {
2045     ObjectFactory *factory = ecmaVm->GetFactory();
2046     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
2047     JSHandle<EcmaString> transfer(factory->NewFromASCII("transfer"));
2048     ValueSerializer *serializer = new ValueSerializer(thread);
2049     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
2050                                           JSHandle<JSTaggedValue>(transfer),
2051                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2052     EXPECT_FALSE(success);
2053     std::unique_ptr<SerializeData> data = serializer->Release();
2054     BaseDeserializer deserializer(thread, data.release());
2055     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
2056     EXPECT_TRUE(res.IsEmpty());
2057     delete serializer;
2058 };
2059 
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer7)2060 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer7)
2061 {
2062     ObjectFactory *factory = ecmaVm->GetFactory();
2063     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
2064     JSHandle<EcmaString> transfer(factory->NewFromASCII("transfer"));
2065     JSHandle<JSArray> array = factory->NewJSArray();
2066     // set value to array
2067     array->SetArrayLength(thread, 1);
2068     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(transfer));
2069     ValueSerializer *serializer = new ValueSerializer(thread);
2070     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
2071                                           JSHandle<JSTaggedValue>(array),
2072                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2073     EXPECT_FALSE(success);
2074     std::unique_ptr<SerializeData> data = serializer->Release();
2075     BaseDeserializer deserializer(thread, data.release());
2076     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
2077     EXPECT_TRUE(res.IsEmpty());
2078     delete serializer;
2079 };
2080 
HWTEST_F_L0(JSSerializerTest,SerializeJSArrayBufferShared2)2081 HWTEST_F_L0(JSSerializerTest, SerializeJSArrayBufferShared2)
2082 {
2083     std::string msg = "hello world";
2084     int msgBufferLen = static_cast<int>(msg.length()) + 1;
2085     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2086     JSHandle<JSArrayBuffer> jsArrayBuffer = factory->NewJSSharedArrayBuffer(msgBufferLen);
2087     JSHandle<JSTaggedValue> BufferData(thread, jsArrayBuffer->GetArrayBufferData());
2088     JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(BufferData);
2089     void *buffer = resNp->GetExternalPointer();
2090     if (memcpy_s(buffer, msgBufferLen, msg.c_str(), msgBufferLen) != EOK) {
2091         EXPECT_TRUE(false) << " memcpy error";
2092     }
2093 
2094     ValueSerializer *serializer = new ValueSerializer(thread);
2095     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsArrayBuffer),
2096                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2097                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2098     EXPECT_TRUE(success) << "Serialize JSSharedArrayBuffer fail";
2099     std::unique_ptr<SerializeData> data = serializer->Release();
2100     JSDeserializerTest jsDeserializerTest;
2101     std::string changeStr = "world hello";
2102     std::thread t1(&JSDeserializerTest::JSSharedArrayBufferTest,
2103                    jsDeserializerTest, data.release(), 12, changeStr.c_str());
2104     ThreadSuspensionScope scope(thread);
2105     t1.join();
2106     EXPECT_TRUE(strcmp((char *)buffer, "world hello") == 0) << "Serialize JSArrayBuffer fail";
2107     delete serializer;
2108 };
2109 
HWTEST_F_L0(JSSerializerTest,SerializeJSArrayBufferShared3)2110 HWTEST_F_L0(JSSerializerTest, SerializeJSArrayBufferShared3)
2111 {
2112     std::string msg = "hello world";
2113     int msgBufferLen = static_cast<int>(msg.length()) + 1;
2114     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2115     JSHandle<JSArrayBuffer> jsArrayBuffer = factory->NewJSSharedArrayBuffer(msgBufferLen);
2116     JSHandle<JSTaggedValue> BufferData(thread, jsArrayBuffer->GetArrayBufferData());
2117     JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(BufferData);
2118     void *buffer = resNp->GetExternalPointer();
2119     if (memcpy_s(buffer, msgBufferLen, msg.c_str(), msgBufferLen) != EOK) {
2120         EXPECT_TRUE(false) << " memcpy error";
2121     }
2122 
2123     ValueSerializer *serializer = new ValueSerializer(thread);
2124     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsArrayBuffer),
2125                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2126                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2127     EXPECT_TRUE(success) << "Serialize JSSharedArrayBuffer fail";
2128     std::unique_ptr<SerializeData> data = serializer->Release();
2129     JSDeserializerTest jsDeserializerTest;
2130     std::string changeStr = "world hello";
2131     std::thread t1(&JSDeserializerTest::JSSharedArrayBufferTest,
2132                    jsDeserializerTest, data.get(), 12, changeStr.c_str());
2133     {
2134         ThreadSuspensionScope scope(thread);
2135         t1.join();
2136         EXPECT_TRUE(strcmp((char *)buffer, "world hello") == 0) << "Serialize JSArrayBuffer fail";
2137         changeStr = "world hella";
2138         JSDeserializerTest jsDeserializerTest1;
2139         std::thread t2(&JSDeserializerTest::JSSharedArrayBufferTest,
2140                     jsDeserializerTest1, data.get(), 12, changeStr.c_str());
2141         t2.join();
2142         EXPECT_TRUE(strcmp((char *)buffer, "world hella") == 0) << "Serialize JSArrayBuffer fail";
2143         changeStr = "world hellb";
2144         JSDeserializerTest jsDeserializerTest2;
2145         std::thread t3(&JSDeserializerTest::JSSharedArrayBufferTest,
2146                     jsDeserializerTest2, data.get(), 12, changeStr.c_str());
2147         t3.join();
2148         EXPECT_TRUE(strcmp((char *)buffer, "world hellb") == 0) << "Serialize JSArrayBuffer fail";
2149     }
2150     delete serializer;
2151     data.reset();
2152     EXPECT_TRUE(JSHandle<JSTaggedValue>(jsArrayBuffer)->IsSharedArrayBuffer());
2153 };
2154 
HWTEST_F_L0(JSSerializerTest,SerializeJSNativePointer)2155 HWTEST_F_L0(JSSerializerTest, SerializeJSNativePointer)
2156 {
2157     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2158     JSHandle<JSNativePointer> np = factory->NewJSNativePointer(nullptr);
2159     ValueSerializer *serializer = new ValueSerializer(thread);
2160     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(np),
2161                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2162                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2163     // Don't support serialize JSNativePointer directly
2164     EXPECT_TRUE(!success);
2165     std::unique_ptr<SerializeData> data = serializer->Release();
2166     EXPECT_TRUE(data->IsIncompleteData());
2167     delete serializer;
2168 }
2169 
CreateTestJSArrayBuffer(JSThread * thread)2170 JSArrayBuffer *CreateTestJSArrayBuffer(JSThread *thread)
2171 {
2172     JSHandle<JSArrayBuffer> jsArrayBuffer(thread, CreateJSArrayBuffer(thread));
2173     int32_t byteLength = 10;
2174     thread->GetEcmaVM()->GetFactory()->NewJSArrayBufferData(jsArrayBuffer, byteLength);
2175     jsArrayBuffer->SetArrayBufferByteLength(byteLength);
2176     JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(jsArrayBuffer);
2177     JSMutableHandle<JSTaggedValue> number(thread, JSTaggedValue::Undefined());
2178     for (int i = 0; i < 10; i++) { // 10: arrayLength
2179         number.Update(JSTaggedValue(i));
2180         BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), i, DataViewType::UINT8,
2181             number, true);
2182     }
2183     return *jsArrayBuffer;
2184 }
2185 
HWTEST_F_L0(JSSerializerTest,SerializeJSTypedArray1)2186 HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray1)
2187 {
2188     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2189     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2190     JSHandle<JSTaggedValue> target = env->GetInt8ArrayFunction();
2191     JSHandle<JSTypedArray> int8Array =
2192         JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
2193     JSHandle<JSTaggedValue> viewedArrayBuffer(thread, CreateTestJSArrayBuffer(thread));
2194     int8Array->SetViewedArrayBufferOrByteArray(thread, viewedArrayBuffer);
2195     int byteLength = 10;
2196     int byteOffset = 0;
2197     int arrayLength = (byteLength - byteOffset) / (sizeof(int8_t));
2198     int8Array->SetByteLength(byteLength);
2199     int8Array->SetByteOffset(byteOffset);
2200     int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
2201     int8Array->SetArrayLength(arrayLength);
2202     int8Array->SetContentType(ContentType::Number);
2203 
2204     ValueSerializer *serializer = new ValueSerializer(thread);
2205     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(int8Array),
2206                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2207                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2208     EXPECT_TRUE(success) << "Serialize type array fail";
2209     std::unique_ptr<SerializeData> data = serializer->Release();
2210     JSDeserializerTest jsDeserializerTest;
2211     std::thread t1(&JSDeserializerTest::TypedArrayTest1, jsDeserializerTest, data.release());
2212     ThreadSuspensionScope scope(thread);
2213     t1.join();
2214     delete serializer;
2215 };
2216 
HWTEST_F_L0(JSSerializerTest,SerializeJSTypedArray2)2217 HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray2)
2218 {
2219     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2220     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2221     JSHandle<JSTaggedValue> target = env->GetInt8ArrayFunction();
2222     JSHandle<JSTypedArray> int8Array =
2223         JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
2224     uint8_t value = 255; // 255 : test case
2225     JSTaggedType val = JSTaggedValue(value).GetRawData();
2226     int byteArrayLength = 10; // 10: arrayLength
2227     JSHandle<ByteArray> byteArray = factory->NewByteArray(byteArrayLength, sizeof(value));
2228     for (int i = 0; i < byteArrayLength; i++) {
2229         byteArray->Set(thread, i, DataViewType::UINT8, val);
2230     }
2231     int8Array->SetViewedArrayBufferOrByteArray(thread, byteArray);
2232     int byteLength = 10;
2233     int byteOffset = 0;
2234     int arrayLength = (byteLength - byteOffset) / (sizeof(int8_t));
2235     int8Array->SetByteLength(byteLength);
2236     int8Array->SetByteOffset(byteOffset);
2237     int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
2238     int8Array->SetArrayLength(arrayLength);
2239     int8Array->SetContentType(ContentType::Number);
2240 
2241     ValueSerializer *serializer = new ValueSerializer(thread);
2242     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(int8Array),
2243                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2244                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2245     EXPECT_TRUE(success) << "Serialize type array fail";
2246     std::unique_ptr<SerializeData> data = serializer->Release();
2247     JSDeserializerTest jsDeserializerTest;
2248     std::thread t1(&JSDeserializerTest::TypedArrayTest2, jsDeserializerTest, data.release());
2249     ThreadSuspensionScope scope(thread);
2250     t1.join();
2251     delete serializer;
2252 };
2253 
CreateEmptySObject(JSThread * thread)2254 JSHandle<JSObject> CreateEmptySObject(JSThread *thread)
2255 {
2256     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2257     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2258     JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull();
2259     JSHandle<LayoutInfo> emptyLayout = factory->CreateSLayoutInfo(0);
2260     JSHandle<JSHClass> hclass = factory->NewSEcmaHClass(JSSharedObject::SIZE, 0, JSType::JS_SHARED_OBJECT, nullHandle,
2261                                                         JSHandle<JSTaggedValue>(emptyLayout));
2262     return factory->NewSharedOldSpaceJSObject(hclass);
2263 }
2264 
CreateSObject(JSThread * thread)2265 JSHandle<JSObject> CreateSObject(JSThread *thread)
2266 {
2267     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2268     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2269     JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull();
2270 
2271     uint32_t index = 0;
2272     PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
2273     attributes.SetIsInlinedProps(true);
2274     attributes.SetRepresentation(Representation::TAGGED);
2275     uint32_t length = 4;
2276     JSHandle<LayoutInfo> layout = factory->CreateSLayoutInfo(length);
2277 
2278     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
2279     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
2280 
2281     while (index < length) {
2282         attributes.SetOffset(index);
2283         attributes.SetIsAccessor(false);
2284         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(thread->GetEcmaVM(), key2, key1));
2285         auto stringTable = thread->GetEcmaVM()->GetEcmaStringTable();
2286         stringTable->GetOrInternString(thread->GetEcmaVM(), *key2);
2287         layout->AddKey(thread, index++, key2.GetTaggedValue(), attributes);
2288     }
2289 
2290     JSHandle<JSHClass> hclass = factory->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
2291                                                         nullHandle, JSHandle<JSTaggedValue>(layout));
2292     JSHandle<JSObject> object = factory->NewSharedOldSpaceJSObject(hclass);
2293     uint32_t fieldIndex = 0;
2294     while (fieldIndex < length) {
2295         JSHandle<JSObject> emptyObject = CreateEmptySObject(thread);
2296         object->SetPropertyInlinedProps(thread, fieldIndex++, emptyObject.GetTaggedValue());
2297     }
2298     return object;
2299 }
2300 
CreateSSet(JSThread * thread)2301 JSHandle<JSSharedSet> CreateSSet(JSThread *thread)
2302 {
2303     auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
2304     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2305     JSHandle<JSTaggedValue> proto = globalEnv->GetSharedSetPrototype();
2306     auto emptySLayout = thread->GlobalConstants()->GetHandledEmptySLayoutInfo();
2307     JSHandle<JSHClass> setClass = factory->NewSEcmaHClass(JSSharedSet::SIZE, 0,
2308         JSType::JS_SHARED_SET, proto, emptySLayout);
2309     JSHandle<JSSharedSet> jsSet = JSHandle<JSSharedSet>::Cast(factory->NewSharedOldSpaceJSObjectWithInit(setClass));
2310     JSHandle<LinkedHashSet> linkedSet(
2311         LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED));
2312     jsSet->SetLinkedSet(thread, linkedSet);
2313     jsSet->SetModRecord(0);
2314     return jsSet;
2315 }
2316 
CreateSMap(JSThread * thread)2317 JSHandle<JSSharedMap> CreateSMap(JSThread *thread)
2318 {
2319     auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
2320     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2321     JSHandle<JSTaggedValue> proto = globalEnv->GetSharedMapPrototype();
2322     auto emptySLayout = thread->GlobalConstants()->GetHandledEmptySLayoutInfo();
2323     JSHandle<JSHClass> mapClass = factory->NewSEcmaHClass(JSSharedMap::SIZE, 0,
2324         JSType::JS_SHARED_MAP, proto, emptySLayout);
2325     JSHandle<JSSharedMap> jsMap = JSHandle<JSSharedMap>::Cast(factory->NewSharedOldSpaceJSObjectWithInit(mapClass));
2326     JSHandle<LinkedHashMap> linkedMap(
2327         LinkedHashMap::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED));
2328     jsMap->SetLinkedMap(thread, linkedMap);
2329     jsMap->SetModRecord(0);
2330     return jsMap;
2331 }
2332 
HWTEST_F_L0(JSSerializerTest,SerializeCloneListTest1)2333 HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest1)
2334 {
2335     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2336     JSHandle<JSObject> shareObj = CreateSObject(thread);
2337     Region *region = Region::ObjectAddressToRange(*shareObj);
2338     EXPECT_TRUE(region->InSharedHeap());
2339 
2340     JSHandle<EcmaString> key(factory->NewFromASCII("str2str1"));
2341     JSHandle<JSTaggedValue> shareObj1 =
2342         JSObject::GetProperty(thread, JSHandle<JSObject>(shareObj), JSHandle<JSTaggedValue>(key)).GetValue();
2343     Region *region1 = Region::ObjectAddressToRange(shareObj1->GetTaggedObject());
2344     EXPECT_TRUE(region1->InSharedHeap());
2345 
2346     JSHandle<JSArray> array = factory->NewJSArray();
2347     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(shareObj));
2348 
2349     ValueSerializer *serializer = new ValueSerializer(thread);
2350     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(shareObj),
2351                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2352                                           JSHandle<JSTaggedValue>(array));
2353     EXPECT_TRUE(success) << "SerializeCloneListTest1: Serialize shared obj fail";
2354     std::unique_ptr<SerializeData> data = serializer->Release();
2355     JSDeserializerTest jsDeserializerTest;
2356     std::thread t1(&JSDeserializerTest::SerializeCloneListTest1, jsDeserializerTest, data.release());
2357     ThreadSuspensionScope scope(thread);
2358     t1.join();
2359     delete serializer;
2360 };
2361 
HWTEST_F_L0(JSSerializerTest,SerializeCloneListTest2)2362 HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest2)
2363 {
2364     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2365     JSHandle<JSObject> rootObj = factory->NewEmptyJSObject();
2366     JSHandle<JSObject> shareObj = CreateSObject(thread);
2367     JSHandle<JSObject> noShareObj = CreateSObject(thread);
2368 
2369     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("shareObj"));
2370     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("noShareObj"));
2371 
2372     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(rootObj), key1, JSHandle<JSTaggedValue>(shareObj));
2373     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(rootObj), key2, JSHandle<JSTaggedValue>(noShareObj));
2374 
2375     JSHandle<JSArray> array = factory->NewJSArray();
2376     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(shareObj));
2377 
2378     ValueSerializer *serializer = new ValueSerializer(thread);
2379     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(rootObj),
2380                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2381                                           JSHandle<JSTaggedValue>(array));
2382     EXPECT_TRUE(success) << "SerializeCloneListTest2: Serialize shared obj fail";
2383     std::unique_ptr<SerializeData> data = serializer->Release();
2384     JSDeserializerTest jsDeserializerTest;
2385     std::thread t1(&JSDeserializerTest::SerializeCloneListTest2, jsDeserializerTest, data.release());
2386     ThreadSuspensionScope scope(thread);
2387     t1.join();
2388     delete serializer;
2389 };
2390 
HWTEST_F_L0(JSSerializerTest,SerializeCloneListTest3)2391 HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest3)
2392 {
2393     ObjectFactory *factory = ecmaVm->GetFactory();
2394     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
2395     JSHandle<EcmaString> cloneList(factory->NewFromASCII("cloneList"));
2396     ValueSerializer *serializer = new ValueSerializer(thread);
2397     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
2398                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2399                                           JSHandle<JSTaggedValue>(cloneList));
2400     EXPECT_FALSE(success);
2401     std::unique_ptr<SerializeData> data = serializer->Release();
2402     BaseDeserializer deserializer(thread, data.release());
2403     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
2404     EXPECT_TRUE(res.IsEmpty());
2405     delete serializer;
2406 };
2407 
HWTEST_F_L0(JSSerializerTest,SerializeCloneListTest4)2408 HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest4)
2409 {
2410     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2411     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
2412 
2413     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(0);
2414     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
2415     JSHandle<JSArray> array = factory->NewJSArray();
2416     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, arrBufTag);
2417 
2418     ValueSerializer *serializer = new ValueSerializer(thread);
2419     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
2420                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2421                                           JSHandle<JSTaggedValue>(array));
2422     EXPECT_TRUE(success) << "SerializeCloneListTest4: Serialize shared obj fail";
2423     std::unique_ptr<SerializeData> data = serializer->Release();
2424     JSDeserializerTest jsDeserializerTest;
2425     std::thread t1(&JSDeserializerTest::SerializeCloneListTest4, jsDeserializerTest, data.release());
2426     ThreadSuspensionScope scope(thread);
2427     t1.join();
2428     delete serializer;
2429 };
2430 
HWTEST_F_L0(JSSerializerTest,SerializeCloneListTest5)2431 HWTEST_F_L0(JSSerializerTest, SerializeCloneListTest5)
2432 {
2433     ObjectFactory *factory = ecmaVm->GetFactory();
2434     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
2435     JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
2436     JSHandle<JSArray> array = factory->NewJSArray();
2437     // set value to array
2438     array->SetArrayLength(thread, 1);
2439     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(obj1));
2440     ValueSerializer *serializer = new ValueSerializer(thread);
2441     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
2442                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2443                                           JSHandle<JSTaggedValue>(array));
2444     EXPECT_FALSE(success);
2445     std::unique_ptr<SerializeData> data = serializer->Release();
2446     BaseDeserializer deserializer(thread, data.release());
2447     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
2448     EXPECT_TRUE(res.IsEmpty());
2449     delete serializer;
2450 };
2451 
HWTEST_F_L0(JSSerializerTest,SerializeJSSharedSetBasic1)2452 HWTEST_F_L0(JSSerializerTest, SerializeJSSharedSetBasic1)
2453 {
2454     JSHandle<JSSharedSet> jsSet = CreateSSet(thread);
2455     ValueSerializer *serializer = new ValueSerializer(thread);
2456     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsSet),
2457                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2458                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2459     EXPECT_TRUE(success) << "Serialize JSSharedSet failed";
2460     std::unique_ptr<SerializeData> data = serializer->Release();
2461     {
2462         for (int i = 0; i < INITIALIZE_SIZE; i++) {
2463             JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)));
2464         }
2465         JSDeserializerTest jsDeserializerTest;
2466         // The Deserializer thread will clear the shared set
2467         std::thread t1(&JSDeserializerTest::JSSharedSetBasicTest1,
2468                        jsDeserializerTest, data.get());
2469         ThreadSuspensionScope scope(thread);
2470         t1.join();
2471         EXPECT_TRUE(JSSharedSet::GetSize(thread, jsSet) == 0);
2472     }
2473     {
2474         for (int i = 0; i < INITIALIZE_SIZE; i++) {
2475             JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)));
2476         }
2477         EXPECT_TRUE(!JSSharedSet::Has(thread, jsSet, JSTaggedValue(INITIALIZE_SIZE)));
2478         JSDeserializerTest jsDeserializerTest;
2479         // The Deserializer thread will add and delete a element
2480         std::thread t1(&JSDeserializerTest::JSSharedSetBasicTest2,
2481                        jsDeserializerTest, data.get());
2482         ThreadSuspensionScope scope(thread);
2483         t1.join();
2484         EXPECT_TRUE(!JSSharedSet::Has(thread, jsSet, JSTaggedValue(0)));
2485         EXPECT_TRUE(JSSharedSet::Has(thread, jsSet, JSTaggedValue(INITIALIZE_SIZE)));
2486     }
2487     delete serializer;
2488 };
2489 
HWTEST_F_L0(JSSerializerTest,SerializeMultiThreadJSSharedSet)2490 HWTEST_F_L0(JSSerializerTest, SerializeMultiThreadJSSharedSet)
2491 {
2492     Reset();
2493     JSHandle<JSSharedSet> jsSet = CreateSSet(thread);
2494     ValueSerializer *serializer = new ValueSerializer(thread);
2495     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsSet),
2496                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2497                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2498     EXPECT_TRUE(success) << "Serialize JSSharedSet fail";
2499     std::unique_ptr<SerializeData> data = serializer->Release();
2500     for (int i = 0; i < INITIALIZE_SIZE; i++) {
2501         JSSharedSet::Add(thread, jsSet, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)));
2502     }
2503     constexpr uint32_t maxNumDeserializers = 10;
2504     JSDeserializerTest jsDeserializerTests[maxNumDeserializers];
2505     std::thread threads[maxNumDeserializers];
2506     for (int32_t i = 0; i < maxNumDeserializers; i++) {
2507         threads[i] = std::thread(&JSDeserializerTest::JSSharedSetMultiThreadTest1,
2508             jsDeserializerTests[i], data.get());
2509     }
2510     ThreadSuspensionScope scope(thread);
2511     for (int i = 0; i < maxNumDeserializers; i++) {
2512         threads[i].join();
2513     }
2514     EXPECT_TRUE(jsSet->GetModRecord() == 0);
2515     delete serializer;
2516 };
2517 
HWTEST_F_L0(JSSerializerTest,SerializeJSSharedMapBasic)2518 HWTEST_F_L0(JSSerializerTest, SerializeJSSharedMapBasic)
2519 {
2520     JSHandle<JSSharedMap> jsMap = CreateSMap(thread);
2521     ValueSerializer *serializer = new ValueSerializer(thread);
2522     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsMap),
2523                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2524                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2525     EXPECT_TRUE(success) << "Serialize JSSharedMap failed";
2526     std::unique_ptr<SerializeData> data = serializer->Release();
2527     {
2528         for (int i = 0; i < INITIALIZE_SIZE; i++) {
2529             JSSharedMap::Set(thread, jsMap, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)),
2530                 JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)));
2531         }
2532         JSDeserializerTest jsDeserializerTest;
2533         // The Deserializer thread will clear the shared map
2534         std::thread t1(&JSDeserializerTest::JSSharedMapBasicTest1,
2535                        jsDeserializerTest, data.get());
2536         ThreadSuspensionScope scope(thread);
2537         t1.join();
2538         EXPECT_TRUE(JSSharedMap::GetSize(thread, jsMap) == 0);
2539     }
2540     {
2541         for (int i = 0; i < INITIALIZE_SIZE; i++) {
2542             JSSharedMap::Set(thread, jsMap, JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)),
2543                 JSHandle<JSTaggedValue>(thread, JSTaggedValue(i)));
2544         }
2545         EXPECT_TRUE(!JSSharedMap::Has(thread, jsMap, JSTaggedValue(INITIALIZE_SIZE)));
2546         JSDeserializerTest jsDeserializerTest;
2547         // The Deserializer thread will add and delete a element
2548         std::thread t1(&JSDeserializerTest::JSSharedMapBasicTest2,
2549                        jsDeserializerTest, data.get());
2550         ThreadSuspensionScope scope(thread);
2551         t1.join();
2552         EXPECT_TRUE(!JSSharedMap::Has(thread, jsMap, JSTaggedValue(0)));
2553         EXPECT_TRUE(JSSharedMap::Has(thread, jsMap, JSTaggedValue(INITIALIZE_SIZE)));
2554     }
2555     delete serializer;
2556 };
2557 
HWTEST_F_L0(JSSerializerTest,SerializeMultiSharedRegion)2558 HWTEST_F_L0(JSSerializerTest, SerializeMultiSharedRegion)
2559 {
2560     ObjectFactory *factory = ecmaVm->GetFactory();
2561     JSHandle<TaggedArray> array = factory->NewSTaggedArray(10 * 1024, JSTaggedValue::Hole()); // 10 * 1024: array length
2562     for (int i = 0; i < 5; i++) {
2563         JSHandle<TaggedArray> element = factory->NewSTaggedArray((11 + i) * 1024, JSTaggedValue::Hole());
2564         array->Set(thread, i, element);
2565     }
2566     JSHandle<JSObject> sobj = CreateEmptySObject(thread);
2567     sobj->SetElements(thread, array);
2568     ValueSerializer *serializer = new ValueSerializer(thread, false, true);
2569     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(sobj),
2570                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2571                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
2572     EXPECT_TRUE(success);
2573     std::unique_ptr<SerializeData> data = serializer->Release();
2574     JSDeserializerTest jsDeserializerTest;
2575     std::thread t1(&JSDeserializerTest::SerializeMultiSharedRegionTest, jsDeserializerTest, data.release());
2576     ThreadSuspensionScope scope(thread);
2577     t1.join();
2578     delete serializer;
2579 };
2580 }  // namespace panda::test
2581