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 <cstddef>
17 #include "ecmascript/builtins/builtins.h"
18 #include "ecmascript/builtins/builtins_function.h"
19 #include "ecmascript/builtins/builtins_object.h"
20 #include "ecmascript/compiler/aot_file/an_file_data_manager.h"
21 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
22 #include "ecmascript/compiler/circuit_builder_helper.h"
23 #include "ecmascript/deoptimizer/deoptimizer.h"
24 #include "ecmascript/ecma_global_storage.h"
25 #include "ecmascript/ecma_vm.h"
26 #include "ecmascript/global_env.h"
27 #include "ecmascript/js_api/js_api_tree_map.h"
28 #include "ecmascript/js_api/js_api_tree_set.h"
29 #include "ecmascript/js_api/js_api_vector.h"
30 #include "ecmascript/js_array.h"
31 #include "ecmascript/js_bigint.h"
32 #include "ecmascript/js_date_time_format.h"
33 #include "ecmascript/js_generator_object.h"
34 #include "ecmascript/js_map.h"
35 #include "ecmascript/js_map_iterator.h"
36 #include "ecmascript/js_primitive_ref.h"
37 #include "ecmascript/js_regexp.h"
38 #include "ecmascript/js_runtime_options.h"
39 #include "ecmascript/js_set.h"
40 #include "ecmascript/js_set_iterator.h"
41 #include "ecmascript/js_tagged_value.h"
42 #include "ecmascript/js_thread.h"
43 #include "ecmascript/js_weak_container.h"
44 #include "ecmascript/linked_hash_table.h"
45 #include "ecmascript/mem/mem_map_allocator.h"
46 #include "ecmascript/module/js_module_manager.h"
47 #include "ecmascript/module/js_module_source_text.h"
48 #include "ecmascript/napi/include/jsnapi.h"
49 #include "ecmascript/napi/include/jsnapi_internals.h"
50 #include "ecmascript/napi/jsnapi_helper.h"
51 #include "ecmascript/object_factory.h"
52 #include "ecmascript/pgo_profiler/pgo_profiler.h"
53 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
54 #include "ecmascript/pgo_profiler/pgo_profiler_encoder.h"
55 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
56 #include "ecmascript/tagged_array.h"
57 #include "ecmascript/tests/test_helper.h"
58 #include "ecmascript/tagged_tree.h"
59 #include "ecmascript/weak_vector.h"
60 #include "gtest/gtest.h"
61
62 using namespace panda;
63 using namespace panda::ecmascript;
64 using namespace panda::ecmascript::kungfu;
65
66 static constexpr char16_t UTF_16[] = u"This is a char16 array";
67 static constexpr const char *DUPLICATE_KEY = "duplicateKey";
68 static constexpr const char *SIMPLE_KEY = "simpleKey";
69 static constexpr const char ERROR_MESSAGE[] = "ErrorTest";
70 namespace panda::test {
71 using BuiltinsFunction = ecmascript::builtins::BuiltinsFunction;
72 using PGOProfilerManager = panda::ecmascript::pgo::PGOProfilerManager;
73 using FunctionForRef = Local<JSValueRef> (*)(JsiRuntimeCallInfo *);
74 class JSNApiTests : public testing::Test {
75 public:
SetUpTestCase()76 static void SetUpTestCase()
77 {
78 GTEST_LOG_(INFO) << "SetUpTestCase";
79 }
80
TearDownTestCase()81 static void TearDownTestCase()
82 {
83 GTEST_LOG_(INFO) << "TearDownCase";
84 }
85
SetUp()86 void SetUp() override
87 {
88 RuntimeOption option;
89 option.SetLogLevel(common::LOG_LEVEL::ERROR);
90 vm_ = JSNApi::CreateJSVM(option);
91 ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
92 thread_ = vm_->GetJSThread();
93 vm_->SetEnableForceGC(true);
94 thread_->ManagedCodeBegin();
95 }
96
TearDown()97 void TearDown() override
98 {
99 thread_->ManagedCodeEnd();
100 vm_->SetEnableForceGC(false);
101 JSNApi::DestroyJSVM(vm_);
102 }
103
TestNumberRef(T val,TaggedType expected)104 template <typename T> void TestNumberRef(T val, TaggedType expected)
105 {
106 LocalScope scope(vm_);
107 Local<NumberRef> obj = NumberRef::New(vm_, val);
108 ASSERT_TRUE(obj->IsNumber());
109 JSTaggedType res = JSNApiHelper::ToJSTaggedValue(*obj).GetRawData();
110 ASSERT_EQ(res, expected);
111 if constexpr (std::is_floating_point_v<T>) {
112 if (std::isnan(val)) {
113 ASSERT_TRUE(std::isnan(obj->Value()));
114 } else {
115 ASSERT_EQ(obj->Value(), val);
116 }
117 } else if constexpr (sizeof(T) >= sizeof(int32_t)) {
118 ASSERT_EQ(obj->IntegerValue(vm_), val);
119 } else if constexpr (std::is_signed_v<T>) {
120 ASSERT_EQ(obj->Int32Value(vm_), val);
121 } else {
122 ASSERT_EQ(obj->Uint32Value(vm_), val);
123 }
124 }
125
ConvertDouble(double val)126 TaggedType ConvertDouble(double val)
127 {
128 return base::bit_cast<JSTaggedType>(val) + JSTaggedValue::DOUBLE_ENCODE_OFFSET;
129 }
130
JSNApiGetXRefGlobalHandleAddr(const EcmaVM * vm,uintptr_t localAddress)131 uintptr_t JSNApiGetXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
132 {
133 return JSNApi::GetXRefGlobalHandleAddr(vm, localAddress);
134 }
135
JSNApiDisposeXRefGlobalHandleAddr(const EcmaVM * vm,uintptr_t addr)136 void JSNApiDisposeXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr)
137 {
138 JSNApi::DisposeXRefGlobalHandleAddr(vm, addr);
139 }
140
141 protected:
142 void RegisterStringCacheTable();
143
144 JSThread *thread_ = nullptr;
145 EcmaVM *vm_ = nullptr;
146 bool isStringCacheTableCreated_ = false;
147 };
148
RegisterStringCacheTable()149 void JSNApiTests::RegisterStringCacheTable()
150 {
151 constexpr uint32_t STRING_CACHE_TABLE_SIZE = 100;
152 auto res = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
153 if (isStringCacheTableCreated_) {
154 ASSERT_FALSE(res);
155 } else {
156 ASSERT_TRUE(res);
157 }
158 }
159
FunctionCallback(JsiRuntimeCallInfo * info)160 Local<JSValueRef> FunctionCallback(JsiRuntimeCallInfo *info)
161 {
162 EscapeLocalScope scope(info->GetVM());
163 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
164 }
165
WeakRefCallback(EcmaVM * vm)166 void WeakRefCallback(EcmaVM *vm)
167 {
168 LocalScope scope(vm);
169 Local<ObjectRef> object = ObjectRef::New(vm);
170 Global<ObjectRef> globalObject(vm, object);
171 globalObject.SetWeak();
172 Local<ObjectRef> object1 = ObjectRef::New(vm);
173 Global<ObjectRef> globalObject1(vm, object1);
174 globalObject1.SetWeak();
175 vm->CollectGarbage(TriggerGCType::YOUNG_GC);
176 vm->CollectGarbage(TriggerGCType::OLD_GC);
177 globalObject.FreeGlobalHandleAddr();
178 }
179
ThreadCheck(const EcmaVM * vm)180 void ThreadCheck(const EcmaVM *vm)
181 {
182 EXPECT_TRUE(vm->GetJSThread()->GetThreadId() != JSThread::GetCurrentThreadId());
183 }
184
CheckReject(JsiRuntimeCallInfo * info)185 void CheckReject(JsiRuntimeCallInfo *info)
186 {
187 ASSERT_EQ(info->GetArgsNumber(), 1U);
188 Local<JSValueRef> reason = info->GetCallArgRef(0);
189 ASSERT_TRUE(reason->IsString(info->GetVM()));
190 ASSERT_EQ(Local<StringRef>(reason)->ToString(info->GetVM()), "Reject");
191 }
192
RejectCallback(JsiRuntimeCallInfo * info)193 Local<JSValueRef> RejectCallback(JsiRuntimeCallInfo *info)
194 {
195 LocalScope scope(info->GetVM());
196 CheckReject(info);
197 return JSValueRef::Undefined(info->GetVM());
198 }
199
200 struct StackInfo {
201 uint64_t stackLimit;
202 uint64_t lastLeaveFrame;
203 };
204
205 /**
206 * @tc.number: ffi_interface_api_105
207 * @tc.name: JSValueRef_IsGeneratorObject
208 * @tc.desc: Determine if it is a Generator generator object
209 * @tc.type: FUNC
210 * @tc.require: parameter
211 */
HWTEST_F_L0(JSNApiTests,JSValueRef_IsGeneratorObject)212 HWTEST_F_L0(JSNApiTests, JSValueRef_IsGeneratorObject)
213 {
214 LocalScope scope(vm_);
215 ObjectFactory *factory = vm_->GetFactory();
216 auto env = vm_->GetGlobalEnv();
217 JSHandle<JSTaggedValue> genFunc = env->GetGeneratorFunctionFunction();
218 JSHandle<JSGeneratorObject> genObjHandleVal = factory->NewJSGeneratorObject(genFunc);
219 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
220 JSHandle<JSFunction> generatorFunc = JSHandle<JSFunction>::Cast(factory->NewJSObject(hclass));
221 JSFunction::InitializeJSFunction(thread_, generatorFunc, FunctionKind::GENERATOR_FUNCTION);
222 JSHandle<GeneratorContext> generatorContext = factory->NewGeneratorContext();
223 generatorContext->SetMethod(thread_, generatorFunc.GetTaggedValue());
224 JSHandle<JSTaggedValue> generatorContextVal = JSHandle<JSTaggedValue>::Cast(generatorContext);
225 genObjHandleVal->SetGeneratorContext(thread_, generatorContextVal.GetTaggedValue());
226 JSHandle<JSTaggedValue> genObjTagHandleVal = JSHandle<JSTaggedValue>::Cast(genObjHandleVal);
227 Local<JSValueRef> genObjectRef = JSNApiHelper::ToLocal<GeneratorObjectRef>(genObjTagHandleVal);
228 ASSERT_TRUE(genObjectRef->IsGeneratorObject(vm_));
229 }
230
JSObjectTestCreate(JSThread * thread)231 static JSFunction *JSObjectTestCreate(JSThread *thread)
232 {
233 EcmaVM *ecmaVM = thread->GetEcmaVM();
234 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
235 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
236 }
237
238 /**
239 * @tc.number: ffi_interface_api_106
240 * @tc.name: JSValueRef_IsProxy
241 * @tc.desc: Determine if it is the type of proxy
242 * @tc.type: FUNC
243 * @tc.require: parameter
244 */
HWTEST_F_L0(JSNApiTests,JSValueRef_IsProxy)245 HWTEST_F_L0(JSNApiTests, JSValueRef_IsProxy)
246 {
247 LocalScope scope(vm_);
248 JSHandle<JSTaggedValue> hclass(thread_, JSObjectTestCreate(thread_));
249 JSHandle<JSTaggedValue> targetHandle(
250 thread_->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
251
252 JSHandle<JSTaggedValue> key(thread_->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
253 JSHandle<JSTaggedValue> value(thread_, JSTaggedValue(1));
254 JSObject::SetProperty(thread_, targetHandle, key, value);
255 EXPECT_EQ(JSObject::GetProperty(thread_, targetHandle, key).GetValue()->GetInt(), 1);
256
257 JSHandle<JSTaggedValue> handlerHandle(
258 thread_->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
259 EXPECT_TRUE(handlerHandle->IsECMAObject());
260
261 JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread_, targetHandle, handlerHandle);
262 EXPECT_TRUE(*proxyHandle != nullptr);
263
264 EXPECT_EQ(JSProxy::GetProperty(thread_, proxyHandle, key).GetValue()->GetInt(), 1);
265 PropertyDescriptor desc(thread_);
266 JSProxy::GetOwnProperty(thread_, proxyHandle, key, desc);
267 EXPECT_EQ(desc.GetValue()->GetInt(), 1);
268 Local<JSValueRef> proxy = JSNApiHelper::ToLocal<JSProxy>(JSHandle<JSTaggedValue>(proxyHandle));
269 ASSERT_TRUE(proxy->IsProxy(vm_));
270 }
271
272 /**
273 * @tc.number: ffi_interface_api_107
274 * @tc.name: BufferRef_New_ByteLength
275 * @tc.desc:
276 * New:Create a buffer and specify the length size
277 * ByteLength:Returns the length of the buffer
278 * @tc.type: FUNC
279 * @tc.require: parameter
280 */
HWTEST_F_L0(JSNApiTests,BufferRef_New_ByteLength)281 HWTEST_F_L0(JSNApiTests, BufferRef_New_ByteLength)
282 {
283 LocalScope scope(vm_);
284 int32_t length = 10;
285 Local<BufferRef> buffer = BufferRef::New(vm_, length);
286 ASSERT_TRUE(buffer->IsBuffer(vm_));
287 EXPECT_EQ(buffer->ByteLength(vm_), length);
288 }
289
290 /**
291 * @tc.number: ffi_interface_api_108
292 * @tc.name: BufferRef_New_ByteLength_GetBuffer
293 * @tc.desc:
294 * New:Create a buffer and specify the length size
295 * ByteLength:Returns the length of the buffer
296 * GetBuffer:Return buffer pointer
297 * @tc.type: FUNC
298 * @tc.require: parameter
299 */
HWTEST_F_L0(JSNApiTests,BufferRef_New_ByteLength_GetBuffer)300 HWTEST_F_L0(JSNApiTests, BufferRef_New_ByteLength_GetBuffer)
301 {
302 LocalScope scope(vm_);
303 int32_t length = 10;
304 Local<BufferRef> buffer = BufferRef::New(vm_, length);
305 ASSERT_TRUE(buffer->IsBuffer(vm_));
306 EXPECT_EQ(buffer->ByteLength(vm_), 10U);
307 ASSERT_NE(buffer->GetBuffer(vm_), nullptr);
308 }
309
310 /**
311 * @tc.number: ffi_interface_api_109
312 * @tc.name: BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback
313 * @tc.desc:
314 * BufferToStringCallback:Implement callback when calling ToString (vm) mode in buffer
315 * @tc.type: FUNC
316 * @tc.require: parameter
317 */
HWTEST_F_L0(JSNApiTests,BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback)318 HWTEST_F_L0(JSNApiTests, BufferRef_New01_ByteLength_GetBuffer_BufferToStringCallback)
319 {
320 LocalScope scope(vm_);
321 static bool isFree = false;
322 struct Data {
323 int32_t length;
324 };
325 const int32_t length = 15;
326 NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void {
327 delete[] reinterpret_cast<uint8_t *>(buffer);
328 Data *currentData = reinterpret_cast<Data *>(data);
329 delete currentData;
330 isFree = true;
331 };
332 isFree = false;
333 uint8_t *buffer = new uint8_t[length]();
334 Data *data = new Data();
335 data->length = length;
336 Local<BufferRef> bufferRef = BufferRef::New(vm_, buffer, length, deleter, data);
337 ASSERT_TRUE(bufferRef->IsBuffer(vm_));
338 ASSERT_TRUE(bufferRef->IsBuffer(vm_));
339 EXPECT_EQ(bufferRef->ByteLength(vm_), 15U);
340 Local<StringRef> bufferStr = bufferRef->ToString(vm_);
341 ASSERT_TRUE(bufferStr->IsString(vm_));
342 }
343
344 /**
345 * @tc.number: ffi_interface_api_110
346 * @tc.name: LocalScope_LocalScope
347 * @tc.desc: Build Escape LocalScope sub Vm scope
348 * @tc.type: FUNC
349 * @tc.require: parameter
350 */
HWTEST_F_L0(JSNApiTests,LocalScope_LocalScope)351 HWTEST_F_L0(JSNApiTests, LocalScope_LocalScope)
352 {
353 EscapeLocalScope scope(vm_);
354 LocalScope *perScope = nullptr;
355 perScope = &scope;
356 ASSERT_TRUE(perScope != nullptr);
357 }
358
359 /**
360 * @tc.number: ffi_interface_api_112
361 * @tc.name: JSNApi_CreateJSVM_DestroyJSVM
362 * @tc.desc: Create/delete JSVM
363 * @tc.type: FUNC
364 * @tc.require: parameter
365 */
HWTEST_F_L0(JSNApiTests,JSNApi_CreateJSVM_DestroyJSVM)366 HWTEST_F_L0(JSNApiTests, JSNApi_CreateJSVM_DestroyJSVM)
367 {
368 LocalScope scope(vm_);
369 std::thread t1([&](){
370 EcmaVM *vm1_ = nullptr;
371 RuntimeOption option;
372 option.SetLogLevel(common::LOG_LEVEL::ERROR);
373 vm1_ = JSNApi::CreateJSVM(option);
374 ASSERT_TRUE(vm1_ != nullptr) << "Cannot create Runtime";
375 vm1_->SetEnableForceGC(true);
376 vm1_->SetEnableForceGC(false);
377 JSNApi::DestroyJSVM(vm1_);
378 });
379 {
380 ecmascript::ThreadSuspensionScope suspensionScope(thread_);
381 t1.join();
382 }
383 }
384
385 /**
386 * @tc.number: ffi_interface_api_114
387 * @tc.name: JSNApi_GetUncaughtException
388 * @tc.desc: Get uncaught exceptions
389 * @tc.type: FUNC
390 * @tc.require: parameter
391 */
HWTEST_F_L0(JSNApiTests,JSNApi_GetUncaughtException)392 HWTEST_F_L0(JSNApiTests, JSNApi_GetUncaughtException)
393 {
394 LocalScope scope(vm_);
395 Local<ObjectRef> excep = JSNApi::GetUncaughtException(vm_);
396 ASSERT_TRUE(excep.IsNull()) << "CreateInstance occur Exception";
397 }
398
FuncRefNewCallbackForTest(JsiRuntimeCallInfo * info)399 Local<JSValueRef> FuncRefNewCallbackForTest(JsiRuntimeCallInfo *info)
400 {
401 GTEST_LOG_(INFO) << "runing FuncRefNewCallbackForTest";
402 EscapeLocalScope scope(info->GetVM());
403 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
404 }
405
406 /**
407 * @tc.number: ffi_interface_api_115
408 * @tc.name: ObjectRef_SetAccessorProperty
409 * @tc.desc:
410 * SetAccessorProperty:Set AccessorPro Properties
411 * GetVM:Obtain environment information for runtime calls
412 * LocalScope:Build Vm Scope
413 * @tc.type: FUNC
414 * @tc.require: parameter
415 */
HWTEST_F_L0(JSNApiTests,ObjectRef_SetAccessorProperty_JsiRuntimeCallInfo_GetVM)416 HWTEST_F_L0(JSNApiTests, ObjectRef_SetAccessorProperty_JsiRuntimeCallInfo_GetVM)
417 {
418 LocalScope scope(vm_);
419 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
420 FunctionForRef nativeFunc = FuncRefNewCallbackForTest;
421 Local<FunctionRef> getter = FunctionRef::New(vm_, nativeFunc);
422 Local<FunctionRef> setter = FunctionRef::New(vm_, nativeFunc);
423 Local<ObjectRef> object = ObjectRef::New(vm_);
424 ASSERT_TRUE(object->SetAccessorProperty(vm_, key, getter, setter));
425 }
426
427 /*
428 * @tc.number: ffi_interface_api_116
429 * @tc.name: JSNApi_IsBoolean
430 * @tc.desc: Judge whether obj is a boolean type
431 * @tc.type: FUNC
432 * @tc.require: parameter
433 */
HWTEST_F_L0(JSNApiTests,IsBoolean)434 HWTEST_F_L0(JSNApiTests, IsBoolean)
435 {
436 LocalScope scope(vm_);
437 char16_t utf16[] = u"This is a char16 array";
438 int size = sizeof(utf16);
439 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
440 ASSERT_FALSE(obj->IsBoolean());
441 }
442
443 /*
444 * @tc.number: ffi_interface_api_117
445 * @tc.name: JSNApi_IsNULL
446 * @tc.desc: Judge whether obj is a null type
447 * @tc.type: FUNC
448 * @tc.require: parameter
449 */
HWTEST_F_L0(JSNApiTests,IsNULL)450 HWTEST_F_L0(JSNApiTests, IsNULL)
451 {
452 LocalScope scope(vm_);
453 char16_t utf16[] = u"This is a char16 array";
454 int size = sizeof(utf16);
455 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
456 ASSERT_FALSE(obj->IsNull());
457 }
458
459 /*
460 * @tc.number: ffi_interface_api_118
461 * @tc.name: JSNApi_GetTime
462 * @tc.desc: This function is to catch time
463 * @tc.type: FUNC
464 * @tc.require: parameter
465 */
HWTEST_F_L0(JSNApiTests,GetTime)466 HWTEST_F_L0(JSNApiTests, GetTime)
467 {
468 LocalScope scope(vm_);
469 const double time = 14.29;
470 Local<DateRef> date = DateRef::New(vm_, time);
471 ASSERT_EQ(date->GetTime(vm_), time);
472 }
473
474 /*
475 * @tc.number: ffi_interface_api_119
476 * @tc.name: JSNApi_IsDetach
477 * @tc.desc: Judge whether arraybuffer is detached
478 * @tc.type: FUNC
479 * @tc.require: parameter
480 */
HWTEST_F_L0(JSNApiTests,IsDetach)481 HWTEST_F_L0(JSNApiTests, IsDetach)
482 {
483 LocalScope scope(vm_);
484 const int32_t length = 33;
485 Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
486 ASSERT_FALSE(arraybuffer->IsDetach(vm_));
487 }
488
489 /*
490 * @tc.number: ffi_interface_api_120
491 * @tc.name: JSNApi_Detach
492 * @tc.desc: This function is to detach arraybuffer
493 * @tc.type: FUNC
494 * @tc.require: parameter
495 */
HWTEST_F_L0(JSNApiTests,Detach)496 HWTEST_F_L0(JSNApiTests, Detach)
497 {
498 LocalScope scope(vm_);
499 const int32_t length = 33;
500 Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
501 arraybuffer->Detach(vm_);
502 }
503
504 /*
505 * @tc.number: ffi_interface_api_121
506 * @tc.name: JSNApi_New1
507 * @tc.desc: create a obj that is a arraybuffer type
508 * @tc.type: FUNC
509 * @tc.require: parameter
510 */
HWTEST_F_L0(JSNApiTests,New1)511 HWTEST_F_L0(JSNApiTests, New1)
512 {
513 LocalScope scope(vm_);
514 const int32_t length = 33;
515 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
516 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_));
517 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
518 ASSERT_NE(arrayBuffer->GetBuffer(vm_), nullptr);
519 }
520
521 /*
522 * @tc.number: ffi_interface_api_122
523 * @tc.name: JSNApi_New1
524 * @tc.desc: create a obj that is a arraybuffer type
525 * @tc.type: FUNC
526 * @tc.require: parameter
527 */
HWTEST_F_L0(JSNApiTests,New2)528 HWTEST_F_L0(JSNApiTests, New2)
529 {
530 static bool isFree = false;
531 struct Data {
532 int32_t length;
533 };
534 const int32_t length = 15;
535 Data *data = new Data();
536 data->length = length;
537 NativePointerCallback deleter = []([[maybe_unused]] void *env, void *buffer, void *data) -> void {
538 delete[] reinterpret_cast<uint8_t *>(buffer);
539 Data *currentData = reinterpret_cast<Data *>(data);
540 ASSERT_EQ(currentData->length, 15); // 5 : size of arguments
541 delete currentData;
542 isFree = true;
543 };
544 {
545 LocalScope scope(vm_);
546 uint8_t *buffer = new uint8_t[length]();
547 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data);
548 ASSERT_TRUE(arrayBuffer->IsArrayBuffer(vm_));
549 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
550 ASSERT_EQ(arrayBuffer->GetBuffer(vm_), buffer);
551 }
552 }
553
554 /*
555 * @tc.number: ffi_interface_api_123
556 * @tc.name: JSNApi_Bytelength
557 * @tc.desc: capture bytelength of arraybuffer
558 * @tc.type: FUNC
559 * @tc.require: parameter
560 */
HWTEST_F_L0(JSNApiTests,Bytelength)561 HWTEST_F_L0(JSNApiTests, Bytelength)
562 {
563 LocalScope scope(vm_);
564 const int32_t length = 33;
565 Local<ArrayBufferRef> arrayBuffer = ArrayBufferRef::New(vm_, length);
566 ASSERT_EQ(arrayBuffer->ByteLength(vm_), length);
567 }
568
569 /*
570 * @tc.number: ffi_interface_api_124
571 * @tc.name: JSNApi_GetBuffer
572 * @tc.desc: capture buffer of arraybuffer
573 * @tc.type: FUNC
574 * @tc.require: parameter
575 */
HWTEST_F_L0(JSNApiTests,GetBuffer)576 HWTEST_F_L0(JSNApiTests, GetBuffer)
577 {
578 LocalScope scope(vm_);
579 const int32_t length = 33;
580 Local<ArrayBufferRef> arraybuffer = ArrayBufferRef::New(vm_, length);
581 ASSERT_NE(arraybuffer->GetBuffer(vm_), nullptr);
582 }
583
584 /*
585 * @tc.number: ffi_interface_api_125
586 * @tc.name: JSNApi_Is32Arraytest
587 * @tc.desc: judge whether obj is a int32array type,
588 * judge whether obj is a uint32array type,
589 * judge whether obj is a float32array type,
590 * judge whether obj is a float64array type,
591 * @tc.type: FUNC
592 * @tc.require: parameter
593 */
HWTEST_F_L0(JSNApiTests,Is32Arraytest)594 HWTEST_F_L0(JSNApiTests, Is32Arraytest)
595 {
596 LocalScope scope(vm_);
597 char16_t utf16[] = u"This is a char16 array";
598 int size = sizeof(utf16);
599 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
600 ASSERT_FALSE(obj->IsInt32Array(vm_));
601 ASSERT_FALSE(obj->IsUint32Array(vm_));
602 ASSERT_FALSE(obj->IsFloat32Array(vm_));
603 ASSERT_FALSE(obj->IsFloat64Array(vm_));
604 }
605
606 /*
607 * @tc.number: ffi_interface_api_126
608 * @tc.name: JSNApi_SynchronizVMInfo
609 * @tc.desc: capture synchronous info of vm
610 * @tc.type: FUNC
611 * @tc.require: parameter
612 */
HWTEST_F_L0(JSNApiTests,SynchronizVMInfo)613 HWTEST_F_L0(JSNApiTests, SynchronizVMInfo)
614 {
615 LocalScope scope(vm_);
616 std::thread t1([&]() {
617 JSRuntimeOptions option;
618 EcmaVM *hostVM = JSNApi::CreateEcmaVM(option);
619 {
620 LocalScope scope2(hostVM);
621 JSNApi::SynchronizVMInfo(vm_, hostVM);
622 }
623 JSNApi::DestroyJSVM(hostVM);
624 });
625 {
626 ecmascript::ThreadSuspensionScope suspensionScope(thread_);
627 t1.join();
628 }
629 }
630
631 /*
632 * @tc.number: ffi_interface_api_127
633 * @tc.name: JSNApi_IsProfiling
634 * @tc.desc: judge whether vm is profiling
635 * @tc.type: FUNC
636 * @tc.require: parameter
637 */
HWTEST_F_L0(JSNApiTests,IsProfiling)638 HWTEST_F_L0(JSNApiTests, IsProfiling)
639 {
640 LocalScope scope(vm_);
641 ASSERT_FALSE(JSNApi::IsProfiling(vm_));
642 }
643
644 /*
645 * @tc.number: ffi_interface_api_128
646 * @tc.name: JSNApi_SetProfilerState
647 * @tc.desc: This function is to set state of profiler
648 * @tc.type: FUNC
649 * @tc.require: parameter
650 */
HWTEST_F_L0(JSNApiTests,SetProfilerState)651 HWTEST_F_L0(JSNApiTests, SetProfilerState)
652 {
653 bool value = true;
654 bool value2 = false;
655 LocalScope scope(vm_);
656 JSNApi::SetProfilerState(vm_, value);
657 JSNApi::SetProfilerState(vm_, value2);
658 }
659
660 /*
661 * @tc.number: ffi_interface_api_129
662 * @tc.name: JSNApi_SetLoop
663 * @tc.desc: This function is to set loop
664 * @tc.type: FUNC
665 * @tc.require: parameter
666 */
HWTEST_F_L0(JSNApiTests,SetLoop)667 HWTEST_F_L0(JSNApiTests, SetLoop)
668 {
669 LocalScope scope(vm_);
670 void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
671 JSNApi::SetLoop(vm_, data);
672 }
673
674 /*
675 * @tc.number: ffi_interface_api_130
676 * @tc.name: JSNApi_SetHostPromiseRejectionTracker
677 * @tc.desc: This function is to set host promise rejection about tracker
678 * @tc.type: FUNC
679 * @tc.require: parameter
680 */
HWTEST_F_L0(JSNApiTests,SetHostPromiseRejectionTracker)681 HWTEST_F_L0(JSNApiTests, SetHostPromiseRejectionTracker)
682 {
683 LocalScope scope(vm_);
684 void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
685 void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
686 JSNApi::SetHostPromiseRejectionTracker(vm_, cb, data);
687 }
688
689 /*
690 * @tc.number: ffi_interface_api_131
691 * @tc.name: JSNApi_SetHostResolveBufferTracker
692 * @tc.desc: This function is to set host resolve buffer about tracker
693 * @tc.type: FUNC
694 * @tc.require: parameter
695 */
HWTEST_F_L0(JSNApiTests,SetHostResolveBufferTracker)696 HWTEST_F_L0(JSNApiTests, SetHostResolveBufferTracker)
697 {
698 LocalScope scope(vm_);
699 JSNApi::SetHostResolveBufferTracker(vm_,
700 [&](std::string, uint8_t **, size_t *, std::string &) -> bool { return true; });
701 }
702
703 /*
704 * @tc.number: ffi_interface_api_132
705 * @tc.name: JSNApi_SetUnloadNativeModuleCallback
706 * @tc.desc: This function is to set unload native module about callback
707 * @tc.type: FUNC
708 * @tc.require: parameter
709 */
HWTEST_F_L0(JSNApiTests,SetUnloadNativeModuleCallback)710 HWTEST_F_L0(JSNApiTests, SetUnloadNativeModuleCallback)
711 {
712 LocalScope scope(vm_);
713 JSNApi::SetUnloadNativeModuleCallback(vm_, [&](const std::string &) -> bool { return true; });
714 }
715
716 /*
717 * @tc.number: ffi_interface_api_133
718 * @tc.name: JSNApi_SetNativePtrGetter
719 * @tc.desc: This function is to set a native pointer about getter
720 * @tc.type: FUNC
721 * @tc.require: parameter
722 */
HWTEST_F_L0(JSNApiTests,SetNativePtrGetter)723 HWTEST_F_L0(JSNApiTests, SetNativePtrGetter)
724 {
725 LocalScope scope(vm_);
726 void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
727 JSNApi::SetNativePtrGetter(vm_, cb);
728 }
729
730 /*
731 * @tc.number: ffi_interface_api_134
732 * @tc.name: JSNApi_PreFork
733 * @tc.desc: This function is to set prefork
734 * @tc.type: FUNC
735 * @tc.require: parameter
736 */
HWTEST_F_L0(JSNApiTests,PreFork)737 HWTEST_F_L0(JSNApiTests, PreFork)
738 {
739 RuntimeOption option;
740 ecmascript::ThreadNativeScope nativeScope(vm_->GetJSThread());
741 LocalScope scope(vm_);
742 JSNApi::PreFork(vm_);
743 JSNApi::PostFork(vm_, option);
744 }
745
746 /*
747 * @tc.number: ffi_interface_api_135
748 * @tc.name: JSNApi_PostFork
749 * @tc.desc: This function is to set postfork
750 * @tc.type: FUNC
751 * @tc.require: parameter
752 */
HWTEST_F_L0(JSNApiTests,PostFork)753 HWTEST_F_L0(JSNApiTests, PostFork)
754 {
755 RuntimeOption option;
756 ecmascript::ThreadNativeScope nativeScope(vm_->GetJSThread());
757 LocalScope scope(vm_);
758 JSNApi::PreFork(vm_);
759 JSNApi::PostFork(vm_, option);
760 }
761
762
763 /*
764 * @tc.number: ffi_interface_api_136
765 * @tc.name: JSNApi_NewFromUtf8
766 * @tc.desc: create a newfromutf8 object
767 * @tc.type: FUNC
768 * @tc.require: parameter
769 */
HWTEST_F_L0(JSNApiTests,NewFromUtf8)770 HWTEST_F_L0(JSNApiTests, NewFromUtf8)
771 {
772 LocalScope scope(vm_);
773 char utf8[] = "hello world!";
774 int length = strlen(utf8);
775 Local<StringRef> result = StringRef::NewFromUtf8(vm_, utf8, length);
776 ASSERT_EQ(result->Utf8Length(vm_), length + 1);
777 }
778
779 /*
780 * @tc.number: ffi_interface_api_137
781 * @tc.name: JSNApi_NewFromUtf16
782 * @tc.desc: create a newfromutf16 object
783 * @tc.type: FUNC
784 * @tc.require: parameter
785 */
HWTEST_F_L0(JSNApiTests,NewFromUtf16)786 HWTEST_F_L0(JSNApiTests, NewFromUtf16)
787 {
788 LocalScope scope(vm_);
789 char16_t utf16[] = u"This is a char16 array";
790 int length = sizeof(utf16);
791 Local<StringRef> result = StringRef::NewFromUtf16(vm_, utf16, length);
792 ASSERT_EQ(result->Length(vm_), length);
793 }
794
795 /*
796 * @tc.number: ffi_interface_api_138
797 * @tc.name: JSNApi_GetNapiWrapperString
798 * @tc.desc: This function is to get a napiwrapper string
799 * @tc.type: FUNC
800 * @tc.require: parameter
801 */
HWTEST_F_L0(JSNApiTests,GetNapiWrapperString)802 HWTEST_F_L0(JSNApiTests, GetNapiWrapperString)
803 {
804 LocalScope scope(vm_);
805 Local<StringRef> result = StringRef::GetNapiWrapperString(vm_);
806 ASSERT_TRUE(result->IsString(vm_));
807 }
808
809 /*
810 * @tc.number: ffi_interface_api_139
811 * @tc.name: JSNApi_JSExecutionScope
812 * @tc.desc: This function is to construct a object of jsexecutionscope
813 * @tc.type: FUNC
814 * @tc.require: parameter
815 */
HWTEST_F_L0(JSNApiTests,JSExecutionScope)816 HWTEST_F_L0(JSNApiTests, JSExecutionScope)
817 {
818 LocalScope scope(vm_);
819 JSExecutionScope jsexecutionScope(vm_);
820 }
821
822 /*
823 * @tc.number: ffi_interface_api_140
824 * @tc.name: WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue
825 * @tc.desc: This function is to set a weakmap and capture it's size ,
826 * key, value and total elements
827 * @tc.type: FUNC
828 * @tc.require: parameter
829 */
HWTEST_F_L0(JSNApiTests,WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue)830 HWTEST_F_L0(JSNApiTests, WeakMapRef_GetSize_GetTotalElements_GetKey_GetValue)
831 {
832 LocalScope scope(vm_);
833 JSThread *thread = vm_->GetJSThread();
834 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
835 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
836 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakMapFunction();
837 JSHandle<JSWeakMap> weakMap =
838 JSHandle<JSWeakMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
839 JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
840 weakMap->SetLinkedMap(thread, hashMap);
841 JSHandle<JSTaggedValue> weakMapTag = JSHandle<JSTaggedValue>::Cast(weakMap);
842
843 Local<WeakMapRef> map = JSNApiHelper::ToLocal<WeakMapRef>(weakMapTag);
844 EXPECT_TRUE(map->IsWeakMap(vm_));
845 JSHandle<JSTaggedValue> value(factory->NewFromASCII("value"));
846 JSHandle<JSTaggedValue> key(factory->NewFromASCII("key"));
847 JSWeakMap::Set(thread, weakMap, key, value);
848 int32_t num = map->GetSize(vm_);
849 int32_t num1 = map->GetTotalElements(vm_);
850 ASSERT_EQ(num, 1);
851 ASSERT_EQ(num1, 1);
852 Local<JSValueRef> res1 = map->GetKey(vm_, 0);
853 ASSERT_EQ(res1->ToString(vm_)->ToString(vm_), "key");
854 Local<JSValueRef> res2 = map->GetValue(vm_, 0);
855 ASSERT_EQ(res2->ToString(vm_)->ToString(vm_), "value");
856 }
857
858 /*
859 * @tc.number: ffi_interface_api_141
860 * @tc.name: JSNApi_ IsAGJA
861 * @tc.desc: This function is to judge whether object is a argumentsobject or
862 * is a generatorfunction or is a asyncfunction
863 * @tc.type: FUNC
864 * @tc.require: parameter
865 */
HWTEST_F_L0(JSNApiTests,IsAGJA)866 HWTEST_F_L0(JSNApiTests, IsAGJA)
867 {
868 LocalScope scope(vm_);
869 char16_t utf16[] = u"This is a char16 array";
870 int size = sizeof(utf16);
871 Local<StringRef> obj = StringRef::NewFromUtf16(vm_, utf16, size);
872 ASSERT_FALSE(obj->IsArgumentsObject(vm_));
873 ASSERT_FALSE(obj->IsGeneratorFunction(vm_));
874 ASSERT_FALSE(obj->IsAsyncFunction(vm_));
875 }
876
877 /**
878 * @tc.number: ffi_interface_api_143
879 * @tc.name: Int32Array
880 * @tc.desc: Catch exceptions correctly
881 * @tc.type: FUNC
882 * @tc.require: parameter
883 */
HWTEST_F_L0(JSNApiTests,HasCaught)884 HWTEST_F_L0(JSNApiTests, HasCaught)
885 {
886 LocalScope scope(vm_);
887 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
888 Local<JSValueRef> error = Exception::Error(vm_, message);
889 ASSERT_TRUE(error->IsError(vm_));
890 JSNApi::ThrowException(vm_, error);
891 TryCatch tryCatch(vm_);
892 ASSERT_TRUE(tryCatch.HasCaught());
893 vm_->GetJSThread()->ClearException();
894 ASSERT_FALSE(tryCatch.HasCaught());
895 }
896
897 /**
898 * @tc.number: ffi_interface_api_144
899 * @tc.name: Int32Array
900 * @tc.desc: Rethrow the exception
901 * @tc.type: FUNC
902 * @tc.require: parameter
903 */
HWTEST_F_L0(JSNApiTests,Rethrow)904 HWTEST_F_L0(JSNApiTests, Rethrow)
905 {
906 LocalScope scope(vm_);
907 TryCatch tryCatch(vm_);
908 tryCatch.Rethrow();
909 ASSERT_TRUE(tryCatch.getrethrow_());
910 }
911
912 /**
913 * @tc.number: ffi_interface_api_145
914 * @tc.name: Int32Array
915 * @tc.desc: Clear caught exceptions
916 * @tc.type: FUNC
917 * @tc.require: parameter
918 */
HWTEST_F_L0(JSNApiTests,GetAndClearException)919 HWTEST_F_L0(JSNApiTests, GetAndClearException)
920 {
921 LocalScope scope(vm_);
922 Local<StringRef> message = StringRef::NewFromUtf8(vm_, "ErrorTest");
923 Local<JSValueRef> error = Exception::Error(vm_, message);
924 ASSERT_TRUE(error->IsError(vm_));
925 JSNApi::ThrowException(vm_, error);
926 ASSERT_TRUE(vm_->GetJSThread()->HasPendingException());
927 TryCatch tryCatch(vm_);
928 tryCatch.GetAndClearException();
929 EXPECT_FALSE(vm_->GetJSThread()->HasPendingException());
930 }
931 /**
932 * @tc.number: ffi_interface_api_146
933 * @tc.name: Int32Array
934 * @tc.desc: trycatch class construction
935 * @tc.type: FUNC
936 * @tc.require: parameter
937 */
HWTEST_F_L0(JSNApiTests,TryCatch)938 HWTEST_F_L0(JSNApiTests, TryCatch)
939 {
940 LocalScope scope(vm_);
941 TryCatch tryCatch(vm_);
942 EXPECT_EQ(tryCatch.getrethrow_(), false);
943 EXPECT_FALSE(tryCatch.HasCaught());
944 tryCatch.Rethrow();
945 EXPECT_EQ(tryCatch.getrethrow_(), true);
946 }
947
HWTEST_F_L0(JSNApiTests,NewObjectWithProperties)948 HWTEST_F_L0(JSNApiTests, NewObjectWithProperties)
949 {
950 LocalScope scope(vm_);
951 Local<JSValueRef> keys[1100];
952 Local<JSValueRef> values[1100];
953 PropertyAttribute attributes[1100];
954 for (int i = 0; i < 1100; i += (i < 80 ? (i < 10 ? 1 : 80) : 1000)) {
955 for (int j = 0; j <= i; ++j) {
956 std::string strKey("TestKey" + std::to_string(i) + "_" + std::to_string(j));
957 std::string strVal("TestValue" + std::to_string(i) + "_" + std::to_string(j));
958 keys[j] = StringRef::NewFromUtf8(vm_, strKey.c_str());
959 values[j] = StringRef::NewFromUtf8(vm_, strVal.c_str());
960 attributes[j] = PropertyAttribute(values[j], true, true, true);
961 }
962 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, i + 1, keys, attributes);
963 for (int j = 0; j <= i; ++j) {
964 Local<JSValueRef> value1 = object->Get(vm_, keys[j]);
965 EXPECT_TRUE(values[j]->IsStrictEquals(vm_, value1));
966 }
967 JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(object));
968 uint32_t propCount = obj->GetJSHClass()->NumberOfProps();
969 if (i + 1 > PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
970 EXPECT_TRUE(propCount == 0);
971 EXPECT_TRUE(obj->GetJSHClass()->IsDictionaryMode());
972 JSHandle<NameDictionary> dict(thread_, obj->GetProperties(thread_));
973 EXPECT_TRUE(dict->EntriesCount() == i + 1);
974 } else {
975 EXPECT_TRUE(propCount == i + 1);
976 int32_t in_idx = obj->GetJSHClass()->GetNextInlinedPropsIndex();
977 int32_t nonin_idx = obj->GetJSHClass()->GetNextNonInlinedPropsIndex();
978 if (i + 1 < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
979 EXPECT_TRUE(in_idx == i + 1);
980 EXPECT_TRUE(nonin_idx == -1);
981 } else {
982 EXPECT_TRUE(in_idx == -1);
983 EXPECT_TRUE(nonin_idx == 0);
984 }
985 }
986 }
987 }
988
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertieNonPureStringKey)989 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertieNonPureStringKey)
990 {
991 LocalScope scope(vm_);
992 Local<JSValueRef> keys[] = {
993 StringRef::NewFromUtf8(vm_, "1"),
994 };
995 Local<JSValueRef> values[] = {
996 StringRef::NewFromUtf8(vm_, "value1"),
997 };
998 PropertyAttribute attributes[] = {
999 PropertyAttribute(values[0], true, true, true),
1000 };
1001 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 1, keys, attributes);
1002 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1003 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1004 thread_->ClearException();
1005 }
1006
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicate)1007 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicate)
1008 {
1009 LocalScope scope(vm_);
1010 Local<JSValueRef> keys[] = {
1011 StringRef::NewFromUtf8(vm_, DUPLICATE_KEY),
1012 StringRef::NewFromUtf8(vm_, SIMPLE_KEY),
1013 StringRef::NewFromUtf8(vm_, DUPLICATE_KEY),
1014 };
1015 Local<JSValueRef> values[] = {
1016 StringRef::NewFromUtf8(vm_, "value1"),
1017 StringRef::NewFromUtf8(vm_, "value2"),
1018 StringRef::NewFromUtf8(vm_, "value3"),
1019 };
1020 PropertyAttribute attributes[] = {
1021 PropertyAttribute(values[0], true, true, true),
1022 PropertyAttribute(values[1], true, true, true),
1023 PropertyAttribute(values[2], true, true, true),
1024 };
1025 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1026 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1027 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1028 thread_->ClearException();
1029 }
1030
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedProperties)1031 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedProperties)
1032 {
1033 LocalScope scope(vm_);
1034 const char *keys[1100];
1035 std::string strKeys[1100];
1036 Local<JSValueRef> values[1100];
1037 for (int i = 0; i < 1100; i += (i < 80 ? (i < 10 ? 1 : 80) : 1000)) {
1038 for (int j = 0; j <= i; ++j) {
1039 strKeys[j] = "TestKey" + std::to_string(i) + "_" + std::to_string(j);
1040 std::string strVal("TestValue" + std::to_string(i) + "_" + std::to_string(j));
1041 keys[j] = const_cast<char *>(strKeys[j].c_str());
1042 values[j] = StringRef::NewFromUtf8(vm_, strVal.c_str());
1043 }
1044 Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, i + 1, keys, values);
1045 for (int j = 0; j <= i; ++j) {
1046 Local<JSValueRef> value1 = object->Get(vm_, StringRef::NewFromUtf8(vm_, keys[j]));
1047 EXPECT_TRUE(values[j]->IsStrictEquals(vm_, value1));
1048 }
1049 JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(object));
1050 uint32_t propCount = obj->GetJSHClass()->NumberOfProps();
1051 if (i + 1 > PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
1052 EXPECT_TRUE(propCount == 0);
1053 EXPECT_TRUE(obj->GetJSHClass()->IsDictionaryMode());
1054 JSHandle<NameDictionary> dict(thread_, obj->GetProperties(thread_));
1055 EXPECT_TRUE(dict->EntriesCount() == i + 1);
1056 } else {
1057 EXPECT_TRUE(propCount == i + 1);
1058 int32_t in_idx = obj->GetJSHClass()->GetNextInlinedPropsIndex();
1059 int32_t nonin_idx = obj->GetJSHClass()->GetNextNonInlinedPropsIndex();
1060 if (i + 1 < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
1061 EXPECT_TRUE(in_idx == i + 1);
1062 EXPECT_TRUE(nonin_idx == -1);
1063 } else {
1064 EXPECT_TRUE(in_idx == -1);
1065 EXPECT_TRUE(nonin_idx == 0);
1066 }
1067 }
1068 }
1069 }
1070
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedPropertieNonPureStringKey)1071 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedPropertieNonPureStringKey)
1072 {
1073 LocalScope scope(vm_);
1074 const char *keys[] = {
1075 "1",
1076 };
1077 Local<JSValueRef> values[] = {
1078 StringRef::NewFromUtf8(vm_, "value1"),
1079 };
1080 Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, 2, keys, values);
1081 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1082 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1083 thread_->ClearException();
1084 }
1085
HWTEST_F_L0(JSNApiTests,NewObjectWithNamedPropertiesDuplicate)1086 HWTEST_F_L0(JSNApiTests, NewObjectWithNamedPropertiesDuplicate)
1087 {
1088 LocalScope scope(vm_);
1089 const char *keys[] = {
1090 DUPLICATE_KEY,
1091 SIMPLE_KEY,
1092 DUPLICATE_KEY,
1093 };
1094 Local<JSValueRef> values[] = {
1095 StringRef::NewFromUtf8(vm_, "value1"),
1096 StringRef::NewFromUtf8(vm_, "value2"),
1097 StringRef::NewFromUtf8(vm_, "value3"),
1098 };
1099 Local<ObjectRef> object = ObjectRef::NewWithNamedProperties(vm_, 3, keys, values);
1100 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1101 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1102 thread_->ClearException();
1103 }
1104
HWTEST_F_L0(JSNApiTests,GetNamedPropertyByPassingUtf8Key)1105 HWTEST_F_L0(JSNApiTests, GetNamedPropertyByPassingUtf8Key)
1106 {
1107 LocalScope scope(vm_);
1108 Local<ObjectRef> object = ObjectRef::New(vm_);
1109 const char* utf8Key = "TestKey";
1110 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, utf8Key);
1111 Local<JSValueRef> value = ObjectRef::New(vm_);
1112 PropertyAttribute attribute(value, true, true, true);
1113
1114 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
1115 Local<JSValueRef> value1 = object->Get(vm_, utf8Key);
1116 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1117 }
1118
HWTEST_F_L0(JSNApiTests,SetNamedPropertyByPassingUtf8Key)1119 HWTEST_F_L0(JSNApiTests, SetNamedPropertyByPassingUtf8Key)
1120 {
1121 LocalScope scope(vm_);
1122 Local<ObjectRef> object = ObjectRef::New(vm_);
1123 const char* utf8Key = "TestKey";
1124 Local<JSValueRef> value = ObjectRef::New(vm_);
1125
1126 ASSERT_TRUE(object->Set(vm_, utf8Key, value));
1127 Local<JSValueRef> value1 = object->Get(vm_, utf8Key);
1128 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1129 }
1130
HWTEST_F_L0(JSNApiTests,NapiFastPathGetNamedProperty)1131 HWTEST_F_L0(JSNApiTests, NapiFastPathGetNamedProperty)
1132 {
1133 LocalScope scope(vm_);
1134 Local<ObjectRef> object = ObjectRef::New(vm_);
1135 const char* utf8Key = "TestKey";
1136 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, utf8Key);
1137 Local<JSValueRef> value = ObjectRef::New(vm_);
1138 PropertyAttribute attribute(value, true, true, true);
1139
1140 ASSERT_TRUE(object->DefineProperty(vm_, key, attribute));
1141 Local<JSValueRef> value1 = JSNApi::NapiGetNamedProperty(vm_, reinterpret_cast<uintptr_t>(*object), utf8Key);
1142 ASSERT_TRUE(value->IsStrictEquals(vm_, value1));
1143 }
1144
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable)1145 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable)
1146 {
1147 LocalScope scope(vm_);
1148 Local<JSValueRef> keys[] = {
1149 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY),
1150 StringRef::NewFromUtf8WithoutStringTable(vm_, SIMPLE_KEY),
1151 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY),
1152 };
1153 Local<JSValueRef> values[] = {
1154 StringRef::NewFromUtf8WithoutStringTable(vm_, "value1"),
1155 StringRef::NewFromUtf8WithoutStringTable(vm_, "value2"),
1156 StringRef::NewFromUtf8WithoutStringTable(vm_, "value3"),
1157 };
1158 PropertyAttribute attributes[] = {
1159 PropertyAttribute(values[0], true, true, true),
1160 PropertyAttribute(values[1], true, true, true),
1161 PropertyAttribute(values[2], true, true, true),
1162 };
1163 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1164 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1165 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1166 thread_->ClearException();
1167 }
1168
HWTEST_F_L0(JSNApiTests,NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable1)1169 HWTEST_F_L0(JSNApiTests, NewObjectWithPropertiesDuplicateWithKeyNotFromStringTable1)
1170 {
1171 LocalScope scope(vm_);
1172 Local<JSValueRef> keys[] = {
1173 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY, 0),
1174 StringRef::NewFromUtf8WithoutStringTable(vm_, SIMPLE_KEY, 0),
1175 StringRef::NewFromUtf8WithoutStringTable(vm_, DUPLICATE_KEY, 0),
1176 };
1177 Local<JSValueRef> values[] = {
1178 StringRef::NewFromUtf16WithoutStringTable(vm_, UTF_16, 0),
1179 StringRef::NewFromUtf16WithoutStringTable(vm_, UTF_16, 0),
1180 StringRef::NewFromUtf16WithoutStringTable(vm_, UTF_16, 0),
1181 };
1182 PropertyAttribute attributes[] = {
1183 PropertyAttribute(values[0], true, true, true),
1184 PropertyAttribute(values[1], true, true, true),
1185 PropertyAttribute(values[2], true, true, true),
1186 };
1187 Local<ObjectRef> object = ObjectRef::NewWithProperties(vm_, 3, keys, attributes);
1188 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(object);
1189 EXPECT_TRUE(obj.GetTaggedValue() == JSTaggedValue::Undefined());
1190 thread_->ClearException();
1191 }
1192
HWTEST_F_L0(JSNApiTests,EcmaObjectToInt)1193 HWTEST_F_L0(JSNApiTests, EcmaObjectToInt)
1194 {
1195 LocalScope scope(vm_);
1196 Local<FunctionRef> toPrimitiveFunc = FunctionRef::New(vm_,
1197 [](JsiRuntimeCallInfo *runtimeInfo) -> Local<JSValueRef> {
1198 EcmaVM *vm = runtimeInfo->GetVM();
1199 return JSValueRef::True(vm);
1200 });
1201 Local<ObjectRef> obj = ObjectRef::New(vm_);
1202 PropertyAttribute attribute(toPrimitiveFunc, true, true, true);
1203 Local<JSValueRef> toPrimitiveKey = JSNApiHelper::ToLocal<JSValueRef>(vm_->GetGlobalEnv()->GetToPrimitiveSymbol());
1204 obj->DefineProperty(vm_, toPrimitiveKey, attribute);
1205 {
1206 // Test that Uint32Value and Int32Value should transition to Running if needed.
1207 ecmascript::ThreadNativeScope nativeScope(thread_);
1208 uint32_t res = obj->Uint32Value(vm_);
1209 EXPECT_TRUE(res == 1);
1210 res = obj->Int32Value(vm_);
1211 EXPECT_TRUE(res == 1);
1212 }
1213 }
1214
HWTEST_F_L0(JSNApiTests,NapiTryFastTest)1215 HWTEST_F_L0(JSNApiTests, NapiTryFastTest)
1216 {
1217 Local<ObjectRef> object = ObjectRef::New(vm_);
1218 JSTaggedValue a(0);
1219 JSHandle<JSTaggedValue> handle(thread_, a);
1220 Local<JSValueRef> key = JSNApiHelper::ToLocal<JSValueRef>(handle);
1221 const char* utf8Key = "TestKey";
1222 Local<JSValueRef> key2 = StringRef::NewFromUtf8(vm_, utf8Key);
1223 Local<JSValueRef> value = ObjectRef::New(vm_);
1224 object->Set(vm_, key, value);
1225 object->Set(vm_, key2, value);
1226 Local<JSValueRef> res1 = JSNApi::NapiGetProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1227 reinterpret_cast<uintptr_t>(*key));
1228 ASSERT_TRUE(value->IsStrictEquals(vm_, res1));
1229 Local<JSValueRef> res2 = JSNApi::NapiGetProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1230 reinterpret_cast<uintptr_t>(*key2));
1231 ASSERT_TRUE(value->IsStrictEquals(vm_, res2));
1232
1233 Local<JSValueRef> flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object),
1234 reinterpret_cast<uintptr_t>(*key));
1235 ASSERT_TRUE(flag->BooleaValue(vm_));
1236 flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1237 ASSERT_TRUE(flag->BooleaValue(vm_));
1238
1239 flag = JSNApi::NapiDeleteProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key));
1240 ASSERT_TRUE(flag->BooleaValue(vm_));
1241 flag = JSNApi::NapiDeleteProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1242 ASSERT_TRUE(flag->BooleaValue(vm_));
1243
1244 flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key));
1245 ASSERT_FALSE(flag->BooleaValue(vm_));
1246 flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*object), reinterpret_cast<uintptr_t>(*key2));
1247 ASSERT_FALSE(flag->BooleaValue(vm_));
1248 }
1249
HWTEST_F_L0(JSNApiTests,NapiTryFastHasMethodTest)1250 HWTEST_F_L0(JSNApiTests, NapiTryFastHasMethodTest)
1251 {
1252 LocalScope scope(vm_);
1253 auto array = JSArray::ArrayCreate(thread_, JSTaggedNumber(0));
1254 auto arr = JSNApiHelper::ToLocal<ObjectRef>(array);
1255 const char* utf8Key = "concat";
1256 Local<JSValueRef> key3 = StringRef::NewFromUtf8(vm_, utf8Key);
1257 auto flag = JSNApi::NapiHasProperty(vm_, reinterpret_cast<uintptr_t>(*arr), reinterpret_cast<uintptr_t>(*key3));
1258 ASSERT_TRUE(flag->BooleaValue(vm_));
1259 }
1260
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest001)1261 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest001)
1262 {
1263 isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, 0);
1264 ASSERT_FALSE(isStringCacheTableCreated_);
1265 }
1266
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest002)1267 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest002)
1268 {
1269 constexpr uint32_t STRING_CACHE_TABLE_SIZE = 300;
1270 isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
1271 ASSERT_FALSE(isStringCacheTableCreated_);
1272 }
1273
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest003)1274 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest003)
1275 {
1276 constexpr uint32_t STRING_CACHE_TABLE_SIZE = 100;
1277 isStringCacheTableCreated_ = ExternalStringCache::RegisterStringCacheTable(vm_, STRING_CACHE_TABLE_SIZE);
1278 ASSERT_TRUE(isStringCacheTableCreated_);
1279 }
1280
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest004)1281 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest004)
1282 {
1283 RegisterStringCacheTable();
1284 constexpr uint32_t PROPERTY_INDEX = 101;
1285 constexpr char property[] = "hello";
1286 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1287 ASSERT_FALSE(res);
1288 }
1289
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest005)1290 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest005)
1291 {
1292 RegisterStringCacheTable();
1293 constexpr uint32_t PROPERTY_INDEX = 0;
1294 constexpr char property[] = "hello";
1295 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1296 ASSERT_TRUE(res);
1297 }
1298
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest006)1299 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest006)
1300 {
1301 RegisterStringCacheTable();
1302 constexpr uint32_t PROPERTY_INDEX = 1;
1303 constexpr char property[] = "hello";
1304 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1305 ASSERT_TRUE(res);
1306
1307 constexpr uint32_t QUERY_PROPERTY_INDEX = 2;
1308 res = ExternalStringCache::HasCachedString(vm_, QUERY_PROPERTY_INDEX);
1309 ASSERT_FALSE(res);
1310 }
1311
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest007)1312 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest007)
1313 {
1314 RegisterStringCacheTable();
1315 constexpr uint32_t PROPERTY_INDEX = 2;
1316 constexpr char property[] = "hello";
1317 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1318 ASSERT_TRUE(res);
1319
1320 constexpr uint32_t QUERY_PROPERTY_INDEX = 2;
1321 res = ExternalStringCache::HasCachedString(vm_, QUERY_PROPERTY_INDEX);
1322 ASSERT_TRUE(res);
1323 }
1324
HWTEST_F_L0(JSNApiTests,NapiExternalStringCacheTest008)1325 HWTEST_F_L0(JSNApiTests, NapiExternalStringCacheTest008)
1326 {
1327 RegisterStringCacheTable();
1328 constexpr uint32_t PROPERTY_INDEX = 3;
1329 constexpr char property[] = "hello world";
1330 auto res = ExternalStringCache::SetCachedString(vm_, property, PROPERTY_INDEX);
1331 ASSERT_TRUE(res);
1332 Local<StringRef> value = ExternalStringCache::GetCachedString(vm_, PROPERTY_INDEX);
1333 ASSERT_FALSE(value->IsUndefined());
1334 EXPECT_EQ(value->ToString(vm_), property);
1335 }
1336
HWTEST_F_L0(JSNApiTests,SetExecuteMode)1337 HWTEST_F_L0(JSNApiTests, SetExecuteMode)
1338 {
1339 ecmascript::ModuleManager *moduleManager = thread_->GetModuleManager();
1340 ecmascript::ModuleExecuteMode res1 = moduleManager->GetExecuteMode();
1341 EXPECT_EQ(res1, ecmascript::ModuleExecuteMode::ExecuteZipMode);
1342
1343 JSNApi::SetExecuteBufferMode(vm_);
1344 ecmascript::ModuleExecuteMode res2 = moduleManager->GetExecuteMode();
1345 EXPECT_EQ(res2, ecmascript::ModuleExecuteMode::ExecuteBufferMode);
1346 }
1347
HWTEST_F_L0(JSNApiTests,ToEcmaObject)1348 HWTEST_F_L0(JSNApiTests, ToEcmaObject)
1349 {
1350 LocalScope scope(vm_);
1351 Local<ObjectRef> res = ObjectRef::New(vm_);
1352 res->ToEcmaObject(vm_);
1353 ASSERT_TRUE(res->IsObject(vm_));
1354 }
1355
HWTEST_F_L0(JSNApiTests,GetValueInt64)1356 HWTEST_F_L0(JSNApiTests, GetValueInt64)
1357 {
1358 LocalScope scope(vm_);
1359 bool isNumber = true;
1360 int32_t input = 4;
1361 Local<IntegerRef> res = IntegerRef::New(vm_, input);
1362 res->ToBigInt(vm_);
1363 ASSERT_TRUE(res->GetValueInt64(isNumber));
1364 res->ToNumber(vm_);
1365 ASSERT_TRUE(res->GetValueInt64(isNumber));
1366 isNumber = false;
1367 ASSERT_TRUE(res->GetValueInt64(isNumber));
1368 }
1369
HWTEST_F_L0(JSNApiTests,GetDataViewInfo)1370 HWTEST_F_L0(JSNApiTests, GetDataViewInfo)
1371 {
1372 LocalScope scope(vm_);
1373 Local<JSValueRef> key = StringRef::NewFromUtf8(vm_, "TestKey");
1374 bool isDataView = false;
1375 key->GetDataViewInfo(vm_, isDataView, nullptr, nullptr, nullptr, nullptr);
1376 ASSERT_FALSE(isDataView);
1377 isDataView = true;
1378 key->GetDataViewInfo(vm_, isDataView, nullptr, nullptr, nullptr, nullptr);
1379 ASSERT_FALSE(isDataView);
1380 }
1381
HWTEST_F_L0(JSNApiTests,ByteLength002)1382 HWTEST_F_L0(JSNApiTests, ByteLength002)
1383 {
1384 LocalScope scope(vm_);
1385 const int32_t length = 4; // define array length
1386 Local<ArrayBufferRef> array = ArrayBufferRef::New(vm_, length);
1387 int32_t arrayLen = array->ByteLength(vm_);
1388 EXPECT_EQ(length, arrayLen);
1389 }
1390
HWTEST_F_L0(JSNApiTests,SetData)1391 HWTEST_F_L0(JSNApiTests, SetData)
1392 {
1393 LocalScope scope(vm_);
1394 Local<FunctionRef> functioncallback = FunctionRef::New(vm_, FunctionCallback);
1395 struct Data {
1396 int32_t length;
1397 };
1398 const int32_t length = 15;
1399 Data *data = new Data();
1400 data->length = length;
1401 functioncallback->SetData(vm_, data);
1402 }
1403
HWTEST_F_L0(JSNApiTests,GetData)1404 HWTEST_F_L0(JSNApiTests, GetData)
1405 {
1406 LocalScope scope(vm_);
1407 Local<FunctionRef> functioncallback = FunctionRef::New(vm_, FunctionCallback);
1408 functioncallback->GetData(vm_);
1409 }
1410
HWTEST_F_L0(JSNApiTests,GetData002)1411 HWTEST_F_L0(JSNApiTests, GetData002)
1412 {
1413 LocalScope scope(vm_);
1414 int32_t argvLength = 10;
1415 auto ecmaRuntimeCallInfo =
1416 TestHelper::CreateEcmaRuntimeCallInfo(vm_->GetJSThread(), JSTaggedValue::Undefined(), argvLength);
1417 JsiRuntimeCallInfo *jsiRuntimeCallInfo = reinterpret_cast<JsiRuntimeCallInfo *>(ecmaRuntimeCallInfo);
1418 jsiRuntimeCallInfo->GetData();
1419 }
1420
HWTEST_F_L0(JSNApiTests,SetStopPreLoadSoCallback)1421 HWTEST_F_L0(JSNApiTests, SetStopPreLoadSoCallback)
1422 {
1423 auto callback = []()->void {
1424 LOG_FULL(INFO) << "Call stopPreLoadSoCallback";
1425 };
1426 JSNApi::SetStopPreLoadSoCallback(vm_, callback);
1427 auto stopPreLoadCallbacks = vm_->GetStopPreLoadCallbacks();
1428 EXPECT_EQ(stopPreLoadCallbacks.size(), 1);
1429 vm_->StopPreLoadSoOrAbc();
1430
1431 stopPreLoadCallbacks = vm_->GetStopPreLoadCallbacks();
1432 EXPECT_EQ(stopPreLoadCallbacks.size(), 0);
1433 }
1434
HWTEST_F_L0(JSNApiTests,UpdatePkgContextInfoList)1435 HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoList)
1436 {
1437 std::map<std::string, std::vector<std::vector<std::string>>> pkgList;
1438 std::vector<std::string> entryList = {
1439 "entry",
1440 "packageName", "entry",
1441 "bundleName", "",
1442 "moduleName", "",
1443 "version", "",
1444 "entryPath", "src/main/",
1445 "isSO", "false"
1446 };
1447 pkgList["entry"] = {entryList};
1448 JSNApi::SetpkgContextInfoList(vm_, pkgList);
1449
1450 std::map<std::string, std::vector<std::vector<std::string>>> newPkgList;
1451 std::vector<std::string> hspList = {
1452 "hsp",
1453 "packageName", "hsp",
1454 "bundleName", "",
1455 "moduleName", "",
1456 "version", "1.1.0",
1457 "entryPath", "Index.ets",
1458 "isSO", "false"
1459 };
1460 newPkgList["hsp"] = {hspList};
1461 JSNApi::UpdatePkgContextInfoList(vm_, newPkgList);
1462
1463 CMap<CString, CMap<CString, CVector<CString>>> vmPkgList = vm_->GetPkgContextInfoList();
1464 EXPECT_EQ(vmPkgList.size(), 2);
1465 EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 12);
1466 EXPECT_EQ(vmPkgList["hsp"].size(), 1);
1467 EXPECT_EQ(vmPkgList["hsp"]["hsp"].size(), 12);
1468 }
1469
HWTEST_F_L0(JSNApiTests,UpdatePkgNameList)1470 HWTEST_F_L0(JSNApiTests, UpdatePkgNameList)
1471 {
1472 std::map<std::string, std::string> pkgNameList;
1473 pkgNameList["moduleName1"] = "pkgName1";
1474 JSNApi::SetPkgNameList(vm_, pkgNameList);
1475
1476 std::map<std::string, std::string> newPkgNameList;
1477 newPkgNameList["moduleName2"] = "pkgName2";
1478 JSNApi::UpdatePkgNameList(vm_, newPkgNameList);
1479
1480 CMap<CString, CString> vmPkgNameList = vm_->GetPkgNameList();
1481 EXPECT_EQ(vmPkgNameList.size(), 2);
1482 EXPECT_EQ(vmPkgNameList["moduleName1"], "pkgName1");
1483 EXPECT_EQ(vmPkgNameList["moduleName2"], "pkgName2");
1484 }
1485
HWTEST_F_L0(JSNApiTests,UpdatePkgAliasList)1486 HWTEST_F_L0(JSNApiTests, UpdatePkgAliasList)
1487 {
1488 std::map<std::string, std::string> aliasNameList;
1489 aliasNameList["aliasName1"] = "pkgName1";
1490 JSNApi::SetPkgAliasList(vm_, aliasNameList);
1491
1492 std::map<std::string, std::string> newAliasNameList;
1493 newAliasNameList["aliasName2"] = "pkgName2";
1494 JSNApi::UpdatePkgAliasList(vm_, newAliasNameList);
1495
1496 CMap<CString, CString> vmAliasNameList = vm_->GetPkgAliasList();
1497 EXPECT_EQ(vmAliasNameList.size(), 2);
1498 EXPECT_EQ(vmAliasNameList["aliasName1"], "pkgName1");
1499 EXPECT_EQ(vmAliasNameList["aliasName2"], "pkgName2");
1500 }
1501
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest001)1502 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest001)
1503 {
1504 LocalScope scope(vm_);
1505 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1506 Local<ArrayRef> array = ArrayRef::New(vm_, ARRAY_LENGTH);
1507 Local<JSValueRef> value(array);
1508 bool isJSArray = value->IsJSArray(vm_);
1509 ASSERT_EQ(isJSArray, true);
1510
1511 bool isPendingException = true;
1512 bool isArrayOrSharedArray = false;
1513 uint32_t arrayLength = 0;
1514 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1515 ASSERT_EQ(isPendingException, false);
1516 ASSERT_EQ(isArrayOrSharedArray, true);
1517 ASSERT_EQ(arrayLength, ARRAY_LENGTH);
1518 }
1519
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest002)1520 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest002)
1521 {
1522 LocalScope scope(vm_);
1523 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1524 Local<SendableArrayRef> sArray = SendableArrayRef::New(vm_, ARRAY_LENGTH);
1525 Local<JSValueRef> value(sArray);
1526 bool isSArray = value->IsSharedArray(vm_);
1527 ASSERT_EQ(isSArray, true);
1528
1529 bool isPendingException = true;
1530 bool isArrayOrSharedArray = false;
1531 uint32_t arrayLength = 0;
1532 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1533 ASSERT_EQ(isPendingException, false);
1534 ASSERT_EQ(isArrayOrSharedArray, true);
1535 ASSERT_EQ(arrayLength, ARRAY_LENGTH);
1536 }
1537
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest003)1538 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest003)
1539 {
1540 LocalScope scope(vm_);
1541 Local<ObjectRef> object = ObjectRef::New(vm_);
1542 Local<JSValueRef> value(object);
1543 bool isObject = value->IsObject(vm_);
1544 ASSERT_EQ(isObject, true);
1545
1546 bool isPendingException = true;
1547 bool isArrayOrSharedArray = false;
1548 const uint32_t INIT_VALUE = 10; // 10 means a randon initial value
1549 uint32_t arrayLength = INIT_VALUE;
1550 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1551 ASSERT_EQ(isPendingException, false);
1552 ASSERT_EQ(isArrayOrSharedArray, false);
1553 ASSERT_EQ(arrayLength, INIT_VALUE);
1554 }
1555
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest004)1556 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest004)
1557 {
1558 LocalScope scope(vm_);
1559 // create array
1560 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1561 Local<ArrayRef> array = ArrayRef::New(vm_, ARRAY_LENGTH);
1562 Local<JSValueRef> value(array);
1563 bool isJSArray = value->IsJSArray(vm_);
1564 ASSERT_EQ(isJSArray, true);
1565
1566 // throw error in thread
1567 Local<JSValueRef> error = Exception::Error(vm_, StringRef::NewFromUtf8(vm_, ERROR_MESSAGE));
1568 ASSERT_EQ(error->IsError(vm_), true);
1569 JSNApi::ThrowException(vm_, error);
1570 JSThread *thread = vm_->GetJSThread();
1571 ASSERT_EQ(thread->HasPendingException(), true);
1572
1573 // test TryGetArrayLength
1574 bool isPendingException = false;
1575 bool isArrayOrSharedArray = false;
1576 uint32_t arrayLength = ARRAY_LENGTH;
1577 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1578 ASSERT_EQ(isPendingException, true);
1579 ASSERT_EQ(isArrayOrSharedArray, true);
1580 ASSERT_EQ(arrayLength, 0);
1581
1582 // clear exception
1583 JSNApi::GetAndClearUncaughtException(vm_);
1584 ASSERT_EQ(thread->HasPendingException(), false);
1585 }
1586
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest005)1587 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest005)
1588 {
1589 LocalScope scope(vm_);
1590 // create array
1591 const uint32_t ARRAY_LENGTH = 10; // 10 means array length
1592 Local<SendableArrayRef> sArray = SendableArrayRef::New(vm_, ARRAY_LENGTH);
1593 Local<JSValueRef> value(sArray);
1594 bool isSArray = value->IsSharedArray(vm_);
1595 ASSERT_EQ(isSArray, true);
1596
1597 // throw error in thread
1598 Local<JSValueRef> error = Exception::Error(vm_, StringRef::NewFromUtf8(vm_, ERROR_MESSAGE));
1599 ASSERT_EQ(error->IsError(vm_), true);
1600 JSNApi::ThrowException(vm_, error);
1601 JSThread *thread = vm_->GetJSThread();
1602 ASSERT_EQ(thread->HasPendingException(), true);
1603
1604 // test TryGetArrayLength
1605 bool isPendingException = false;
1606 bool isArrayOrSharedArray = false;
1607 uint32_t arrayLength = ARRAY_LENGTH;
1608 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1609 ASSERT_EQ(isPendingException, true);
1610 ASSERT_EQ(isArrayOrSharedArray, true);
1611 ASSERT_EQ(arrayLength, 0);
1612
1613 // clear exception
1614 JSNApi::GetAndClearUncaughtException(vm_);
1615 ASSERT_EQ(thread->HasPendingException(), false);
1616 }
1617
HWTEST_F_L0(JSNApiTests,TryGetArrayLengthTest006)1618 HWTEST_F_L0(JSNApiTests, TryGetArrayLengthTest006)
1619 {
1620 LocalScope scope(vm_);
1621 Local<ObjectRef> object = ObjectRef::New(vm_);
1622 Local<JSValueRef> value(object);
1623 bool isObject = value->IsObject(vm_);
1624 ASSERT_EQ(isObject, true);
1625
1626 // throw error in thread
1627 Local<JSValueRef> error = Exception::Error(vm_, StringRef::NewFromUtf8(vm_, ERROR_MESSAGE));
1628 ASSERT_EQ(error->IsError(vm_), true);
1629 JSNApi::ThrowException(vm_, error);
1630 JSThread *thread = vm_->GetJSThread();
1631 ASSERT_EQ(thread->HasPendingException(), true);
1632
1633 // test TryGetArrayLength
1634 bool isPendingException = false;
1635 bool isArrayOrSharedArray = true;
1636 const uint32_t INIT_VALUE = 10; // 10 means a randon initial value
1637 uint32_t arrayLength = INIT_VALUE;
1638 value->TryGetArrayLength(vm_, &isPendingException, &isArrayOrSharedArray, &arrayLength);
1639 ASSERT_EQ(isPendingException, true);
1640 ASSERT_EQ(isArrayOrSharedArray, false);
1641 ASSERT_EQ(arrayLength, INIT_VALUE);
1642
1643 // clear exception
1644 JSNApi::GetAndClearUncaughtException(vm_);
1645 ASSERT_EQ(thread->HasPendingException(), false);
1646 }
1647
1648 /**
1649 * @tc.number: ffi_interface_api_147
1650 * @tc.name: UpdateStackInfo
1651 * @tc.desc: Used to verify whether the function of update stack info was successful.
1652 * @tc.type: FUNC
1653 * @tc.require: parameter
1654 */
HWTEST_F_L0(JSNApiTests,UpdateStackInfo)1655 HWTEST_F_L0(JSNApiTests, UpdateStackInfo)
1656 {
1657 LocalScope scope(vm_);
1658 StackInfo stackInfo = { 0x10000, 0 };
1659 uint64_t currentStackLimit = vm_->GetJSThread()->GetStackLimit();
1660 JSNApi::UpdateStackInfo(vm_, &stackInfo, 0);
1661 ASSERT_EQ(vm_->GetJSThread()->GetStackLimit(), 0x10000);
1662 JSNApi::UpdateStackInfo(vm_, &stackInfo, 1);
1663 ASSERT_EQ(vm_->GetJSThread()->GetStackLimit(), currentStackLimit);
1664 JSNApi::UpdateStackInfo(vm_, nullptr, 0);
1665 ASSERT_EQ(vm_->GetJSThread()->GetStackLimit(), currentStackLimit);
1666 }
1667
HWTEST_F_L0(JSNApiTests,JSNApi_CreateContext001)1668 HWTEST_F_L0(JSNApiTests, JSNApi_CreateContext001)
1669 {
1670 LocalScope scope(vm_);
1671 Local<JSValueRef> contextValue = JSNApi::CreateContext(vm_);
1672 EXPECT_TRUE(contextValue->IsHeapObject());
1673 EXPECT_TRUE(contextValue->IsJsGlobalEnv(vm_));
1674 }
1675
HWTEST_F_L0(JSNApiTests,JSNApi_GetCurrentContext001)1676 HWTEST_F_L0(JSNApiTests, JSNApi_GetCurrentContext001)
1677 {
1678 LocalScope scope(vm_);
1679 Local<JSValueRef> contextValue = JSNApi::GetCurrentContext(vm_);
1680 EXPECT_TRUE(contextValue->IsHeapObject());
1681 EXPECT_TRUE(contextValue->IsJsGlobalEnv(vm_));
1682 }
1683
HWTEST_F_L0(JSNApiTests,JSNApi_Local_Operator_equal001)1684 HWTEST_F_L0(JSNApiTests, JSNApi_Local_Operator_equal001)
1685 {
1686 LocalScope scope(vm_);
1687 Local<JSValueRef> contextValue = JSNApi::CreateContext(vm_);
1688 Local<JSValueRef> newContext = Local<JSValueRef>(contextValue);
1689 EXPECT_TRUE(contextValue == newContext);
1690 }
1691
HWTEST_F_L0(JSNApiTests,JSNApi_SwitchContext001)1692 HWTEST_F_L0(JSNApiTests, JSNApi_SwitchContext001)
1693 {
1694 LocalScope scope(vm_);
1695 Local<JSValueRef> contextValue = JSNApi::CreateContext(vm_);
1696 EXPECT_TRUE(contextValue->IsHeapObject());
1697 EXPECT_TRUE(contextValue->IsJsGlobalEnv(vm_));
1698 Local<JSValueRef> currentContext = JSNApi::GetCurrentContext(vm_);
1699 EXPECT_FALSE(currentContext == contextValue);
1700
1701 JSNApi::SwitchContext(vm_, contextValue);
1702 Local<JSValueRef> switchedContext = JSNApi::GetCurrentContext(vm_);
1703 EXPECT_TRUE(switchedContext == contextValue);
1704 }
1705
HWTEST_F_L0(JSNApiTests,XRefGlobalHandleAddr)1706 HWTEST_F_L0(JSNApiTests, XRefGlobalHandleAddr)
1707 {
1708 JSNApi::InitHybridVMEnv(vm_);
1709 JSHandle<TaggedArray> weakRefArray = vm_->GetFactory()->NewTaggedArray(2, JSTaggedValue::Hole());
1710 uintptr_t xRefArrayAddress;
1711 vm_->SetEnableForceGC(false);
1712 {
1713 [[maybe_unused]] EcmaHandleScope scope(thread_);
1714 JSHandle<JSTaggedValue> xRefArray = JSArray::ArrayCreate(thread_, JSTaggedNumber(1));
1715 JSHandle<JSTaggedValue> normalArray = JSArray::ArrayCreate(thread_, JSTaggedNumber(2));
1716 xRefArrayAddress = JSNApiGetXRefGlobalHandleAddr(vm_, xRefArray.GetAddress());
1717 weakRefArray->Set(thread_, 0, xRefArray.GetTaggedValue().CreateAndGetWeakRef());
1718 weakRefArray->Set(thread_, 1, normalArray.GetTaggedValue().CreateAndGetWeakRef());
1719 }
1720 vm_->CollectGarbage(TriggerGCType::FULL_GC);
1721 EXPECT_TRUE(!weakRefArray->Get(thread_, 0).IsUndefined());
1722 EXPECT_TRUE(weakRefArray->Get(thread_, 1).IsUndefined());
1723
1724 JSNApiDisposeXRefGlobalHandleAddr(vm_, xRefArrayAddress);
1725 vm_->CollectGarbage(TriggerGCType::FULL_GC);
1726 vm_->SetEnableForceGC(true);
1727 EXPECT_TRUE(weakRefArray->Get(thread_, 0).IsUndefined());
1728 }
1729
HWTEST_F_L0(JSNApiTests,InitHybridVMEnv)1730 HWTEST_F_L0(JSNApiTests, InitHybridVMEnv)
1731 {
1732 LocalScope scope(vm_);
1733 JSNApi::InitHybridVMEnv(vm_);
1734
1735 auto instance = ecmascript::Runtime::GetInstance();
1736 ASSERT(instance != nullptr);
1737
1738 EXPECT_TRUE(instance->IsHybridVm());
1739 }
1740 } // namespace panda::test
1741