• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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 <iostream>
17 #include "ets_vm_api.h"
18 #include "ets_vm.h"
19 #include "generated/base_options.h"
20 
21 #ifdef PANDA_TARGET_OHOS
22 #include <hilog/log.h>
23 
LogPrint(int id,int level,const char * component,const char * fmt,const char * msg)24 static void LogPrint([[maybe_unused]] int id, int level, const char *component, [[maybe_unused]] const char *fmt,
25                      const char *msg)
26 {
27 #ifdef PANDA_USE_OHOS_LOG
28     constexpr static unsigned int ARK_DOMAIN = 0xD003F00;
29     constexpr static auto TAG = "ArkEtsVm";
30     constexpr static OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, ARK_DOMAIN, TAG};
31     switch (level) {
32         case ark::Logger::PandaLog2MobileLog::DEBUG:
33             OHOS::HiviewDFX::HiLog::Debug(LABEL, "%{public}s", msg);
34             break;
35         case ark::Logger::PandaLog2MobileLog::INFO:
36             OHOS::HiviewDFX::HiLog::Info(LABEL, "%{public}s", msg);
37             break;
38         case ark::Logger::PandaLog2MobileLog::ERROR:
39             OHOS::HiviewDFX::HiLog::Error(LABEL, "%{public}s", msg);
40             break;
41         case ark::Logger::PandaLog2MobileLog::FATAL:
42             OHOS::HiviewDFX::HiLog::Fatal(LABEL, "%{public}s", msg);
43             break;
44         case ark::Logger::PandaLog2MobileLog::WARN:
45             OHOS::HiviewDFX::HiLog::Warn(LABEL, "%{public}s", msg);
46             break;
47         default:
48             UNREACHABLE();
49     }
50 #else
51     switch (level) {
52         case ark::Logger::PandaLog2MobileLog::DEBUG:
53             OH_LOG_Print(LOG_APP, LOG_DEBUG, 0xFF00, "ArkEtsVm", "%s: %s", component, msg);
54             break;
55         case ark::Logger::PandaLog2MobileLog::INFO:
56             OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "ArkEtsVm", "%s: %s", component, msg);
57             break;
58         case ark::Logger::PandaLog2MobileLog::ERROR:
59             OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "ArkEtsVm", "%s: %s", component, msg);
60             break;
61         case ark::Logger::PandaLog2MobileLog::FATAL:
62             OH_LOG_Print(LOG_APP, LOG_FATAL, 0xFF00, "ArkEtsVm", "%s: %s", component, msg);
63             break;
64         case ark::Logger::PandaLog2MobileLog::WARN:
65             OH_LOG_Print(LOG_APP, LOG_WARN, 0xFF00, "ArkEtsVm", "%s: %s", component, msg);
66             break;
67         default:
68             UNREACHABLE();
69     }
70 #endif  // PANDA_USE_OHOS_LOG
71 }
72 #else
LogPrint(int id,int level,const char * component,const char * fmt,const char * msg)73 static void LogPrint([[maybe_unused]] int id, [[maybe_unused]] int level, [[maybe_unused]] const char *component,
74                      [[maybe_unused]] const char *fmt, const char *msg)
75 {
76     std::cerr << msg << "\n";
77 }
78 #endif  // PANDA_TARGET_OHOS
79 
80 namespace ark::ets {
81 
CreateRuntime(std::function<bool (base_options::Options *,RuntimeOptions *)> const & addOptions)82 bool CreateRuntime(std::function<bool(base_options::Options *, RuntimeOptions *)> const &addOptions)
83 {
84     auto runtimeOptions = ark::RuntimeOptions("app");
85     runtimeOptions.SetLoadRuntimes({"ets"});
86 #ifdef PANDA_TARGET_OHOS
87     runtimeOptions.SetMobileLog(reinterpret_cast<void *>(LogPrint));
88 #endif
89 
90     ark::base_options::Options baseOptions("app");
91 
92     if (!addOptions(&baseOptions, &runtimeOptions)) {
93         return false;
94     }
95 
96     ark::Logger::Initialize(baseOptions);
97 
98     LOG(DEBUG, RUNTIME) << "CreateRuntime";
99 
100     if (!ark::Runtime::Create(runtimeOptions)) {
101         LOG(ERROR, RUNTIME) << "CreateRuntime: cannot create ets runtime";
102         return false;
103     }
104     return true;
105 }
106 
CreateRuntime(const std::string & stdlibAbc,const std::string & pathAbc,const bool useJit,const bool useAot)107 bool CreateRuntime(const std::string &stdlibAbc, const std::string &pathAbc, const bool useJit, const bool useAot)
108 {
109     auto addOpts = [&stdlibAbc, &pathAbc, useJit, useAot](base_options::Options *baseOptions,
110                                                           ark::RuntimeOptions *runtimeOptions) {
111         baseOptions->SetLogLevel("info");
112         runtimeOptions->SetBootPandaFiles({stdlibAbc, pathAbc});
113         runtimeOptions->SetPandaFiles({pathAbc});
114         runtimeOptions->SetGcTriggerType("heap-trigger");
115         runtimeOptions->SetCompilerEnableJit(useJit);
116         runtimeOptions->SetEnableAn(useAot);
117         runtimeOptions->SetCoroutineJsMode(true);
118         runtimeOptions->SetCoroutineImpl("stackful");
119         return true;
120     };
121     return CreateRuntime(addOpts);
122 }
123 
DestroyRuntime()124 bool DestroyRuntime()
125 {
126     LOG(DEBUG, RUNTIME) << "DestroyEtsRuntime: enter";
127     auto res = ark::Runtime::Destroy();
128     LOG(DEBUG, RUNTIME) << "DestroyEtsRuntime: result = " << res;
129     return res;
130 }
131 
ExecuteMain()132 std::pair<bool, int> ExecuteMain()
133 {
134     auto runtime = ark::Runtime::GetCurrent();
135     auto pfPath = runtime->GetPandaFiles()[0];
136     LOG(INFO, RUNTIME) << "ExecuteEtsMain: '" << pfPath << "'";
137     auto res = ark::Runtime::GetCurrent()->ExecutePandaFile(pfPath, "ETSGLOBAL::main", {});
138     LOG(INFO, RUNTIME) << "ExecuteEtsMain: result = " << (res ? std::to_string(res.Value()) : "failed");
139     return res ? std::make_pair(true, res.Value()) : std::make_pair(false, 1);
140 }
141 
BindNative(const char * classDescriptor,const char * methodName,void * impl)142 bool BindNative(const char *classDescriptor, const char *methodName, void *impl)
143 {
144     auto *runtime = ark::Runtime::GetCurrent();
145     auto *classLinker = runtime->GetClassLinker();
146     auto *ext = classLinker->GetExtension(ark::SourceLanguage::ETS);
147     auto *klass = ext->GetClass(ark::utf::CStringAsMutf8(classDescriptor));
148 
149     if (klass == nullptr) {
150         ark::ManagedThread::GetCurrent()->ClearException();
151         LOG(DEBUG, RUNTIME) << "BindNative: Cannot find class '" << classDescriptor << "'";
152         return false;
153     }
154 
155     auto *method = klass->GetDirectMethod(ark::utf::CStringAsMutf8(methodName));
156 
157     if (method == nullptr) {
158         ark::ManagedThread::GetCurrent()->ClearException();
159         LOG(DEBUG, RUNTIME) << "BindNative: Cannot find method '" << classDescriptor << "." << methodName << "'`";
160         return false;
161     }
162 
163     method->SetCompiledEntryPoint(impl);
164     return true;
165 }
166 
LogError(const std::string & msg)167 void LogError(const std::string &msg)
168 {
169     LogPrint(0, ark::Logger::PandaLog2MobileLog::ERROR, nullptr, nullptr, msg.c_str());
170 }
171 
172 }  // namespace ark::ets
173