• 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 // [Start oh_jsvm_get_value_external]
17 #include "napi/native_api.h"
18 #include "ark_runtime/jsvm.h"
19 #include "hilog/log.h"
20 // [StartExclude oh_jsvm_get_value_external]
21 #define LOG_DOMAIN 0x3200
22 #define LOG_TAG "APP"
23 
24 static int g_aa = 0;
25 
26 #define CHECK_RET(theCall)                                                                                             \
27     do {                                                                                                               \
28         JSVM_Status cond = theCall;                                                                                    \
29         if ((cond) != JSVM_OK) {                                                                                       \
30             const JSVM_ExtendedErrorInfo *info;                                                                        \
31             OH_JSVM_GetLastErrorInfo(env, &info);                                                                      \
32             OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", \
33                          __FILE__, __LINE__, cond, info != nullptr ? info->errorMessage : "");                         \
34             return -1;                                                                                                 \
35         }                                                                                                              \
36     } while (0)
37 
38 #define CHECK(theCall)                                                                                                 \
39     do {                                                                                                               \
40         JSVM_Status cond = theCall;                                                                                    \
41         if ((cond) != JSVM_OK) {                                                                                       \
42             OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d", __FILE__, __LINE__,  \
43                          cond);                                                                                        \
44             return -1;                                                                                                 \
45         }                                                                                                              \
46     } while (0)
47 
48 // 用于调用theCall并检查其返回值是否为JSVM_OK。
49 // 如果不是,则调用OH_JSVM_GetLastErrorInfo处理错误并返回retVal。
50 #define JSVM_CALL_BASE(env, theCall, retVal)                                                                           \
51     do {                                                                                                               \
52         JSVM_Status cond = theCall;                                                                                    \
53         if (cond != JSVM_OK) {                                                                                         \
54             const JSVM_ExtendedErrorInfo *info;                                                                        \
55             OH_JSVM_GetLastErrorInfo(env, &info);                                                                      \
56             OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", \
57                          __FILE__, __LINE__, cond, info != nullptr ? info->errorMessage : "");                         \
58             return retVal;                                                                                             \
59         }                                                                                                              \
60     } while (0)
61 
62 // JSVM_CALL_BASE的简化版本,返回nullptr
63 #define JSVM_CALL(theCall) JSVM_CALL_BASE(env, theCall, nullptr)
64 // [EndExclude oh_jsvm_get_value_external]
65 
66 // OH_JSVM_GetValueExternal的样例方法
GetValueExternal(JSVM_Env env,JSVM_CallbackInfo info)67 static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info)
68 {
69     static int data = 0x12345;
70     JSVM_Value externalValue = nullptr;
71     JSVM_Status status = OH_JSVM_CreateExternal(env, (void*)&data, nullptr, nullptr, &externalValue);
72     if (status != JSVM_OK) {
73         OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail");
74     } else {
75         OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateExternal success");
76     }
77     void *dataValue;
78     status = OH_JSVM_GetValueExternal(env, externalValue, &dataValue);
79     if (status != JSVM_OK) {
80         OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail");
81     } else {
82         OH_LOG_INFO(LOG_APP, "JSVM GetValueExternal success");
83     }
84     // 将符号位转化为int类型传出去
85     JSVM_Value returnValue = nullptr;
86     int retData = *static_cast<int *>(dataValue);
87     OH_JSVM_CreateInt32(env, retData, &returnValue);
88     return returnValue;
89 }
90 // GetValueExternal注册回调
91 static JSVM_CallbackStruct param[] = {
92     {.data = nullptr, .callback = GetValueExternal},
93 };
94 static JSVM_CallbackStruct *method = param;
95 // GetValueExternal方法别名,供JS调用
96 static JSVM_PropertyDescriptor descriptor[] = {
97     {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
98 };
99 // 样例测试js
100 const char* SRC_CALL_NATIVE = R"JS(getValueExternal())JS";
101 // [End oh_jsvm_get_value_external]
102 
TestJSVM()103 static int32_t TestJSVM()
104 {
105     JSVM_InitOptions initOptions = {0};
106     JSVM_VM vm;
107     JSVM_Env env = nullptr;
108     JSVM_VMScope vmScope;
109     JSVM_EnvScope envScope;
110     JSVM_HandleScope handleScope;
111     JSVM_Value result;
112     // 初始化JavaScript引擎实例
113     if (g_aa == 0) {
114         g_aa++;
115         CHECK(OH_JSVM_Init(&initOptions));
116     }
117     // 创建JSVM环境
118     CHECK(OH_JSVM_CreateVM(nullptr, &vm));
119     CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env));
120     CHECK(OH_JSVM_OpenVMScope(vm, &vmScope));
121     CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
122     CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));
123 
124     // 通过script调用测试函数
125     JSVM_Script script;
126     JSVM_Value jsSrc;
127     CHECK_RET(OH_JSVM_CreateStringUtf8(env, SRC_CALL_NATIVE, JSVM_AUTO_LENGTH, &jsSrc));
128     CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
129     CHECK_RET(OH_JSVM_RunScript(env, script, &result));
130 
131     // 销毁JSVM环境
132     CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
133     CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
134     CHECK(OH_JSVM_CloseVMScope(vm, vmScope));
135     CHECK(OH_JSVM_DestroyEnv(env));
136     CHECK(OH_JSVM_DestroyVM(vm));
137     return 0;
138 }
139 
RunTest(napi_env env,napi_callback_info info)140 static napi_value RunTest(napi_env env, napi_callback_info info)
141 {
142     TestJSVM();
143     return nullptr;
144 }
145 
146 // 模块注册信息,供arkts侧调用
147 EXTERN_C_START
Init(napi_env env,napi_value exports)148 static napi_value Init(napi_env env, napi_value exports)
149 {
150     napi_property_descriptor desc[] = {{"runTest", nullptr, RunTest, nullptr, nullptr, nullptr, napi_default, nullptr}};
151     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
152     return exports;
153 }
154 EXTERN_C_END
155 
156 static napi_module demoModule = {
157     .nm_version = 1,
158     .nm_flags = 0,
159     .nm_filename = nullptr,
160     .nm_register_func = Init,
161     .nm_modname = "getvalueexternal",
162     .nm_priv = ((void *)0),
163     .reserved = {0},
164 };
165 
RegisterEntryModule(void)166 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
167