1# 使用JSVM-API接口进行生命周期相关开发 2 3## 简介 4 5在JSVM-API中,JSVM_Value是一个表示JavaScript值的抽象类型,它可以表示任何JavaScript值,包括基本类型(如数字、字符串、布尔值)和对象类型(如数组、函数、对象等)。 6JSVM_Value的生命周期与其在JavaScript中的对应值的生命周期紧密相关。当JavaScript值被垃圾回收时,与之关联的JSVM_Value也将不再有效。重要的是不要在JavaScript值不再存在时尝试使用JSVM_Value。 7 8框架层的scope通常用于管理JSVM_Value的生命周期。在JSVM-API中,可以使用OH_JSVM_OpenHandleScope和OH_JSVM_CloseHandleScope函数来创建和销毁scope。通过在scope内创建JSVM_Value,可以确保在scope结束时自动释放JSVM_Value,避免内存泄漏。 9 10JSVM_Ref是一个JSVM-API类型,用于管理JSVM_Value的生命周期。JSVM_Ref允许您在JSVM_Value的生命周期内保持对其的引用,即使它已经超出了其原始上下文的范围。这使得您可以在不同的上下文中共享JSVM_Value,并确保在不再需要时正确释放其内存。 11 12合理使用OH_JSVM_OpenHandleScope和OH_JSVM_CloseHandleScope管理JSVM_Value的生命周期,做到生命周期最小化,避免发生内存泄漏问题。 13 14每个JSVM_Value属于特定的HandleScope,HandleScope通过OH_JSVM_OpenHandleScope和OH_JSVM_CloseHandleScope来建立和关闭,HandleScope关闭后,所属的JSVM_Value就会自动释放。 15 16## 基本概念 17 18JSVM-API提供了一组功能,使开发人员能够在JSVM-API模块中创建和操作JavaScript对象,管理引用和生命周期,并注册垃圾回收回调函数等。下面是一些基本概念: 19 20- **作用域**:用于创建一个范围,在范围内声明的引用在范围外部将不再生效。JSVM-API提供了创建、关闭普通和可逃逸的作用域的函数。 21- **引用管理**:JSVM-API提供函数来创建、删除和管理对象的引用,以延长对象的生命周期,并避免在使用对象时发生内存泄漏。 22- **可逃逸的作用域**:允许在创建的作用域中声明的对象返回到父作用域,通过OH_JSVM_OpenEscapableHandleScope和OH_JSVM_CloseEscapableHandleScope进行管理。 23- **垃圾回收回调**:允许注册回调函数,以便在JavaScript对象被垃圾回收时执行特定的清理操作。 24 25这些基本概念使开发人员能够在JSVM-API模块中安全且有效地操作JavaScript对象,并确保正确管理对象的生命周期。 26 27## 接口说明 28 29| 接口 | 功能说明 | 30|----------------------------|--------------------------------| 31| OH_JSVM_OpenHandleScope | 打开一个Handle scope,确保scope范围内的JSVM_Value不被GC回收 | 32| OH_JSVM_CloseHandleScope | 关闭Handle scope| 33| OH_JSVM_OpenEscapableHandleScope | 打开一个新的scope逃逸Handle scope,在关闭该scope之前创建的对象与父作用域有相同的生命周期 | 34| OH_JSVM_CloseEscapableHandleScope | 关闭一个scope,在此scope范围外创建的对象不受父作用域保护 | 35| OH_JSVM_EscapeHandle | 将JavaScript对象的句柄提升到外部作用域,确保在外部作用域中可以持续地使用该对象 | 36| OH_JSVM_CreateReference | 以指定的引用计数为JavaScript对象创建一个新的引用,该引用将指向传入的对象,引用允许在不同的上下文中使用和共享对象,并且可以有效地跟踪对象的生命周期 | 37| OH_JSVM_DeleteReference | 释放由OH_JSVM_CreateReference创建的引用,确保对象在不再被使用时能够被正确地释放和回收,避免内存泄漏 | 38| OH_JSVM_ReferenceRef | 增加由OH_JSVM_CreateReference创建的引用的引用计数,以确保对象在有引用时不会被提前释放 | 39| OH_JSVM_ReferenceUnref | 减少引用计数,用于管理引用计数。| 40| OH_JSVM_GetReferenceValue | 减少由OH_JSVM_CreateReference创建的引用的引用计数,以确保没有任何引用指向该对象时能正确地释放和回收 | 41| OH_JSVM_AddFinalizer | 为对象添加JSVM_Finalize回调,以便在JavaScript对象被垃圾回收时调用来释放原生对象。| 42 43## 使用示例 44 45JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。 46 47### OH_JSVM_OpenHandleScope、OH_JSVM_CloseHandleScope 48 49通过接口OH_JSVM_OpenHandleScope创建一个上下文环境使用。需要使用OH_JSVM_CloseHandleScope进行关闭。用于管理JavaScript对象的生命周期确保在JSVM-API模块代码处理JavaScript对象时能够正确地管理其句柄,以避免出现垃圾回收相关的问题。 50 51cpp部分代码 52 53```cpp 54// hello.cpp 55#include "napi/native_api.h" 56#include "ark_runtime/jsvm.h" 57#include <hilog/log.h> 58// HandleScopeTest、HandleScope、HandleScopeFor注册回调 59static JSVM_CallbackStruct param[] = { 60 {.data = nullptr, .callback = HandleScopeTest}, 61 {.data = nullptr, .callback = HandleScope}, 62 {.data = nullptr, .callback = HandleScopeFor}, 63}; 64static JSVM_CallbackStruct *method = param; 65// HandleScopeTest、HandleScope、HandleScopeFor方法别名,供JS调用 66static JSVM_PropertyDescriptor descriptor[] = { 67 {"handleScopeTest", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 68 {"handleScope", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 69 {"handleScopeFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 70}; 71static int DIFF_VALUE_HUNDRED_THOUSAND = 100000; 72// OH_JSVM_OpenHandleScope、OH_JSVM_CloseHandleScope的三种样例方法 73static JSVM_Value HandleScopeFor(JSVM_Env env, JSVM_CallbackInfo info) 74{ 75 // 在for循环中频繁调用JSVM接口创建js对象时,要加handle_scope及时释放不再使用的资源。 76 // 下面例子中,每次循环结束局部变量res的生命周期已结束,因此加scope及时释放其持有的js对象,防止内存泄漏 77 JSVM_Value checked = nullptr; 78 for (int i = 0; i < DIFF_VALUE_HUNDRED_THOUSAND; i++) { 79 JSVM_HandleScope scope = nullptr; 80 JSVM_Status status = OH_JSVM_OpenHandleScope(env, &scope); 81 if (status != JSVM_OK || scope == nullptr) { 82 OH_JSVM_GetBoolean(env, false, &checked); 83 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_OpenHandleScope: failed"); 84 return checked; 85 } 86 JSVM_Value res = nullptr; 87 OH_JSVM_CreateObject(env, &res); 88 status = OH_JSVM_CloseHandleScope(env, scope); 89 if (status != JSVM_OK) { 90 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CloseHandleScope: failed"); 91 } 92 } 93 OH_JSVM_GetBoolean(env, true, &checked); 94 OH_LOG_INFO(LOG_APP, "JSVM HandleScopeFor: success"); 95 return checked; 96} 97 98static JSVM_Value HandleScopeTest(JSVM_Env env, JSVM_CallbackInfo info) 99{ 100 // 注意: 101 // 以下代码中obj是在句柄作用域内创建的,然后通过OH_JSVM_OpenHandleScope关闭了句柄作用域。 102 // 但在此情况下可以正常返回出去。 103 // 这是因为在这段代码中,obj是通过将其返回作为函数的返回值的方式, 104 // 而不需要在句柄作用域之外继续使用obj。因此,代码中obj能够正常返回出去。 105 // 通过调用OH_JSVM_OpenHandleScope来创建一个句柄作用域 106 JSVM_HandleScope scope = nullptr; 107 JSVM_Status status = OH_JSVM_OpenHandleScope(env, &scope); 108 if (status != JSVM_OK) { 109 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_OpenHandleScope: failed"); 110 return nullptr; 111 } 112 // 在句柄作用域内创建一个obj 113 JSVM_Value obj = nullptr; 114 OH_JSVM_CreateObject(env, &obj); 115 // 在对象中添加属性 116 JSVM_Value value = nullptr; 117 OH_JSVM_CreateStringUtf8(env, "test handleScope", JSVM_AUTO_LENGTH, &value); 118 OH_JSVM_SetNamedProperty(env, obj, "name", value); 119 // 关闭句柄作用域,自动释放在该作用域内创建的对象句柄 120 status = OH_JSVM_CloseHandleScope(env, scope); 121 if (status != JSVM_OK) { 122 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CloseHandleScope: failed"); 123 return nullptr; 124 } 125 OH_LOG_INFO(LOG_APP, "JSVM HandleScopeTest: success"); 126 return obj; 127} 128 129static JSVM_Value HandleScope(JSVM_Env env, JSVM_CallbackInfo info) 130{ 131 // 通过调用OH_JSVM_OpenHandleScope来创建一个句柄作用域 132 JSVM_HandleScope scope = nullptr; 133 JSVM_Status status = OH_JSVM_OpenHandleScope(env, &scope); 134 if (status != JSVM_OK) { 135 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_OpenHandleScope: failed"); 136 return nullptr; 137 } 138 // 在句柄作用域内创建一个obj 139 JSVM_Value obj = nullptr; 140 OH_JSVM_CreateObject(env, &obj); 141 // 在对象中添加属性 142 JSVM_Value value = nullptr; 143 OH_JSVM_CreateStringUtf8(env, "handleScope", JSVM_AUTO_LENGTH, &value); 144 OH_JSVM_SetNamedProperty(env, obj, "name", value); 145 // 关闭句柄作用域,自动释放在该作用域内创建的对象句柄 146 status = OH_JSVM_CloseHandleScope(env, scope); 147 if (status != JSVM_OK) { 148 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CloseHandleScope: failed"); 149 return nullptr; 150 } 151 // 关闭句柄作用域之后继续在对象中添加属性,jsvm中原先设置的name失效 152 OH_JSVM_CreateStringUtf8(env, "001", JSVM_AUTO_LENGTH, &value); 153 OH_JSVM_SetNamedProperty(env, obj, "id", value); 154 // 此处的obj的name失效 155 bool result = true; 156 OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &value); 157 OH_JSVM_HasProperty(env, obj, value, &result); 158 if (!result) { 159 OH_LOG_INFO(LOG_APP, "JSVM HandleScope: success"); 160 } 161 return obj; 162} 163``` 164 165ArkTS侧示例代码 166 167```ts 168import hilog from "@ohos.hilog" 169// 通过import的方式,引入Native能力。 170import napitest from "libentry.so" 171try { 172 let script: string = `handleScopeTest()`; 173 let result = napitest.runJsVm(script); 174 hilog.info(0x0000, 'testJSVM', 'Test JSVM handleScopeTest: %{public}s', result); 175} catch (error) { 176 hilog.error(0x0000, 'testJSVM', 'Test JSVM handleScopeTest error: %{public}s', error.message); 177} 178try { 179 let script: string = `handleScope()`; 180 let result = napitest.runJsVm(script); 181 hilog.info(0x0000, 'testJSVM', 'Test JSVM handleScope: %{public}s', result); 182} catch (error) { 183 hilog.error(0x0000, 'testJSVM', 'Test JSVM handleScope error: %{public}s', error.message); 184} 185try { 186 let script: string = `handleScopeFor()`; 187 let result = napitest.runJsVm(script); 188 hilog.info(0x0000, 'testJSVM', 'Test JSVM handleScopeFor: %{public}s', result); 189} catch (error) { 190 hilog.error(0x0000, 'testJSVM', 'Test JSVM handleScopeFor error: %{public}s', error.message); 191} 192``` 193 194### OH_JSVM_OpenEscapableHandleScope、OH_JSVM_CloseEscapableHandleScope、OH_JSVM_EscapeHandle 195 196通过接口OH_JSVM_OpenEscapableHandleScope创建出一个可逃逸的handel scope,可将范围内声明的值返回到父作用域。需要使用OH_JSVM_CloseEscapableHandleScope进行关闭。OH_JSVM_EscapeHandle用于提升传入的JavaScript对象的生命周期到其父作用域。 197通过上述接口可以更灵活的使用管理传入的JavaScript对象,特别是在处理跨作用域的值传递时非常有用。 198 199cpp部分代码 200 201```cpp 202// hello.cpp 203#include "napi/native_api.h" 204#include "ark_runtime/jsvm.h" 205#include <hilog/log.h> 206// EscapableHandleScopeTest注册回调 207static JSVM_CallbackStruct param[] = { 208 {.data = nullptr, .callback = EscapableHandleScopeTest}, 209}; 210static JSVM_CallbackStruct *method = param; 211// EscapableHandleScopeTest方法别名,供JS调用 212static JSVM_PropertyDescriptor descriptor[] = { 213 {"escapableHandleScopeTest", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 214}; 215// OH_JSVM_OpenEscapableHandleScope、OH_JSVM_CloseEscapableHandleScope、OH_JSVM_EscapeHandle的样例方法 216static JSVM_Value EscapableHandleScopeTest(JSVM_Env env, JSVM_CallbackInfo info) 217{ 218 // 创建一个可逃逸的句柄作用域 219 JSVM_EscapableHandleScope scope = nullptr; 220 JSVM_Status status = OH_JSVM_OpenEscapableHandleScope(env, &scope); 221 if (status != JSVM_OK) { 222 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_OpenEscapableHandleScope: failed"); 223 return nullptr; 224 } 225 // 在可逃逸的句柄作用域内创建一个obj 226 JSVM_Value obj; 227 OH_JSVM_CreateObject(env, &obj); 228 // 在对象中添加属性 229 JSVM_Value value = nullptr; 230 OH_JSVM_CreateStringUtf8(env, "Test jsvm_escapable_handle_scope", JSVM_AUTO_LENGTH, &value); 231 OH_JSVM_SetNamedProperty(env, obj, "name", value); 232 // 调用OH_JSVM_EscapeHandle将对象逃逸到作用域之外 233 JSVM_Value escapedObj = nullptr; 234 OH_JSVM_EscapeHandle(env, scope, obj, &escapedObj); 235 // 关闭可逃逸的句柄作用域,清理资源 236 status = OH_JSVM_CloseEscapableHandleScope(env, scope); 237 if (status != JSVM_OK) { 238 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CloseEscapableHandleScope: failed"); 239 return nullptr; 240 } 241 // 在作用域外继续使用escapedObj 此时的escapedObj已逃逸,可以设置成功,在ArkTS侧可以取到东西 242 OH_JSVM_CreateStringUtf8(env, "001", JSVM_AUTO_LENGTH, &value); 243 OH_JSVM_SetNamedProperty(env, obj, "id", value); 244 bool result = false; 245 OH_JSVM_CreateStringUtf8(env, "id", JSVM_AUTO_LENGTH, &value); 246 OH_JSVM_HasProperty(env, obj, value, &result); 247 if (result) { 248 OH_LOG_INFO(LOG_APP, "JSVM EscapableHandleScopeTest: success"); 249 } 250 return escapedObj; 251} 252``` 253 254接口声明 255 256ArkTS侧示例代码 257 258```ts 259import hilog from "@ohos.hilog" 260// 通过import的方式,引入Native能力。 261import napitest from "libentry.so" 262try { 263 let script: string = `escapableHandleScopeTest()`; 264 let result = napitest.runJsVm(script); 265 hilog.info(0x0000, 'testJSVM', 'Test JSVM escapableHandleScopeTest: %{public}s', result); 266} catch (error) { 267 hilog.error(0x0000, 'testJSVM', 'Test JSVM escapableHandleScopeTest error: %{public}s', error.message); 268} 269``` 270 271### OH_JSVM_CreateReference、OH_JSVM_DeleteReference 272 273为Object创建一个reference,以延长其生命周期。调用者需要自己管理reference生命周期。可以调用OH_JSVM_DeleteReference删除传入的reference。 274 275### OH_JSVM_ReferenceRef、OH_JSVM_ReferenceUnref 276 277增加/减少 传入的reference的引用计数,并获取新的计数。 278 279### OH_JSVM_GetReferenceValue 280 281获取与reference相关联的JavaScript Object。 282 283### OH_JSVM_AddFinalizer 284 285当JavaScript Object中的对象被垃圾回收时调用注册的OH_JSVM_AddFinalizer回调。 286 287cpp部分代码 288 289```cpp 290// hello.cpp 291#include "napi/native_api.h" 292#include "ark_runtime/jsvm.h" 293#include <hilog/log.h> 294// CreateReference、UseReference、DeleteReference注册回调 295static JSVM_CallbackStruct param[] = { 296 {.data = nullptr, .callback = CreateReference}, 297 {.data = nullptr, .callback = UseReference}, 298 {.data = nullptr, .callback = DeleteReference}, 299}; 300static JSVM_CallbackStruct *method = param; 301// CreateReference、UseReference、DeleteReference方法别名,供JS调用 302static JSVM_PropertyDescriptor descriptor[] = { 303 {"createReference", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 304 {"useReference", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 305 {"deleteReference", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 306}; 307// OH_JSVM_CreateReference、OH_JSVM_AddFinalizer的样例方法 308static JSVM_Value CreateReference(JSVM_Env env, JSVM_CallbackInfo info) 309{ 310 JSVM_Ref g_ref = nullptr; 311 JSVM_Value obj = nullptr; 312 OH_JSVM_CreateObject(env, &obj); 313 JSVM_Value value = nullptr; 314 OH_JSVM_CreateStringUtf8(env, "CreateReference", JSVM_AUTO_LENGTH, &value); 315 // 将键值对添加到对象中 316 OH_JSVM_SetNamedProperty(env, obj, "name", value); 317 // 创建对JavaScript对象的引用 318 JSVM_Status status = OH_JSVM_CreateReference(env, obj, 1, &g_ref); 319 if (status != JSVM_OK) { 320 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateReference: failed"); 321 return nullptr; 322 } 323 JSVM_Finalize jSVM_Finalize = nullptr; 324 OH_JSVM_AddFinalizer(env, obj, nullptr, jSVM_Finalize, nullptr, &g_ref); 325 // 增加传入引用的引用计数并返回生成的引用计数 326 uint32_t result; 327 OH_JSVM_ReferenceRef(env, g_ref, &result); 328 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_ReferenceRef, count = %{public}d.", result); 329 if (result != 2) { 330 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_ReferenceRef: failed"); 331 return nullptr; 332 } 333 OH_LOG_INFO(LOG_APP, "JSVM CreateReference success"); 334 return obj; 335} 336// OH_JSVM_ReferenceRef、OH_JSVM_GetReferenceValue的样例方法 337static JSVM_Value UseReference(JSVM_Env env, JSVM_CallbackInfo info) 338{ 339 JSVM_Ref g_ref = nullptr; 340 JSVM_Value obj = nullptr; 341 OH_JSVM_CreateObject(env, &obj); 342 JSVM_Value value = nullptr; 343 OH_JSVM_CreateStringUtf8(env, "UseReference", JSVM_AUTO_LENGTH, &value); 344 // 将键值对添加到对象中 345 OH_JSVM_SetNamedProperty(env, obj, "name", value); 346 // 创建对JavaScript对象的引用 347 JSVM_Status status = OH_JSVM_CreateReference(env, obj, 1, &g_ref); 348 if (status != JSVM_OK) { 349 return nullptr; 350 } 351 JSVM_Finalize jSVM_Finalize = nullptr; 352 OH_JSVM_AddFinalizer(env, obj, nullptr, jSVM_Finalize, nullptr, &g_ref); 353 // 增加传入引用的引用计数并返回生成的引用计数 354 uint32_t result; 355 OH_JSVM_ReferenceRef(env, g_ref, &result); 356 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_ReferenceRef, count = %{public}d.", result); 357 if (result != 2) { 358 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_ReferenceRef: failed"); 359 return nullptr; 360 } 361 JSVM_Value object = nullptr; 362 // 通过调用OH_JSVM_GetReferenceValue获取引用的JavaScript对象 363 status = OH_JSVM_GetReferenceValue(env, g_ref, &object); 364 if (status != JSVM_OK) { 365 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetReferenceValue: failed"); 366 return nullptr; 367 } 368 // 将获取到的对象返回 369 OH_LOG_INFO(LOG_APP, "JSVM UseReference success"); 370 return object; 371} 372// OH_JSVM_ReferenceUnref、OH_JSVM_DeleteReference的样例方法 373static JSVM_Value DeleteReference(JSVM_Env env, JSVM_CallbackInfo info) 374{ 375 JSVM_Ref g_ref = nullptr; 376 JSVM_Value obj = nullptr; 377 OH_JSVM_CreateObject(env, &obj); 378 JSVM_Value value = nullptr; 379 OH_JSVM_CreateStringUtf8(env, "DeleteReference", JSVM_AUTO_LENGTH, &value); 380 // 将键值对添加到对象中 381 OH_JSVM_SetNamedProperty(env, obj, "name", value); 382 // 创建对JavaScript对象的引用 383 JSVM_Status status = OH_JSVM_CreateReference(env, obj, 1, &g_ref); 384 if (status != JSVM_OK) { 385 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateReference: failed"); 386 return nullptr; 387 } 388 JSVM_Finalize jSVM_Finalize = nullptr; 389 OH_JSVM_AddFinalizer(env, obj, nullptr, jSVM_Finalize, nullptr, &g_ref); 390 // 增加传入引用的引用计数并返回生成的引用计数 391 uint32_t result; 392 OH_JSVM_ReferenceRef(env, g_ref, &result); 393 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_ReferenceRef, count = %{public}d.", result); 394 if (result != 2) { 395 return nullptr; 396 } 397 // 减少传入引用的引用计数并返回生成的引用计数 398 uint32_t num; 399 OH_JSVM_ReferenceUnref(env, g_ref, &num); 400 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_ReferenceUnref, count = %{public}d.", num); 401 if (num != 1) { 402 return nullptr; 403 } 404 // 通过调用OH_JSVM_DeleteReference删除对JavaScript对象的引用 405 status = OH_JSVM_DeleteReference(env, g_ref); 406 if (status != JSVM_OK) { 407 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_DeleteReference: failed"); 408 return nullptr; 409 } 410 JSVM_Value returnResult = nullptr; 411 OH_JSVM_CreateStringUtf8(env, "OH_JSVM_DeleteReference success", JSVM_AUTO_LENGTH, &returnResult); 412 OH_LOG_INFO(LOG_APP, "JSVM DeleteReference success"); 413 return returnResult; 414} 415``` 416 417ArkTS侧示例代码 418 419```ts 420import hilog from "@ohos.hilog" 421// 通过import的方式,引入Native能力。 422import napitest from "libentry.so" 423try { 424 let script: string = `createReference();`; 425 let result = napitest.runJsVm(script); 426 hilog.info(0x0000, 'testJSVM', 'Test JSVM createReference: %{public}s', result); 427} catch (error) { 428 hilog.error(0x0000, 'testJSVM', 'Test JSVM createReference error: %{public}s', error.message); 429} 430try { 431 let script: string = `useReference();`; 432 let result = napitest.runJsVm(script); 433 hilog.info(0x0000, 'testJSVM', 'Test JSVM useReference: %{public}s', result); 434} catch (error) { 435 hilog.error(0x0000, 'testJSVM', 'Test JSVM useReference error: %{public}s', error.message); 436} 437try { 438 let script: string = `deleteReference();`; 439 let result = napitest.runJsVm(script); 440 hilog.info(0x0000, 'testJSVM', 'Test JSVM deleteReference: %{public}s', result); 441} catch (error) { 442 hilog.error(0x0000, 'testJSVM', 'Test JSVM deleteReference error: %{public}s', error.message); 443} 444``` 445