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