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