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