• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ark_native_engine.h"
17 
18 #include "ark_native_deferred.h"
19 #include "ark_native_reference.h"
20 #include "scope_manager/native_scope_manager.h"
21 
22 #ifdef ENABLE_CONTAINER_SCOPE
23 #include "core/common/container_scope.h"
24 #endif
25 
26 #include "native_engine/native_property.h"
27 
28 #include "native_value/ark_native_array.h"
29 #include "native_value/ark_native_array_buffer.h"
30 #include "native_value/ark_native_buffer.h"
31 #include "native_value/ark_native_big_int.h"
32 #include "native_value/ark_native_boolean.h"
33 #include "native_value/ark_native_data_view.h"
34 #include "native_value/ark_native_external.h"
35 #include "native_value/ark_native_function.h"
36 #include "native_value/ark_native_number.h"
37 #include "native_value/ark_native_object.h"
38 #include "native_value/ark_native_string.h"
39 #include "native_value/ark_native_typed_array.h"
40 #include "native_value/ark_native_date.h"
41 
42 #ifdef ENABLE_HITRACE
43 #include "hitrace_meter.h"
44 #endif
45 #if !defined(PREVIEW) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
46 #include "parameters.h"
47 #endif
48 #include "securec.h"
49 #include "utils/log.h"
50 #ifdef ENABLE_HITRACE
51 #include "parameter.h"
52 #endif
53 
54 using panda::JsiRuntimeCallInfo;
55 using panda::BooleanRef;
56 using panda::ObjectRef;
57 using panda::StringRef;
58 using panda::FunctionRef;
59 using panda::PrimitiveRef;
60 using panda::JSValueRef;
61 using panda::ArrayBufferRef;
62 using panda::TypedArrayRef;
63 using panda::PromiseCapabilityRef;
64 using panda::NativePointerRef;
65 using panda::SymbolRef;
66 using panda::IntegerRef;
67 using panda::DateRef;
68 using panda::BigIntRef;
69 static constexpr auto PANDA_MAIN_FUNCTION = "_GLOBAL::func_main_0";
70 #ifdef ENABLE_HITRACE
71 constexpr auto NAPI_PROFILER_PARAM_SIZE = 10;
72 #endif
73 
74 std::string ArkNativeEngine::tempModuleName_ {""};
75 bool ArkNativeEngine::napiProfilerEnabled {false};
76 bool ArkNativeEngine::napiProfilerParamReaded {false};
77 PermissionCheckCallback ArkNativeEngine::permissionCheckCallback_ {nullptr};
78 
79 struct MoudleNameLocker {
MoudleNameLockerMoudleNameLocker80     explicit MoudleNameLocker(std::string moduleName)
81     {
82         ArkNativeEngine::tempModuleName_ = moduleName;
83     }
~MoudleNameLockerMoudleNameLocker84     ~MoudleNameLocker()
85     {
86         ArkNativeEngine::tempModuleName_ = "";
87     }
88 };
89 
ArkNativeEngine(EcmaVM * vm,void * jsEngine)90 ArkNativeEngine::ArkNativeEngine(EcmaVM* vm, void* jsEngine) : NativeEngine(jsEngine), vm_(vm), topScope_(vm)
91 {
92     HILOG_DEBUG("ArkNativeEngine::ArkNativeEngine");
93 #ifdef ENABLE_HITRACE
94     if (!ArkNativeEngine::napiProfilerParamReaded) {
95         char napiProfilerParam[NAPI_PROFILER_PARAM_SIZE] = {0};
96         int ret = GetParameter("persist.hiviewdfx.napiprofiler.enabled", "false",
97             napiProfilerParam, sizeof(napiProfilerParam));
98         if (ret > 0 && strcmp(napiProfilerParam, "true") == 0) {
99             ArkNativeEngine::napiProfilerEnabled = true;
100         }
101         ArkNativeEngine::napiProfilerParamReaded = true;
102     }
103 #endif
104     LocalScope scope(vm_);
105     Local<StringRef> requireInternalName = StringRef::NewFromUtf8(vm, "requireInternal");
106     void* requireData = static_cast<void*>(this);
107 
108     Local<FunctionRef> requireNapi =
109         FunctionRef::New(
110             vm,
111             [](JsiRuntimeCallInfo *info) -> Local<JSValueRef> {
112                 EcmaVM *ecmaVm = info->GetVM();
113                 panda::EscapeLocalScope scope(ecmaVm);
114                 NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
115                 ArkNativeEngine* arkNativeEngine = static_cast<ArkNativeEngine*>(info->GetData());
116                 Local<StringRef> moduleName(info->GetCallArgRef(0));
117                 NativeModule* module = nullptr;
118                 bool isAppModule = false;
119 #ifdef IOS_PLATFORM
120                 module =
121                     moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, false, false);
122 #else
123                 const uint32_t lengthMax = 2;
124                 if (info->GetArgsNumber() >= lengthMax) {
125                     Local<BooleanRef> ret(info->GetCallArgRef(1));
126                     isAppModule = ret->Value();
127                 }
128                 if (info->GetArgsNumber() == 3) { // 3:Determine if the number of parameters is equal to 3
129                     Local<StringRef> path(info->GetCallArgRef(2)); // 2:Take the second parameter
130                     module =
131                         moduleManager->LoadNativeModule(moduleName->ToString().c_str(), path->ToString().c_str(),
132                             isAppModule, false);
133                 } else if (info->GetArgsNumber() == 4) { // 4:Determine if the number of parameters is equal to 4
134                     Local<StringRef> path(info->GetCallArgRef(2)); // 2:Take the second parameter
135                     Local<StringRef> relativePath(info->GetCallArgRef(3)); // 3:Take the second parameter
136                     module =
137                         moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, isAppModule, false,
138                             relativePath->ToString().c_str());
139                 } else {
140                     module =
141                         moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, isAppModule, false);
142                 }
143 #endif
144                 Local<JSValueRef> exports(JSValueRef::Undefined(ecmaVm));
145                 if (module != nullptr) {
146                     auto it = arkNativeEngine->loadedModules_.find(module);
147                     if (it != arkNativeEngine->loadedModules_.end()) {
148                         return scope.Escape(it->second.ToLocal(ecmaVm));
149                     }
150                     std::string strModuleName = moduleName->ToString();
151                     moduleManager->SetNativeEngine(strModuleName, arkNativeEngine);
152                     MoudleNameLocker nameLocker(strModuleName);
153 
154                     if (module->jsCode == nullptr && module->getABCCode != nullptr) {
155                         module->getABCCode(&module->jsCode, &module->jsCodeLen);
156                     }
157                     if (module->jsCode != nullptr) {
158                         char fileName[NAPI_PATH_MAX] = { 0 };
159                         const char* name = module->name;
160                         if (sprintf_s(fileName, sizeof(fileName), "lib%s.z.so/%s.js", name, name) == -1) {
161                             HILOG_ERROR("sprintf_s file name failed");
162                             return scope.Escape(exports);
163                         }
164                         HILOG_DEBUG("load js code from %{public}s", fileName);
165                         NativeValue* exportObject = arkNativeEngine->LoadArkModule(module->jsCode,
166                             module->jsCodeLen, fileName);
167                         if (exportObject == nullptr) {
168                             HILOG_ERROR("load module failed");
169                             return scope.Escape(exports);
170                         } else {
171                             Global<JSValueRef> globalExports = *exportObject;
172                             exports = globalExports.ToLocal(ecmaVm);
173                             arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports);
174                         }
175                     } else if (module->registerCallback != nullptr) {
176                         NativeScopeManager* scopeManager = arkNativeEngine->GetScopeManager();
177                         if (scopeManager == nullptr) {
178                             HILOG_ERROR("scope manager is null");
179                             return scope.Escape(exports);
180                         }
181                         NativeScope* nativeScope = scopeManager->Open();
182                         NativeValue* exportObject = arkNativeEngine->CreateObject();
183                         if (!arkNativeEngine) {
184                             HILOG_ERROR("init module failed");
185                             scopeManager->Close(nativeScope);
186                             return scope.Escape(exports);
187                         }
188 #ifdef ENABLE_HITRACE
189                         StartTrace(HITRACE_TAG_ACE, "NAPI module init, name = " + std::string(module->name));
190 #endif
191                         ArkNativeObject* exportObj = reinterpret_cast<ArkNativeObject*>(exportObject);
192                         arkNativeEngine->SetModuleName(exportObj, module->name);
193                         module->registerCallback(arkNativeEngine, exportObject);
194 #ifdef ENABLE_HITRACE
195                         FinishTrace(HITRACE_TAG_ACE);
196 #endif
197                         Global<JSValueRef> globalExports = *exportObject;
198                         exports = globalExports.ToLocal(ecmaVm);
199                         arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports);
200                         scopeManager->Close(nativeScope);
201                     } else {
202                         HILOG_ERROR("init module failed");
203                         return scope.Escape(exports);
204                     }
205                 }
206                 return scope.Escape(exports);
207             },
208             nullptr,
209             requireData);
210 
211     Local<FunctionRef> requireInternal =
212         FunctionRef::New(
213             vm,
214             [](JsiRuntimeCallInfo *info) -> Local<JSValueRef> {
215                 EcmaVM *ecmaVm = info->GetVM();
216                 panda::EscapeLocalScope scope(ecmaVm);
217                 NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
218                 ArkNativeEngine* arkNativeEngine = static_cast<ArkNativeEngine*>(info->GetData());
219                 Local<StringRef> moduleName(info->GetCallArgRef(0));
220                 NativeModule* module = moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, false);
221                 Local<JSValueRef> exports(JSValueRef::Undefined(ecmaVm));
222                 MoudleNameLocker nameLocker(moduleName->ToString());
223                 if (module != nullptr && arkNativeEngine) {
224                     auto it = arkNativeEngine->loadedModules_.find(module);
225                     if (it != arkNativeEngine->loadedModules_.end()) {
226                         return scope.Escape(it->second.ToLocal(ecmaVm));
227                     }
228                     std::string strModuleName = moduleName->ToString();
229                     moduleManager->SetNativeEngine(strModuleName, arkNativeEngine);
230                     NativeScopeManager* scopeManager = arkNativeEngine->GetScopeManager();
231                     if (scopeManager == nullptr) {
232                         HILOG_ERROR("scope manager is null");
233                         return scope.Escape(exports);
234                     }
235                     NativeScope* nativeScope = scopeManager->Open();
236                     NativeValue* exportObject = arkNativeEngine->CreateObject();
237                     if (exportObject != nullptr) {
238                         if (!arkNativeEngine) {
239                             HILOG_ERROR("exportObject is nullptr");
240                             scopeManager->Close(nativeScope);
241                             return scope.Escape(exports);
242                         }
243                         ArkNativeObject* exportObj = reinterpret_cast<ArkNativeObject*>(exportObject);
244                         arkNativeEngine->SetModuleName(exportObj, module->name);
245                         module->registerCallback(arkNativeEngine, exportObject);
246                         Global<JSValueRef> globalExports = *exportObject;
247                         exports = globalExports.ToLocal(ecmaVm);
248                         arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports);
249                         scopeManager->Close(nativeScope);
250                     } else {
251                         HILOG_ERROR("exportObject is nullptr");
252                         scopeManager->Close(nativeScope);
253                         return scope.Escape(exports);
254                     }
255                 }
256                 return scope.Escape(exports);
257             },
258             nullptr,
259             requireData);
260 
261     Local<ObjectRef> global = panda::JSNApi::GetGlobalObject(vm);
262 #if !defined(PREVIEW)
263     Local<StringRef> requireName = StringRef::NewFromUtf8(vm, "requireNapi");
264     global->Set(vm, requireName, requireNapi);
265 #else
266     Local<StringRef> requireNapiPreview = StringRef::NewFromUtf8(vm, "requireNapiPreview");
267     global->Set(vm, requireNapiPreview, requireNapi);
268 #endif
269     global->Set(vm, requireInternalName, requireInternal);
270     JSNApi::SetNativePtrGetter(vm, reinterpret_cast<void*>(ArkNativeFunction::GetNativePtrCallBack));
271     // need to call init of base class.
272     NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
273     JSNApi::SetUnloadNativeModuleCallback(vm, std::bind(&NativeModuleManager::UnloadNativeModule,
274         moduleManager, std::placeholders::_1));
275     Init();
276     panda::JSNApi::SetLoop(vm, loop_);
277 }
278 
~ArkNativeEngine()279 ArkNativeEngine::~ArkNativeEngine()
280 {
281     HILOG_INFO("ArkNativeEngine::~ArkNativeEngine");
282     Deinit();
283     // Free cached objects
284     for (auto&& [module, exportObj] : loadedModules_) {
285         exportObj.FreeGlobalHandleAddr();
286     }
287     // Free callbackRef
288     if (promiseRejectCallbackRef_ != nullptr) {
289         delete promiseRejectCallbackRef_;
290     }
291     if (checkCallbackRef_ != nullptr) {
292         delete checkCallbackRef_;
293     }
294 }
295 
GetEcmaVm() const296 const EcmaVM* ArkNativeEngine::GetEcmaVm() const
297 {
298     return vm_;
299 }
300 
GetModuleFromName(const std::string & moduleName,bool isAppModule,const std::string & id,const std::string & param,const std::string & instanceName,void ** instance)301 panda::Local<panda::ObjectRef> ArkNativeEngine::GetModuleFromName(
302     const std::string& moduleName, bool isAppModule, const std::string& id, const std::string& param,
303     const std::string& instanceName, void** instance)
304 {
305     panda::EscapeLocalScope scope(vm_);
306     Local<ObjectRef> exports(JSValueRef::Undefined(vm_));
307     NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
308     NativeModule* module = moduleManager->LoadNativeModule(moduleName.c_str(), nullptr, isAppModule);
309     if (module != nullptr) {
310         NativeChunk& chunk = GetNativeChunk();
311         NativeValue* idValue = chunk.New<ArkNativeString>(this, id.c_str(), id.size());
312         NativeValue* paramValue = chunk.New<ArkNativeString>(this, param.c_str(), param.size());
313         NativeValue* exportObject = chunk.New<ArkNativeObject>(this);
314 
315         NativePropertyDescriptor idProperty, paramProperty;
316         idProperty.utf8name = "id";
317         idProperty.value = idValue;
318         paramProperty.utf8name = "param";
319         paramProperty.value = paramValue;
320 
321         ArkNativeObject* exportObj = reinterpret_cast<ArkNativeObject*>(exportObject);
322         SetModuleName(exportObj, module->name);
323         exportObj->DefineProperty(idProperty);
324         exportObj->DefineProperty(paramProperty);
325         MoudleNameLocker nameLocker(module->name);
326         module->registerCallback(this, exportObject);
327 
328         napi_value nExport = reinterpret_cast<napi_value>(exportObject);
329         napi_value exportInstance = nullptr;
330         napi_status status = napi_get_named_property(
331             reinterpret_cast<napi_env>(this), nExport, instanceName.c_str(), &exportInstance);
332         if (status != napi_ok) {
333             HILOG_ERROR("GetModuleFromName napi_get_named_property status != napi_ok");
334         }
335 
336         status = napi_unwrap(reinterpret_cast<napi_env>(this), exportInstance, reinterpret_cast<void**>(instance));
337         if (status != napi_ok) {
338             HILOG_ERROR("GetModuleFromName napi_unwrap status != napi_ok");
339         }
340 
341         Global<ObjectRef> globalExports = *exportObject;
342         exports = globalExports.ToLocal(vm_);
343     }
344     return scope.Escape(exports);
345 }
346 
LoadModuleByName(const std::string & moduleName,bool isAppModule,const std::string & param,const std::string & instanceName,void * instance,const std::string & path)347 panda::Local<panda::ObjectRef> ArkNativeEngine::LoadModuleByName(const std::string& moduleName, bool isAppModule,
348     const std::string& param, const std::string& instanceName, void* instance, const std::string& path)
349 {
350     panda::EscapeLocalScope scope(vm_);
351     Local<ObjectRef> exports(JSValueRef::Undefined(vm_));
352     NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
353     NativeModule* module =
354         moduleManager->LoadNativeModule(moduleName.c_str(), path.empty() ? nullptr : path.c_str(), isAppModule);
355     if (module != nullptr) {
356         NativeValue* exportObject = new ArkNativeObject(this);
357         ArkNativeObject* exportObj = reinterpret_cast<ArkNativeObject*>(exportObject);
358 
359         NativePropertyDescriptor paramProperty, instanceProperty;
360 
361         NativeValue* paramValue =
362             new ArkNativeString(this, param.c_str(), param.size());
363         paramProperty.utf8name = "param";
364         paramProperty.value = paramValue;
365 
366         auto instanceValue = new ArkNativeObject(this);
367         instanceValue->SetNativePointer(instance, nullptr, nullptr);
368         instanceProperty.utf8name = instanceName.c_str();
369         instanceProperty.value = instanceValue;
370 
371         SetModuleName(exportObj, module->name);
372         exportObj->DefineProperty(paramProperty);
373         exportObj->DefineProperty(instanceProperty);
374 
375         MoudleNameLocker nameLocker(module->name);
376         module->registerCallback(this, exportObject);
377         Global<ObjectRef> globalExports = *exportObject;
378         exports = globalExports.ToLocal(vm_);
379     }
380     return scope.Escape(exports);
381 }
382 
Loop(LoopMode mode,bool needSync)383 void ArkNativeEngine::Loop(LoopMode mode, bool needSync)
384 {
385     LocalScope scope(vm_);
386     NativeEngine::Loop(mode, needSync);
387     panda::JSNApi::ExecutePendingJob(vm_);
388 }
389 
SetModuleName(ArkNativeObject * nativeObj,std::string moduleName)390 inline void ArkNativeEngine::SetModuleName(ArkNativeObject *nativeObj, std::string moduleName)
391 {
392 #ifdef ENABLE_HITRACE
393     if (ArkNativeEngine::napiProfilerEnabled) {
394         nativeObj->SetModuleName(moduleName);
395     }
396 #endif
397 }
398 
GetGlobal()399 NativeValue* ArkNativeEngine::GetGlobal()
400 {
401     LocalScope scope(vm_);
402     Local<ObjectRef> value = panda::JSNApi::GetGlobalObject(vm_);
403     return ArkValueToNativeValue(this, value);
404 }
405 
CreateNull()406 NativeValue* ArkNativeEngine::CreateNull()
407 {
408     LocalScope scope(vm_);
409     Local<PrimitiveRef> value = JSValueRef::Null(vm_);
410     return GetNativeChunk().New<ArkNativeValue>(this, value);
411 }
412 
CreateUndefined()413 NativeValue* ArkNativeEngine::CreateUndefined()
414 {
415     LocalScope scope(vm_);
416     Local<PrimitiveRef> value = JSValueRef::Undefined(vm_);
417     return GetNativeChunk().New<ArkNativeValue>(this, value);
418 }
419 
CreateBoolean(bool value)420 NativeValue* ArkNativeEngine::CreateBoolean(bool value)
421 {
422     return GetNativeChunk().New<ArkNativeBoolean>(this, value);
423 }
424 
CreateNumber(int32_t value)425 NativeValue* ArkNativeEngine::CreateNumber(int32_t value)
426 {
427     return GetNativeChunk().New<ArkNativeNumber>(this, value);
428 }
429 
CreateNumber(uint32_t value)430 NativeValue* ArkNativeEngine::CreateNumber(uint32_t value)
431 {
432     return GetNativeChunk().New<ArkNativeNumber>(this, value);
433 }
434 
CreateNumber(int64_t value)435 NativeValue* ArkNativeEngine::CreateNumber(int64_t value)
436 {
437     return GetNativeChunk().New<ArkNativeNumber>(this, value);
438 }
439 
CreateNumber(double value)440 NativeValue* ArkNativeEngine::CreateNumber(double value)
441 {
442     return GetNativeChunk().New<ArkNativeNumber>(this, value);
443 }
444 
CreateBigInt(int64_t value)445 NativeValue* ArkNativeEngine::CreateBigInt(int64_t value)
446 {
447     return GetNativeChunk().New<ArkNativeBigInt>(this, value);
448 }
449 
CreateBigInt(uint64_t value)450 NativeValue* ArkNativeEngine::CreateBigInt(uint64_t value)
451 {
452     return GetNativeChunk().New<ArkNativeBigInt>(this, value, true);
453 }
454 
CreateString(const char * value,size_t length)455 NativeValue* ArkNativeEngine::CreateString(const char* value, size_t length)
456 {
457     return GetNativeChunk().New<ArkNativeString>(this, value, length);
458 }
459 
CreateString16(const char16_t * value,size_t length)460 NativeValue* ArkNativeEngine::CreateString16(const char16_t* value, size_t length)
461 {
462     return GetNativeChunk().New<ArkNativeString>(this, value, length);
463 }
464 
CreateSymbol(NativeValue * value)465 NativeValue* ArkNativeEngine::CreateSymbol(NativeValue* value)
466 {
467     LocalScope scope(vm_);
468     Global<StringRef> str = *value;
469     Local<SymbolRef> symbol = SymbolRef::New(vm_, str.ToLocal(vm_));
470     return GetNativeChunk().New<ArkNativeValue>(this, symbol);
471 }
472 
CreateExternal(void * value,NativeFinalize callback,void * hint,size_t nativeBindingSize)473 NativeValue* ArkNativeEngine::CreateExternal(void* value, NativeFinalize callback, void* hint,
474     size_t nativeBindingSize)
475 {
476     return GetNativeChunk().New<ArkNativeExternal>(this, value, callback, hint, nativeBindingSize);
477 }
478 
CreateObject()479 NativeValue* ArkNativeEngine::CreateObject()
480 {
481     return GetNativeChunk().New<ArkNativeObject>(this);
482 }
483 
CreateFunction(const char * name,size_t length,NativeCallback cb,void * value)484 NativeValue* ArkNativeEngine::CreateFunction(const char* name, size_t length, NativeCallback cb, void* value)
485 {
486     return GetNativeChunk().New<ArkNativeFunction>(this, name, length, cb, value);
487 }
488 
CreateArray(size_t length)489 NativeValue* ArkNativeEngine::CreateArray(size_t length)
490 {
491     return GetNativeChunk().New<ArkNativeArray>(this, length);
492 }
493 
CreateArrayBuffer(void ** value,size_t length)494 NativeValue* ArkNativeEngine::CreateArrayBuffer(void** value, size_t length)
495 {
496     return GetNativeChunk().New<ArkNativeArrayBuffer>(this, (uint8_t**)value, length);
497 }
498 
CreateArrayBufferExternal(void * value,size_t length,NativeFinalize cb,void * hint)499 NativeValue* ArkNativeEngine::CreateArrayBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint)
500 {
501     return GetNativeChunk().New<ArkNativeArrayBuffer>(this, (uint8_t*)value, length, cb, hint);
502 }
503 
CreateTypedArray(NativeTypedArrayType type,NativeValue * value,size_t length,size_t offset)504 NativeValue* ArkNativeEngine::CreateTypedArray(
505     NativeTypedArrayType type, NativeValue* value, size_t length, size_t offset)
506 {
507     LocalScope scope(vm_);
508     Global<ArrayBufferRef> globalBuffer = *value;
509     Local<ArrayBufferRef> buffer = globalBuffer.ToLocal(vm_);
510     Local<TypedArrayRef> typedArray(JSValueRef::Undefined(vm_));
511 
512     switch (type) {
513         case NATIVE_INT8_ARRAY:
514             typedArray = panda::Int8ArrayRef::New(vm_, buffer, offset, length);
515             break;
516         case NATIVE_UINT8_ARRAY:
517             typedArray = panda::Uint8ArrayRef::New(vm_, buffer, offset, length);
518             break;
519         case NATIVE_UINT8_CLAMPED_ARRAY:
520             typedArray = panda::Uint8ClampedArrayRef::New(vm_, buffer, offset, length);
521             break;
522         case NATIVE_INT16_ARRAY:
523             typedArray = panda::Int16ArrayRef::New(vm_, buffer, offset, length);
524             break;
525         case NATIVE_UINT16_ARRAY:
526             typedArray = panda::Uint16ArrayRef::New(vm_, buffer, offset, length);
527             break;
528         case NATIVE_INT32_ARRAY:
529             typedArray = panda::Int32ArrayRef::New(vm_, buffer, offset, length);
530             break;
531         case NATIVE_UINT32_ARRAY:
532             typedArray = panda::Uint32ArrayRef::New(vm_, buffer, offset, length);
533             break;
534         case NATIVE_FLOAT32_ARRAY:
535             typedArray = panda::Float32ArrayRef::New(vm_, buffer, offset, length);
536             break;
537         case NATIVE_FLOAT64_ARRAY:
538             typedArray = panda::Float64ArrayRef::New(vm_, buffer, offset, length);
539             break;
540         case NATIVE_BIGINT64_ARRAY:
541             typedArray = panda::BigInt64ArrayRef::New(vm_, buffer, offset, length);
542             break;
543         case NATIVE_BIGUINT64_ARRAY:
544             typedArray = panda::BigUint64ArrayRef::New(vm_, buffer, offset, length);
545             break;
546         default:
547             return nullptr;
548     }
549     return GetNativeChunk().New<ArkNativeTypedArray>(this, typedArray);
550 }
551 
CreateDataView(NativeValue * value,size_t length,size_t offset)552 NativeValue* ArkNativeEngine::CreateDataView(NativeValue* value, size_t length, size_t offset)
553 {
554     return GetNativeChunk().New<ArkNativeDataView>(this, value, length, offset);
555 }
556 
CreatePromise(NativeDeferred ** deferred)557 NativeValue* ArkNativeEngine::CreatePromise(NativeDeferred** deferred)
558 {
559     LocalScope scope(vm_);
560     Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
561     *deferred = new ArkNativeDeferred(this, capability);
562     return GetNativeChunk().New<ArkNativeObject>(this, capability->GetPromise(vm_));
563 }
564 
CreateError(NativeValue * code,NativeValue * message)565 NativeValue* ArkNativeEngine::CreateError(NativeValue* code, NativeValue* message)
566 {
567     LocalScope scope(vm_);
568     Local<JSValueRef> errorVal = panda::Exception::Error(vm_, *message);
569     if (code != nullptr) {
570         Local<StringRef> codeKey = StringRef::NewFromUtf8(vm_, "code");
571         Local<ObjectRef> errorObj(errorVal);
572         errorObj->Set(vm_, codeKey, *code);
573     }
574     return ArkValueToNativeValue(this, errorVal);
575 }
576 
ConcurrentCallbackFunc(Local<JSValueRef> result,bool success,void * taskInfo,void * data)577 static void ConcurrentCallbackFunc(Local<JSValueRef> result, bool success, void *taskInfo, void *data)
578 {
579     if (data == nullptr) {
580         return;
581     }
582     auto engine = static_cast<ArkNativeEngine *>(data);
583     auto concurrentCallbackFunc = engine->GetConcurrentCallbackFunc();
584     if (concurrentCallbackFunc == nullptr) {
585         return;
586     }
587     concurrentCallbackFunc(engine, ArkNativeEngine::ArkValueToNativeValue(engine, result), success, taskInfo);
588 }
589 
InitTaskPoolThread(NativeEngine * engine,NapiConcurrentCallback callback)590 bool ArkNativeEngine::InitTaskPoolThread(NativeEngine* engine, NapiConcurrentCallback callback)
591 {
592     concurrentCallbackFunc_ = callback;
593     return JSNApi::InitForConcurrentThread(vm_, ConcurrentCallbackFunc, static_cast<void *>(this));
594 }
595 
InitTaskPoolFunc(NativeEngine * engine,NativeValue * func,void * taskInfo)596 bool ArkNativeEngine::InitTaskPoolFunc(NativeEngine* engine, NativeValue* func, void* taskInfo)
597 {
598     LocalScope scope(vm_);
599     Global<JSValueRef> globalObj = *func;
600     Local<JSValueRef> function = globalObj.ToLocal(vm_);
601     return JSNApi::InitForConcurrentFunction(vm_, function, taskInfo);
602 }
603 
GetCurrentTaskInfo() const604 void* ArkNativeEngine::GetCurrentTaskInfo() const
605 {
606     return JSNApi::GetCurrentTaskInfo(vm_);
607 }
608 
CallFunction(NativeValue * thisVar,NativeValue * function,NativeValue * const * argv,size_t argc)609 NativeValue* ArkNativeEngine::CallFunction(
610     NativeValue* thisVar, NativeValue* function, NativeValue* const* argv, size_t argc)
611 {
612     if (function == nullptr) {
613         return nullptr;
614     }
615     LocalScope scope(vm_);
616     NativeScopeManager* scopeManager = GetScopeManager();
617     if (scopeManager == nullptr) {
618         HILOG_ERROR("scope manager is null");
619         return nullptr;
620     }
621     NativeScope* nativeScope = scopeManager->Open();
622     Local<JSValueRef> thisObj = JSValueRef::Undefined(vm_);
623     if (thisVar != nullptr) {
624         Global<JSValueRef> globalObj = *thisVar;
625         thisObj = globalObj.ToLocal(vm_);
626     }
627     Global<FunctionRef> funcObj = *function;
628 #ifdef ENABLE_CONTAINER_SCOPE
629     auto nativeFunction = static_cast<NativeFunction*>(function->GetInterface(NativeFunction::INTERFACE_ID));
630     if (nativeFunction == nullptr) {
631         HILOG_ERROR("nativeFunction is null");
632         return nullptr;
633     }
634     auto arkNativeFunc = static_cast<ArkNativeFunction*>(nativeFunction);
635     OHOS::Ace::ContainerScope containerScope(arkNativeFunc->GetScopeId());
636 #endif
637     std::vector<Local<JSValueRef>> args;
638     args.reserve(argc);
639     for (size_t i = 0; i < argc; i++) {
640         if (argv[i] != nullptr) {
641             Global<JSValueRef> arg = *argv[i];
642             args.emplace_back(arg.ToLocal(vm_));
643         } else {
644             args.emplace_back(JSValueRef::Undefined(vm_));
645         }
646     }
647 
648     Local<JSValueRef> value = funcObj->Call(vm_, thisObj, args.data(), argc);
649     scopeManager->Close(nativeScope);
650     if (panda::JSNApi::HasPendingException(vm_)) {
651         HILOG_ERROR("pending exception when js function called");
652         HILOG_ERROR("print exception info: ");
653         panda::JSNApi::PrintExceptionInfo(vm_);
654         return nullptr;
655     }
656 
657     return ArkValueToNativeValue(this, value);
658 }
659 
RunScript(NativeValue * script)660 NativeValue* ArkNativeEngine::RunScript(NativeValue* script)
661 {
662     return nullptr;
663 }
664 
RunScriptPath(const char * path)665 NativeValue* ArkNativeEngine::RunScriptPath(const char* path)
666 {
667     panda::JSExecutionScope executionScope(vm_);
668     LocalScope scope(vm_);
669     [[maybe_unused]] bool ret = panda::JSNApi::Execute(vm_, path, PANDA_MAIN_FUNCTION);
670     if (panda::JSNApi::HasPendingException(vm_)) {
671         HandleUncaughtException();
672         return nullptr;
673     }
674     return CreateUndefined();
675 }
676 
SuspendVMById(uint32_t tid)677 bool ArkNativeEngine::SuspendVMById(uint32_t tid)
678 {
679 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
680     return DFXJSNApi::SuspendVMById(vm_, tid);
681 #else
682     HILOG_WARN("ARK does not support dfx on windows");
683     return false;
684 #endif
685 }
686 
ResumeVMById(uint32_t tid)687 void ArkNativeEngine::ResumeVMById(uint32_t tid)
688 {
689 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
690     DFXJSNApi::ResumeVMById(vm_, tid);
691 #else
692     HILOG_WARN("ARK does not support dfx on windows");
693     return;
694 #endif
695 }
696 
697 // The security interface needs to be modified accordingly.
RunScriptBuffer(const char * path,std::vector<uint8_t> & buffer,bool isBundle)698 NativeValue* ArkNativeEngine::RunScriptBuffer(const char* path, std::vector<uint8_t>& buffer, bool isBundle)
699 {
700     panda::JSExecutionScope executionScope(vm_);
701     LocalScope scope(vm_);
702     [[maybe_unused]] bool ret = false;
703     if (isBundle) {
704         ret = panda::JSNApi::Execute(vm_, buffer.data(), buffer.size(), PANDA_MAIN_FUNCTION, path);
705     } else {
706         ret = panda::JSNApi::ExecuteModuleBuffer(vm_, buffer.data(), buffer.size(), path);
707     }
708 
709     if (panda::JSNApi::HasPendingException(vm_)) {
710         HandleUncaughtException();
711         return nullptr;
712     }
713     return CreateUndefined();
714 }
715 
RunScriptBuffer(const std::string & path,uint8_t * buffer,size_t size,bool isBundle)716 bool ArkNativeEngine::RunScriptBuffer(const std::string& path, uint8_t* buffer, size_t size, bool isBundle)
717 {
718     panda::JSExecutionScope executionScope(vm_);
719     LocalScope scope(vm_);
720     bool ret = false;
721     if (isBundle) {
722         ret = panda::JSNApi::ExecuteSecure(vm_, buffer, size, PANDA_MAIN_FUNCTION, path);
723     } else {
724         ret = panda::JSNApi::ExecuteModuleBufferSecure(vm_, buffer, size, path);
725     }
726 
727     if (panda::JSNApi::HasPendingException(vm_)) {
728         HandleUncaughtException();
729         return false;
730     }
731     return ret;
732 }
733 
SetPackagePath(const std::string appLibPathKey,const std::vector<std::string> & packagePath)734 void ArkNativeEngine::SetPackagePath(const std::string appLibPathKey, const std::vector<std::string>& packagePath)
735 {
736     auto moduleManager = NativeModuleManager::GetInstance();
737     if (moduleManager && !packagePath.empty()) {
738         moduleManager->SetAppLibPath(appLibPathKey, packagePath);
739     }
740 }
741 
DefineClass(const char * name,NativeCallback callback,void * data,const NativePropertyDescriptor * properties,size_t length)742 NativeValue* ArkNativeEngine::DefineClass(const char* name, NativeCallback callback,
743     void* data, const NativePropertyDescriptor* properties, size_t length)
744 {
745     LocalScope scope(vm_);
746     std::string className(name);
747     if (ArkNativeEngine::napiProfilerEnabled) {
748         className = ArkNativeEngine::tempModuleName_ + "." + name;
749     }
750     NativeChunk& chunk = GetNativeChunk();
751     auto classConstructor = chunk.New<ArkNativeFunction>(this, className.c_str(), callback, data);
752     SetModuleName(classConstructor, className);
753     auto classPrototype = classConstructor->GetFunctionPrototype();
754 
755     for (size_t i = 0; i < length; i++) {
756         if (properties[i].attributes & NATIVE_STATIC) {
757             classConstructor->DefineProperty(properties[i]);
758         } else {
759             if (classPrototype == nullptr) {
760                 HILOG_ERROR("ArkNativeEngineImpl::Class's prototype is null");
761                 continue;
762             }
763             ArkNativeObject* arkNativeobj = static_cast<ArkNativeObject*>(classPrototype);
764             SetModuleName(arkNativeobj, className);
765             arkNativeobj->DefineProperty(properties[i]);
766         }
767     }
768 
769     return classConstructor;
770 }
771 
CreateInstance(NativeValue * constructor,NativeValue * const * argv,size_t argc)772 NativeValue* ArkNativeEngine::CreateInstance(NativeValue* constructor, NativeValue* const *argv, size_t argc)
773 {
774     if (constructor == nullptr) {
775         return nullptr;
776     }
777     LocalScope scope(vm_);
778     Global<FunctionRef> value = *constructor;
779     std::vector<Local<JSValueRef>> args;
780     args.reserve(argc);
781     for (size_t i = 0; i < argc; i++) {
782         if (argv[i] != nullptr) {
783             Global<JSValueRef> arg = *argv[i];
784             args.emplace_back(arg.ToLocal(vm_));
785         } else {
786             args.emplace_back(JSValueRef::Undefined(vm_));
787         }
788     }
789     Local<JSValueRef> instance = value->Constructor(vm_, args.data(), argc);
790     Local<ObjectRef> excep = panda::JSNApi::GetUncaughtException(vm_);
791     if (!excep.IsNull()) {
792         HILOG_ERROR("ArkNativeEngineImpl::CreateInstance occur Exception");
793         return nullptr;
794     }
795     return ArkValueToNativeValue(this, instance);
796 }
797 
CreateReference(NativeValue * value,uint32_t initialRefcount,NativeFinalize callback,void * data,void * hint)798 NativeReference* ArkNativeEngine::CreateReference(NativeValue* value, uint32_t initialRefcount,
799     NativeFinalize callback, void* data, void* hint)
800 {
801     return new ArkNativeReference(this, value, initialRefcount, false);
802 }
803 
IsExceptionPending() const804 bool ArkNativeEngine::IsExceptionPending() const
805 {
806     return panda::JSNApi::HasPendingException(vm_);
807 }
808 
GetAndClearLastException()809 NativeValue* ArkNativeEngine::GetAndClearLastException()
810 {
811     LocalScope scope(vm_);
812     Local<ObjectRef> exception = panda::JSNApi::GetAndClearUncaughtException(vm_);
813     if (exception.IsNull()) {
814         return nullptr;
815     }
816 
817     return ArkValueToNativeValue(this, exception);
818 }
819 
Throw(NativeValue * error)820 bool ArkNativeEngine::Throw(NativeValue* error)
821 {
822     LocalScope scope(vm_);
823     Global<JSValueRef> errorVal = *error;
824     panda::JSNApi::ThrowException(vm_, errorVal.ToLocal(vm_));
825     return true;
826 }
827 
Throw(NativeErrorType type,const char * code,const char * message)828 bool ArkNativeEngine::Throw(NativeErrorType type, const char* code, const char* message)
829 {
830     LocalScope scope(vm_);
831     Local<JSValueRef> error(JSValueRef::Undefined(vm_));
832     switch (type) {
833         case NATIVE_COMMON_ERROR:
834             error = panda::Exception::Error(vm_, StringRef::NewFromUtf8(vm_, message));
835             break;
836         case NATIVE_TYPE_ERROR:
837             error = panda::Exception::TypeError(vm_, StringRef::NewFromUtf8(vm_, message));
838             break;
839         case NATIVE_RANGE_ERROR:
840             error = panda::Exception::RangeError(vm_, StringRef::NewFromUtf8(vm_, message));
841             break;
842         default:
843             return false;
844     }
845     if (code != nullptr) {
846         Local<JSValueRef> codeKey = StringRef::NewFromUtf8(vm_, "code");
847         Local<JSValueRef> codeValue = StringRef::NewFromUtf8(vm_, code);
848         Local<ObjectRef> errorObj(error);
849         errorObj->Set(vm_, codeKey, codeValue);
850     }
851 
852     panda::JSNApi::ThrowException(vm_, error);
853     return true;
854 }
855 
CreateRuntimeFunc(NativeEngine * engine,void * jsEngine)856 NativeEngine* ArkNativeEngine::CreateRuntimeFunc(NativeEngine* engine, void* jsEngine)
857 {
858     panda::RuntimeOption option;
859 #if defined(OHOS_PLATFORM) && !defined(IOS_PLATFORM)
860     int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1);
861     std::string bundleName = OHOS::system::GetParameter("persist.ark.arkbundlename", "");
862     size_t gcThreadNum = OHOS::system::GetUintParameter<size_t>("persist.ark.gcthreads", 7);
863     size_t longPauseTime = OHOS::system::GetUintParameter<size_t>("persist.ark.longpausetime", 40);
864     bool asmInterpreterEnabled = OHOS::system::GetBoolParameter("persist.ark.asminterpreter", true);
865     std::string asmOpcodeDisableRange = OHOS::system::GetParameter("persist.ark.asmopcodedisablerange", "");
866     bool builtinsLazyEnabled = OHOS::system::GetBoolParameter("persist.ark.enablebuiltinslazy", true);
867     option.SetEnableBuiltinsLazy(builtinsLazyEnabled);
868     option.SetArkProperties(arkProperties);
869     option.SetArkBundleName(bundleName);
870     option.SetGcThreadNum(gcThreadNum);
871     option.SetLongPauseTime(longPauseTime);
872     option.SetEnableAsmInterpreter(asmInterpreterEnabled);
873     option.SetAsmOpcodeDisableRange(asmOpcodeDisableRange);
874     option.SetIsWorker();
875     HILOG_INFO("ArkNativeEngineImpl::CreateRuntimeFunc ark properties = %{public}d, bundlename = %{public}s",
876         arkProperties, bundleName.c_str());
877 #endif
878     option.SetGcType(panda::RuntimeOption::GC_TYPE::GEN_GC);
879     const int64_t poolSize = 0x1000000;
880     option.SetGcPoolSize(poolSize);
881 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
882     option.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::INFO);
883 #endif
884     option.SetDebuggerLibraryPath("");
885     EcmaVM* vm = panda::JSNApi::CreateJSVM(option);
886     if (vm == nullptr) {
887         return nullptr;
888     }
889     // worker adaptation mergeabc
890     const panda::ecmascript::EcmaVM* hostVM = reinterpret_cast<ArkNativeEngine*>(engine)->GetEcmaVm();
891     panda::JSNApi::SynchronizVMInfo(vm, hostVM);
892     ArkNativeEngine* arkEngine = new ArkNativeEngine(vm, jsEngine);
893     // init callback
894     arkEngine->RegisterWorkerFunction(engine);
895     arkEngine->SetHostEngine(engine);
896 
897     auto cleanEnv = [vm]() {
898         if (vm != nullptr) {
899             HILOG_INFO("cleanEnv is called");
900             panda::JSNApi::DestroyJSVM(vm);
901         }
902     };
903     arkEngine->SetCleanEnv(cleanEnv);
904 
905     if (hostVM != nullptr) {
906         panda::JSNApi::addWorker(const_cast<EcmaVM*>(hostVM), vm);
907     }
908     return arkEngine;
909 }
910 
CreateRuntime()911 void* ArkNativeEngine::CreateRuntime()
912 {
913     return ArkNativeEngine::CreateRuntimeFunc(this, jsEngine_);
914 }
915 
Serialize(NativeEngine * context,NativeValue * value,NativeValue * transfer)916 NativeValue* ArkNativeEngine::Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer)
917 {
918     const panda::ecmascript::EcmaVM* vm = reinterpret_cast<ArkNativeEngine*>(context)->GetEcmaVm();
919     LocalScope scope(vm);
920     Global<JSValueRef> arkValue = *value;
921     Global<JSValueRef> arkTransfer = *transfer;
922     void* result = panda::JSNApi::SerializeValue(vm, arkValue.ToLocal(vm), arkTransfer.ToLocal(vm));
923     return reinterpret_cast<NativeValue*>(result);
924 }
925 
Deserialize(NativeEngine * context,NativeValue * recorder)926 NativeValue* ArkNativeEngine::Deserialize(NativeEngine* context, NativeValue* recorder)
927 {
928     const panda::ecmascript::EcmaVM* vm = reinterpret_cast<ArkNativeEngine*>(context)->GetEcmaVm();
929     LocalScope scope(vm);
930     Local<JSValueRef> result = panda::JSNApi::DeserializeValue(vm, recorder, reinterpret_cast<void*>(context));
931     return ArkValueToNativeValue(this, result);
932 }
933 
DeleteSerializationData(NativeValue * value) const934 void ArkNativeEngine::DeleteSerializationData(NativeValue* value) const
935 {
936     void* data = reinterpret_cast<void*>(value);
937     panda::JSNApi::DeleteSerializationData(data);
938 }
939 
StartCpuProfiler(const std::string & fileName)940 void ArkNativeEngine::StartCpuProfiler(const std::string& fileName)
941 {
942     JSNApi::SetNativePtrGetter(vm_, reinterpret_cast<void*>(ArkNativeFunction::GetNativePtrCallBack));
943     DFXJSNApi::StartCpuProfilerForFile(vm_, fileName);
944 }
945 
StopCpuProfiler()946 void ArkNativeEngine::StopCpuProfiler()
947 {
948     DFXJSNApi::StopCpuProfilerForFile(vm_);
949     JSNApi::SetNativePtrGetter(vm_, nullptr);
950 }
951 
ResumeVM()952 void ArkNativeEngine::ResumeVM()
953 {
954     DFXJSNApi::ResumeVM(vm_);
955 }
956 
SuspendVM()957 bool ArkNativeEngine::SuspendVM()
958 {
959     return DFXJSNApi::SuspendVM(vm_);
960 }
961 
IsSuspended()962 bool ArkNativeEngine::IsSuspended()
963 {
964     return DFXJSNApi::IsSuspended(vm_);
965 }
966 
CheckSafepoint()967 bool ArkNativeEngine::CheckSafepoint()
968 {
969     return DFXJSNApi::CheckSafepoint(vm_);
970 }
971 
RunBufferScript(std::vector<uint8_t> & buffer)972 NativeValue* ArkNativeEngine::RunBufferScript(std::vector<uint8_t>& buffer)
973 {
974     panda::JSExecutionScope executionScope(vm_);
975     LocalScope scope(vm_);
976     [[maybe_unused]] bool ret = panda::JSNApi::Execute(vm_, buffer.data(), buffer.size(), PANDA_MAIN_FUNCTION);
977 
978     if (panda::JSNApi::HasPendingException(vm_)) {
979         HandleUncaughtException();
980         return nullptr;
981     }
982     return CreateUndefined();
983 }
984 
RunActor(std::vector<uint8_t> & buffer,const char * descriptor)985 NativeValue* ArkNativeEngine::RunActor(std::vector<uint8_t>& buffer, const char* descriptor)
986 {
987     panda::JSExecutionScope executionScope(vm_);
988     LocalScope scope(vm_);
989     std::string desc(descriptor);
990     [[maybe_unused]] bool ret = false;
991     if (panda::JSNApi::IsBundle(vm_) || !buffer.empty()) {
992         ret = panda::JSNApi::Execute(vm_, buffer.data(), buffer.size(), PANDA_MAIN_FUNCTION, desc);
993     } else {
994         ret = panda::JSNApi::Execute(vm_, desc, PANDA_MAIN_FUNCTION);
995     }
996 
997     if (panda::JSNApi::HasPendingException(vm_)) {
998         HandleUncaughtException();
999         return nullptr;
1000     }
1001     return CreateUndefined();
1002 }
1003 
LoadArkModule(const char * str,int32_t len,const std::string & fileName)1004 NativeValue* ArkNativeEngine::LoadArkModule(const char* str, int32_t len, const std::string& fileName)
1005 {
1006     HILOG_DEBUG("ArkNativeEngineImpl::LoadModule start, buffer = %{public}s", str);
1007     if (str == nullptr || len <= 0 || fileName.empty()) {
1008         HILOG_ERROR("fileName is nullptr or source code is nullptr");
1009         return nullptr;
1010     }
1011 
1012     bool res = JSNApi::ExecuteModuleFromBuffer(vm_, str, len, fileName);
1013     if (!res) {
1014         HILOG_ERROR("Execute module failed");
1015         return nullptr;
1016     }
1017 
1018     LocalScope scope(vm_);
1019     Local<ObjectRef> exportObj = JSNApi::GetExportObjectFromBuffer(vm_, fileName, "default");
1020     if (exportObj->IsNull()) {
1021         HILOG_ERROR("Get export object failed");
1022         return nullptr;
1023     }
1024 
1025     HILOG_DEBUG("ArkNativeEngineImpl::LoadModule end");
1026     return ArkValueToNativeValue(this, exportObj);
1027 }
1028 
LoadModule(NativeValue * str,const std::string & fileName)1029 NativeValue* ArkNativeEngine::LoadModule(NativeValue* str, const std::string& fileName)
1030 {
1031     return nullptr;
1032 }
1033 
GetNativeChunk()1034 NativeChunk& ArkNativeEngine::GetNativeChunk()
1035 {
1036     return GetScopeManager()->GetNativeChunk();
1037 }
1038 
ArkValueToNativeValue(ArkNativeEngine * engine,Local<JSValueRef> value)1039 NativeValue* ArkNativeEngine::ArkValueToNativeValue(ArkNativeEngine* engine, Local<JSValueRef> value)
1040 {
1041     NativeValue* result = nullptr;
1042     NativeChunk& chunk = engine->GetNativeChunk();
1043     if (value->IsNull() || value->IsUndefined() || value->IsSymbol()) {
1044         result = chunk.New<ArkNativeValue>(engine, value);
1045     } else if (value->IsNumber()) {
1046         result = chunk.New<ArkNativeNumber>(engine, value);
1047     } else if (value->IsString()) {
1048         result = chunk.New<ArkNativeString>(engine, value);
1049     } else if (value->IsArray(engine->GetEcmaVm())) {
1050         result = chunk.New<ArkNativeArray>(engine, value);
1051     } else if (value->IsFunction()) {
1052         result = chunk.New<ArkNativeFunction>(engine, value);
1053     } else if (value->IsArrayBuffer()) {
1054         result = chunk.New<ArkNativeArrayBuffer>(engine, value);
1055     } else if (value->IsBuffer()) {
1056         result = chunk.New<ArkNativeBuffer>(engine, value);
1057     } else if (value->IsDataView()) {
1058         result = chunk.New<ArkNativeDataView>(engine, value);
1059     } else if (value->IsTypedArray()) {
1060         result = chunk.New<ArkNativeTypedArray>(engine, value);
1061     } else if (value->IsNativePointer()) {
1062         result = chunk.New<ArkNativeExternal>(engine, value);
1063     } else if (value->IsDate()) {
1064         result = chunk.New<ArkNativeDate>(engine, value);
1065     } else if (value->IsBigInt()) {
1066         result = chunk.New<ArkNativeBigInt>(engine, value);
1067     } else if (value->IsObject() || value->IsPromise()) {
1068         result = chunk.New<ArkNativeObject>(engine, value);
1069     } else if (value->IsBoolean()) {
1070         result = chunk.New<ArkNativeBoolean>(engine, value);
1071     } else {
1072         result = chunk.New<ArkNativeValue>(engine, value);
1073     }
1074     return result;
1075 }
1076 
ValueToNativeValue(JSValueWrapper & value)1077 NativeValue* ArkNativeEngine::ValueToNativeValue(JSValueWrapper& value)
1078 {
1079     LocalScope scope(vm_);
1080     Global<JSValueRef> arkValue = value;
1081     return ArkValueToNativeValue(this, arkValue.ToLocal(vm_));
1082 }
1083 
ExecuteJsBin(const std::string & fileName)1084 bool ArkNativeEngine::ExecuteJsBin(const std::string& fileName)
1085 {
1086     panda::JSExecutionScope executionScope(vm_);
1087     LocalScope scope(vm_);
1088     bool ret = JSNApi::Execute(vm_, fileName, PANDA_MAIN_FUNCTION);
1089     return ret;
1090 }
1091 
CreateBuffer(void ** value,size_t length)1092 NativeValue* ArkNativeEngine::CreateBuffer(void** value, size_t length)
1093 {
1094     return GetNativeChunk().New<ArkNativeBuffer>(this, (uint8_t**)value, length);
1095 }
1096 
CreateBufferCopy(void ** value,size_t length,const void * data)1097 NativeValue* ArkNativeEngine::CreateBufferCopy(void** value, size_t length, const void* data)
1098 {
1099     return GetNativeChunk().New<ArkNativeBuffer>(this, (uint8_t**)value, length, (uint8_t*)data);
1100 }
1101 
CreateBufferExternal(void * value,size_t length,NativeFinalize cb,void * hint)1102 NativeValue* ArkNativeEngine::CreateBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint)
1103 {
1104     return GetNativeChunk().New<ArkNativeBuffer>(this, (uint8_t*)value, length, cb, hint);
1105 }
1106 
CreateDate(double value)1107 NativeValue* ArkNativeEngine::CreateDate(double value)
1108 {
1109     LocalScope scope(vm_);
1110     return ArkValueToNativeValue(this, DateRef::New(vm_, value));
1111 }
1112 
CreateBigWords(int sign_bit,size_t word_count,const uint64_t * words)1113 NativeValue* ArkNativeEngine::CreateBigWords(int sign_bit, size_t word_count, const uint64_t* words)
1114 {
1115     constexpr int bigintMod = 2; // 2 : used for even number judgment
1116     bool sign = false;
1117     if ((sign_bit % bigintMod) == 1) {
1118         sign = true;
1119     }
1120     uint32_t size = (uint32_t)word_count;
1121 
1122     LocalScope scope(vm_);
1123     Local<JSValueRef> value = BigIntRef::CreateBigWords(vm_, sign, size, words);
1124     return GetNativeChunk().New<ArkNativeBigInt>(this, value);
1125 }
1126 
TriggerFatalException(NativeValue * error)1127 bool ArkNativeEngine::TriggerFatalException(NativeValue* error)
1128 {
1129     return true;
1130 }
1131 
AdjustExternalMemory(int64_t ChangeInBytes,int64_t * AdjustedValue)1132 bool ArkNativeEngine::AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue)
1133 {
1134     return true;
1135 }
1136 
SetPromiseRejectCallback(NativeReference * rejectCallbackRef,NativeReference * checkCallbackRef)1137 void ArkNativeEngine::SetPromiseRejectCallback(NativeReference* rejectCallbackRef, NativeReference* checkCallbackRef)
1138 {
1139     if (rejectCallbackRef == nullptr || checkCallbackRef == nullptr) {
1140         HILOG_ERROR("rejectCallbackRef or checkCallbackRef is nullptr");
1141         return;
1142     }
1143     promiseRejectCallbackRef_ = rejectCallbackRef;
1144     checkCallbackRef_ = checkCallbackRef;
1145     JSNApi::SetHostPromiseRejectionTracker(vm_, reinterpret_cast<void*>(PromiseRejectCallback),
1146                                            reinterpret_cast<void*>(this));
1147 }
1148 
PromiseRejectCallback(void * info)1149 void ArkNativeEngine::PromiseRejectCallback(void* info)
1150 {
1151     panda::PromiseRejectInfo* promiseRejectInfo = reinterpret_cast<panda::PromiseRejectInfo*>(info);
1152     ArkNativeEngine* env = reinterpret_cast<ArkNativeEngine*>(promiseRejectInfo->GetData());
1153 
1154     if (env == nullptr) {
1155         HILOG_ERROR("engine is nullptr");
1156         return;
1157     }
1158 
1159     if (env->promiseRejectCallbackRef_ == nullptr || env->checkCallbackRef_ == nullptr) {
1160         HILOG_ERROR("promiseRejectCallbackRef or checkCallbackRef is nullptr");
1161         return;
1162     }
1163     panda::ecmascript::EcmaVM* vm = const_cast<EcmaVM*>(env->GetEcmaVm());
1164     LocalScope scope(vm);
1165     Local<JSValueRef> promise = promiseRejectInfo->GetPromise();
1166     Local<JSValueRef> reason = promiseRejectInfo->GetReason();
1167     panda::PromiseRejectInfo::PROMISE_REJECTION_EVENT operation = promiseRejectInfo->GetOperation();
1168 
1169     Local<JSValueRef> type(IntegerRef::New(vm, static_cast<int32_t>(operation)));
1170 
1171     Local<JSValueRef> args[] = {type, promise, reason};
1172     Global<FunctionRef> promiseRejectCallback = *(env->promiseRejectCallbackRef_->Get());
1173     if (!promiseRejectCallback.IsEmpty()) {
1174         promiseRejectCallback->Call(vm, JSValueRef::Undefined(vm), args, 3); // 3 args size
1175     }
1176 
1177     if (operation == panda::PromiseRejectInfo::PROMISE_REJECTION_EVENT::REJECT) {
1178         Global<JSValueRef> checkCallback = *(env->checkCallbackRef_->Get());
1179         if (!checkCallback.IsEmpty()) {
1180             JSNApi::SetHostEnqueueJob(vm, checkCallback.ToLocal(vm));
1181         }
1182     }
1183 }
1184 
DumpHeapSnapshot(const std::string & path,bool isVmMode,DumpFormat dumpFormat)1185 void ArkNativeEngine::DumpHeapSnapshot(const std::string& path, bool isVmMode, DumpFormat dumpFormat)
1186 {
1187     if (dumpFormat == DumpFormat::JSON) {
1188         DFXJSNApi::DumpHeapSnapshot(vm_, 0, path, isVmMode);
1189     }
1190     if (dumpFormat == DumpFormat::BINARY) {
1191         DFXJSNApi::DumpHeapSnapshot(vm_, 1, path, isVmMode);
1192     }
1193     if (dumpFormat == DumpFormat::OTHER) {
1194         DFXJSNApi::DumpHeapSnapshot(vm_, 2, path, isVmMode); // 2:enum is 2
1195     }
1196 }
1197 
DumpHeapSnapshot(bool isVmMode,DumpFormat dumpFormat,bool isPrivate)1198 void ArkNativeEngine::DumpHeapSnapshot(bool isVmMode, DumpFormat dumpFormat, bool isPrivate)
1199 {
1200     if (dumpFormat == DumpFormat::JSON) {
1201         DFXJSNApi::DumpHeapSnapshot(vm_, 0, isVmMode, isPrivate);
1202     }
1203     if (dumpFormat == DumpFormat::BINARY) {
1204         DFXJSNApi::DumpHeapSnapshot(vm_, 1, isVmMode, isPrivate);
1205     }
1206     if (dumpFormat == DumpFormat::OTHER) {
1207         DFXJSNApi::DumpHeapSnapshot(vm_, 2, isVmMode, isPrivate); // 2:enum is 2
1208     }
1209 }
1210 
BuildNativeAndJsStackTrace(std::string & stackTraceStr)1211 bool ArkNativeEngine::BuildNativeAndJsStackTrace(std::string& stackTraceStr)
1212 {
1213 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
1214     return DFXJSNApi::BuildNativeAndJsStackTrace(vm_, stackTraceStr);
1215 #else
1216     HILOG_WARN("ARK does not support dfx on windows");
1217     return false;
1218 #endif
1219 }
1220 
BuildJsStackTrace(std::string & stackTraceStr)1221 bool ArkNativeEngine::BuildJsStackTrace(std::string& stackTraceStr)
1222 {
1223 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
1224     return DFXJSNApi::BuildJsStackTrace(vm_, stackTraceStr);
1225 #else
1226     HILOG_WARN("ARK does not support dfx on windows");
1227     return false;
1228 #endif
1229 }
1230 
BuildJsStackInfoList(uint32_t tid,std::vector<JsFrameInfo> & jsFrames)1231 bool ArkNativeEngine::BuildJsStackInfoList(uint32_t tid, std::vector<JsFrameInfo>& jsFrames)
1232 {
1233 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
1234     std::vector<ArkJsFrameInfo> arkJsFrames;
1235     bool sign = DFXJSNApi::BuildJsStackInfoList(vm_, tid, arkJsFrames);
1236     for (auto jf : arkJsFrames) {
1237         struct JsFrameInfo jsframe;
1238         jsframe.fileName = jf.fileName;
1239         jsframe.functionName = jf.functionName;
1240         jsframe.pos = jf.pos;
1241         jsframe.nativePointer = jf.nativePointer;
1242         jsFrames.emplace_back(jsframe);
1243     }
1244     return sign;
1245 #else
1246     HILOG_WARN("ARK does not support dfx on windows");
1247     return false;
1248 #endif
1249 }
1250 
DeleteWorker(NativeEngine * workerEngine)1251 bool ArkNativeEngine::DeleteWorker(NativeEngine* workerEngine)
1252 {
1253     if (workerEngine != nullptr) {
1254 #if !defined(PREVIEW)
1255         const panda::ecmascript::EcmaVM* workerVM = reinterpret_cast<ArkNativeEngine*>(workerEngine)->GetEcmaVm();
1256         if (workerVM != nullptr) {
1257             return panda::JSNApi::DeleteWorker(vm_, const_cast<EcmaVM*>(workerVM));
1258         }
1259 #else
1260         HILOG_WARN("ARK does not support dfx on windows");
1261 #endif
1262         return false;
1263         }
1264     return false;
1265 }
1266 
StartHeapTracking(double timeInterval,bool isVmMode)1267 bool ArkNativeEngine::StartHeapTracking(double timeInterval, bool isVmMode)
1268 {
1269     return DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode);
1270 }
1271 
StopHeapTracking(const std::string & filePath)1272 bool ArkNativeEngine::StopHeapTracking(const std::string &filePath)
1273 {
1274     return DFXJSNApi::StopHeapTracking(vm_, filePath);
1275 }
1276 
1277 #if !defined(PREVIEW)
PrintStatisticResult()1278 void ArkNativeEngine::PrintStatisticResult()
1279 {
1280     DFXJSNApi::PrintStatisticResult(vm_);
1281 }
1282 
StartRuntimeStat()1283 void ArkNativeEngine::StartRuntimeStat()
1284 {
1285     DFXJSNApi::StartRuntimeStat(vm_);
1286 }
1287 
StopRuntimeStat()1288 void ArkNativeEngine::StopRuntimeStat()
1289 {
1290     DFXJSNApi::StopRuntimeStat(vm_);
1291 }
1292 
GetArrayBufferSize()1293 size_t ArkNativeEngine::GetArrayBufferSize()
1294 {
1295     return DFXJSNApi::GetArrayBufferSize(vm_);
1296 }
1297 
GetHeapTotalSize()1298 size_t ArkNativeEngine::GetHeapTotalSize()
1299 {
1300     return DFXJSNApi::GetHeapTotalSize(vm_);
1301 }
1302 
GetHeapUsedSize()1303 size_t ArkNativeEngine::GetHeapUsedSize()
1304 {
1305     return DFXJSNApi::GetHeapUsedSize(vm_);
1306 }
1307 
NotifyApplicationState(bool inBackground)1308 void ArkNativeEngine::NotifyApplicationState(bool inBackground)
1309 {
1310     DFXJSNApi::NotifyApplicationState(vm_, inBackground);
1311 }
1312 
NotifyIdleStatusControl(std::function<void (bool)> callback)1313 void ArkNativeEngine::NotifyIdleStatusControl(std::function<void(bool)> callback)
1314 {
1315     DFXJSNApi::NotifyIdleStatusControl(vm_, callback);
1316 }
1317 
NotifyIdleTime(int idleMicroSec)1318 void ArkNativeEngine::NotifyIdleTime(int idleMicroSec)
1319 {
1320     DFXJSNApi::NotifyIdleTime(vm_, idleMicroSec);
1321 }
1322 
NotifyMemoryPressure(bool inHighMemoryPressure)1323 void ArkNativeEngine::NotifyMemoryPressure(bool inHighMemoryPressure)
1324 {
1325     DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
1326 }
1327 #else
PrintStatisticResult()1328 void ArkNativeEngine::PrintStatisticResult()
1329 {
1330     HILOG_WARN("ARK does not support dfx on windows");
1331 }
1332 
StartRuntimeStat()1333 void ArkNativeEngine::StartRuntimeStat()
1334 {
1335     HILOG_WARN("ARK does not support dfx on windows");
1336 }
1337 
StopRuntimeStat()1338 void ArkNativeEngine::StopRuntimeStat()
1339 {
1340     HILOG_WARN("ARK does not support dfx on windows");
1341 }
1342 
GetArrayBufferSize()1343 size_t ArkNativeEngine::GetArrayBufferSize()
1344 {
1345     HILOG_WARN("ARK does not support dfx on windows");
1346     return 0;
1347 }
1348 
GetHeapTotalSize()1349 size_t ArkNativeEngine::GetHeapTotalSize()
1350 {
1351     HILOG_WARN("ARK does not support dfx on windows");
1352     return 0;
1353 }
1354 
GetHeapUsedSize()1355 size_t ArkNativeEngine::GetHeapUsedSize()
1356 {
1357     HILOG_WARN("ARK does not support dfx on windows");
1358     return 0;
1359 }
1360 
NotifyApplicationState(bool inBackground)1361 void ArkNativeEngine::NotifyApplicationState([[maybe_unused]] bool inBackground)
1362 {
1363     HILOG_WARN("ARK does not support dfx on windows");
1364 }
1365 
NotifyIdleStatusControl(std::function<void (bool)> callback)1366 void ArkNativeEngine::NotifyIdleStatusControl([[maybe_unused]] std::function<void(bool)> callback)
1367 {
1368     HILOG_WARN("ARK does not support dfx on windows");
1369 }
1370 
NotifyIdleTime(int idleMicroSec)1371 void ArkNativeEngine::NotifyIdleTime([[maybe_unused]] int idleMicroSec)
1372 {
1373     HILOG_WARN("ARK does not support dfx on windows");
1374 }
1375 
NotifyMemoryPressure(bool inHighMemoryPressure)1376 void ArkNativeEngine::NotifyMemoryPressure([[maybe_unused]] bool inHighMemoryPressure)
1377 {
1378     HILOG_WARN("ARK does not support dfx on windows");
1379 }
1380 #endif
1381 
RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback)1382 void ArkNativeEngine::RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback)
1383 {
1384     JSNApi::EnableUserUncaughtErrorHandler(vm_);
1385     uncaughtExceptionCallback_ = callback;
1386 }
1387 
HandleUncaughtException()1388 void ArkNativeEngine::HandleUncaughtException()
1389 {
1390     if (uncaughtExceptionCallback_ == nullptr) {
1391         return;
1392     }
1393     LocalScope scope(vm_);
1394     Local<ObjectRef> exception = JSNApi::GetAndClearUncaughtException(vm_);
1395     if (!exception.IsEmpty() && !exception->IsHole()) {
1396         uncaughtExceptionCallback_(ArkValueToNativeValue(this, exception));
1397     }
1398 }
1399 
HasPendingException()1400 bool ArkNativeEngine::HasPendingException()
1401 {
1402     return panda::JSNApi::HasPendingException(vm_);
1403 }
1404 
RegisterPermissionCheck(PermissionCheckCallback callback)1405 void ArkNativeEngine::RegisterPermissionCheck(PermissionCheckCallback callback)
1406 {
1407     if (permissionCheckCallback_ == nullptr) {
1408         permissionCheckCallback_ = callback;
1409     }
1410 }
1411 
ExecutePermissionCheck()1412 bool ArkNativeEngine::ExecutePermissionCheck()
1413 {
1414     if (permissionCheckCallback_ != nullptr) {
1415         return permissionCheckCallback_();
1416     } else {
1417         HILOG_INFO("permissionCheckCallback_ is still nullptr when executing permission check!");
1418         return true;
1419     }
1420 }
1421 
RegisterTranslateBySourceMap(SourceMapCallback callback)1422 void ArkNativeEngine::RegisterTranslateBySourceMap(SourceMapCallback callback)
1423 {
1424     if (SourceMapCallback_ == nullptr) {
1425         SourceMapCallback_ = callback;
1426     }
1427 }
1428 
ExecuteTranslateBySourceMap(const std::string & rawStack)1429 std::string ArkNativeEngine::ExecuteTranslateBySourceMap(const std::string& rawStack)
1430 {
1431     if (SourceMapCallback_ != nullptr) {
1432         return SourceMapCallback_(rawStack);
1433     } else {
1434         HILOG_WARN("SourceMapCallback_ is nullptr.");
1435         return "";
1436     }
1437 }
1438 
IsMixedDebugEnabled()1439 bool ArkNativeEngine::IsMixedDebugEnabled()
1440 {
1441     return JSNApi::IsMixedDebugEnabled(vm_);
1442 }
1443 
NotifyNativeCalling(const void * nativeAddress)1444 void ArkNativeEngine::NotifyNativeCalling(const void *nativeAddress)
1445 {
1446     JSNApi::NotifyNativeCalling(vm_, nativeAddress);
1447 }
1448 
AllowCrossThreadExecution() const1449 void ArkNativeEngine::AllowCrossThreadExecution() const
1450 {
1451     JSNApi::AllowCrossThreadExecution(vm_);
1452 }
1453