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