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