• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <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