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