• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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