1e41f4b71Sopenharmony_ci# JSVM-API Debugging
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciJavaScript virtual machine (JSVM) is a standard JavaScript (JS) code execution engine that strictly complies with the ECMAScript specification. For details, see [JSVM](../reference/common/_j_s_v_m.md).
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThe JSVM-based code debugging and tuning capabilities include Debugger, CPU Profiler, Heap Snapshot and Heap Statistics. The following APIs are involved:
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci| API |  Description|
8e41f4b71Sopenharmony_ci|---|---|
9e41f4b71Sopenharmony_ci| OH_JSVM_GetVM  |  Obtains a VM instance.|
10e41f4b71Sopenharmony_ci| OH_JSVM_GetHeapStatistics  |  Obtains heap statistics of a VM.|
11e41f4b71Sopenharmony_ci| OH_JSVM_StartCpuProfiler  |  Creates and starts a CPU profiler instance.|
12e41f4b71Sopenharmony_ci| OH_JSVM_StopCpuProfiler  |  Stops the CPU profiler and outputs the result to a stream.|
13e41f4b71Sopenharmony_ci| OH_JSVM_TakeHeapSnapshot  |  Obtains a snapshot of the current heap and outputs it to a stream.|
14e41f4b71Sopenharmony_ci| OH_JSVM_OpenInspector  |  Opens an inspector instance on the specified host and port for debugging JS code.|
15e41f4b71Sopenharmony_ci| OH_JSVM_OpenInspectorWithName | Opens an inspector instance based on the PID and name. |
16e41f4b71Sopenharmony_ci| OH_JSVM_CloseInspector  |  Closes all remaining inspector connections.|
17e41f4b71Sopenharmony_ci| OH_JSVM_WaitForDebugger  |  Waits for the host to set up a socket connection with an inspector. After the connection is set up, the application continues to run. You can use **Runtime.runIfWaitingForDebugger** to run paused targets.|
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ciThis topic describes how to use Debugger, CPU Profiler, and Heap Snapshot.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci## Using Debugger
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci### Using OH_JSVM_OpenInspector
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci1. Configure the permission for accessing the Internet in the **module.json** file of the application project.
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci   ```
29e41f4b71Sopenharmony_ci   "requestPermissions": [{
30e41f4b71Sopenharmony_ci     "name": "ohos.permission.INTERNET",
31e41f4b71Sopenharmony_ci     "reason": "$string:app_name",
32e41f4b71Sopenharmony_ci     "usedScene": {
33e41f4b71Sopenharmony_ci       "abilities": [
34e41f4b71Sopenharmony_ci         "FromAbility"
35e41f4b71Sopenharmony_ci       ],
36e41f4b71Sopenharmony_ci       "when": "inuse"
37e41f4b71Sopenharmony_ci     }
38e41f4b71Sopenharmony_ci   }]
39e41f4b71Sopenharmony_ci   ```
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ci2. To prevent the pause during the debugging process from being falsely reported as no response, [enable the DevEco Studio debug mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-debug-arkts-debug-0000001767796366-V5) without setting breakpoints or run JSVM-API in threads except the main thread.
42e41f4b71Sopenharmony_ci3. Call **OH_JSVM_OpenInspector** to open an inspector instance on the specified host and port. For example, call **OH_JSVM_OpenInspector(env, "localhost", 9225)** to create a socket on local port 9225 of the device.
43e41f4b71Sopenharmony_ci4. Call **OH_JSVM_WaitForDebugger** to wait for the setup of a socket connection.
44e41f4b71Sopenharmony_ci5. Check whether the port on the device is enabled successfully. For example, run **hdc shell "netstat -anp | grep 9225"**. If the status of port 9225 is **LISTEN**, the port is enabled.
45e41f4b71Sopenharmony_ci6. Forward port. For example, run **hdc fport tcp:9229 tcp:9225** to forward PC port 9229 to device port 9225. If the command output is **Forwardport result:OK**, the port is forwarded successfully.
46e41f4b71Sopenharmony_ci7. Enter **localhost:9229/json** in the address box of the Chrome browser and press **Enter**. Obtain port connection information. Copy the URL in the **devtoolsFrontendUrl** field to the address box and press **Enter**. <br>On the DevTools source code page displayed, the JS source code executed by **OH_JSVM_RunScript** in the application is displayed. The Debugger pauses at the first line of the JS source code.
47e41f4b71Sopenharmony_ci8. You can set breakpoints on the source code page, send debugging commands using the buttons to control JS code execution, and view variables.
48e41f4b71Sopenharmony_ci9. Call **OH_JSVM_CloseInspector** to close the inspector instance and release the socket connection.
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci#### Example
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci```cpp
53e41f4b71Sopenharmony_ci#include "ark_runtime/jsvm.h"
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci#include <string>
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ciusing namespace std;
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci// JS source code to be debugged.
60e41f4b71Sopenharmony_cistatic string srcDebugger = R"JS(
61e41f4b71Sopenharmony_ciconst concat = (...args) => args.reduce((a, b) => a + b);
62e41f4b71Sopenharmony_civar dialogue = concat('"What ', 'is ', 'your ', 'name ', '?"');
63e41f4b71Sopenharmony_cidialogue = concat(dialogue, ' --', '"My ', 'name ', 'is ', 'Bob ', '."');
64e41f4b71Sopenharmony_ci)JS";
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci// Enable the debugger.
67e41f4b71Sopenharmony_cistatic void EnableInspector(JSVM_Env env) {
68e41f4b71Sopenharmony_ci    // Open an inspector instance on the specified host and port to create a socket.
69e41f4b71Sopenharmony_ci    OH_JSVM_OpenInspector(env, "localhost", 9225);
70e41f4b71Sopenharmony_ci    // Wait for the host to set up a socket connection with the inspector.
71e41f4b71Sopenharmony_ci    OH_JSVM_WaitForDebugger(env, true);
72e41f4b71Sopenharmony_ci}
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci// Close the Debugger.
75e41f4b71Sopenharmony_cistatic void CloseInspector(JSVM_Env env) {
76e41f4b71Sopenharmony_ci    // Close the inspector to release the socket connection.
77e41f4b71Sopenharmony_ci    OH_JSVM_CloseInspector(env);
78e41f4b71Sopenharmony_ci}
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_cistatic void RunScript(JSVM_Env env) {
81e41f4b71Sopenharmony_ci    JSVM_HandleScope handleScope;
82e41f4b71Sopenharmony_ci    OH_JSVM_OpenHandleScope(env, &handleScope);
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci    JSVM_Value jsSrc;
85e41f4b71Sopenharmony_ci    OH_JSVM_CreateStringUtf8(env, srcDebugger.c_str(), srcDebugger.size(), &jsSrc);
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ci    JSVM_Script script;
88e41f4b71Sopenharmony_ci    OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script);
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci    JSVM_Value result;
91e41f4b71Sopenharmony_ci    OH_JSVM_RunScript(env, script, &result);
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ci    OH_JSVM_CloseHandleScope(env, handleScope);
94e41f4b71Sopenharmony_ci}
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_civoid RunDemo() {
97e41f4b71Sopenharmony_ci    JSVM_InitOptions initOptions{};
98e41f4b71Sopenharmony_ci    OH_JSVM_Init(&initOptions);
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci    JSVM_VM vm;
101e41f4b71Sopenharmony_ci    OH_JSVM_CreateVM(nullptr, &vm);
102e41f4b71Sopenharmony_ci    JSVM_VMScope vmScope;
103e41f4b71Sopenharmony_ci    OH_JSVM_OpenVMScope(vm, &vmScope);
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci    JSVM_Env env;
106e41f4b71Sopenharmony_ci    OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
107e41f4b71Sopenharmony_ci    // Enable the Debugger before executing the JS code.
108e41f4b71Sopenharmony_ci    EnableInspector(env);
109e41f4b71Sopenharmony_ci    JSVM_EnvScope envScope;
110e41f4b71Sopenharmony_ci    OH_JSVM_OpenEnvScope(env, &envScope);
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci    // Execute the JS code.
113e41f4b71Sopenharmony_ci    RunScript(env);
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci    OH_JSVM_CloseEnvScope(env, envScope);
116e41f4b71Sopenharmony_ci    // Close the Debugger after the JS code is executed.
117e41f4b71Sopenharmony_ci    CloseInspector(env);
118e41f4b71Sopenharmony_ci    OH_JSVM_DestroyEnv(env);
119e41f4b71Sopenharmony_ci    OH_JSVM_CloseVMScope(vm, vmScope);
120e41f4b71Sopenharmony_ci    OH_JSVM_DestroyVM(vm);
121e41f4b71Sopenharmony_ci}
122e41f4b71Sopenharmony_ci```
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci### Using OH_JSVM_OpenInspectorWithName
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci1. Configure the permission for accessing the Internet in the **module.json** file of the application project.
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci   ```
129e41f4b71Sopenharmony_ci   "requestPermissions": [{
130e41f4b71Sopenharmony_ci     "name": "ohos.permission.INTERNET",
131e41f4b71Sopenharmony_ci     "reason": "$string:app_name",
132e41f4b71Sopenharmony_ci     "usedScene": {
133e41f4b71Sopenharmony_ci       "abilities": [
134e41f4b71Sopenharmony_ci         "FromAbility"
135e41f4b71Sopenharmony_ci       ],
136e41f4b71Sopenharmony_ci       "when": "inuse"
137e41f4b71Sopenharmony_ci     }
138e41f4b71Sopenharmony_ci   }]
139e41f4b71Sopenharmony_ci   ```
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci2. To prevent the pause during the debugging process from being falsely reported as no response, [enable the DevEco Studio debug mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-debug-arkts-debug-0000001767796366-V5) without setting breakpoints or run JSVM-API in threads except the main thread.
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci3. Enable the inspector port and connect to devtools for debugging.<br>Before executing the JS code, call **OH_JSVM_OpenInspector** to open an inspector instance on the specified host and port and create a socket. For example, call **OH_JSVM_OpenInspectorWithName (env, 123, "test")** to create a TCP socket and the corresponding unixdomain port.
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci4. Call **OH_JSVM_WaitForDebugger** to wait for the setup of a socket connection.
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci5. Check whether the port on the device is enabled successfully. <br>Run **hdc shell "cat /proc/net/unix | grep jsvm"**. 
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci   The Unix port is displayed, for example, **jsvm_devtools_remote_9229_123**, where **9229** is the TCP port number and **123** is the PID.
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ci6. Forward port. <br>Run **hdc fport tcp:9229 tcp:9229**. In this example, PC port 9229 is forwarded to device port 9229.<br>
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci   If the command output is **Forwardport result:OK**, the port is forwarded successfully.
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci7. Enter **localhost:9229/json** in the address box of the Google Chrome browser and press **Enter**. Obtain port connection information. Open the Chrome developer tool, copy the URL in the **devtoolsFrontendUrl** field to the address box, and press **Enter**. <br>On the DevTools source code page displayed, the JS source code executed by **OH_JSVM_RunScript** is displayed. The Debugger pauses at the first line of the JS source code.
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci8. You can set breakpoints on the source code page, send debugging commands using the buttons to control JS code execution, and view variables.
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci9. Call **OH_JSVM_CloseInspector** to close the inspector instance and release the socket connection.
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci#### Example
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ciReplace the "//Enable the debugger" section with the following:
164e41f4b71Sopenharmony_ci```cpp
165e41f4b71Sopenharmony_ci// Enable the debugger.
166e41f4b71Sopenharmony_cistatic void EnableInspector(JSVM_Env env) {
167e41f4b71Sopenharmony_ci    // Open an inspector instance on the specified host and port to create a socket.
168e41f4b71Sopenharmony_ci    OH_JSVM_OpenInspectorWithName(env, 123, "test");
169e41f4b71Sopenharmony_ci    // Wait for the host to set up a socket connection with the inspector.
170e41f4b71Sopenharmony_ci    OH_JSVM_WaitForDebugger(env, true);
171e41f4b71Sopenharmony_ci}
172e41f4b71Sopenharmony_ci```
173e41f4b71Sopenharmony_ci
174e41f4b71Sopenharmony_ci## Using CPU Profiler and Heap Snapshot
175e41f4b71Sopenharmony_ci
176e41f4b71Sopenharmony_ci### Using CPU Profiler APIs
177e41f4b71Sopenharmony_ci
178e41f4b71Sopenharmony_ci1. Before executing the JS code, call **OH_JSVM_StartCpuProfiler** to start sampling and return a **JSVM_CpuProfiler** instance.
179e41f4b71Sopenharmony_ci2. Run the JS code and call **OH_JSVM_StopCpuProfiler**, in which you need to pass in the **JSVM_CpuProfiler** instance (obtained in step 1), callback for the output stream, and pointer to the output stream. Then, the profiling data will be written to the specified output stream.
180e41f4b71Sopenharmony_ci3. Obtain the output data in JSON strings. You can also save it to the **.cpuprofile** file, which can be parsed into profiling views with the Chrome DevTools-JavaScript Profiler.
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci### Using Heap Snapshot APIs
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci1. To analyze the heap object creation of a piece of JS code, call **OH_JSVM_TakeHeapSnapshot** before and after the JS code is executed. You need to pass in the callback used to return the output stream and the pointer to the output stream. Then, the data will be written to the specified output stream.
185e41f4b71Sopenharmony_ci2. Save the output data to the **.heapsnapshot** file, which can be parsed into memory analysis views with the Chrome DevTools-Memory.
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci### Example
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ci```cpp
190e41f4b71Sopenharmony_ci#include "ark_runtime/jsvm.h"
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ci#include <fstream>
193e41f4b71Sopenharmony_ci#include <iostream>
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ciusing namespace std;
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci// JS code to be optimized.
198e41f4b71Sopenharmony_cistatic string srcProf = R"JS(
199e41f4b71Sopenharmony_cifunction sleep(delay) {
200e41f4b71Sopenharmony_ci    var start = (new Date()).getTime();
201e41f4b71Sopenharmony_ci    while ((new Date()).getTime() - start < delay) {
202e41f4b71Sopenharmony_ci        continue;
203e41f4b71Sopenharmony_ci    }
204e41f4b71Sopenharmony_ci}
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_cifunction work3() {
207e41f4b71Sopenharmony_ci    sleep(300);
208e41f4b71Sopenharmony_ci}
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_cifunction work2() {
211e41f4b71Sopenharmony_ci    work3();
212e41f4b71Sopenharmony_ci    sleep(200);
213e41f4b71Sopenharmony_ci}
214e41f4b71Sopenharmony_ci
215e41f4b71Sopenharmony_cifunction work1() {
216e41f4b71Sopenharmony_ci    work2();
217e41f4b71Sopenharmony_ci    sleep(100);
218e41f4b71Sopenharmony_ci}
219e41f4b71Sopenharmony_ci
220e41f4b71Sopenharmony_ciwork1();
221e41f4b71Sopenharmony_ci)JS";
222e41f4b71Sopenharmony_ci
223e41f4b71Sopenharmony_ci// Callback for the data output stream, which is customized to process the returned data. In this example, the output data is written to a file.
224e41f4b71Sopenharmony_cistatic bool OutputStream(const char *data, int size, void *streamData) {
225e41f4b71Sopenharmony_ci    auto &os = *reinterpret_cast<ofstream *>(streamData);
226e41f4b71Sopenharmony_ci    if (data) {
227e41f4b71Sopenharmony_ci        os.write(data, size);
228e41f4b71Sopenharmony_ci    } else {
229e41f4b71Sopenharmony_ci        os.close();
230e41f4b71Sopenharmony_ci    }
231e41f4b71Sopenharmony_ci    return true;
232e41f4b71Sopenharmony_ci}
233e41f4b71Sopenharmony_ci
234e41f4b71Sopenharmony_cistatic JSVM_CpuProfiler ProfilingBegin(JSVM_VM vm) {
235e41f4b71Sopenharmony_ci    // Specify the path of the file saving the output profiling data. In this example, the sandbox path is /data/storage/el2/base/files, and the bundle name is com.example.helloworld.
236e41f4b71Sopenharmony_ci    // The output data will be saved to /data/app/el2/100/base/com.example.helloworld/files/heap-snapshot-begin.heapsnapshot.
237e41f4b71Sopenharmony_ci    ofstream heapSnapshot("/data/storage/el2/base/files/heap-snapshot-begin.heapsnapshot",
238e41f4b71Sopenharmony_ci                          ios::out | ios:: binary | ios::trunc);
239e41f4b71Sopenharmony_ci    // Task a heap snapshot before the JS code is executed.
240e41f4b71Sopenharmony_ci    OH_JSVM_TakeHeapSnapshot(vm, OutputStream, &heapSnapshot);
241e41f4b71Sopenharmony_ci    JSVM_CpuProfiler cpuProfiler;
242e41f4b71Sopenharmony_ci    // Start the CPU Profiler.
243e41f4b71Sopenharmony_ci    OH_JSVM_StartCpuProfiler(vm, &cpuProfiler);
244e41f4b71Sopenharmony_ci    return cpuProfiler;
245e41f4b71Sopenharmony_ci}
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ci// Stop the profiling data collection tool.
248e41f4b71Sopenharmony_cistatic void ProfilingEnd(JSVM_VM vm, JSVM_CpuProfiler cpuProfiler) {
249e41f4b71Sopenharmony_ci    // Specify the path of the file saving the output profiling data. In this example, the sandbox path is /data/storage/el2/base/files, and the bundle name is com.example.helloworld.
250e41f4b71Sopenharmony_ci    // The output data will be saved to /data/app/el2/100/base/com.example.helloworld/files/cpu-profile.cpuprofile.
251e41f4b71Sopenharmony_ci    ofstream cpuProfile("/data/storage/el2/base/files/cpu-profile.cpuprofile",
252e41f4b71Sopenharmony_ci                        ios::out | ios:: binary | ios::trunc);
253e41f4b71Sopenharmony_ci    // Stop the CPU Profiler to obtain data.
254e41f4b71Sopenharmony_ci    OH_JSVM_StopCpuProfiler(vm, cpuProfiler, OutputStream, &cpuProfile);
255e41f4b71Sopenharmony_ci    ofstream heapSnapshot("/data/storage/el2/base/files/heap-snapshot-end.heapsnapshot",
256e41f4b71Sopenharmony_ci                              ios::out | ios:: binary | ios::trunc);
257e41f4b71Sopenharmony_ci    // After the JS is executed, take a heap snapshot again and compare the two snapshots for further analysis.
258e41f4b71Sopenharmony_ci    OH_JSVM_TakeHeapSnapshot(vm, OutputStream, &heapSnapshot);
259e41f4b71Sopenharmony_ci}
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_cistatic void RunScriptWithStatistics(JSVM_Env env) {
262e41f4b71Sopenharmony_ci    JSVM_VM vm;
263e41f4b71Sopenharmony_ci    OH_JSVM_GetVM(env, &vm);
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci    // Start profiling.
266e41f4b71Sopenharmony_ci    auto cpuProfiler = ProfilingBegin(vm);
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ci    JSVM_HandleScope handleScope;
269e41f4b71Sopenharmony_ci    OH_JSVM_OpenHandleScope(env, &handleScope);
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci    JSVM_Value jsSrc;
272e41f4b71Sopenharmony_ci    OH_JSVM_CreateStringUtf8(env, srcProf.c_str(), srcProf.size(), &jsSrc);
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci    JSVM_Script script;
275e41f4b71Sopenharmony_ci    OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script);
276e41f4b71Sopenharmony_ci
277e41f4b71Sopenharmony_ci    JSVM_Value result;
278e41f4b71Sopenharmony_ci    // Execute the JS code.
279e41f4b71Sopenharmony_ci    OH_JSVM_RunScript(env, script, &result);
280e41f4b71Sopenharmony_ci
281e41f4b71Sopenharmony_ci    OH_JSVM_CloseHandleScope(env, handleScope);
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci    // End profiling.
284e41f4b71Sopenharmony_ci    ProfilingEnd(vm, cpuProfiler);
285e41f4b71Sopenharmony_ci}
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_civoid RunDemo() {
288e41f4b71Sopenharmony_ci    JSVM_InitOptions initOptions{};
289e41f4b71Sopenharmony_ci    OH_JSVM_Init(&initOptions);
290e41f4b71Sopenharmony_ci
291e41f4b71Sopenharmony_ci    JSVM_VM vm;
292e41f4b71Sopenharmony_ci    OH_JSVM_CreateVM(nullptr, &vm);
293e41f4b71Sopenharmony_ci    JSVM_VMScope vmScope;
294e41f4b71Sopenharmony_ci    OH_JSVM_OpenVMScope(vm, &vmScope);
295e41f4b71Sopenharmony_ci
296e41f4b71Sopenharmony_ci    JSVM_Env env;
297e41f4b71Sopenharmony_ci    OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
298e41f4b71Sopenharmony_ci    JSVM_EnvScope envScope;
299e41f4b71Sopenharmony_ci    OH_JSVM_OpenEnvScope(env, &envScope);
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci    RunScriptWithStatistics(env);
302e41f4b71Sopenharmony_ci
303e41f4b71Sopenharmony_ci    OH_JSVM_CloseEnvScope(env, envScope);
304e41f4b71Sopenharmony_ci    OH_JSVM_DestroyEnv(env);
305e41f4b71Sopenharmony_ci    OH_JSVM_CloseVMScope(vm, vmScope);
306e41f4b71Sopenharmony_ci    OH_JSVM_DestroyVM(vm);
307e41f4b71Sopenharmony_ci}
308e41f4b71Sopenharmony_ci```
309e41f4b71Sopenharmony_ci<!--no_check-->