• 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_serializer.h"
29 #include "ecmascript/js_set.h"
30 #include "ecmascript/js_thread.h"
31 #include "ecmascript/js_typed_array.h"
32 #include "ecmascript/jspandafile/js_pandafile.h"
33 #include "ecmascript/jspandafile/js_pandafile_manager.h"
34 #include "ecmascript/linked_hash_table.h"
35 #include "ecmascript/mem/c_containers.h"
36 #include "ecmascript/object_factory.h"
37 #include "ecmascript/tests/test_helper.h"
38 
39 #include "ecmascript/serializer/value_serializer.h"
40 #include "ecmascript/serializer/base_deserializer.h"
41 
42 using namespace panda::ecmascript;
43 using namespace testing::ext;
44 using namespace panda::ecmascript::builtins;
45 
46 namespace panda::test {
47 using DeserializeFunc = void (*)(SerializeData* data);
48 using Clock = std::chrono::high_resolution_clock;
49 using Duration = std::chrono::duration<uint64_t, std::nano>;
50 
51 class JSDeserializerTest {
52 public:
JSDeserializerTest()53     JSDeserializerTest() : ecmaVm(nullptr), scope(nullptr), thread(nullptr) {}
Init()54     void Init()
55     {
56         JSRuntimeOptions options;
57         options.SetEnableForceGC(true);
58         ecmaVm = JSNApi::CreateEcmaVM(options);
59         ecmaVm->SetEnableForceGC(true);
60         EXPECT_TRUE(ecmaVm != nullptr) << "Cannot create Runtime";
61         thread = ecmaVm->GetJSThread();
62         scope = new EcmaHandleScope(thread);
63     }
Destroy()64     void Destroy()
65     {
66         delete scope;
67         scope = nullptr;
68         ecmaVm->SetEnableForceGC(false);
69         thread->ClearException();
70         JSNApi::DestroyJSVM(ecmaVm);
71     }
72 
JSSpecialValueTest(SerializeData * data)73     void JSSpecialValueTest(SerializeData* data)
74     {
75         Init();
76         JSHandle<JSTaggedValue> jsTrue(thread, JSTaggedValue::True());
77         JSHandle<JSTaggedValue> jsFalse(thread, JSTaggedValue::False());
78         JSHandle<JSTaggedValue> jsUndefined(thread, JSTaggedValue::Undefined());
79         JSHandle<JSTaggedValue> jsNull(thread, JSTaggedValue::Null());
80         JSHandle<JSTaggedValue> jsHole(thread, JSTaggedValue::Hole());
81 
82         BaseDeserializer deserializer(thread, data);
83         JSHandle<JSTaggedValue> retTrue = deserializer.ReadValue();
84         EXPECT_TRUE(JSTaggedValue::SameValue(jsTrue, retTrue)) << "Not same value for JS_TRUE";
85         JSHandle<JSTaggedValue> retFalse = deserializer.ReadValue();
86         EXPECT_TRUE(JSTaggedValue::SameValue(jsFalse, retFalse)) << "Not same value for JS_FALSE";
87         JSHandle<JSTaggedValue> retUndefined = deserializer.ReadValue();
88         JSHandle<JSTaggedValue> retNull = deserializer.ReadValue();
89         JSHandle<JSTaggedValue> retHole = deserializer.ReadValue();
90 
91         EXPECT_TRUE(JSTaggedValue::SameValue(jsUndefined, retUndefined)) << "Not same value for JS_UNDEFINED";
92         EXPECT_TRUE(JSTaggedValue::SameValue(jsNull, retNull)) << "Not same value for JS_NULL";
93         EXPECT_TRUE(JSTaggedValue::SameValue(jsHole, retHole)) << "Not same value for JS_HOLE";
94         Destroy();
95     }
96 
LineStringTest(SerializeData * data)97     void LineStringTest(SerializeData* data)
98     {
99         Init();
100         BaseDeserializer deserializer(thread, data);
101         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
102         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
103         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
104 
105         EXPECT_FALSE(res.IsEmpty());
106         EXPECT_TRUE(res->IsLineString());
107 
108         Destroy();
109     }
110 
TreeStringTest(SerializeData * data)111     void TreeStringTest(SerializeData* data)
112     {
113         Init();
114         BaseDeserializer deserializer(thread, data);
115         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
116         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
117         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
118 
119         EXPECT_FALSE(res.IsEmpty());
120         EXPECT_TRUE(res->IsLineString());
121 
122         Destroy();
123     }
124 
SlicedStringTest(SerializeData * data)125     void SlicedStringTest(SerializeData* data)
126     {
127         Init();
128         BaseDeserializer deserializer(thread, data);
129         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
130         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
131         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
132 
133         EXPECT_FALSE(res.IsEmpty());
134         EXPECT_TRUE(res->IsLineString());
135 
136         Destroy();
137     }
138 
JSPlainObjectTest1(SerializeData * data)139     void JSPlainObjectTest1(SerializeData* data)
140     {
141         Init();
142         BaseDeserializer deserializer(thread, data);
143         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
144         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
145         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
146 
147         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
148         EXPECT_FALSE(retObj.IsEmpty());
149 
150         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj);
151         uint32_t length = array->GetLength();
152         EXPECT_EQ(length, 4U); // 4 : test case
153         double sum = 0.0;
154         for (uint32_t i = 0; i < length; i++) {
155             JSHandle<JSTaggedValue> key(thread, array->Get(i));
156             double a = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue()->GetNumber();
157             sum += a;
158         }
159         EXPECT_EQ(sum, 10); // 10 : test case
160 
161         Destroy();
162     }
163 
JSPlainObjectTest2(SerializeData * data)164     void JSPlainObjectTest2(SerializeData* data)
165     {
166         Init();
167         BaseDeserializer deserializer(thread, data);
168         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
169         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
170         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
171 
172         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
173         EXPECT_FALSE(retObj.IsEmpty());
174 
175         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj);
176         uint32_t length = array->GetLength();
177         EXPECT_EQ(length, 10U);
178         for (uint32_t i = 0; i < length; i++) {
179             JSHandle<JSTaggedValue> key(thread, array->Get(i));
180             JSHandle<JSTaggedValue> value =
181                 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue();
182             EXPECT_TRUE(value->GetTaggedObject()->GetClass()->IsJSObject());
183         }
184 
185         Destroy();
186     }
187 
JSPlainObjectTest3(SerializeData * data)188     void JSPlainObjectTest3(SerializeData* data)
189     {
190         Init();
191         BaseDeserializer deserializer(thread, data);
192         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
193         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
194         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
195 
196         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
197         EXPECT_FALSE(retObj.IsEmpty());
198         EXPECT_TRUE(retObj->GetClass()->IsDictionaryMode());
199 
200         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj);
201         uint32_t length = array->GetLength();
202         EXPECT_EQ(length, 1030U);
203         for (uint32_t i = 0; i < length; i++) {
204             JSHandle<JSTaggedValue> key(thread, array->Get(i));
205             JSHandle<JSTaggedValue> value =
206                 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue();
207             EXPECT_TRUE(value->IsInt());
208         }
209 
210         Destroy();
211     }
212 
JSPlainObjectTest4(SerializeData * data)213     void JSPlainObjectTest4(SerializeData* data)
214     {
215         Init();
216         ObjectFactory *factory = ecmaVm->GetFactory();
217         JSHandle<JSTaggedValue> key(factory->NewFromASCII("str1"));
218 
219         BaseDeserializer deserializer(thread, data);
220         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
221         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
222         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
223 
224         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
225         EXPECT_FALSE(retObj.IsEmpty());
226 
227         JSHandle<JSTaggedValue> value =
228             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue();
229         EXPECT_TRUE(value->IsTaggedArray());
230         TaggedArray *array = reinterpret_cast<TaggedArray *>(value->GetTaggedObject());
231         size_t length = array->GetLength();
232         EXPECT_EQ(length, 102400U); // 102400: array length
233         for (uint32_t i = 0; i < length; i++) {
234             EXPECT_TRUE(array->Get(i).IsHole());
235         }
236 
237         Destroy();
238     }
239 
JSErrorTest1(SerializeData * data)240     void JSErrorTest1(SerializeData* data)
241     {
242         Init();
243 
244         BaseDeserializer deserializer(thread, data);
245         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
246         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
247         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
248 
249         EXPECT_FALSE(objValue.IsEmpty());
250         EXPECT_TRUE(objValue->IsJSError());
251 
252         Destroy();
253     }
254 
JSErrorTest2(SerializeData * data)255     void JSErrorTest2(SerializeData* data)
256     {
257         Init();
258 
259         BaseDeserializer deserializer(thread, data);
260         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
261         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
262         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
263 
264         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
265         EXPECT_FALSE(retObj.IsEmpty());
266 
267         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj);
268         uint32_t length = array->GetLength();
269         EXPECT_EQ(length, 2U);
270         for (uint32_t i = 0; i < length; i++) {
271             JSHandle<JSTaggedValue> key(thread, array->Get(i));
272             JSHandle<JSTaggedValue> value =
273                 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue();
274             EXPECT_TRUE(value->IsJSError());
275         }
276 
277         Destroy();
278     }
279 
BigIntTest(SerializeData * data)280     void BigIntTest(SerializeData* data)
281     {
282         Init();
283         BaseDeserializer deserializer(thread, data);
284         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
285         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
286         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
287 
288         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
289         EXPECT_FALSE(retObj.IsEmpty());
290 
291         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj);
292         uint32_t length = array->GetLength();
293         EXPECT_EQ(length, 2U);
294         for (uint32_t i = 0; i < length; i++) {
295             JSHandle<JSTaggedValue> key(thread, array->Get(i));
296             JSHandle<JSTaggedValue> value =
297                 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue();
298             EXPECT_TRUE(value->GetTaggedObject()->GetClass()->IsBigInt());
299         }
300 
301         Destroy();
302     }
303 
NativeBindingObjectTest1(SerializeData * data)304     void NativeBindingObjectTest1(SerializeData* data)
305     {
306         Init();
307         BaseDeserializer deserializer(thread, data);
308         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
309         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
310         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
311         EXPECT_TRUE(objValue->IsUndefined());
312         Destroy();
313     }
314 
NativeBindingObjectTest2(SerializeData * data)315     void NativeBindingObjectTest2(SerializeData* data)
316     {
317         Init();
318         BaseDeserializer deserializer(thread, data);
319         JSHandle<JSTaggedValue> objValue = deserializer.ReadValue();
320         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
321         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
322         EXPECT_TRUE(objValue->IsJSObject());
323 
324         JSHandle<JSObject> retObj = JSHandle<JSObject>::Cast(objValue);
325         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, retObj);
326         uint32_t length = array->GetLength();
327         EXPECT_EQ(length, 2U);
328         JSHandle<JSTaggedValue> key(thread, array->Get(0));
329         JSHandle<JSTaggedValue> value =
330             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retObj), key).GetValue();
331         EXPECT_TRUE(value->IsUndefined());
332 
333         Destroy();
334     }
335 
JSSetTest(SerializeData * data)336     void JSSetTest(SerializeData* data)
337     {
338         Init();
339         ObjectFactory *factory = ecmaVm->GetFactory();
340         JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7)); // 7 : test case
341         JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9)); // 9 : test case
342         JSHandle<JSTaggedValue> value3(factory->NewFromASCII("x"));
343         JSHandle<JSTaggedValue> value4(factory->NewFromASCII("y"));
344 
345         BaseDeserializer deserializer(thread, data);
346         JSHandle<JSTaggedValue> setValue = deserializer.ReadValue();
347         EXPECT_TRUE(!setValue.IsEmpty());
348         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
349         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
350 
351         JSHandle<JSSet> retSet = JSHandle<JSSet>::Cast(setValue);
352         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>::Cast(retSet));
353         uint32_t propertyLength = array->GetLength();
354         EXPECT_EQ(propertyLength, 2U); // 2 : test case
355         int sum = 0;
356         for (uint32_t i = 0; i < propertyLength; i++) {
357             JSHandle<JSTaggedValue> key(thread, array->Get(i));
358             double a = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retSet), key).GetValue()->GetNumber();
359             sum += a;
360         }
361         EXPECT_EQ(sum, 16); // 16 : test case
362 
363         EXPECT_EQ(retSet->GetSize(), 4);  // 4 : test case
364         EXPECT_TRUE(retSet->Has(thread, value1.GetTaggedValue()));
365         EXPECT_TRUE(retSet->Has(thread, value2.GetTaggedValue()));
366         EXPECT_TRUE(retSet->Has(thread, value3.GetTaggedValue()));
367         EXPECT_TRUE(retSet->Has(thread, value4.GetTaggedValue()));
368         Destroy();
369     }
370 
JSArrayTest(SerializeData * data)371     void JSArrayTest(SerializeData* data)
372     {
373         Init();
374         BaseDeserializer deserializer(thread, data);
375         JSHandle<JSTaggedValue> arrayValue = deserializer.ReadValue();
376         EXPECT_TRUE(!arrayValue.IsEmpty());
377         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
378         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
379 
380         JSHandle<JSArray> retArray = JSHandle<JSArray>::Cast(arrayValue);
381 
382         JSHandle<TaggedArray> keyArray = JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>(retArray));
383         uint32_t propertyLength = keyArray->GetLength();
384         EXPECT_EQ(propertyLength, 23U);  // 23 : test case
385         int sum = 0;
386         for (uint32_t i = 0; i < propertyLength; i++) {
387             JSHandle<JSTaggedValue> key(thread, keyArray->Get(i));
388             double a = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(retArray), key).GetValue()->GetNumber();
389             sum += a;
390         }
391         EXPECT_EQ(sum, 226);  // 226 : test case
392 
393         // test get value from array
394         for (int i = 0; i < 20; i++) {  // 20 : test case
395             JSHandle<JSTaggedValue> value = JSArray::FastGetPropertyByValue(thread, arrayValue, i);
396             EXPECT_EQ(i, value.GetTaggedValue().GetInt());
397         }
398         Destroy();
399     }
400 
EcmaStringTest1(SerializeData * data)401     void EcmaStringTest1(SerializeData* data)
402     {
403         Init();
404         const char *rawStr = "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
405         "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
406         "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
407         "ssssss";
408         JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(rawStr);
409 
410         BaseDeserializer deserializer(thread, data);
411         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
412         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ecmaString fail";
413         EXPECT_TRUE(res->IsString()) << "[NotString] Deserialize ecmaString fail";
414         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
415         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
416 
417         JSHandle<EcmaString> resEcmaString = JSHandle<EcmaString>::Cast(res);
418         auto ecmaStringCode = EcmaStringAccessor(ecmaString).GetHashcode();
419         auto resEcmaStringCode = EcmaStringAccessor(resEcmaString).GetHashcode();
420         EXPECT_TRUE(ecmaStringCode == resEcmaStringCode) << "Not same HashCode";
421         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*ecmaString, *resEcmaString)) << "Not same EcmaString";
422         Destroy();
423     }
424 
EcmaStringTest2(SerializeData * data)425     void EcmaStringTest2(SerializeData* data)
426     {
427         Init();
428         JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromStdString("你好,世界");
429         JSHandle<EcmaString> ecmaString1 = thread->GetEcmaVM()->GetFactory()->NewFromStdString("你好,世界");
430         auto ecmaStringCode1 = EcmaStringAccessor(ecmaString).GetHashcode();
431         auto ecmaString1Code = EcmaStringAccessor(ecmaString1).GetHashcode();
432         EXPECT_TRUE(ecmaStringCode1 == ecmaString1Code) << "Not same HashCode";
433         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*ecmaString, *ecmaString1)) << "Not same EcmaString";
434 
435         BaseDeserializer deserializer(thread, data);
436         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
437         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ecmaString fail";
438         EXPECT_TRUE(res->IsString()) << "[NotString] Deserialize ecmaString fail";
439         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
440         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
441 
442         JSHandle<EcmaString> resEcmaString = JSHandle<EcmaString>::Cast(res);
443         auto ecmaStringCode2 = EcmaStringAccessor(ecmaString).GetHashcode();
444         auto resEcmaStringCode = EcmaStringAccessor(resEcmaString).GetHashcode();
445         EXPECT_TRUE(ecmaStringCode2 == resEcmaStringCode) << "Not same HashCode";
446         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*ecmaString, *resEcmaString)) << "Not same EcmaString";
447         Destroy();
448     }
449 
Int32Test(SerializeData * data)450     void Int32Test(SerializeData* data)
451     {
452         Init();
453         int32_t a = 64;
454         int32_t min = -2147483648;
455         int32_t b = -63;
456         BaseDeserializer deserializer(thread, data);
457         JSHandle<JSTaggedValue> resA = deserializer.ReadValue();
458         JSHandle<JSTaggedValue> resMin = deserializer.ReadValue();
459         JSHandle<JSTaggedValue> resB = deserializer.ReadValue();
460         EXPECT_TRUE(!resA.IsEmpty() && !resMin.IsEmpty() && !resB.IsEmpty()) << "[Empty] Deserialize Int32 fail";
461         EXPECT_TRUE(resA->IsInt() && resMin->IsInt() && resB->IsInt()) << "[NotInt] Deserialize Int32 fail";
462         EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resA) == a) << "Not Same Value";
463         EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resMin) == min) << "Not Same Value";
464         EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resB) == b) << "Not Same Value";
465         Destroy();
466     }
467 
DoubleTest(SerializeData * data)468     void DoubleTest(SerializeData* data)
469     {
470         Init();
471         double a = 3.1415926535;
472         double b = -3.1415926535;
473         BaseDeserializer deserializer(thread, data);
474         JSHandle<JSTaggedValue> resA = deserializer.ReadValue();
475         JSHandle<JSTaggedValue> resB = deserializer.ReadValue();
476         EXPECT_TRUE(!resA.IsEmpty() && !resB.IsEmpty()) << "[Empty] Deserialize double fail";
477         EXPECT_TRUE(resA->IsDouble() && resB->IsDouble()) << "[NotInt] Deserialize double fail";
478         EXPECT_TRUE(resA->GetDouble() == a) << "Not Same Value";
479         EXPECT_TRUE(resB->GetDouble() == b) << "Not Same Value";
480         Destroy();
481     }
482 
JSDateTest(SerializeData * data)483     void JSDateTest(SerializeData* data)
484     {
485         Init();
486         double tm = 28 * 60 * 60 * 1000;  // 28 * 60 * 60 * 1000 : test case
487         BaseDeserializer deserializer(thread, data);
488         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
489         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSDate fail";
490         EXPECT_TRUE(res->IsDate()) << "[NotJSDate] Deserialize JSDate fail";
491         JSHandle<JSDate> resDate = JSHandle<JSDate>(res);
492         EXPECT_TRUE(resDate->GetTimeValue() == JSTaggedValue(tm)) << "Not Same Time Value";
493         Destroy();
494     }
495 
JSMapTest(SerializeData * data,const JSHandle<JSMap> & originMap)496     void JSMapTest(SerializeData* data, const JSHandle<JSMap> &originMap)
497     {
498         Init();
499         BaseDeserializer deserializer(thread, data);
500         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
501         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSMap fail";
502         EXPECT_TRUE(res->IsJSMap()) << "[NotJSMap] Deserialize JSMap fail";
503         JSHandle<JSMap> resMap = JSHandle<JSMap>::Cast(res);
504         EXPECT_TRUE(originMap->GetSize() == resMap->GetSize()) << "the map size Not equal";
505         uint32_t resSize = static_cast<uint32_t>(resMap->GetSize());
506         for (uint32_t i = 0; i < resSize; i++) {
507             JSHandle<JSTaggedValue> resKey(thread, resMap->GetKey(i));
508             JSHandle<JSTaggedValue> resValue(thread, resMap->GetValue(i));
509             JSHandle<JSTaggedValue> key(thread, originMap->GetKey(i));
510             JSHandle<JSTaggedValue> value(thread, originMap->GetValue(i));
511 
512             JSHandle<EcmaString> resKeyStr = JSHandle<EcmaString>::Cast(resKey);
513             JSHandle<EcmaString> keyStr = JSHandle<EcmaString>::Cast(key);
514             EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*resKeyStr, *keyStr)) << "Not same map key";
515             EXPECT_TRUE(JSTaggedValue::ToInt32(thread, resValue) == JSTaggedValue::ToInt32(thread, value))
516                 << "Not same map value";
517         }
518         Destroy();
519     }
520 
JSSharedArrayBufferTest(SerializeData * data,const JSHandle<JSArrayBuffer> & originArrayBuffer,int32_t byteLength,const char * msg)521     void JSSharedArrayBufferTest(SerializeData *data,
522                            const JSHandle<JSArrayBuffer> &originArrayBuffer, int32_t byteLength, const char *msg)
523     {
524         Init();
525         BaseDeserializer deserializer(thread, data);
526         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
527         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSArrayBuffer fail";
528         EXPECT_TRUE(res->IsSharedArrayBuffer()) << "[NotJSArrayBuffer] Deserialize JSArrayBuffer fail";
529         JSHandle<JSArrayBuffer> resJSArrayBuffer = JSHandle<JSArrayBuffer>::Cast(res);
530         int32_t resByteLength = static_cast<int32_t>(resJSArrayBuffer->GetArrayBufferByteLength());
531         EXPECT_TRUE(resByteLength == byteLength) << "Not Same ByteLength";
532         JSHandle<JSTaggedValue> bufferData(thread, originArrayBuffer->GetArrayBufferData());
533         auto np = JSHandle<JSNativePointer>::Cast(bufferData);
534         void *buffer = np->GetExternalPointer();
535         ASSERT_NE(buffer, nullptr);
536         JSHandle<JSTaggedValue> resBufferData(thread, resJSArrayBuffer->GetArrayBufferData());
537         JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(resBufferData);
538         void *resBuffer = resNp->GetExternalPointer();
539         ASSERT_NE(resBuffer, nullptr);
540         EXPECT_TRUE(buffer == resBuffer) << "Not Same pointer!";
541         for (int32_t i = 0; i < resByteLength; i++) {
542             EXPECT_TRUE(static_cast<char *>(resBuffer)[i] == static_cast<char *>(buffer)[i]) << "Not Same Buffer";
543         }
544 
545         if (msg != nullptr) {
546             if (memcpy_s(resBuffer, byteLength, msg, byteLength) != EOK) {
547                 EXPECT_TRUE(false) << " memcpy error!";
548             }
549         }
550         Destroy();
551     }
552 
JSRegexpTest(SerializeData * data)553     void JSRegexpTest(SerializeData *data)
554     {
555         Init();
556         JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2");
557         JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i");
558         char buffer[] = "1234567";  // use char buffer to simulate byteCodeBuffer
559         uint32_t bufferSize = 7;
560 
561         BaseDeserializer deserializer(thread, data);
562         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
563         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize JSRegExp fail";
564         EXPECT_TRUE(res->IsJSRegExp()) << "[NotJSRegexp] Deserialize JSRegExp fail";
565         JSHandle<JSRegExp> resJSRegexp(res);
566 
567         uint32_t resBufferSize = resJSRegexp->GetLength();
568         EXPECT_TRUE(resBufferSize == bufferSize) << "Not Same Length";
569         JSHandle<JSTaggedValue> originalSource(thread, resJSRegexp->GetOriginalSource());
570         EXPECT_TRUE(originalSource->IsString());
571         JSHandle<JSTaggedValue> originalFlags(thread, resJSRegexp->GetOriginalFlags());
572         EXPECT_TRUE(originalFlags->IsString());
573         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(originalSource), *pattern));
574         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(originalFlags), *flags));
575         JSHandle<JSTaggedValue> resBufferData(thread, resJSRegexp->GetByteCodeBuffer());
576         JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(resBufferData);
577         void *resBuffer = resNp->GetExternalPointer();
578         ASSERT_NE(resBuffer, nullptr);
579 
580         for (uint32_t i = 0; i < resBufferSize; i++) {
581             EXPECT_TRUE(static_cast<char *>(resBuffer)[i] == buffer[i]) << "Not Same ByteCode";
582         }
583 
584         Destroy();
585     }
586 
TypedArrayTest1(SerializeData * data)587     void TypedArrayTest1(SerializeData *data)
588     {
589         Init();
590         JSHandle<JSTaggedValue> originTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
591         BaseDeserializer deserializer(thread, data);
592         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
593         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TypedArray fail";
594         EXPECT_TRUE(res->IsJSInt8Array()) << "[NotJSInt8Array] Deserialize TypedArray fail";
595         JSHandle<JSTypedArray> resJSInt8Array = JSHandle<JSTypedArray>::Cast(res);
596 
597         JSHandle<JSTaggedValue> typedArrayName(thread, resJSInt8Array->GetTypedArrayName());
598         uint32_t byteLength = resJSInt8Array->GetByteLength();
599         uint32_t byteOffset = resJSInt8Array->GetByteOffset();
600         uint32_t arrayLength = resJSInt8Array->GetArrayLength();
601         ContentType contentType = resJSInt8Array->GetContentType();
602         JSHandle<JSTaggedValue> viewedArrayBuffer(thread, resJSInt8Array->GetViewedArrayBufferOrByteArray());
603 
604         EXPECT_TRUE(typedArrayName->IsString());
605         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(typedArrayName),
606                                                         *JSHandle<EcmaString>(originTypedArrayName)));
607         EXPECT_EQ(byteLength, 10) << "Not Same ByteLength"; // 10: bufferLength
608         EXPECT_EQ(byteOffset, 0) << "Not Same ByteOffset";
609         EXPECT_EQ(arrayLength, 10) << "Not Same ArrayLength"; // 10: arrayLength
610         EXPECT_TRUE(contentType == ContentType::Number) << "Not Same ContentType";
611 
612         // check arrayBuffer
613         EXPECT_TRUE(viewedArrayBuffer->IsArrayBuffer());
614         JSHandle<JSArrayBuffer> resJSArrayBuffer(viewedArrayBuffer);
615         uint32_t resTaggedLength = resJSArrayBuffer->GetArrayBufferByteLength();
616         EXPECT_EQ(resTaggedLength, 10) << "Not same viewedBuffer length"; // 10: bufferLength
617         JSHandle<JSTaggedValue> resBufferData(thread, resJSArrayBuffer->GetArrayBufferData());
618         JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(resBufferData);
619         void *resBuffer = resNp->GetExternalPointer();
620         for (uint32_t i = 0; i < resTaggedLength; i++) {
621             EXPECT_EQ(static_cast<uint8_t *>(resBuffer)[i], i) << "Not same viewedBuffer";
622         }
623         Destroy();
624     }
625 
TypedArrayTest2(SerializeData * data)626     void TypedArrayTest2(SerializeData *data)
627     {
628         Init();
629         JSHandle<JSTaggedValue> originTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
630         BaseDeserializer deserializer(thread, data);
631         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
632         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TypedArray fail";
633         EXPECT_TRUE(res->IsJSInt8Array()) << "[NotJSInt8Array] Deserialize TypedArray fail";
634         JSHandle<JSTypedArray> resJSInt8Array = JSHandle<JSTypedArray>::Cast(res);
635 
636         JSHandle<JSTaggedValue> typedArrayName(thread, resJSInt8Array->GetTypedArrayName());
637         uint32_t byteLength = resJSInt8Array->GetByteLength();
638         uint32_t byteOffset = resJSInt8Array->GetByteOffset();
639         uint32_t arrayLength = resJSInt8Array->GetArrayLength();
640         ContentType contentType = resJSInt8Array->GetContentType();
641         JSHandle<JSTaggedValue> byteArray(thread, resJSInt8Array->GetViewedArrayBufferOrByteArray());
642 
643         EXPECT_TRUE(typedArrayName->IsString());
644         EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>(typedArrayName),
645                                                         *JSHandle<EcmaString>(originTypedArrayName)));
646         EXPECT_EQ(byteLength, 10) << "Not Same ByteLength"; // 10: bufferLength
647         EXPECT_EQ(byteOffset, 0) << "Not Same ByteOffset";
648         EXPECT_EQ(arrayLength, 10) << "Not Same ArrayLength"; // 10: arrayLength
649         EXPECT_TRUE(contentType == ContentType::Number) << "Not Same ContentType";
650 
651         // check byteArray
652         EXPECT_TRUE(byteArray->IsByteArray());
653         JSHandle<ByteArray> resByteArray(byteArray);
654         uint32_t resTaggedLength = resByteArray->GetArrayLength();
655         EXPECT_EQ(resTaggedLength, 10) << "Not same viewedBuffer length"; // 10: bufferLength
656         uint32_t resElementSize = resByteArray->GetByteLength();
657         EXPECT_EQ(resElementSize, 1) << "Not same byteArray size";
658         for (uint32_t i = 0; i < resTaggedLength; i++) {
659             JSHandle<JSTaggedValue> taggedVal(thread, resByteArray->Get(thread, i, DataViewType::UINT8));
660             int32_t byteArrayVal = JSTaggedValue::ToInt32(thread, taggedVal);
661             EXPECT_EQ(byteArrayVal, 255) << "Not same byteArray value"; // 255: value in byteArray
662         }
663         Destroy();
664     }
665 
SharedObjectTest1(SerializeData * data)666     void SharedObjectTest1(SerializeData *data)
667     {
668         Init();
669         BaseDeserializer deserializer(thread, data);
670         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
671         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize SharedObject fail";
672         EXPECT_TRUE(res->IsJSSharedObject()) << "[NotJSSharedObject] Deserialize SharedObject fail";
673         JSHandle<JSObject> sObj = JSHandle<JSObject>::Cast(res);
674 
675         ObjectFactory *factory = ecmaVm->GetFactory();
676         JSHandle<JSTaggedValue> key1(factory->NewFromASCII("number1"));
677         JSHandle<JSTaggedValue> key2(factory->NewFromASCII("boolean2"));
678         JSHandle<JSTaggedValue> key3(factory->NewFromASCII("string3"));
679         JSHandle<JSTaggedValue> key4(factory->NewFromASCII("funcA"));
680         JSHandle<JSTaggedValue> val1 = JSObject::GetProperty(thread, sObj, key1).GetRawValue();
681         JSHandle<JSTaggedValue> val2 = JSObject::GetProperty(thread, sObj, key2).GetRawValue();
682         JSHandle<JSTaggedValue> val3 = JSObject::GetProperty(thread, sObj, key3).GetRawValue();
683         JSHandle<JSTaggedValue> val4 = JSObject::GetProperty(thread, sObj, key4).GetRawValue();
684         EXPECT_TRUE(val4->IsJSSharedFunction());
685         EXPECT_EQ(val1->GetInt(), 1024);    // 1024 is the expected value
686         EXPECT_TRUE(val2->ToBoolean());
687         JSHandle<EcmaString> str3 = JSHandle<EcmaString>(val3);
688         JSHandle<EcmaString> strTest3 = factory->NewFromStdString("hello world!");
689         EXPECT_TRUE(JSTaggedValue::StringCompare(*str3, *strTest3));
690         Destroy();
691     }
692 
SharedObjectTest2(SerializeData * data)693     void SharedObjectTest2(SerializeData *data)
694     {
695         Init();
696         BaseDeserializer deserializer(thread, data);
697         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
698         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize SharedObject fail";
699         EXPECT_TRUE(res->IsJSSharedObject()) << "[NotJSSharedObject] Deserialize SharedObject fail";
700         JSHandle<JSObject> sObj = JSHandle<JSObject>::Cast(res);
701 
702         ObjectFactory *factory = ecmaVm->GetFactory();
703         JSHandle<JSTaggedValue> key1(factory->NewFromASCII("funcA"));
704         JSHandle<JSTaggedValue> key2(factory->NewFromASCII("funcB"));
705         JSHandle<JSTaggedValue> val1 = JSObject::GetProperty(thread, sObj, key1).GetRawValue();
706         JSHandle<JSTaggedValue> val2 = JSObject::GetProperty(thread, sObj, key2).GetRawValue();
707         EXPECT_TRUE(val1->IsJSSharedFunction());
708         EXPECT_TRUE(val2->IsJSSharedFunction());
709         EXPECT_TRUE(val1->IsCallable());
710         JSHandle<JSFunction> func1(val1);
711         EXPECT_FALSE(func1->GetProtoOrHClass().IsHole());
712         EXPECT_TRUE(func1->GetLexicalEnv().IsTaggedArray());
713         EXPECT_TRUE(func1->GetHomeObject().IsJSSharedObject());
714         Destroy();
715     }
716 
SharedObjectTest3(SerializeData * data)717     void SharedObjectTest3(SerializeData* data)
718     {
719         Init();
720         BaseDeserializer deserializer(thread, data);
721         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
722         EXPECT_FALSE(res.IsEmpty());
723         EXPECT_TRUE(res->IsJSSharedObject()) << "[NotJSSharedObject] Deserialize SharedObject fail";
724 
725         JSHandle<JSObject> sObj = JSHandle<JSObject>::Cast(res);
726         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, sObj);
727         uint32_t length = array->GetLength();
728         EXPECT_EQ(length, 10U);
729         for (uint32_t i = 0; i < length; i++) {
730             JSHandle<JSTaggedValue> key(thread, array->Get(i));
731             JSHandle<JSTaggedValue> value =
732                 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(sObj), key).GetValue();
733             EXPECT_TRUE(value->GetTaggedObject()->GetClass()->IsJSObject());
734         }
735 
736         Destroy();
737     }
738 
SharedObjectTest4(SerializeData * data)739     void SharedObjectTest4(SerializeData* data)
740     {
741         Init();
742         BaseDeserializer deserializer(thread, data);
743         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
744         EXPECT_FALSE(res.IsEmpty());
745         EXPECT_TRUE(res->IsJSSharedObject()) << "[NotJSSharedObject] Deserialize SharedObject fail";
746 
747         JSHandle<JSObject> sObj = JSHandle<JSObject>::Cast(res);
748         JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, sObj);
749         uint32_t length = array->GetLength();
750         EXPECT_EQ(length, 512U);
751         for (uint32_t i = 0; i < length; i++) {
752             JSHandle<JSTaggedValue> key(thread, array->Get(i));
753             JSHandle<JSTaggedValue> value =
754                 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(sObj), key).GetValue();
755             EXPECT_TRUE(value->IsInt());
756         }
757 
758         Destroy();
759     }
760 
SerializeSharedFunctionTest(SerializeData * data)761     void SerializeSharedFunctionTest(SerializeData *data)
762     {
763         Init();
764         BaseDeserializer deserializer(thread, data);
765         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
766         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize SharedFunction fail";
767         EXPECT_TRUE(res->IsJSSharedFunction()) << "[NotJSSharedFunction] Deserialize SharedFunction fail";
768         JSHandle<JSSharedFunction> sFunc = JSHandle<JSSharedFunction>::Cast(res);
769 
770         EXPECT_TRUE(sFunc->IsCallable());
771         EXPECT_FALSE(sFunc->GetProtoOrHClass().IsHole());
772         EXPECT_TRUE(sFunc->GetLexicalEnv().IsTaggedArray());
773         EXPECT_TRUE(sFunc->GetHomeObject().IsJSSharedObject());
774         JSHandle<JSSharedObject> sObj(thread, sFunc->GetHomeObject());
775         Destroy();
776     }
777 
SerializeSharedFunctionTest1(SerializeData * data)778     void SerializeSharedFunctionTest1(SerializeData *data)
779     {
780         Init();
781         BaseDeserializer deserializer(thread, data);
782         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
783         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize SharedFunction fail";
784         EXPECT_TRUE(res->IsJSSharedFunction()) << "[NotJSSharedFunction] Deserialize SharedFunction fail";
785         Destroy();
786     }
787 
ConcurrentFunctionTest(std::pair<uint8_t *,size_t> data)788     void ConcurrentFunctionTest(std::pair<uint8_t *, size_t> data)
789     {
790         Init();
791         JSDeserializer deserializer(thread, data.first, data.second);
792         JSHandle<JSTaggedValue> res = deserializer.Deserialize();
793         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ConcurrentFunction fail";
794         EXPECT_TRUE(res->IsJSFunction()) << "[NotJSFunction] Deserialize ConcurrentFunction fail";
795         Destroy();
796     }
797 
ObjectWithConcurrentFunctionTest(SerializeData * data)798     void ObjectWithConcurrentFunctionTest(SerializeData* data)
799     {
800         Init();
801         ObjectFactory *factory = ecmaVm->GetFactory();
802         BaseDeserializer deserializer(thread, data);
803         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
804         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
805         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
806         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize ObjectWithConcurrentFunction fail";
807 
808         JSHandle<JSTaggedValue> key1(factory->NewFromASCII("abc"));
809         OperationResult result1 = JSObject::GetProperty(thread, res, key1);
810         JSHandle<JSTaggedValue> value1 = result1.GetRawValue();
811         EXPECT_TRUE(value1->IsString());
812 
813         JSHandle<JSTaggedValue> key2(factory->NewFromASCII("2"));
814         OperationResult result2 = JSObject::GetProperty(thread, res, key2);
815         JSHandle<JSTaggedValue> value2 = result2.GetRawValue();
816         EXPECT_TRUE(value2->IsJSFunction());
817 
818         JSHandle<JSTaggedValue> key3(factory->NewFromASCII("key"));
819         OperationResult result3 = JSObject::GetProperty(thread, res, key3);
820         JSHandle<JSTaggedValue> value3 = result3.GetRawValue();
821         EXPECT_TRUE(value3->IsJSFunction());
822 
823         Destroy();
824     }
825 
TransferJSArrayBufferTest1(SerializeData * data,uintptr_t bufferAddrCheck)826     void TransferJSArrayBufferTest1(SerializeData *data, uintptr_t bufferAddrCheck)
827     {
828         Init();
829         BaseDeserializer deserializer(thread, data);
830         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
831         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
832         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
833 
834         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer1 fail";
835         EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer1 fail";
836 
837         JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res);
838         EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 5); // 5: bufferLength
839         JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData());
840         EXPECT_TRUE(nativePtr->IsJSNativePointer()) << "[NotJSNativePointer] Deserialize TransferJSArrayBuffer1 fail";
841         JSHandle<JSNativePointer> np = JSHandle<JSNativePointer>::Cast(nativePtr);
842         uintptr_t bufferAddr = reinterpret_cast<uintptr_t>(np->GetExternalPointer());
843         // The deserialized C buffer pointer shall be same to the original one
844         EXPECT_EQ(static_cast<uint64_t>(bufferAddr), static_cast<uint64_t>(bufferAddrCheck));
845         Destroy();
846     }
847 
TransferJSArrayBufferTest2(SerializeData * data,uintptr_t bufferAddrCheck)848     void TransferJSArrayBufferTest2(SerializeData *data, uintptr_t bufferAddrCheck)
849     {
850         Init();
851         BaseDeserializer deserializer(thread, data);
852         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
853         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
854         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
855         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer2 fail";
856         EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer2 fail";
857 
858         JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res);
859         EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 5); // 5: bufferLength
860         JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData());
861         EXPECT_TRUE(nativePtr->IsJSNativePointer()) << "[NotJSNativePointer] Deserialize TransferJSArrayBuffer2 fail";
862         JSHandle<JSNativePointer> np = JSHandle<JSNativePointer>::Cast(nativePtr);
863         uintptr_t bufferAddr = reinterpret_cast<uintptr_t>(np->GetExternalPointer());
864         // The deserialized C buffer pointer shall be different to the original one
865         EXPECT_NE(static_cast<uint64_t>(bufferAddr), static_cast<uint64_t>(bufferAddrCheck));
866         Destroy();
867     }
868 
TransferJSArrayBufferTest3(SerializeData * data)869     void TransferJSArrayBufferTest3(SerializeData *data)
870     {
871         Init();
872         BaseDeserializer deserializer(thread, data);
873         JSHandle<JSTaggedValue> res = deserializer.ReadValue();
874         ecmaVm->CollectGarbage(TriggerGCType::YOUNG_GC);
875         ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
876 
877         EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TransferJSArrayBuffer3 fail";
878         EXPECT_TRUE(res->IsArrayBuffer()) << "[NotJSArrayBuffer] Deserialize TransferJSArrayBuffer3 fail";
879 
880         JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(res);
881         EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 0);
882         JSHandle<JSTaggedValue> nativePtr(thread, arrBuf->GetArrayBufferData());
883         EXPECT_TRUE(nativePtr->IsUndefined()) << "[NotJSNativePointer] Deserialize TransferJSArrayBuffer3 fail";
884         Destroy();
885     }
886 
887 private:
888     EcmaVM *ecmaVm = nullptr;
889     EcmaHandleScope *scope = nullptr;
890     JSThread *thread = nullptr;
891 };
892 
893 class JSSerializerTest : public testing::Test {
894 public:
SetUpTestCase()895     static void SetUpTestCase()
896     {
897         GTEST_LOG_(INFO) << "SetUpTestCase";
898     }
899 
TearDownTestCase()900     static void TearDownTestCase()
901     {
902         GTEST_LOG_(INFO) << "TearDownCase";
903     }
904 
SetUp()905     void SetUp() override
906     {
907         TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
908     }
909 
TearDown()910     void TearDown() override
911     {
912         TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
913     }
914 
915     JSThread *thread {nullptr};
916     EcmaVM *ecmaVm {nullptr};
917     EcmaHandleScope *scope {nullptr};
918 };
919 
HWTEST_F_L0(JSSerializerTest,SerializeJSSpecialValue)920 HWTEST_F_L0(JSSerializerTest, SerializeJSSpecialValue)
921 {
922     ValueSerializer *serializer = new ValueSerializer(thread);
923     serializer->SerializeJSTaggedValue(JSTaggedValue::True());
924     serializer->SerializeJSTaggedValue(JSTaggedValue::False());
925     serializer->SerializeJSTaggedValue(JSTaggedValue::Undefined());
926     serializer->SerializeJSTaggedValue(JSTaggedValue::Null());
927     serializer->SerializeJSTaggedValue(JSTaggedValue::Hole());
928     std::unique_ptr<SerializeData> data = serializer->Release();
929 
930     JSDeserializerTest jsDeserializerTest;
931     std::thread t1(&JSDeserializerTest::JSSpecialValueTest, jsDeserializerTest, data.release());
932     t1.join();
933     delete serializer;
934 };
935 
HWTEST_F_L0(JSSerializerTest,SerializeLineString)936 HWTEST_F_L0(JSSerializerTest, SerializeLineString)
937 {
938     ObjectFactory *factory = ecmaVm->GetFactory();
939     JSHandle<EcmaString> str(factory->NewFromASCII("123"));
940 
941     ValueSerializer *serializer = new ValueSerializer(thread);
942     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str),
943                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
944                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
945     std::unique_ptr<SerializeData> data = serializer->Release();
946     JSDeserializerTest jsDeserializerTest;
947     std::thread t1(&JSDeserializerTest::LineStringTest, jsDeserializerTest, data.release());
948     t1.join();
949     delete serializer;
950 };
951 
HWTEST_F_L0(JSSerializerTest,SerializeTreeString)952 HWTEST_F_L0(JSSerializerTest, SerializeTreeString)
953 {
954     ObjectFactory *factory = ecmaVm->GetFactory();
955     JSHandle<EcmaString> str1(factory->NewFromASCII("123456789"));
956     JSHandle<EcmaString> str2(factory->NewFromASCII("abcdefghi"));
957 
958     JSHandle<EcmaString> str3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, str1, str2));
959     EXPECT_TRUE(str3.GetTaggedValue().IsTreeString());
960 
961     ValueSerializer *serializer = new ValueSerializer(thread);
962     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str3),
963                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
964                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
965     std::unique_ptr<SerializeData> data = serializer->Release();
966     JSDeserializerTest jsDeserializerTest;
967     std::thread t1(&JSDeserializerTest::TreeStringTest, jsDeserializerTest, data.release());
968     t1.join();
969     delete serializer;
970 };
971 
HWTEST_F_L0(JSSerializerTest,SerializeSlicedString)972 HWTEST_F_L0(JSSerializerTest, SerializeSlicedString)
973 {
974     ObjectFactory *factory = ecmaVm->GetFactory();
975     JSHandle<EcmaString> str1(factory->NewFromASCII("123456789abcedfghijk"));
976 
977     JSHandle<EcmaString> str2 =
978         JSHandle<EcmaString>(thread, EcmaStringAccessor::GetSubString(ecmaVm, str1, 2, 13)); // 2: start, 3: len
979     EXPECT_TRUE(str2.GetTaggedValue().IsSlicedString());
980 
981     ValueSerializer *serializer = new ValueSerializer(thread);
982     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(str2),
983                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
984                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
985     std::unique_ptr<SerializeData> data = serializer->Release();
986     JSDeserializerTest jsDeserializerTest;
987     std::thread t1(&JSDeserializerTest::SlicedStringTest, jsDeserializerTest, data.release());
988     t1.join();
989     delete serializer;
990 };
991 
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject1)992 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject1)
993 {
994     ObjectFactory *factory = ecmaVm->GetFactory();
995     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
996 
997     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("2"));
998     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("3"));
999     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("x"));
1000     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("y"));
1001     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1002     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
1003     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3));
1004     JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4));
1005 
1006     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
1007     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
1008     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3);
1009     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4);
1010 
1011     ValueSerializer *serializer = new ValueSerializer(thread);
1012     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1013                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1014                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1015     std::unique_ptr<SerializeData> data = serializer->Release();
1016     JSDeserializerTest jsDeserializerTest;
1017     std::thread t1(&JSDeserializerTest::JSPlainObjectTest1, jsDeserializerTest, data.release());
1018     t1.join();
1019     delete serializer;
1020 };
1021 
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject2)1022 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject2)
1023 {
1024     ObjectFactory *factory = ecmaVm->GetFactory();
1025     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1026     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1027     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
1028     for (int i = 0; i < 10; i++) {
1029         JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1030         JSHandle<EcmaString> key3(factory->NewFromASCII("str3"));
1031         for (int j = 0; j < 10; j++) {
1032             key3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key3, key1));
1033             JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), JSHandle<JSTaggedValue>(key3),
1034                                   JSHandle<JSTaggedValue>(factory->NewEmptyJSObject()));
1035         }
1036         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1));
1037         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2),
1038                               JSHandle<JSTaggedValue>(obj1));
1039     }
1040 
1041     ValueSerializer *serializer = new ValueSerializer(thread);
1042     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1043                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1044                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1045     std::unique_ptr<SerializeData> data = serializer->Release();
1046     JSDeserializerTest jsDeserializerTest;
1047     std::thread t1(&JSDeserializerTest::JSPlainObjectTest2, jsDeserializerTest, data.release());
1048     t1.join();
1049     delete serializer;
1050 };
1051 
1052 // test dictionary mode
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject3)1053 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject3)
1054 {
1055     ObjectFactory *factory = ecmaVm->GetFactory();
1056     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1057     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1058     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
1059     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1060     for (int i = 0; i < 1030; i++) {
1061         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1));
1062         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), value1);
1063     }
1064 
1065     EXPECT_TRUE(obj->GetClass()->IsDictionaryMode());
1066 
1067     ValueSerializer *serializer = new ValueSerializer(thread);
1068     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1069                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1070                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1071     std::unique_ptr<SerializeData> data = serializer->Release();
1072     JSDeserializerTest jsDeserializerTest;
1073     std::thread t1(&JSDeserializerTest::JSPlainObjectTest3, jsDeserializerTest, data.release());
1074     t1.join();
1075     delete serializer;
1076 };
1077 
1078 // test huge object serialize
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject4)1079 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject4)
1080 {
1081     ObjectFactory *factory = ecmaVm->GetFactory();
1082     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1083     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1084     // new huge tagged array
1085     JSHandle<TaggedArray> taggedArray =
1086         factory->NewTaggedArray(1024 * 100, JSTaggedValue::Hole(), MemSpaceType::OLD_SPACE);
1087 
1088     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1),
1089                           JSHandle<JSTaggedValue>(taggedArray));
1090 
1091     ValueSerializer *serializer = new ValueSerializer(thread);
1092     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1093                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1094                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1095     std::unique_ptr<SerializeData> data = serializer->Release();
1096     JSDeserializerTest jsDeserializerTest;
1097     std::thread t1(&JSDeserializerTest::JSPlainObjectTest4, jsDeserializerTest, data.release());
1098     t1.join();
1099     delete serializer;
1100 };
1101 
HWTEST_F_L0(JSSerializerTest,SerializeJSPlainObject5)1102 HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject5)
1103 {
1104     ObjectFactory *factory = ecmaVm->GetFactory();
1105     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1106 
1107     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("2"));
1108     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("3"));
1109     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("x"));
1110     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("y"));
1111     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("func"));
1112     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1113     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
1114     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3));
1115     JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4));
1116     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1117     JSHandle<JSFunction> function = factory->NewJSFunction(env, nullptr, FunctionKind::NORMAL_FUNCTION);
1118     EXPECT_TRUE(function->IsJSFunction());
1119     JSHandle<JSTaggedValue> value5 = JSHandle<JSTaggedValue>::Cast(function);
1120 
1121     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
1122     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
1123     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3);
1124     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4);
1125     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key5, value5);
1126 
1127     ValueSerializer *serializer = new ValueSerializer(thread);
1128     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1129                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1130                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1131     EXPECT_FALSE(success);
1132     std::unique_ptr<SerializeData> data = serializer->Release();
1133     BaseDeserializer deserializer(thread, data.release());
1134     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
1135     EXPECT_TRUE(res.IsEmpty());
1136     delete serializer;
1137 };
1138 
HWTEST_F_L0(JSSerializerTest,SerializeJSError1)1139 HWTEST_F_L0(JSSerializerTest, SerializeJSError1)
1140 {
1141     ObjectFactory *factory = ecmaVm->GetFactory();
1142     JSHandle<EcmaString> msg(factory->NewFromASCII("this is error"));
1143     JSHandle<JSTaggedValue> errorTag =
1144         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::ERROR, msg));
1145 
1146     ValueSerializer *serializer = new ValueSerializer(thread);
1147     serializer->WriteValue(thread, errorTag, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1148                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1149     std::unique_ptr<SerializeData> data = serializer->Release();
1150     JSDeserializerTest jsDeserializerTest;
1151     std::thread t1(&JSDeserializerTest::JSErrorTest1, jsDeserializerTest, data.release());
1152     t1.join();
1153     delete serializer;
1154 };
1155 
HWTEST_F_L0(JSSerializerTest,SerializeJSError2)1156 HWTEST_F_L0(JSSerializerTest, SerializeJSError2)
1157 {
1158 #ifdef NDEBUG
1159     ObjectFactory *factory = ecmaVm->GetFactory();
1160     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1161     JSHandle<EcmaString> key1(factory->NewFromASCII("error1"));
1162     JSHandle<EcmaString> key2(factory->NewFromASCII("error2"));
1163     JSHandle<EcmaString> msg(factory->NewFromASCII("this is error"));
1164     JSHandle<JSTaggedValue> errorTag =
1165         JSHandle<JSTaggedValue>::Cast(factory->NewJSError(base::ErrorType::ERROR, msg));
1166 
1167 
1168     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1), errorTag);
1169     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2), errorTag);
1170 
1171     ValueSerializer *serializer = new ValueSerializer(thread);
1172     serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1173                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1174                            JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1175     std::unique_ptr<SerializeData> data = serializer->Release();
1176     JSDeserializerTest jsDeserializerTest;
1177     std::thread t1(&JSDeserializerTest::JSErrorTest2, jsDeserializerTest, data.release());
1178     t1.join();
1179     delete serializer;
1180 #endif
1181 };
1182 
HWTEST_F_L0(JSSerializerTest,SerializeBigInt)1183 HWTEST_F_L0(JSSerializerTest, SerializeBigInt)
1184 {
1185     ObjectFactory *factory = ecmaVm->GetFactory();
1186     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1187     JSHandle<EcmaString> key1(factory->NewFromASCII("pss"));
1188     JSHandle<EcmaString> key2(factory->NewFromASCII("nativeHeap"));
1189     CString value1 = "365769";
1190     CString value2 = "139900";
1191     JSHandle<BigInt> bigInt1 = BigIntHelper::SetBigInt(thread, value1);
1192     JSHandle<BigInt> bigInt2 = BigIntHelper::SetBigInt(thread, value1);
1193 
1194     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key1),
1195                           JSHandle<JSTaggedValue>(bigInt1));
1196     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), JSHandle<JSTaggedValue>(key2),
1197                           JSHandle<JSTaggedValue>(bigInt2));
1198 
1199 
1200     ValueSerializer *serializer = new ValueSerializer(thread);
1201     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1202                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1203                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1204     EXPECT_TRUE(success) << "Serialize bigInt fail";
1205     std::unique_ptr<SerializeData> data = serializer->Release();
1206     JSDeserializerTest jsDeserializerTest;
1207     std::thread t1(&JSDeserializerTest::BigIntTest, jsDeserializerTest, data.release());
1208     t1.join();
1209     delete serializer;
1210 };
1211 
Detach(void * param1,void * param2,void * hint,void * detachData)1212 static void* Detach(void *param1, void *param2, void *hint, void *detachData)
1213 {
1214     GTEST_LOG_(INFO) << "detach is running";
1215     if (param1 == nullptr && param2 == nullptr) {
1216         GTEST_LOG_(INFO) << "detach: two params is nullptr";
1217     }
1218     if (hint == nullptr && detachData) {
1219         GTEST_LOG_(INFO) << "detach: hint is nullptr";
1220     }
1221     return nullptr;
1222 }
1223 
Attach(void * enginePointer,void * buffer,void * hint,void * attachData)1224 static void* Attach([[maybe_unused]] void *enginePointer, [[maybe_unused]] void *buffer, [[maybe_unused]] void *hint,
1225                     [[maybe_unused]] void *attachData)
1226 {
1227     GTEST_LOG_(INFO) << "attach is running";
1228     return nullptr;
1229 }
1230 
CreateNativeBindingInfo(void * attach,void * detach)1231 static panda::JSNApi::NativeBindingInfo* CreateNativeBindingInfo(void* attach, void* detach)
1232 {
1233     GTEST_LOG_(INFO) << "CreateNativeBindingInfo";
1234     auto info = panda::JSNApi::NativeBindingInfo::CreateNewInstance();
1235     info->attachFunc = attach;
1236     info->detachFunc = detach;
1237     return info;
1238 }
1239 
HWTEST_F_L0(JSSerializerTest,SerializeNativeBindingObject1)1240 HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject1)
1241 {
1242     ObjectFactory *factory = ecmaVm->GetFactory();
1243     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1244     JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1245 
1246     JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol();
1247     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x"));
1248     auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach));
1249     JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info)));
1250     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1));
1251 
1252     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
1253     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2);
1254     obj1->GetClass()->SetIsNativeBindingObject(true);
1255 
1256     ValueSerializer *serializer = new ValueSerializer(thread);
1257     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj1),
1258                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1259                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1260     EXPECT_TRUE(success) << "Serialize fail";
1261     std::unique_ptr<SerializeData> data = serializer->Release();
1262     JSDeserializerTest jsDeserializerTest;
1263     std::thread t1(&JSDeserializerTest::NativeBindingObjectTest1, jsDeserializerTest, data.release());
1264     t1.join();
1265     delete serializer;
1266 }
1267 
1268 
HWTEST_F_L0(JSSerializerTest,SerializeNativeBindingObject2)1269 HWTEST_F_L0(JSSerializerTest, SerializeNativeBindingObject2)
1270 {
1271     ObjectFactory *factory = ecmaVm->GetFactory();
1272     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1273     JSHandle<JSObject> obj1 = factory->NewEmptyJSObject();
1274     JSHandle<JSObject> obj2 = factory->NewEmptyJSObject();
1275 
1276     JSHandle<JSTaggedValue> key1 = env->GetNativeBindingSymbol();
1277     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("x"));
1278     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("xx"));
1279     auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach));
1280     JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info)));
1281     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1));
1282     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(2));
1283 
1284     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
1285     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value2);
1286     obj1->GetClass()->SetIsNativeBindingObject(true);
1287     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2, JSHandle<JSTaggedValue>(obj1));
1288     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key3, value3);
1289 
1290     ValueSerializer *serializer = new ValueSerializer(thread);
1291     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj2),
1292                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1293                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1294     EXPECT_TRUE(success) << "Serialize fail";
1295     std::unique_ptr<SerializeData> data = serializer->Release();
1296     JSDeserializerTest jsDeserializerTest;
1297     std::thread t1(&JSDeserializerTest::NativeBindingObjectTest2, jsDeserializerTest, data.release());
1298     t1.join();
1299     delete serializer;
1300 }
1301 
1302 
HWTEST_F_L0(JSSerializerTest,TestSerializeJSSet)1303 HWTEST_F_L0(JSSerializerTest, TestSerializeJSSet)
1304 {
1305     ObjectFactory *factory = ecmaVm->GetFactory();
1306     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1307 
1308     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsSetFunction();
1309     JSHandle<JSSet> set =
1310         JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1311     JSHandle<LinkedHashSet> linkedSet = LinkedHashSet::Create(thread);
1312     set->SetLinkedSet(thread, linkedSet);
1313     // set property to set
1314     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7));
1315     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9));
1316     JSHandle<JSTaggedValue> value3(factory->NewFromASCII("x"));
1317     JSHandle<JSTaggedValue> value4(factory->NewFromASCII("y"));
1318 
1319     JSSet::Add(thread, set, value1);
1320     JSSet::Add(thread, set, value2);
1321     JSSet::Add(thread, set, value3);
1322     JSSet::Add(thread, set, value4);
1323 
1324     // set property to object
1325     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("5"));
1326     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("6"));
1327 
1328     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(set), key1, value1);
1329     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(set), key2, value2);
1330 
1331     ValueSerializer *serializer = new ValueSerializer(thread);
1332     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(set),
1333                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1334                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1335     EXPECT_TRUE(success) << "Serialize JSSet fail";
1336     std::unique_ptr<SerializeData> data = serializer->Release();
1337     JSDeserializerTest jsDeserializerTest;
1338     std::thread t1(&JSDeserializerTest::JSSetTest, jsDeserializerTest, data.release());
1339     t1.join();
1340     delete serializer;
1341 };
1342 
JSDateCreate(EcmaVM * ecmaVM)1343 JSDate *JSDateCreate(EcmaVM *ecmaVM)
1344 {
1345     ObjectFactory *factory = ecmaVM->GetFactory();
1346     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
1347     JSHandle<JSTaggedValue> dateFunction = globalEnv->GetDateFunction();
1348     JSHandle<JSDate> dateObject =
1349         JSHandle<JSDate>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dateFunction), dateFunction));
1350     return *dateObject;
1351 }
1352 
HWTEST_F_L0(JSSerializerTest,SerializeDate)1353 HWTEST_F_L0(JSSerializerTest, SerializeDate)
1354 {
1355     double tm = 28 * 60 * 60 * 1000;
1356     JSHandle<JSDate> jsDate(thread, JSDateCreate(ecmaVm));
1357     jsDate->SetTimeValue(thread, JSTaggedValue(tm));
1358 
1359     ValueSerializer *serializer = new ValueSerializer(thread);
1360     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsDate),
1361                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1362                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1363     EXPECT_TRUE(success) << "Serialize JSDate fail";
1364     std::unique_ptr<SerializeData> data = serializer->Release();
1365     JSDeserializerTest jsDeserializerTest;
1366     std::thread t1(&JSDeserializerTest::JSDateTest, jsDeserializerTest, data.release());
1367     t1.join();
1368     delete serializer;
1369 };
1370 
CreateMap(JSThread * thread)1371 JSMap *CreateMap(JSThread *thread)
1372 {
1373     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1374     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1375     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsMapFunction();
1376     JSHandle<JSMap> map =
1377         JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1378     JSHandle<LinkedHashMap> linkedMap = LinkedHashMap::Create(thread);
1379     map->SetLinkedMap(thread, linkedMap);
1380     return *map;
1381 }
1382 
HWTEST_F_L0(JSSerializerTest,SerializeJSMap)1383 HWTEST_F_L0(JSSerializerTest, SerializeJSMap)
1384 {
1385     JSHandle<JSMap> map(thread, CreateMap(thread));
1386     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1387     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("3"));
1388     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(12345));
1389     JSMap::Set(thread, map, key1, value1);
1390     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key1"));
1391     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(34567));
1392     JSMap::Set(thread, map, key2, value2);
1393 
1394     ValueSerializer *serializer = new ValueSerializer(thread);
1395     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(map),
1396                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1397                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1398     EXPECT_TRUE(success) << "Serialize JSMap fail";
1399     std::unique_ptr<SerializeData> data = serializer->Release();
1400     JSDeserializerTest jsDeserializerTest;
1401     std::thread t1(&JSDeserializerTest::JSMapTest, jsDeserializerTest, data.release(), map);
1402     t1.join();
1403     delete serializer;
1404 };
1405 
HWTEST_F_L0(JSSerializerTest,SerializeJSRegExp)1406 HWTEST_F_L0(JSSerializerTest, SerializeJSRegExp)
1407 {
1408     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1409     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1410     JSHandle<JSTaggedValue> target = env->GetRegExpFunction();
1411     JSHandle<JSRegExp> jsRegexp =
1412         JSHandle<JSRegExp>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
1413     JSHandle<EcmaString> pattern = thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2");
1414     JSHandle<EcmaString> flags = thread->GetEcmaVM()->GetFactory()->NewFromASCII("i");
1415     char buffer[] = "1234567";  // use char to simulate bytecode
1416     uint32_t bufferSize = 7;
1417     factory->NewJSRegExpByteCodeData(jsRegexp, static_cast<void *>(buffer), bufferSize);
1418     jsRegexp->SetOriginalSource(thread, JSHandle<JSTaggedValue>(pattern));
1419     jsRegexp->SetOriginalFlags(thread, JSHandle<JSTaggedValue>(flags));
1420 
1421     ValueSerializer *serializer = new ValueSerializer(thread);
1422     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsRegexp),
1423                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1424                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1425     EXPECT_TRUE(success) << "Serialize JSRegExp fail";
1426     std::unique_ptr<SerializeData> data = serializer->Release();
1427     JSDeserializerTest jsDeserializerTest;
1428     std::thread t1(&JSDeserializerTest::JSRegexpTest, jsDeserializerTest, data.release());
1429     t1.join();
1430     delete serializer;
1431 };
1432 
HWTEST_F_L0(JSSerializerTest,TestSerializeJSArray)1433 HWTEST_F_L0(JSSerializerTest, TestSerializeJSArray)
1434 {
1435     ObjectFactory *factory = ecmaVm->GetFactory();
1436     JSHandle<JSArray> array = factory->NewJSArray();
1437 
1438     // set property to object
1439     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("abasd"));
1440     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("qweqwedasd"));
1441 
1442     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(7));
1443     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(9));
1444 
1445     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(array), key1, value1);
1446     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(array), key2, value2);
1447 
1448     // set value to array
1449     array->SetArrayLength(thread, 20);
1450     for (int i = 0; i < 20; i++) {
1451         JSHandle<JSTaggedValue> data(thread, JSTaggedValue(i));
1452         JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>::Cast(array), i, data);
1453     }
1454 
1455     ValueSerializer *serializer = new ValueSerializer(thread);
1456     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(array),
1457                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1458                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1459     EXPECT_TRUE(success) << "Serialize JSArray fail";
1460     std::unique_ptr<SerializeData> data = serializer->Release();
1461     JSDeserializerTest jsDeserializerTest;
1462     std::thread t1(&JSDeserializerTest::JSArrayTest, jsDeserializerTest, data.release());
1463     t1.join();
1464     delete serializer;
1465 };
1466 
HWTEST_F_L0(JSSerializerTest,SerializeEcmaString1)1467 HWTEST_F_L0(JSSerializerTest, SerializeEcmaString1)
1468 {
1469     const char *rawStr = "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
1470     "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
1471     "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"\
1472     "ssssss";
1473     JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(rawStr);
1474 
1475     ValueSerializer *serializer = new ValueSerializer(thread);
1476     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(ecmaString),
1477                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1478                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1479     EXPECT_TRUE(success) << "Serialize EcmaString fail";
1480     std::unique_ptr<SerializeData> data = serializer->Release();
1481     JSDeserializerTest jsDeserializerTest;
1482     std::thread t1(&JSDeserializerTest::EcmaStringTest1, jsDeserializerTest, data.release());
1483     t1.join();
1484     delete serializer;
1485 };
1486 
1487 // Test EcmaString contains Chinese Text
HWTEST_F_L0(JSSerializerTest,SerializeEcmaString2)1488 HWTEST_F_L0(JSSerializerTest, SerializeEcmaString2)
1489 {
1490     std::string rawStr = "你好,世界";
1491     JSHandle<EcmaString> ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromStdString(rawStr);
1492 
1493     ValueSerializer *serializer = new ValueSerializer(thread);
1494     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(ecmaString),
1495                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1496                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1497     EXPECT_TRUE(success) << "Serialize EcmaString fail";
1498     std::unique_ptr<SerializeData> data = serializer->Release();
1499     JSDeserializerTest jsDeserializerTest;
1500     std::thread t1(&JSDeserializerTest::EcmaStringTest2, jsDeserializerTest, data.release());
1501     t1.join();
1502     delete serializer;
1503 };
1504 
HWTEST_F_L0(JSSerializerTest,SerializeInt32_t)1505 HWTEST_F_L0(JSSerializerTest, SerializeInt32_t)
1506 {
1507     int32_t a = 64, min = -2147483648, b = -63;
1508     JSTaggedValue aTag(a), minTag(min), bTag(b);
1509 
1510     ValueSerializer *serializer = new ValueSerializer(thread);
1511     serializer->SerializeJSTaggedValue(aTag);
1512     serializer->SerializeJSTaggedValue(minTag);
1513     serializer->SerializeJSTaggedValue(bTag);
1514     std::unique_ptr<SerializeData> data = serializer->Release();
1515 
1516     JSDeserializerTest jsDeserializerTest;
1517     std::thread t1(&JSDeserializerTest::Int32Test, jsDeserializerTest, data.release());
1518     t1.join();
1519     delete serializer;
1520 };
1521 
HWTEST_F_L0(JSSerializerTest,SerializeDouble)1522 HWTEST_F_L0(JSSerializerTest, SerializeDouble)
1523 {
1524     double a = 3.1415926535, b = -3.1415926535;
1525     JSTaggedValue aTag(a), bTag(b);
1526 
1527     ValueSerializer *serializer = new ValueSerializer(thread);
1528     serializer->SerializeJSTaggedValue(aTag);
1529     serializer->SerializeJSTaggedValue(bTag);
1530     std::unique_ptr<SerializeData> data = serializer->Release();
1531 
1532     JSDeserializerTest jsDeserializerTest;
1533     std::thread t1(&JSDeserializerTest::DoubleTest, jsDeserializerTest, data.release());
1534     t1.join();
1535     delete serializer;
1536 };
1537 
CreateJSArrayBuffer(JSThread * thread)1538 JSArrayBuffer *CreateJSArrayBuffer(JSThread *thread)
1539 {
1540     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1541     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1542     JSHandle<JSTaggedValue> target = env->GetArrayBufferFunction();
1543     JSHandle<JSArrayBuffer> jsArrayBuffer =
1544         JSHandle<JSArrayBuffer>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
1545     return *jsArrayBuffer;
1546 }
1547 
HWTEST_F_L0(JSSerializerTest,SerializeObjectWithConcurrentFunction)1548 HWTEST_F_L0(JSSerializerTest, SerializeObjectWithConcurrentFunction)
1549 {
1550     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1551     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1552     JSHandle<JSFunction> concurrentFunction1 = factory->NewJSFunction(env, nullptr, FunctionKind::CONCURRENT_FUNCTION);
1553     EXPECT_TRUE(concurrentFunction1->IsJSFunction());
1554     EXPECT_TRUE(concurrentFunction1->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION);
1555     JSHandle<JSFunction> concurrentFunction2 = factory->NewJSFunction(env, nullptr, FunctionKind::CONCURRENT_FUNCTION);
1556     EXPECT_TRUE(concurrentFunction2->IsJSFunction());
1557     EXPECT_TRUE(concurrentFunction2->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION);
1558     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("1"));
1559     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("2"));
1560     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("abc"));
1561     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("4"));
1562     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("key"));
1563     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(12345));
1564     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("def"));
1565     JSHandle<JSTaggedValue> value3(factory->NewFromASCII("value"));
1566     JSHandle<JSObject> obj = factory->NewEmptyJSObject();
1567     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
1568     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, JSHandle<JSTaggedValue>(concurrentFunction1));
1569     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value2);
1570     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value1);
1571     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key5, JSHandle<JSTaggedValue>(concurrentFunction2));
1572 
1573     ValueSerializer *serializer = new ValueSerializer(thread);
1574     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(obj),
1575                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1576                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1577     EXPECT_TRUE(success) << "Serialize concurrent function fail";
1578     std::unique_ptr<SerializeData> data = serializer->Release();
1579     JSDeserializerTest jsDeserializerTest;
1580 
1581     std::thread t1(&JSDeserializerTest::ObjectWithConcurrentFunctionTest, jsDeserializerTest, data.release());
1582     t1.join();
1583     delete serializer;
1584 };
1585 
1586 // not support most function except concurrent function
HWTEST_F_L0(JSSerializerTest,SerializeFunction)1587 HWTEST_F_L0(JSSerializerTest, SerializeFunction)
1588 {
1589     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1590     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1591     JSHandle<JSFunction> function = factory->NewJSFunction(env, nullptr, FunctionKind::NORMAL_FUNCTION);
1592     EXPECT_TRUE(function->IsJSFunction());
1593 
1594     ValueSerializer *serializer = new ValueSerializer(thread);
1595     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(function),
1596                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1597                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1598     EXPECT_FALSE(success);
1599     std::unique_ptr<SerializeData> data = serializer->Release();
1600     BaseDeserializer deserializer(thread, data.release());
1601     JSHandle<JSTaggedValue> res = deserializer.ReadValue();
1602     EXPECT_TRUE(res.IsEmpty());
1603     delete serializer;
1604 }
1605 
1606 // Test transfer JSArrayBuffer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer1)1607 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer1)
1608 {
1609     ObjectFactory *factory = ecmaVm->GetFactory();
1610 
1611     // create a JSArrayBuffer
1612     size_t length = 5;
1613     uint8_t value = 100;
1614     void *buffer = ecmaVm->GetNativeAreaAllocator()->AllocateBuffer(length);
1615     if (memset_s(buffer, length, value, length) != EOK) {
1616         LOG_ECMA(FATAL) << "this branch is unreachable";
1617         UNREACHABLE();
1618     }
1619     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer,
1620         length, NativeAreaAllocator::FreeBufferFunc, ecmaVm->GetNativeAreaAllocator());
1621     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>(arrBuf);
1622 
1623     JSHandle<JSArray> array = factory->NewJSArray();
1624 
1625     // set value to array
1626     array->SetArrayLength(thread, 1);
1627     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, arrBufTag);
1628 
1629     ValueSerializer *serializer = new ValueSerializer(thread);
1630     bool success = serializer->WriteValue(thread, arrBufTag, JSHandle<JSTaggedValue>(array),
1631                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1632     EXPECT_TRUE(success) << "Serialize transfer JSArrayBuffer fail";
1633     std::unique_ptr<SerializeData> data = serializer->Release();
1634     JSDeserializerTest jsDeserializerTest;
1635     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest1,
1636                    jsDeserializerTest,
1637                    data.release(),
1638                    reinterpret_cast<uintptr_t>(buffer));
1639     t1.join();
1640     delete serializer;
1641     // test if detached
1642     EXPECT_TRUE(arrBuf->IsDetach());
1643 };
1644 
1645 // Test serialize JSArrayBuffer that not transfer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer2)1646 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer2)
1647 {
1648     ObjectFactory *factory = ecmaVm->GetFactory();
1649 
1650     // create a JSArrayBuffer
1651     size_t length = 5;
1652     uint8_t value = 100;
1653     void *buffer = ecmaVm->GetNativeAreaAllocator()->AllocateBuffer(length);
1654     if (memset_s(buffer, length, value, length) != EOK) {
1655         LOG_ECMA(FATAL) << "this branch is unreachable";
1656         UNREACHABLE();
1657     }
1658     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(buffer,
1659         length, NativeAreaAllocator::FreeBufferFunc, ecmaVm->GetNativeAreaAllocator());
1660     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
1661 
1662     ValueSerializer *serializer = new ValueSerializer(thread);
1663     bool success = serializer->WriteValue(thread, arrBufTag,
1664                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1665                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1666     EXPECT_TRUE(success) << "Serialize not transfer JSArrayBuffer fail";
1667     std::unique_ptr<SerializeData> data = serializer->Release();
1668     JSDeserializerTest jsDeserializerTest;
1669     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest2,
1670                    jsDeserializerTest,
1671                    data.release(),
1672                    reinterpret_cast<uintptr_t>(buffer));
1673     t1.join();
1674     delete serializer;
1675     // test if detached
1676     EXPECT_FALSE(arrBuf->IsDetach());
1677 };
1678 
1679 // Test serialize an empty JSArrayBuffer
HWTEST_F_L0(JSSerializerTest,TransferJSArrayBuffer3)1680 HWTEST_F_L0(JSSerializerTest, TransferJSArrayBuffer3)
1681 {
1682     ObjectFactory *factory = ecmaVm->GetFactory();
1683 
1684     // create a JSArrayBuffer
1685     JSHandle<JSArrayBuffer> arrBuf = factory->NewJSArrayBuffer(0);
1686     JSHandle<JSTaggedValue> arrBufTag = JSHandle<JSTaggedValue>::Cast(arrBuf);
1687 
1688     ValueSerializer *serializer = new ValueSerializer(thread);
1689     bool success = serializer->WriteValue(thread, arrBufTag,
1690                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1691                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1692     EXPECT_TRUE(success) << "Serialize empty JSArrayBuffer fail";
1693     std::unique_ptr<SerializeData> data = serializer->Release();
1694     JSDeserializerTest jsDeserializerTest;
1695     std::thread t1(&JSDeserializerTest::TransferJSArrayBufferTest3, jsDeserializerTest, data.release());
1696     t1.join();
1697     delete serializer;
1698     // test if detached
1699     EXPECT_FALSE(arrBuf->IsDetach());
1700 };
1701 
HWTEST_F_L0(JSSerializerTest,SerializeJSArrayBufferShared2)1702 HWTEST_F_L0(JSSerializerTest, SerializeJSArrayBufferShared2)
1703 {
1704     std::string msg = "hello world";
1705     int msgBufferLen = static_cast<int>(msg.length()) + 1;
1706     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1707     JSHandle<JSArrayBuffer> jsArrayBuffer = factory->NewJSSharedArrayBuffer(msgBufferLen);
1708     JSHandle<JSTaggedValue> BufferData(thread, jsArrayBuffer->GetArrayBufferData());
1709     JSHandle<JSNativePointer> resNp = JSHandle<JSNativePointer>::Cast(BufferData);
1710     void *buffer = resNp->GetExternalPointer();
1711     if (memcpy_s(buffer, msgBufferLen, msg.c_str(), msgBufferLen) != EOK) {
1712         EXPECT_TRUE(false) << " memcpy error";
1713     }
1714 
1715     ValueSerializer *serializer = new ValueSerializer(thread);
1716     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(jsArrayBuffer),
1717                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1718                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1719     EXPECT_TRUE(success) << "Serialize JSSharedArrayBuffer fail";
1720     std::unique_ptr<SerializeData> data = serializer->Release();
1721     JSDeserializerTest jsDeserializerTest;
1722     std::string changeStr = "world hello";
1723     std::thread t1(&JSDeserializerTest::JSSharedArrayBufferTest,
1724                    jsDeserializerTest, data.release(), jsArrayBuffer, 12, changeStr.c_str());
1725     t1.join();
1726     EXPECT_TRUE(strcmp((char *)buffer, "world hello") == 0) << "Serialize JSArrayBuffer fail";
1727     delete serializer;
1728 };
1729 
CreateTestJSArrayBuffer(JSThread * thread)1730 JSArrayBuffer *CreateTestJSArrayBuffer(JSThread *thread)
1731 {
1732     JSHandle<JSArrayBuffer> jsArrayBuffer(thread, CreateJSArrayBuffer(thread));
1733     int32_t byteLength = 10;
1734     thread->GetEcmaVM()->GetFactory()->NewJSArrayBufferData(jsArrayBuffer, byteLength);
1735     jsArrayBuffer->SetArrayBufferByteLength(byteLength);
1736     JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(jsArrayBuffer);
1737     JSMutableHandle<JSTaggedValue> number(thread, JSTaggedValue::Undefined());
1738     for (int i = 0; i < 10; i++) { // 10: arrayLength
1739         number.Update(JSTaggedValue(i));
1740         BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), i, DataViewType::UINT8,
1741             number, true);
1742     }
1743     return *jsArrayBuffer;
1744 }
1745 
HWTEST_F_L0(JSSerializerTest,SerializeJSTypedArray1)1746 HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray1)
1747 {
1748     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1749     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1750     JSHandle<JSTaggedValue> target = env->GetInt8ArrayFunction();
1751     JSHandle<JSTypedArray> int8Array =
1752         JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
1753     JSHandle<JSTaggedValue> viewedArrayBuffer(thread, CreateTestJSArrayBuffer(thread));
1754     int8Array->SetViewedArrayBufferOrByteArray(thread, viewedArrayBuffer);
1755     int byteLength = 10;
1756     int byteOffset = 0;
1757     int arrayLength = (byteLength - byteOffset) / (sizeof(int8_t));
1758     int8Array->SetByteLength(byteLength);
1759     int8Array->SetByteOffset(byteOffset);
1760     int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
1761     int8Array->SetArrayLength(arrayLength);
1762     int8Array->SetContentType(ContentType::Number);
1763 
1764     ValueSerializer *serializer = new ValueSerializer(thread);
1765     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(int8Array),
1766                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1767                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1768     EXPECT_TRUE(success) << "Serialize type array fail";
1769     std::unique_ptr<SerializeData> data = serializer->Release();
1770     JSDeserializerTest jsDeserializerTest;
1771     std::thread t1(&JSDeserializerTest::TypedArrayTest1, jsDeserializerTest, data.release());
1772     t1.join();
1773     delete serializer;
1774 };
1775 
HWTEST_F_L0(JSSerializerTest,SerializeJSTypedArray2)1776 HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray2)
1777 {
1778     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1779     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1780     JSHandle<JSTaggedValue> target = env->GetInt8ArrayFunction();
1781     JSHandle<JSTypedArray> int8Array =
1782         JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
1783     uint8_t value = 255; // 255 : test case
1784     JSTaggedType val = JSTaggedValue(value).GetRawData();
1785     int byteArrayLength = 10; // 10: arrayLength
1786     JSHandle<ByteArray> byteArray = factory->NewByteArray(byteArrayLength, sizeof(value));
1787     for (int i = 0; i < byteArrayLength; i++) {
1788         byteArray->Set(thread, i, DataViewType::UINT8, val);
1789     }
1790     int8Array->SetViewedArrayBufferOrByteArray(thread, byteArray);
1791     int byteLength = 10;
1792     int byteOffset = 0;
1793     int arrayLength = (byteLength - byteOffset) / (sizeof(int8_t));
1794     int8Array->SetByteLength(byteLength);
1795     int8Array->SetByteOffset(byteOffset);
1796     int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
1797     int8Array->SetArrayLength(arrayLength);
1798     int8Array->SetContentType(ContentType::Number);
1799 
1800     ValueSerializer *serializer = new ValueSerializer(thread);
1801     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(int8Array),
1802                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1803                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1804     EXPECT_TRUE(success) << "Serialize type array fail";
1805     std::unique_ptr<SerializeData> data = serializer->Release();
1806     JSDeserializerTest jsDeserializerTest;
1807     std::thread t1(&JSDeserializerTest::TypedArrayTest2, jsDeserializerTest, data.release());
1808     t1.join();
1809     delete serializer;
1810 };
1811 
HWTEST_F_L0(JSSerializerTest,SerializeSharedObject1)1812 HWTEST_F_L0(JSSerializerTest, SerializeSharedObject1)
1813 {
1814     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1815     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1816     JSHandle<JSTaggedValue> ctor = env->GetSObjectFunction();
1817     JSHandle<JSSharedObject> sObj =
1818         JSHandle<JSSharedObject>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
1819     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("number1"));
1820     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("boolean2"));
1821     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("string3"));
1822     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("funcA"));
1823     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("funcB"));
1824     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1024));
1825     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue::True());
1826     JSHandle<JSTaggedValue> value3(factory->NewFromStdString("hello world!"));
1827 
1828     // test func
1829     JSHandle<JSFunction> func1 = thread->GetEcmaVM()->GetFactory()->NewSFunction(env, nullptr,
1830         FunctionKind::NORMAL_FUNCTION);
1831     EXPECT_TRUE(*func1 != nullptr);
1832     JSHandle<JSTaggedValue> value4(thread, func1.GetTaggedValue());
1833     EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj), key1, value1));
1834     EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj), key2, value2));
1835     EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj), key3, value3));
1836     EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj), key4, value4));
1837     ValueSerializer *serializer = new ValueSerializer(thread);
1838 
1839     // set value to array
1840     JSHandle<JSArray> array = factory->NewJSArray();
1841     array->SetArrayLength(thread, 1);
1842     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(sObj));
1843     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(sObj),
1844                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1845                                           JSHandle<JSTaggedValue>(array));
1846     EXPECT_TRUE(success) << "Serialize sObj fail";
1847     std::unique_ptr<SerializeData> data = serializer->Release();
1848     JSDeserializerTest jsDeserializerTest;
1849     std::thread t1(&JSDeserializerTest::SharedObjectTest1, jsDeserializerTest, data.release());
1850     t1.join();
1851     delete serializer;
1852 };
1853 
HWTEST_F_L0(JSSerializerTest,SerializeSharedObject2)1854 HWTEST_F_L0(JSSerializerTest, SerializeSharedObject2)
1855 {
1856     ObjectFactory *factory = ecmaVm->GetFactory();
1857     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1858     JSHandle<JSTaggedValue> ctor = env->GetSObjectFunction();
1859     JSHandle<JSSharedObject> sObj =
1860         JSHandle<JSSharedObject>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
1861     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1862     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
1863     for (int i = 0; i < 10; i++) {
1864         JSHandle<JSSharedObject> sObj1 =
1865             JSHandle<JSSharedObject>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
1866         JSHandle<EcmaString> key3(factory->NewFromASCII("str3"));
1867         for (int j = 0; j < 10; j++) {
1868             key3 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key3, key1));
1869             JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj1), JSHandle<JSTaggedValue>(key3),
1870                                   JSHandle<JSTaggedValue>(factory->NewEmptyJSObject()));
1871         }
1872         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1));
1873         EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj), JSHandle<JSTaggedValue>(key2),
1874                               JSHandle<JSTaggedValue>(sObj1)));
1875     }
1876 
1877     ValueSerializer *serializer = new ValueSerializer(thread);
1878     // set value to array
1879     JSHandle<JSArray> array = factory->NewJSArray();
1880     array->SetArrayLength(thread, 1);
1881     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(sObj));
1882     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(sObj),
1883                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1884                                           JSHandle<JSTaggedValue>(array));
1885     EXPECT_TRUE(success) << "Serialize sObj fail";
1886     std::unique_ptr<SerializeData> data = serializer->Release();
1887     JSDeserializerTest jsDeserializerTest;
1888     std::thread t1(&JSDeserializerTest::SharedObjectTest3, jsDeserializerTest, data.release());
1889     t1.join();
1890     delete serializer;
1891 };
1892 
HWTEST_F_L0(JSSerializerTest,SerializeSharedObject3)1893 HWTEST_F_L0(JSSerializerTest, SerializeSharedObject3)
1894 {
1895     ObjectFactory *factory = ecmaVm->GetFactory();
1896     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1897     JSHandle<JSTaggedValue> ctor = env->GetSObjectFunction();
1898     JSHandle<JSSharedObject> sObj =
1899         JSHandle<JSSharedObject>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
1900     JSHandle<EcmaString> key1(factory->NewFromASCII("str1"));
1901     JSHandle<EcmaString> key2(factory->NewFromASCII("str2"));
1902     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1903     for (int i = 0; i < 512; i++) {
1904         key2 = JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(ecmaVm, key2, key1));
1905         EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(sObj), JSHandle<JSTaggedValue>(key2),
1906                                           value1));
1907     }
1908 
1909     ValueSerializer *serializer = new ValueSerializer(thread);
1910     // set value to array
1911     JSHandle<JSArray> array = factory->NewJSArray();
1912     array->SetArrayLength(thread, 1);
1913     JSArray::FastSetPropertyByValue(thread, JSHandle<JSTaggedValue>(array), 0, JSHandle<JSTaggedValue>(sObj));
1914     bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(sObj),
1915                                           JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1916                                           JSHandle<JSTaggedValue>(array));
1917     EXPECT_TRUE(success) << "Serialize sObj fail";
1918     std::unique_ptr<SerializeData> data = serializer->Release();
1919     JSDeserializerTest jsDeserializerTest;
1920     std::thread t1(&JSDeserializerTest::SharedObjectTest4, jsDeserializerTest, data.release());
1921     t1.join();
1922     delete serializer;
1923 };
1924 }  // namespace panda::test
1925