• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi/native_api.h"
17 #include "hilog/log.h"
18 #include "ark_runtime/jsvm.h"
19 
20 #define LOG_DOMAIN 0x3200
21 #define LOG_TAG "APP"
22 
23 static int g_aa = 0;
24 
25 #define CHECK_RET(theCall)                                                                                             \
26     do {                                                                                                               \
27         JSVM_Status cond = theCall;                                                                                    \
28         if ((cond) != JSVM_OK) {                                                                                       \
29             const JSVM_ExtendedErrorInfo *info;                                                                        \
30             OH_JSVM_GetLastErrorInfo(env, &info);                                                                      \
31             OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", \
32                          __FILE__, __LINE__, cond, info != nullptr ? info->errorMessage : "");                         \
33             return -1;                                                                                                 \
34         }                                                                                                              \
35     } while (0)
36 
37 #define CHECK(theCall)                                                                                                 \
38     do {                                                                                                               \
39         JSVM_Status cond = theCall;                                                                                    \
40         if ((cond) != JSVM_OK) {                                                                                       \
41             OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d", __FILE__, __LINE__,  \
42                          cond);                                                                                        \
43             return -1;                                                                                                 \
44         }                                                                                                              \
45     } while (0)
46 
47 // 用于调用theCall并检查其返回值是否为JSVM_OK。
48 // 如果不是,则调用OH_JSVM_GetLastErrorInfo处理错误并返回retVal。
49 #define JSVM_CALL_BASE(env, theCall, retVal)                                                                           \
50     do {                                                                                                               \
51         JSVM_Status cond = theCall;                                                                                    \
52         if (cond != JSVM_OK) {                                                                                         \
53             const JSVM_ExtendedErrorInfo *info;                                                                        \
54             OH_JSVM_GetLastErrorInfo(env, &info);                                                                      \
55             OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", \
56                          __FILE__, __LINE__, cond, info != nullptr ? info->errorMessage : "");                         \
57             return retVal;                                                                                             \
58         }                                                                                                              \
59     } while (0)
60 
61 // JSVM_CALL_BASE的简化版本,返回nullptr
62 #define JSVM_CALL(theCall) JSVM_CALL_BASE(env, theCall, nullptr)
63 
64 // [Start oh_jsvm_get_version_and_vm_info]
65 // OH_JSVM_GetVersion的样例方法
GetVersion(JSVM_Env env,JSVM_CallbackInfo info)66 static JSVM_Value GetVersion(JSVM_Env env, JSVM_CallbackInfo info)
67 {
68     uint32_t jsVersion = 0;
69     // 调用接口,获取当前JSVM运行时支持的最高JSVM API版本
70     JSVM_CALL(OH_JSVM_GetVersion(env, &jsVersion));
71     int value = static_cast<int>(jsVersion);
72     OH_LOG_INFO(LOG_APP, "JSVM GetVersion success:%{public}d", value);
73     return nullptr;
74 }
75 
76 // OH_JSVM_GetVMInfo的样例方法
77 // 打印JSVM(JavaScript虚拟机)的各项信息
PrintVmInfo(JSVM_VMInfo vmInfo)78 void PrintVmInfo(JSVM_VMInfo vmInfo)
79 {
80     OH_LOG_INFO(LOG_APP, "JSVM API apiVersion: %{public}d", vmInfo.apiVersion);
81     OH_LOG_INFO(LOG_APP, "JSVM API engine: %{public}s", vmInfo.engine);
82     OH_LOG_INFO(LOG_APP, "JSVM API version: %{public}s", vmInfo.version);
83     OH_LOG_INFO(LOG_APP, "JSVM API cachedDataVersionTag: 0x%{public}x", vmInfo.cachedDataVersionTag);
84 }
85 
GetVMInfo(JSVM_Env env,JSVM_CallbackInfo info)86 static JSVM_Value GetVMInfo(JSVM_Env env, JSVM_CallbackInfo info)
87 {
88     // 调用接口,获取虚拟机的信息
89     JSVM_VMInfo result;
90     JSVM_CALL(OH_JSVM_GetVMInfo(&result));
91     // 输出VM虚拟机信息
92     PrintVmInfo(result);
93     return nullptr;
94 }
95 
96 // IsStrictEquals注册回调
97 static JSVM_CallbackStruct param[] = {
98     {.data = nullptr, .callback = GetVersion},
99     {.data = nullptr, .callback = GetVMInfo},
100 };
101 static JSVM_CallbackStruct *method = param;
102 // IsStrictEquals方法别名,供JS调用
103 static JSVM_PropertyDescriptor descriptor[] = {
104     {"getVersion", nullptr, method, nullptr, nullptr, nullptr, JSVM_DEFAULT},
105     {"getVMInfo", nullptr, method + 1, nullptr, nullptr, nullptr, JSVM_DEFAULT},
106 };
107 
108 // 样例测试js
109 static const char *STR_TASK = R"JS(getVersion();getVMInfo();)JS";
110 // [End oh_jsvm_get_version_and_vm_info]
111 
TestJSVM()112 static int32_t TestJSVM()
113 {
114     JSVM_InitOptions initOptions = {0};
115     JSVM_VM vm;
116     JSVM_Env env = nullptr;
117     JSVM_VMScope vmScope;
118     JSVM_EnvScope envScope;
119     JSVM_HandleScope handleScope;
120     JSVM_Value result;
121     // 初始化JavaScript引擎实例
122     if (g_aa == 0) {
123         g_aa++;
124         CHECK(OH_JSVM_Init(&initOptions));
125     }
126     // 创建JSVM环境
127     CHECK(OH_JSVM_CreateVM(nullptr, &vm));
128     CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
129     CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
130     CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
131     CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));
132 
133     // 通过script调用测试函数
134     JSVM_Script script;
135     JSVM_Value jsSrc;
136     CHECK_RET(OH_JSVM_CreateStringUtf8(env, STR_TASK, JSVM_AUTO_LENGTH, &jsSrc));
137     CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
138     CHECK_RET(OH_JSVM_RunScript(env, script, &result));
139 
140     // 销毁JSVM环境
141     CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
142     CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
143     CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
144     CHECK(OH_JSVM_DestroyEnv(env));
145     CHECK(OH_JSVM_DestroyVM(vm));
146     return 0;
147 }
148 
RunTest(napi_env env,napi_callback_info info)149 static napi_value RunTest(napi_env env, napi_callback_info info)
150 {
151     TestJSVM();
152     return nullptr;
153 }
154 
155 // 模块注册信息,供arkts侧调用
156 EXTERN_C_START
Init(napi_env env,napi_value exports)157 static napi_value Init(napi_env env, napi_value exports)
158 {
159     napi_property_descriptor desc[] = {{"runTest", nullptr, RunTest, nullptr, nullptr, nullptr, napi_default, nullptr}};
160     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
161     return exports;
162 }
163 EXTERN_C_END
164 
165 static napi_module demoModule = {
166     .nm_version = 1,
167     .nm_flags = 0,
168     .nm_filename = nullptr,
169     .nm_register_func = Init,
170     .nm_modname = "getversion",
171     .nm_priv = ((void *)0),
172     .reserved = {0},
173 };
174 
RegisterEntryModule(void)175 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
176