• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <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_OHOS_USE_INNER_HILOG
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_OHOS_USE_INNER_HILOG
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 #ifdef PANDA_JS_ETS_HYBRID_MODE
101     if ((runtimeOptions.GetXgcTriggerType() != "never") &&
102         (runtimeOptions.GetGcType("ets") != "g1-gc" || runtimeOptions.IsNoAsyncJit())) {
103         // XGC is not implemented for other GC types
104         LOG(ERROR, RUNTIME) << "GC type must be g1-gc and no-async-jit option must be false";
105         return false;
106     }
107 #endif
108 
109     if (!ark::Runtime::Create(runtimeOptions)) {
110         LOG(ERROR, RUNTIME) << "CreateRuntime: cannot create ets runtime";
111         return false;
112     }
113     return true;
114 }
115 
CreateRuntime(const std::string & stdlibAbc,const std::string & pathAbc,const bool useJit,const bool useAot)116 bool CreateRuntime(const std::string &stdlibAbc, const std::string &pathAbc, const bool useJit, const bool useAot)
117 {
118     auto addOpts = [&stdlibAbc, &pathAbc, useJit, useAot](base_options::Options *baseOptions,
119                                                           ark::RuntimeOptions *runtimeOptions) {
120         baseOptions->SetLogLevel("info");
121         runtimeOptions->SetBootPandaFiles({stdlibAbc, pathAbc});
122         runtimeOptions->SetPandaFiles({pathAbc});
123         runtimeOptions->SetGcTriggerType("heap-trigger");
124         runtimeOptions->SetCompilerEnableJit(useJit);
125         runtimeOptions->SetEnableAn(useAot);
126         runtimeOptions->SetCoroutineImpl("stackful");
127         return true;
128     };
129     return CreateRuntime(addOpts);
130 }
131 
DestroyRuntime()132 bool DestroyRuntime()
133 {
134     LOG(DEBUG, RUNTIME) << "DestroyEtsRuntime: enter";
135     auto res = ark::Runtime::Destroy();
136     LOG(DEBUG, RUNTIME) << "DestroyEtsRuntime: result = " << res;
137     return res;
138 }
139 
ExecuteModule(std::string_view name)140 std::pair<bool, int> ExecuteModule(std::string_view name)
141 {
142     auto runtime = ark::Runtime::GetCurrent();
143     auto pfPath = runtime->GetPandaFiles()[0];
144     LOG(INFO, RUNTIME) << "ExecuteEtsModule: '" << pfPath << "'";
145     std::string moduleEp = (name.empty() ? "ETSGLOBAL::main" : std::string(name) + ".ETSGLOBAL::main");
146     auto res = ark::Runtime::GetCurrent()->ExecutePandaFile(pfPath, moduleEp, {});
147     LOG(INFO, RUNTIME) << "ExecuteEtsModule: result = " << (res ? std::to_string(res.Value()) : "failed");
148     return res ? std::make_pair(true, res.Value()) : std::make_pair(false, 1);
149 }
150 
BindNative(const char * classDescriptor,const char * methodName,void * impl)151 bool BindNative(const char *classDescriptor, const char *methodName, void *impl)
152 {
153     auto *runtime = ark::Runtime::GetCurrent();
154     auto *classLinker = runtime->GetClassLinker();
155     auto *ext = classLinker->GetExtension(ark::SourceLanguage::ETS);
156     auto *klass = ext->GetClass(ark::utf::CStringAsMutf8(classDescriptor));
157 
158     if (klass == nullptr) {
159         auto *thread = ark::ManagedThread::GetCurrent();
160         ASSERT(thread != nullptr);
161         thread->ClearException();
162         LOG(DEBUG, RUNTIME) << "BindNative: Cannot find class '" << classDescriptor << "'";
163         return false;
164     }
165 
166     auto *method = klass->GetDirectMethod(ark::utf::CStringAsMutf8(methodName));
167 
168     if (method == nullptr) {
169         ark::ManagedThread::GetCurrent()->ClearException();
170         LOG(DEBUG, RUNTIME) << "BindNative: Cannot find method '" << classDescriptor << "." << methodName << "'`";
171         return false;
172     }
173 
174     method->SetCompiledEntryPoint(impl);
175     return true;
176 }
177 
LogError(const std::string & msg)178 void LogError(const std::string &msg)
179 {
180     LogPrint(0, ark::Logger::PandaLog2MobileLog::ERROR, nullptr, nullptr, msg.c_str());
181 }
182 
183 }  // namespace ark::ets
184