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