• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# JSVM-API Data Types and APIs
2
3## Data Types
4
5### JSVM_Status
6
7Defines an enum for the execution statuses returned by a JSVM-API call.
8
9Each time a JSVM-API function is called, **JSVM_Status** is returned indicating the execution result.
10
11```c++
12    typedef enum {
13        JSVM_OK,                              /* Successful. */
14        JSVM_INVALID_ARG,                     /* Invalid parameters. */
15        JSVM_OBJECT_EXPECTED,                 /* An object is expected. */
16        JSVM_STRING_EXPECTED,                 /* A string is expected. */
17        JSVM_NAME_EXPECTED,                   /* A name is expected. */
18        JSVM_FUNCTION_EXPECTED,               /* A function is expected. */
19        JSVM_NUMBER_EXPECTED,                 /* A number is expected. */
20        JSVM_BOOL_EXPECTED,                   /* A Boolean value is expected. */
21        JSVM_ARRAY_EXPECTED,                  /* An array is expected. */
22        JSVM_GENERIC_FAILURE,                 /* Generic failure. */
23        JSVM_PENDING_EXCEPTION,               /* Pending exception. */
24        JSVM_CENCELLED,                       /* Cancelled. */
25        JSVM_ESCAPE_CALLED_TWICE,             /* Escape is called twice. */
26        JSVM_HANDLE_SCOPE_MISMATCH,           /* Handle scope does not match. */
27        JSVM_CALLBACK_SCOPE_MISMATCH,         /* Callback scope does not match. */
28        JSVM_QUEUE_FULL,                      /* The queue is full. */
29        JSVM_CLOSING,                         /* Closing. */
30        JSVM_BIGINT_EXPECTED,                 /* A Bigint value is expected. */
31        JSVM_DATA_EXPECTED,                   /* A date is expected. */
32        JSVM_ARRAYBUFFER_EXPECTED,            /* An ArrayBuffer is expected. */
33        JSVM_DETACHABLE_ARRAYBUFFER_EXPECTED, /* A detachable ArrayBuffer is expected. */
34        JSVM_WOULD_DEADLOCK,                  /* About to deadlock. */
35        JSVM_NO_EXTERNAL_BUFFERS_ALLOWED,     /* External buffers are not allowed. */
36        JSVM_CANNOT_RUN_JS,                   /* JS cannot be executed. */
37        JSVM_JIT_MODE_EXPECTD,                /* JIT mode is expected. */
38    } JSVM_Status;
39```
40
41### JSVM_ExtendedErrorInfo
42
43Defines a struct that represents detailed error information when a JSVM-API call fails.
44
45```c++
46typedef struct {
47    const char* errorMessage;
48    void* engineReserved;
49    uint32_t engineErrorCode;
50    JSVM_Status errorCode;
51} JSVM_ExtendedErrorInfo;
52```
53
54### JSVM_Value
55
56Defines a pointer to a JavaScript (JS) value.
57
58### JSVM_Env
59
60Defines the context for the underlying JSVM-API implementation. It is passed to the JSVM-API interface in a native function as an input parameter.
61
62- When the native addon exits, **JSVM_Env** becomes invalid and this event is passed to **OH_JSVM_SetInstanceData** via a callback.
63
64- Avoid caching **JSVM_Env** or passing **JSVM_Env** between different worker threads.
65
66- If **JSVM_Env** is shared between different threads, the **threadlocal** variable must be isolated across threads. For this purpose, close the env scope of the current thread before switching to another thread and open a new env scope in each thread switched to.
67
68### JSVM_ValueType
69
70Defines an enum for the **JSVM_Value** types. **JSVM_Value** includes the types defined in ECMAScript. **JSVM_EXTERNAL** indicates an external data type.
71
72```c++
73typedef enum {
74    JSVM_UNDEFINED,
75    JSVM_NULL,
76    JSVM_BOOLEAN,
77    JSVM_NUMBER,
78    JSVM_STRING,
79    JSVM_SYMBOL,
80    JSVM_OBJECT,
81    JSVM_FUNCTION,
82    JSVM_EXTERNAL,
83    JSVM_BIGINT,
84} JSVM_ValueType;
85```
86
87### JSVM_TypedarrayType
88
89Defines an enum for data types of the **TypedArray** object.
90
91```c++
92typedef enum {
93    JSVM_INT8_ARRAY,
94    JSVM_UINT8_ARRAY,
95    JSVM_UINT8_CLAMPED_ARRAY,
96    JSVM_INT16_ARRAY,
97    JSVM_UINT16_ARRAY,
98    JSVM_INT32_ARRAY,
99    JSVM_UINT32_ARRAY,
100    JSVM_FLOAT32_ARRAY,
101    JSVM_FLOAT64_ARRAY,
102    JSVM_BIGINT64_ARRAY,
103    JSVM_BIGUINT64_ARRAY,
104} JSVM_TypedarrayType;
105```
106
107### JSVM_RegExpFlags
108
109Defines an enum for regular expression flags.
110
111```c++
112typedef enum {
113    JSVM_REGEXP_NONE = 0,
114    JSVM_REGEXP_GLOBAL = 1 << 0,
115    JSVM_REGEXP_IGNORE_CASE = 1 << 1,
116    JSVM_REGEXP_MULTILINE = 1 << 2,
117    JSVM_REGEXP_STICKY = 1 << 3,
118    JSVM_REGEXP_UNICODE = 1 << 4,
119    JSVM_REGEXP_DOT_ALL = 1 << 5,
120    JSVM_REGEXP_LINEAR = 1 << 6,
121    JSVM_REGEXP_HAS_INDICES = 1 << 7,
122    JSVM_REGEXP_UNICODE_SETS = 1 << 8,
123} JSVM_RegExpFlags;
124```
125
126### Compilation Option Types
127#### JSVM_CompileOptions
128
129Defines a struct that represents the type of the elements in **options** of **OH_JSVM_CompileScriptWithOptions**.
130
131The struct consists of the following parameters:
132- **id**: identifies a compilation option.
133- **content**: specifies a compilation option.
134
135**id** and **content** together define a compilation option.
136
137```c
138typedef struct {
139    /** Compilation option type. */
140    JSVM_CompileOptionId id;
141    /** Compilation option content. */
142    union {
143      /** ptr type. */
144      void *ptr;
145      /** int type. */
146      int num;
147      /** bool type. */
148      _Bool boolean;
149    } content;
150} JSVM_CompileOptions;
151```
152
153#### JSVM_CompileOptionId
154
155Defines an enum for **id** in **JSVM_CompileOptions**. Each **id** corresponds to a **content** value. The value **JSVM_COMPILE_ENABLE_SOURCE_MAP** corresponds to bool and is valid only when **sourceMapUrl** in **JSVM_ScriptOrigin** is not empty.
156
157```c
158typedef enum {
159    /** Compilation mode. */
160    JSVM_COMPILE_MODE,
161    /** Code cache. */
162    JSVM_COMPILE_CODE_CACHE,
163    /** Script origin. */
164    JSVM_COMPILE_SCRIPT_ORIGIN,
165    /** Compilation profile. */
166    JSVM_COMPILE_COMPILE_PROFILE,
167    /** Switch for source map support. */
168    JSVM_COMPILE_ENABLE_SOURCE_MAP,
169} JSVM_CompileOptionId;
170```
171
172#### JSVM_CompileMode
173
174Defines an enum for the compilation modes when **id** is **JSVM_COMPILE_MODE**.
175
176- **JSVM_COMPILE_MODE_DEFAULT**: indicates the default compilation mode.
177- **JSVM_COMPILE_MODE_CONSUME_CODE_CACHE**: indicates the compilation with the code cache.
178- **JSVM_COMPILE_MODE_EAGER_COMPILE**: indicates full compilation.
179- **JSVM_COMPILE_MODE_PRODUCE_COMPILE_PROFILE**/**JSVM_COMPILE_MODE_CONSUME_COMPILE_PROFILE**: reserved at present.
180
181```c
182typedef enum {
183    /** Default mode. */
184    JSVM_COMPILE_MODE_DEFAULT,
185    /** Compilation by leveraging the code cache. */
186    JSVM_COMPILE_MODE_CONSUME_CODE_CACHE,
187    /** Full compilation. */
188    JSVM_COMPILE_MODE_EAGER_COMPILE,
189    /** Compilation with a preset compilation profile. */
190    JSVM_COMPILE_MODE_PRODUCE_COMPILE_PROFILE,
191    /** Compilation by using a compile profile. */
192    JSVM_COMPILE_MODE_CONSUME_COMPILE_PROFILE,
193} JSVM_CompileMode;
194```
195
196
197#### JSVM_CodeCache
198
199Defines a struct that represents the code cache when **id** is **JSVM_COMPILE_CODE_CACHE**. The struct consists of the following:
200
201- **cache**: pointer to the code cache to use.
202- **length**: size of the code cache.
203
204```c
205typedef struct {
206    /** cache pointer. */
207    uint8_t *cache;
208    /** length. */
209    size_t length;
210} JSVM_CodeCache;
211```
212
213#### JSVM_ScriptOrigin
214
215Defines a struct that represents the source code of the script to compile when **id** is **JSVM_COMPILE_SCRIPT_ORIGIN**. The struct consists of the following:
216
217- **sourceMapUrl**: path of the source map. Currently, only the local paths of the device are supported. This parameter can be left empty.
218- **resourceName**: name of the JS script to be compiled.
219
220```c
221typedef struct {
222    /** Source map URL. */
223    const char* sourceMapUrl;
224    /** Script to compile. */
225    const char* resourceName;
226    /** Line offset in the script. */
227    size_t resourceLineOffset;
228    /** Column offset in the script. */
229    size_t resourceColumnOffset;
230} JSVM_ScriptOrigin;
231```
232
233### JSVM
234### Memory Management Types
235
236JSVM-API provides the following memory management types:
237
238**JSVM_HandleScope**
239
240Data used to manage the lifecycle of JS objects. It allows JS objects to remain active within a certain range for use in JS code. When **JSVM_HandleScope** is created, all JS objects created in this range remain active until the end. This can prevent released objects from being used in JS code, which improves code reliability and performance.
241
242**JSVM_EscapableHandleScope**
243
244- It is created by **OH_JSVM_OpenEscapableHandleScope** and closed by **OH_JSVM_CloseEscapableHandleScope**.
245
246- It is a special type of handle range used to return values created within the scope of **JSVM_EscapableHandleScope** to a parent scope.
247
248- You can use **OH_JSVM_EscapeHandle** to promote **JSVM_EscapableHandleScope** to a JS object so that it is valid for the lifetime of the outer scope.
249
250**JSVM_Ref**
251
252Reference to **JSVM_Value**, which allows you to manage the lifecycle of JS values.
253
254**JSVM_TypeTag**
255
256Struct containing two unsigned 64-bit integers to identify the type of a JSVM-API value.
257
258```c++
259typedef struct {
260    uint64_t lower;
261    uint64_t upper;
262} JSVM_TypeTag;
263```
264
265- It is a 128-bit value stored as two unsigned 64-bit integers. It is used to tag JS objects to ensure that they are of a certain type.
266
267- This is a stronger check than **OH_JSVM_Instanceof** because **OH_JSVM_Instanceof** may report a false positive if the object's prototype is manipulated.
268
269- The combination of **JSVM_TypeTag** and **OH_JSVM_Wrap** is useful because it ensures that the pointer retrieved from a wrapped object can be safely converted to the native type corresponding to the type tag that had been previously applied to the JS object.
270
271### Callback Types
272
273JSVM-API provides the following callback types:
274
275**JSVM_CallbackStruct**
276
277Callback function pointer and data for user-provided native callbacks, which are to be exposed to JS via JSVM-API. For example, you can use **OH_JSVM_CreateFunction** to create a JS function bound to a native callback defined by **JSVM_CallbackStruct**. Unless otherwise required in object lifecycle management, do not create a handle or callback scope in this callback.
278
279```c++
280typedef struct {
281  JSVM_Value(*callback)(JSVM_Env env, JSVM_CallbackInfo info);
282  void* data;
283} JSVM_CallbackStruct;
284```
285
286**JSVM_Callback**
287
288Alias of the **JSVM_CallbackStruct** pointer type.
289
290It is defined as follows:
291
292```c++
293typedef JSVM_CallbackStruct* JSVM_Callback;
294```
295
296**JSVM_CallbackInfo**
297
298User-defined native callback. The type of the first parameter is **JSVM_Env**, and that of the second parameter is **JSVM_CallbackInfo**. **JSVM_CallbackInfo** can be used to obtain additional information about the context in which the callback was invoked, for example, the parameter list. When a native callback is implemented, **OH_JSVM_GetCbInfo** is used to extract the invoking information from **JSVM_CallbackInfo**.
299
300**JSVM_Finalize**
301
302Function pointer, which is passed in APIs such as **OH_JSVM_SetInstanceData**, **OH_JSVM_CreateExternal**, and **OH_JSVM_Wrap**. **JSVM_Finalize** is called to release the native object when a JS object is garbage collected.
303
304The format is as follows:
305
306```c++
307typedef void (*JSVM_Finalize)(JSVM_Env env, void* finalizeData, void* finalizeHint);
308```
309
310**JSVM_PropertyHandlerConfigurationStruct**
311
312Callback to be invoked when the getter(), setter(), deleter(), or enumerator() of an object is executed.
313
314```c++
315typedef struct {
316    JSVM_Value(JSVM_CDECL* genericNamedPropertyGetterCallback)(JSVM_Env env,
317                                                               JSVM_Value name,
318                                                               JSVM_Value thisArg,
319                                                               JSVM_Value namedPropertyData);
320    JSVM_Value(JSVM_CDECL* genericNamedPropertySetterCallback)(JSVM_Env env,
321                                                               JSVM_Value name,
322                                                               JSVM_Value property,
323                                                               JSVM_Value thisArg,
324                                                               JSVM_Value namedPropertyData);
325    JSVM_Value(JSVM_CDECL* genericNamedPropertyDeleterCallback)(JSVM_Env env,
326                                                                JSVM_Value name,
327                                                                JSVM_Value thisArg,
328                                                                JSVM_Value namedPropertyData);
329    JSVM_Value(JSVM_CDECL* genericNamedPropertyEnumeratorCallback)(JSVM_Env env,
330                                                                   JSVM_Value thisArg,
331                                                                   JSVM_Value namedPropertyData);
332    JSVM_Value(JSVM_CDECL* genericIndexedPropertyGetterCallback)(JSVM_Env env,
333                                                                JSVM_Value index,
334                                                                JSVM_Value thisArg,
335                                                                JSVM_Value indexedPropertyData);
336    JSVM_Value(JSVM_CDECL* genericIndexedPropertySetterCallback)(JSVM_Env env,
337                                                                 JSVM_Value index,
338                                                                 JSVM_Value property,
339                                                                 JSVM_Value thisArg,
340                                                                 JSVM_Value indexedPropertyData);
341    JSVM_Value(JSVM_CDECL* genericIndexedPropertyDeleterCallback)(JSVM_Env env,
342                                                                  JSVM_Value index,
343                                                                  JSVM_Value thisArg,
344                                                                  JSVM_Value indexedPropertyData);
345    JSVM_Value(JSVM_CDECL* genericIndexedPropertyEnumeratorCallback)(JSVM_Env env,
346                                                                     JSVM_Value thisArg,
347                                                                     JSVM_Value indexedPropertyData);
348    JSVM_Value namedPropertyData;
349    JSVM_Value indexedPropertyData;
350} JSVM_PropertyHandlerConfigurationStruct;
351```
352
353**JSVM_PropertyHandlerCfg**
354
355Pointer to the struct that contains a callback for property listening.
356
357The usage is as follows:
358
359```c++
360typedef JSVM_PropertyHandlerConfigurationStruct* JSVM_PropertyHandlerCfg;
361```
362
363## APIs
364
365JSVM-API provides capabilities of the standard JS engine. JSVM-API can be dynamically linked to JS engine libraries of different versions to shield the differences between engine interfaces. JSVM-API provides capabilities, such as VM lifecycle management, JS context management, JS code execution, JS/C++ interaction, context snapshot management, and code caching. Read on the following for details.
366
367### Creating a VM Instance and JS Context
368
369#### When to Use
370
371Before executing JS code, you need to create a avaScript virtual machine (JSVM) and JS context.
372
373#### Available APIs
374| API| Description|
375| -------- | -------- |
376| OH_JSVM_Init| Initializes a JS engine instance.|
377| OH_JSVM_CreateVM| Creates a JSVM instance.|
378| OH_JSVM_DestroyVM| Destroys a JSVM instance.|
379| OH_JSVM_OpenVMScope| Opens a VM scope. The VM instance can be used only within the scope and will not be garbage-collected until the scope is closed.|
380| OH_JSVM_CloseVMScope| Closes a VM scope.|
381| OH_JSVM_CreateEnv| Creates a JS context and registers the specified native function.|
382| OH_JSVM_DestroyEnv| Destroys a JS context.|
383| OH_JSVM_OpenEnvScope| Opens a JS context scope. The context can be used only within the scope.|
384| OH_JSVM_CloseEnvScope| Closes a JS context scope.|
385| OH_JSVM_OpenHandleScope| Opens a handle scope. **JSVM_Value** within the scope will not be garbage-collected.|
386| OH_JSVM_CloseHandleScope| Closes a handle scope.|
387
388##### Using **JSVM_InitOptions**
389You can use **JSVM_InitOptions** to initialize VM platforms with different capabilities.
390
391Example 1: Initialize a JSVM in normal mode.
392```c++
393static void NormalInit(bool &vmInit) {
394    if (!vmInit) {
395        // The JSVM only needs to be initialized once.
396        JSVM_InitOptions initOptions;
397        memset(&initOptions, 0, sizeof(initOptions));
398        OH_JSVM_Init(&initOptions);
399        vmInit = true;
400    }
401}
402```
403
404Example 2: Initialize a JSVM with low memory usage.
405```c++
406static void LowMemoryInit(bool &vmInit) {
407    if (!vmInit) {
408        // The JSVM only needs to be initialized once.
409        JSVM_InitOptions initOptions;
410        initOptions.argc = 4;
411        const char* argv[4];
412        argv[1] = "--incremental-marking-hard-trigger=40";
413        argv[2] = "--min-semi-space-size=4";
414        argv[3] = "--max-semi-space-size=1";
415        initOptions.argv = const_cast<char**>(argv);
416        OH_JSVM_Init(&initOptions);
417        vmInit = true;
418    }
419}
420```
421
422Example 3: Initialize a JSVM with a low GC triggering frequency.
423```c++
424static void LowGCFrequencyInit(bool &vmInit) {
425    if (!vmInit) {
426        // The JSVM only needs to be initialized once.
427        JSVM_InitOptions initOptions;
428        initOptions.argc = 4;
429        const char* argv[4];
430        argv[1] = "--incremental-marking-hard-trigger=80";
431        argv[2] = "--min-semi-space-size=16";
432        argv[3] = "--max-semi-space-size=16";
433        initOptions.argv = const_cast<char**>(argv);
434        OH_JSVM_Init(&initOptions);
435        vmInit = true;
436    }
437}
438```
439
440Execution result:
441The preceding three interfaces can be used to initialize JSVMs with different capabilities. After initialization, a JSVM instance can be created to run JS scripts. Among the three interfaces:
442Calling **LowGCFrequencyInit** allows for fewer GCs than calling **NormalInit**. Calling **LowMemoryInit** allows for less memory usage than calling **NormalInit**.
443
444##### Creating a JSVM Instance
445
446Example: Create and destroy a JSVM instance (including the execution context).
447```c++
448bool VM_INIT = false;
449
450static JSVM_Value ConsoleInfo(JSVM_Env env, JSVM_CallbackInfo info) {
451    size_t argc = 1;
452    JSVM_Value args[1];
453    char log[256] = "";
454    size_t logLength;
455    OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
456
457    OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &logLength);
458    log[255] = 0;
459    OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log);
460    return nullptr;
461}
462
463static JSVM_Value Add(JSVM_Env env, JSVM_CallbackInfo info) {
464    size_t argc = 2;
465    JSVM_Value args[2];
466    OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
467    double num1, num2;
468    env, OH_JSVM_GetValueDouble(env, args[0], &num1);
469    OH_JSVM_GetValueDouble(env, args[1], &num2);
470    JSVM_Value sum = nullptr;
471    OH_JSVM_CreateDouble(env, num1 + num2, &sum);
472    return sum;
473}
474
475static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
476    std::thread t([]() {
477        // Initialized a JSVM with the required capability based on service requirements.
478        // 1. Call NormalInit to initialize the default JSVM.
479        // 2. Call LowMemoryInit to initialize a JSVM with low memory usage.
480        // 3. Call LowGCFrequencyInit to initialize a JSVM with a low GC triggering frequency.
481        NormalInit(VM_INIT);
482        // Create a VM instance and open the VM scope.
483        JSVM_VM vm;
484        JSVM_CreateVMOptions options;
485        memset(&options, 0, sizeof(options));
486        OH_JSVM_CreateVM(&options, &vm);
487
488        JSVM_VMScope vmScope;
489        OH_JSVM_OpenVMScope(vm, &vmScope);
490
491        JSVM_CallbackStruct param[] = {
492            {.data = nullptr, .callback = ConsoleInfo},
493            {.data = nullptr, .callback = Add},
494        };
495        JSVM_PropertyDescriptor descriptor[] = {
496            {"consoleinfo", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
497            {"add", NULL, &param[1], NULL, NULL, NULL, JSVM_DEFAULT},
498        };
499        // Create env, register a native method, and open an env scope.
500        JSVM_Env env;
501        OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
502
503        JSVM_EnvScope envScope;
504        OH_JSVM_OpenEnvScope(env, &envScope);
505
506        // Open a handle scope.
507        JSVM_HandleScope handleScope;
508        OH_JSVM_OpenHandleScope(env, &handleScope);
509
510        std::string sourceCodeStr = "\
511{\
512let value = add(4.96, 5.28);\
513consoleinfo('Result is:' + value);\
514}\
515";
516        // Compile the JS script.
517        JSVM_Value sourceCodeValue;
518        OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
519        JSVM_Script script;
520        OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
521        JSVM_Value result;
522        // Run the JS script.
523        OH_JSVM_RunScript(env, script, &result);
524        JSVM_ValueType type;
525        OH_JSVM_Typeof(env, result, &type);
526        OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
527
528        // Exit the VM and release the memory.
529        OH_JSVM_CloseHandleScope(env, handleScope);
530
531        OH_JSVM_CloseEnvScope(env, envScope);
532        OH_JSVM_DestroyEnv(env);
533
534        OH_JSVM_CloseVMScope(vm, vmScope);
535        OH_JSVM_DestroyVM(vm);
536    });
537
538    t.detach();
539
540    return nullptr;
541}
542```
543
544### Compiling and Running JS Code
545
546#### When to Use
547
548Compile and run JS code.
549
550#### Available APIs
551| API                             | Description                                                                              |
552| ------------------------------- | ---------------------------------------------------------------------------------- |
553| OH_JSVM_CompileScript           | Compiles JS code and returns the compiled script bound to the current environment.                                                     |
554| OH_JSVM_CompileScriptWithOrigin | Compiles JS code and returns the compiled script bound to the current environment, with source code information including **sourceMapUrl** and source file name to process source map information.|
555| OH_JSVM_CompileScriptWithOptions | Compiles a script with the specified options. You can pass the compilation options via the **option** array, which supports option extensions.|
556| OH_JSVM_CreateCodeCache         | Creates a code cache for the compiled script.                                                                 |
557| OH_JSVM_RunScript               | Runs a compile script.                                                                            |
558
559#### Example
560
561Compile and run JS code (create a VM, register native functions, execute JS code, and destroy the VM).
562
563```c++
564#include <cstring>
565#include <fstream>
566#include <string>
567#include <vector>
568
569// Add the dependency libjsvm.so.
570#include "ark_runtime/jsvm.h"
571
572using namespace std;
573
574static JSVM_Value Hello(JSVM_Env env, JSVM_CallbackInfo info) {
575    JSVM_Value output;
576    void* data = nullptr;
577    OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
578    OH_JSVM_CreateStringUtf8(env, (char*)data, strlen((char*)data), &output);
579    return output;
580}
581
582static JSVM_CallbackStruct hello_cb = { Hello, (void*)"Hello" };
583
584static string srcGlobal = R"JS(
585const concat = (...args) => args.reduce((a, b) => a + b);
586)JS";
587
588static void RunScriptWithOption(JSVM_Env env, string& src,
589								uint8_t** dataPtr = nullptr,
590								size_t* lengthPtr = nullptr) {
591    JSVM_HandleScope handleScope;
592    OH_JSVM_OpenHandleScope(env, &handleScope);
593
594    JSVM_Value jsSrc;
595    OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
596
597    uint8_t* data = dataPtr ? *dataPtr : nullptr;
598    auto compilMode = data ? JSVM_COMPILE_MODE_CONSUME_CODE_CACHE :  JSVM_COMPILE_MODE_DEFAULT;
599    size_t length = lengthPtr ? *lengthPtr : 0;
600    JSVM_Script script;
601    // Compile the JS code.
602	JSVM_ScriptOrigin origin {
603	    // In this example, the bundle name is helloworld, and the path of the source map is /data/app/el2/100/base/com.example.helloworld/files/index.js.map.
604	    .sourceMapUrl = "/data/app/el2/100/base/com.example.helloworld/files/index.js.map",
605	    // Name of the source file.
606	    .resourceName = "index.js",
607	    // Start row and column number of script in the source file
608	    .resourceLineOffset = 0,
609	    .resourceColumnOffset = 0,
610	};
611	JSVM_CompileOptions option[3];
612	option[0] = {
613		.id = JSVM_COMPILE_MODE,
614		.content = { .num = compilMode }
615	};
616	JSVM_CodeCache codeCache = {
617		.cache = data,
618		.length = length
619	};
620	option[1] = {
621		.id = JSVM_COMPILE_CODE_CACHE,
622		.content = { .ptr = &codeCache }
623	};
624	// The default value of JSVM_COMPILE_ENABLE_SOURCE_MAP is false. If the value is true, sourceMapUrl cannot be empty.
625	option[2] = {
626		.id = JSVM_COMPILE_ENABLE_SOURCE_MAP,
627		.content = { .boolean = true }
628	};
629	OH_JSVM_CompileScriptWithOptions(env, jsSrc, 3, option, &script);
630
631    JSVM_Value result;
632    // Run the JS code.
633    OH_JSVM_RunScript(env, script, &result);
634
635    char resultStr[128];
636    size_t size;
637    OH_JSVM_GetValueStringUtf8(env, result, resultStr, 128, &size);
638    printf("%s\n", resultStr);
639    if (dataPtr && lengthPtr && *dataPtr == nullptr) {
640        // Save the script compiled from the JS source code to the cache to avoid repeated compilation and improve performance.
641        OH_JSVM_CreateCodeCache(env, script, (const uint8_t**)dataPtr, lengthPtr);
642        printf("Code cache created with length = %ld\n", *lengthPtr);
643    }
644
645    OH_JSVM_CloseHandleScope(env, handleScope);
646}
647
648static void RunScript(JSVM_Env env, string& src,
649                       bool withOrigin = false,
650                       uint8_t** dataPtr = nullptr,
651                       size_t* lengthPtr = nullptr) {
652    JSVM_HandleScope handleScope;
653    OH_JSVM_OpenHandleScope(env, &handleScope);
654
655    JSVM_Value jsSrc;
656    OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
657
658    uint8_t* data = dataPtr ? *dataPtr : nullptr;
659    size_t length = lengthPtr ? *lengthPtr : 0;
660    bool cacheRejected = true;
661    JSVM_Script script;
662    // Compile the JS code.
663    if (withOrigin) {
664	    JSVM_ScriptOrigin origin {
665	        // In this example, the bundle name is helloworld, and the path of the source map is /data/app/el2/100/base/com.example.helloworld/files/index.js.map.
666		    .sourceMapUrl = "/data/app/el2/100/base/com.example.helloworld/files/index.js.map",
667		    // Name of the source file.
668		    .resourceName = "index.js",
669		    // Start row and column number of script in the source file
670		    .resourceLineOffset = 0,
671		    .resourceColumnOffset = 0,
672	    };
673		OH_JSVM_CompileScriptWithOrigin(env, jsSrc, data, length, true, &cacheRejected, &origin, &script);
674    } else {
675	    OH_JSVM_CompileScript(env, jsSrc, data, length, true, &cacheRejected, &script);
676    }
677    printf("Code cache is %s\n", cacheRejected ? "rejected" : "used");
678
679    JSVM_Value result;
680    // Run the JS code.
681    OH_JSVM_RunScript(env, script, &result);
682
683    char resultStr[128];
684    size_t size;
685    OH_JSVM_GetValueStringUtf8(env, result, resultStr, 128, &size);
686    printf("%s\n", resultStr);
687    if (dataPtr && lengthPtr && *dataPtr == nullptr) {
688        // Save the script compiled from the JS source code to the cache to avoid repeated compilation and improve performance.
689        OH_JSVM_CreateCodeCache(env, script, (const uint8_t**)dataPtr, lengthPtr);
690        printf("Code cache created with length = %ld\n", *lengthPtr);
691    }
692
693    OH_JSVM_CloseHandleScope(env, handleScope);
694}
695
696static void CreateSnapshot() {
697    JSVM_VM vm;
698    JSVM_CreateVMOptions options;
699    memset(&options, 0, sizeof(options));
700    options.isForSnapshotting = true;
701    OH_JSVM_CreateVM(&options, &vm);
702    JSVM_VMScope vmScope;
703    OH_JSVM_OpenVMScope(vm, &vmScope);
704
705    JSVM_Env env;
706    // Register the native function as a method that can be called by a JS API. hello_cb holds the pointer and parameters of the native function.
707    JSVM_PropertyDescriptor descriptors[] = {
708        { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT }
709    };
710    OH_JSVM_CreateEnv(vm, 1, descriptors, &env);
711
712    JSVM_EnvScope envScope;
713    OH_JSVM_OpenEnvScope(env, &envScope);
714    // Execute the JS source code src, which can contain any JS syntax. The registered native function can also be invoked.
715    string src = srcGlobal + "concat(hello(), ', ', 'World from CreateSnapshot!');";
716    RunScript(env, src, true);
717
718    // Create a snapshot and save the current env to a string. The string can be used to restore the env to avoid repeatedly defining the properties in the env.
719    const char* blobData = nullptr;
720    size_t blobSize = 0;
721    JSVM_Env envs[1] = { env };
722    OH_JSVM_CreateSnapshot(vm, 1, envs, &blobData, &blobSize);
723    printf("Snapshot blob size = %ld\n", blobSize);
724
725    // If you need to save the snapshot to a file, also consider the read/write permissions on the file in the application.
726    ofstream file("/data/storage/el2/base/files/blob.bin", ios::out | ios::binary | ios::trunc);
727    file.write(blobData, blobSize);
728    file.close();
729
730    OH_JSVM_CloseEnvScope(env, envScope);
731    OH_JSVM_DestroyEnv(env);
732    OH_JSVM_CloseVMScope(vm, vmScope);
733    OH_JSVM_DestroyVM(vm);
734}
735
736void RunWithoutSnapshot(uint8_t** dataPtr, size_t* lengthPtr) {
737    // Create a VM instance.
738    JSVM_VM vm;
739    OH_JSVM_CreateVM(nullptr, &vm);
740    JSVM_VMScope vmScope;
741    OH_JSVM_OpenVMScope(vm, &vmScope);
742
743    JSVM_Env env;
744    // Register the native function as a method that can be called by a JS API. hello_cb holds the pointer and parameters of the native function.
745    JSVM_PropertyDescriptor descriptors[] = {
746        { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT }
747    };
748    OH_JSVM_CreateEnv(vm, 1, descriptors, &env);
749    JSVM_EnvScope envScope;
750    OH_JSVM_OpenEnvScope(env, &envScope);
751    // Execute the JS source code src, which can contain any JS syntax. The registered native function can also be invoked.
752    auto src = srcGlobal + "concat(hello(), ', ', 'World', ' from RunWithoutSnapshot!')";
753    // Use RunScriptWithOption, which covers all the functionalities of the **Compile** APIs and provides extensions.
754    RunScriptWithOption(env, src, dataPtr, lengthPtr);
755
756    OH_JSVM_CloseEnvScope(env, envScope);
757    OH_JSVM_DestroyEnv(env);
758    OH_JSVM_CloseVMScope(vm, vmScope);
759    OH_JSVM_DestroyVM(vm);
760}
761
762void RunWithSnapshot(uint8_t **dataPtr, size_t *lengthPtr) {
763    // The lifetime of blobData cannot be shorter than that of the vm.
764    // If the snapshot needs to be read from a file, also consider the read/write permissions on the file in the application.
765    vector<char> blobData;
766    ifstream file("/data/storage/el2/base/files/blob.bin", ios::in | ios::binary | ios::ate);
767    size_t blobSize = file.tellg();
768    blobData.resize(blobSize);
769    file.seekg(0, ios::beg);
770    file.read(blobData.data(), blobSize);
771    file.close();
772
773    // Create a VM instance.
774    JSVM_VM vm;
775    JSVM_CreateVMOptions options;
776    memset(&options, 0, sizeof(options));
777    options.snapshotBlobData = blobData.data();
778    options.snapshotBlobSize = blobSize;
779    OH_JSVM_CreateVM(&options, &vm);
780    JSVM_VMScope vmScope;
781    OH_JSVM_OpenVMScope(vm, &vmScope);
782
783    // Create env from a snapshot.
784    JSVM_Env env;
785    OH_JSVM_CreateEnvFromSnapshot(vm, 0, &env);
786    JSVM_EnvScope envScope;
787    OH_JSVM_OpenEnvScope(env, &envScope);
788
789    // Run the JS script. Because the snapshot contains hello() defined in env, you do not need to redefine hello(). If dataPtr contains the compiled JS script, the JS script can be directly executed, which avoids repeated compilation from the source code.
790    string src = "concat(hello(), ', ', 'World', ' from RunWithSnapshot!')";
791    RunScript(env, src, true, dataPtr, lengthPtr);
792
793    OH_JSVM_CloseEnvScope(env, envScope);
794    OH_JSVM_DestroyEnv(env);
795    OH_JSVM_CloseVMScope(vm, vmScope);
796    OH_JSVM_DestroyVM(vm);
797}
798
799void PrintVmInfo() {
800    JSVM_VMInfo vmInfo;
801    OH_JSVM_GetVMInfo(&vmInfo);
802    printf("apiVersion: %d\n", vmInfo.apiVersion);
803    printf("engine: %s\n", vmInfo.engine);
804    printf("version: %s\n", vmInfo.version);
805    printf("cachedDataVersionTag: 0x%x\n", vmInfo.cachedDataVersionTag);
806}
807
808static intptr_t externals[] = {
809    (intptr_t)&hello_cb,
810    0,
811};
812
813int main(int argc, char *argv[]) {
814    if (argc <= 1) {
815        printf("Usage: %s gen-snapshot|use-snapshot|no-snapshot\n", argv[0]);
816        return 0;
817    }
818
819    JSVM_InitOptions initOptions;
820    memset(&initOptions, 0, sizeof(initOptions));
821    initOptions.externalReferences = externals;
822    // Initialize the VM, which can be initialized only once in a process.
823    OH_JSVM_Init(&initOptions);
824    PrintVmInfo();
825
826    if (argv[1] == string("gen-snapshot")) {
827        CreateSnapshot();
828        return 0;
829    }
830
831    // The snapshot records the JS context at a certain time and can be used to quickly restore JS context across processes as long as the snapshot is within the lifecycle.
832    const auto useSnapshot = argv[1] == string("use-snapshot");
833    const auto run = useSnapshot ? RunWithSnapshot : RunWithoutSnapshot;
834    uint8_t* data = nullptr;
835    size_t length = 0;
836    run(&data, &length);
837    run(&data, &length);
838    delete[] data;
839
840    return 0;
841}
842```
843
844### Compiling the Wasm Module
845
846#### When to Use
847
848JSVM-API provides APIs for compiling the WebAssembly (Wasm) bytecode, optimizing Wasm functions, and serializing and deserializing Wasm caches.
849
850#### Available APIs
851
852| API                         | Description                                                                                |
853| --------------------------- | ------------------------------------------------------------------------------------ |
854| OH_JSVM_CompileWasmModule   | Compiles the Wasm bytecode into a Wasm module. If the **cache** parameter is passed in, the cache will be deserialized into a Wasm module first. The compilation is performed when the deserialization fails.|
855| OH_JSVM_CompileWasmFunction | Compiles the function with the specified ID in a Wasm module into the optimized machine code. Currently, only the highest optimization level is enabled. The validity of the function ID is ensured by the caller.                    |
856| OH_JSVM_IsWasmModuleObject  | Checks whether the input value is a Wasm module.                                                            |
857| OH_JSVM_CreateWasmCache     | Serializes the machine code in a Wasm module into a Wasm cache. If the Wasm module does not contain machine code, the serialization will fail.                   |
858| OH_JSVM_ReleaseCache        | Releases a Wasm cache instance created by JSVM-API. The **cacheType** and **cacheData** passed in must match. Otherwise, undefined behavior may occur.                     |
859
860#### Example
861
862See [Working with Wasm Using JSVM-API](use-jsvm-about-wasm.md).
863
864### Exception Handling
865
866#### When to Use
867
868Capture, throw, and clear JS exceptions as required.
869
870#### Available APIs
871| API| Description|
872| -------- | -------- |
873| OH_JSVM_Throw| Throws a JS value.|
874| OH_JSVM_ThrowTypeError| Throws a JS type error.|
875| OH_JSVM_ThrowRangeError| Throws a JS range error.|
876| OH_JSVM_IsError| Checks whether a JS value indicates an error.|
877| OH_JSVM_CreateError| Creates a JS error.|
878| OH_JSVM_CreateTypeError| Creates a JS type error and returns it.|
879| OH_JSVM_CreateRangeError| Creates a JS range error and returns it.|
880| OH_JSVM_ThrowError| Throws a JS exception.|
881| OH_JSVM_GetAndClearLastException| Obtains and clears the last JS exception.|
882| OH_JSVM_IsExceptionPending| Checks whether an exception occurs.|
883| OH_JSVM_GetLastErrorInfo| Obtains information about the last exception.|
884| OH_JSVM_ThrowSyntaxError| Throws a JS syntax error.|
885| OH_JSVM_CreateSyntaxError| Creates a JS syntax error and returns it.|
886
887#### Example
888Create, judge, and throw a JS type error.
889
890```c++
891JSVM_Value code = nullptr;
892JSVM_Value message = nullptr;
893OH_JSVM_CreateStringUtf8(env, "500", JSVM_AUTO_LENGTH, &code);
894OH_JSVM_CreateStringUtf8(env, "type error 500", JSVM_AUTO_LENGTH, &message);
895JSVM_Value error = nullptr;
896OH_JSVM_CreateTypeError(env, code, message, &error);
897bool isError = false;
898OH_JSVM_IsError(env, error, &isError);
899OH_JSVM_ThrowTypeError(env, nullptr, "type error1");
900```
901
902Call **OH_JSVM_GetAndClearLastException** to log the exception information as a string to the console.
903
904```c++
905if (status != JSVM_OK) // An exception occurs when the execution fails.
906{
907    bool isPending = false;
908    if (JSVM_OK == OH_JSVM_IsExceptionPending((env), &isPending) && isPending)
909    {
910        JSVM_Value error;
911        if (JSVM_OK == OH_JSVM_GetAndClearLastException((env), &error))
912        {
913            // Obtain the exception stack.
914            JSVM_Value stack;
915            OH_JSVM_GetNamedProperty((env), error, "stack", &stack);
916
917            JSVM_Value message;
918            OH_JSVM_GetNamedProperty((env), error, "message", &message);
919
920            char stackstr[256];
921            OH_JSVM_GetValueStringUtf8(env, stack, stackstr, 256, nullptr);
922            OH_LOG_INFO(LOG_APP, "JSVM error stack: %{public}s", stackstr);
923
924            char messagestr[256];
925            OH_JSVM_GetValueStringUtf8(env, message, messagestr, 256, nullptr);
926            OH_LOG_INFO(LOG_APP, "JSVM error message: %{public}s", messagestr);
927        }
928    }
929}
930```
931
932### Object Lifetime Management
933
934When JSVM-API calls are made, handles to objects in the heap for the underlying VM may be returned as **JSVM_Value**s. These handles must hold the objects live until they are no longer required by the native code. Otherwise, the objects will be collected.
935
936 When an object handle is returned, it is associated with a scope. The lifecycle of the default scope is tied to the lifecycle of the native method call. By default, a handle remains valid and the object associated with it will be held live for the lifecycle of the native method call.
937
938However, in many cases, you may need to adjust the lifecycle to be shorter or longer than that of the native method. The following describes the JSVM-API methods that can be used to change the lifecycle of a handle.
939
940#### Available APIs
941| API| Description|
942| -------- | -------- |
943| OH_JSVM_OpenHandleScope| Opens a handle scope. The object within the scope will not be garbage-collected until the handle scope is closed.|
944| OH_JSVM_CloseHandleScope| Closes a handle scope. The object within the scope will be garbage-collected after the handle scope is closed.|
945| OH_JSVM_OpenEscapableHandleScope| Opens an escapable handle scope. Before this scope is closed, the object created within the scope has the same lifecycle as its parent scope.|
946| OH_JSVM_CloseEscapableHandleScope| Closes an escapable handle scope.|
947| OH_JSVM_EscapeHandle| Promotes a handle to a JS object so that it is valid for the lifetime of the outer scope.|
948| OH_JSVM_CreateReference| Creates a new reference with the specified reference count to the value passed in. The reference allows objects to be used and shared in different contexts and effectively monitors the lifecycle of the object.|
949| OH_JSVM_DeleteReference| Release the reference created by **OH_JSVM_CreateReference**. This allows objects to be correctly released and reclaimed when they are no longer required, avoiding memory leaks.|
950| OH_JSVM_ReferenceRef| Increments the reference count of the reference created by **OH_JSVM_CreateReference** so that the object referenced will not be released.|
951| OH_JSVM_ReferenceUnref| Decrements the reference count of the reference created by **OH_JSVM_CreateReference** so that the object can be correctly released and reclaimed when it is not referenced.|
952| OH_JSVM_GetReferenceValue| Obtains the object referenced by **OH_JSVM_CreateReference**.|
953| OH_JSVM_RetainScript | Retains a **JSVM_Script** persistently so that it can be used out of the current scope.|
954| OH_JSVM_ReleaseScript | Releases a **JSVM_Script** that is persistently retained. The released **JSVM_Script** will no longer be used and must be left empty.|
955
956#### Example
957
958Use a handle scope to protect an object created within the scope from being reclaimed.
959
960```c++
961JSVM_HandleScope scope;
962OH_JSVM_OpenHandleScope(env, &scope);
963JSVM_Value obj = nullptr;
964OH_JSVM_CreateObject(env, &obj);
965OH_JSVM_CloseHandleScope(env, scope);
966```
967
968Use an escapable handle scope to protect an object from being reclaimed within its parent scope.
969
970```c++
971JSVM_EscapableHandleScope scope;
972JSVM_CALL(env, OH_JSVM_OpenEscapableHandleScope(env, &scope));
973JSVM_Value output = NULL;
974JSVM_Value escapee = NULL;
975JSVM_CALL(env, OH_JSVM_CreateObject(env, &output));
976JSVM_CALL(env, OH_JSVM_EscapeHandle(env, scope, output, &escapee));
977JSVM_CALL(env, OH_JSVM_CloseEscapableHandleScope(env, scope));
978return escapee;
979```
980
981Reference a JS object and release the reference.
982
983```c++
984JSVM_Value obj = nullptr;
985OH_JSVM_CreateObject(env, &obj);
986// Create a reference.
987JSVM_Ref reference;
988OH_JSVM_CreateReference(env, obj, 1, &reference);
989
990// Create a reference with a JS object.
991JSVM_Value result;
992OH_JSVM_GetReferenceValue(env, reference, &result);
993
994// Release the reference.
995OH_JSVM_DeleteReference(env, reference);
996```
997
998Use **RetainScript()** to persistently hold **JSVM_Script** and use it.
999
1000```c++
1001JSVM_HandleScope scope;
1002OH_JSVM_OpenHandleScope(env, &scope);
1003JSVM_Script script;
1004JSVM_Value jsSrc;
1005std::string src(R"JS(
1006let a = 37;
1007a = a * 9;
1008)JS");
1009OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
1010OH_JSVM_CompileScriptWithOptions(env, jsSrc, 0, nullptr, &script);
1011OH_JSVM_RetainScript(env, script);
1012OH_JSVM_CloseHandleScope(env, scope);
1013
1014// Run a JSVM script.
1015OH_JSVM_OpenHandleScope(env, &scope);
1016JSVM_Value result;
1017OH_JSVM_RunScript(env, script, &result);
1018
1019// Release a JSVM script and set it to null.
1020OH_JSVM_ReleaseScript(env, script);
1021script = nullptr;
1022OH_JSVM_CloseHandleScope(env, scope);
1023```
1024
1025### Creating JS Object Types and Basic Types
1026
1027#### When to Use
1028
1029Create JS object types and basic types.
1030
1031#### Available APIs
1032| API| Description|
1033| -------- | -------- |
1034|OH_JSVM_CreateArray | Creates a JS array object.|
1035|OH_JSVM_CreateArrayWithLength | Creates a JS array object of the specified length.|
1036|OH_JSVM_CreateArraybuffer | Creates an **ArrayBuffer** object of the specified size.|
1037|OH_JSVM_CreateDate | Creates a date object representing the given number of milliseconds.|
1038|OH_JSVM_CreateExternal | Creates a JS object that wraps an external pointer.|
1039|OH_JSVM_CreateObject | Creates a default JS object.|
1040|OH_JSVM_CreateSymbol | Creates a symbol object based on the given descriptor.|
1041|OH_JSVM_SymbolFor | Searches for a symbol with the given key in a global (runtime-wide) symbol registry. If a match is found, the symbol will be returned. Otherwise, a symbol will be created in the registry.|
1042|OH_JSVM_CreateTypedarray | Creates a JS **TypedArray** object for an **ArrayBuffer**. The **TypedArray** object provides an array-like view over an underlying data buffer, where each element has the same underlying binary scalar data type.|
1043|OH_JSVM_CreateDataview | Creates a JS **DataView** object for an **ArrayBuffer**. The **DataView** object provides an array-like view of over an underlying data buffer.|
1044|OH_JSVM_CreateInt32 | Creates a JS number object from a C Int32_t object.|
1045|OH_JSVM_CreateUint32 | Creates a JS number object from a C Uint32_t object.|
1046|OH_JSVM_CreateInt64 | Creates a JS number object from a C Int64_t object.|
1047|OH_JSVM_CreateDouble | Creates a JS number object from a C Double object.|
1048|OH_JSVM_CreateBigintInt64 | Creates a JS BigInt object from a C Int64 object.|
1049|OH_JSVM_CreateBigintUint64 | Creates a JS BigInt object from a C Uint64 object.|
1050|OH_JSVM_CreateBigintWords | Creates a JS BigInt object from a C Uint64_t array.|
1051|OH_JSVM_CreateStringLatin1 | Creates a JS string object from an ISO-8859-1-encoded C string. ISO-8859-1 is also referred to as Latin-1.|
1052|OH_JSVM_CreateStringUtf16 | Creates a JS string object from a UTF16-encoded C string.|
1053|OH_JSVM_CreateStringUtf8 | Creates a JS string object from a UTF8-encoded C string.|
1054|OH_JSVM_CreateMap | Creates a JS **Map** object.|
1055|OH_JSVM_CreateRegExp | Creates a JS regular expression object based on the given string.|
1056|OH_JSVM_CreateSet | Creates a JS **Set** object.|
1057
1058#### Example
1059
1060Create a JS array of the specified length.
1061
1062```c++
1063size_t arrayLength = 2;
1064JSVM_Value arr;
1065
1066OH_JSVM_CreateArrayWithLength(env, arrayLength, &arr);
1067for (uint32_t i = 0; i < arrayLength; i++)
1068{
1069    JSVM_Value element;
1070    OH_JSVM_CreateUint32(env, i * 2, &element);
1071    OH_JSVM_SetElement(env, arr, i, element);
1072}
1073```
1074
1075Create a JS Int32Array.
1076
1077```c++
1078JSVM_Value arrayBuffer = nullptr;
1079void *arrayBufferPtr = nullptr;
1080size_t arrayBufferSize = 16;
1081size_t typedArrayLength = 4;
1082OH_JSVM_CreateArraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer);
1083
1084void *tmpArrayBufferPtr = nullptr;
1085size_t arrayBufferLength = 0;
1086OH_JSVM_GetArraybufferInfo(env, arrayBuffer, &tmpArrayBufferPtr, &arrayBufferLength);
1087
1088JSVM_Value result;
1089OH_JSVM_CreateTypedarray(env, JSVM_TypedarrayType::JSVM_INT32_ARRAY, typedArrayLength, arrayBuffer, 0, &result);
1090return result;
1091```
1092
1093Create JS numbers and strings.
1094
1095```c++
1096const char *testStringStr = "test";
1097JSVM_Value testString = nullptr;
1098OH_JSVM_CreateStringUtf8(env, testStringStr, strlen(testStringStr), &testString);
1099
1100JSVM_Value testNumber1 = nullptr;
1101JSVM_Value testNumber2 = nullptr;
1102OH_JSVM_CreateDouble(env, 10.1, &testNumber1);
1103OH_JSVM_CreateInt32(env, 10, &testNumber2);
1104```
1105
1106Create a map.
1107
1108```c++
1109JSVM_Value value = nullptr;
1110OH_JSVM_CreateMap(env, &value);
1111```
1112
1113Create a regular expression.
1114
1115```c++
1116JSVM_Value value = nullptr;
1117const char testStr[] = "ab+c";
1118OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &value);
1119JSVM_Value result = nullptr;
1120OH_JSVM_CreateRegExp(env, value, JSVM_RegExpFlags::JSVM_REGEXP_GLOBAL, &result);
1121```
1122
1123Create a **set()** instance.
1124
1125```c++
1126JSVM_Value value;
1127OH_JSVM_CreateSet(env, &value);
1128```
1129
1130### Obtaining C Types or JS Type Information from JS Types
1131
1132#### When to Use
1133
1134Obtain C types or JS type information from JS types.
1135
1136#### Available APIs
1137| API| Description|
1138| -------- | -------- |
1139|OH_JSVM_GetArrayLength | Obtains the length of an array.|
1140|OH_JSVM_GetArraybufferInfo | Obtains the underlying data buffer of an **ArrayBuffer** and its length.|
1141|OH_JSVM_GetPrototype | Obtains the prototype of a JS object.|
1142|OH_JSVM_GetTypedarrayInfo | Obtains information about a **TypedArray** object.|
1143|OH_JSVM_GetDataviewInfo | Obtains information about a **DataView** object.|
1144|OH_JSVM_GetDateValue | Obtains the C double primitive of the time value for the given JS **Date** object.|
1145|OH_JSVM_GetValueBool | Obtains the C Boolean primitive equivalent of the given JS Boolean.|
1146|OH_JSVM_GetValueDouble | Obtains the C Double primitive equivalent of the given JS number.|
1147|OH_JSVM_GetValueBigintInt64 | Obtains the C Int64_t primitive equivalent of the given JS BigInt.|
1148|OH_JSVM_GetValueBigintUint64 | Obtains the C Uint64_t primitive equivalent of the given JS BigInt.|
1149|OH_JSVM_GetValueBigintWords | Obtains the underlying data of a given JS BigInt object, that is, the word representation of BigInt data.|
1150|OH_JSVM_GetValueExternal | Obtains the external data pointer previously passed to **OH_JSVM_CreateExternal**.|
1151|OH_JSVM_GetValueInt32 | Obtains the C Int32 primitive equivalent of the given JS number.|
1152|OH_JSVM_GetValueInt64 | Obtains the C Int64 primitive equivalent of the given JS number.|
1153|OH_JSVM_GetValueStringLatin1 | Obtains the ISO-8859-1-encoded string from the given JS string.|
1154|OH_JSVM_GetValueStringUtf8 | Obtains the UTF8-encoded string from the given JS string.|
1155|OH_JSVM_GetValueStringUtf16 | Obtains the UTF16-encoded string from the given JS string.|
1156|OH_JSVM_GetValueUint32 | Obtains the C primitive equivalent (a Uint32) of the given JS number.|
1157|OH_JSVM_GetBoolean | Obtains a JS singleton object that is used to represent the given Boolean value.|
1158|OH_JSVM_GetGlobal | Obtains the **global** object of the current environment.|
1159|OH_JSVM_GetNull | Obtains the JS **null** object.|
1160|OH_JSVM_GetUndefined | Obtains the JS **Undefined** object.|
1161
1162#### Example
1163
1164Create a JS BigInt object from a C Int64 object and obtain the C Int64_t primitive equivalent.
1165
1166```c++
1167int64_t testValue = INT64_MAX;
1168JSVM_Value result = nullptr;
1169OH_JSVM_CreateBigintInt64(env, testValue, &result);
1170int64_t resultValue = 0;
1171bool flag = false;
1172OH_JSVM_GetValueBigintInt64(env, result, &resultValue, &flag);
1173```
1174
1175Create an Int32Array and obtain its information such as the length and byte offset.
1176
1177```c++
1178JSVM_Value arrayBuffer = nullptr;
1179void *arrayBufferPtr = nullptr;
1180size_t arrayBufferSize = 16;
1181size_t typedArrayLength = 4;
1182OH_JSVM_CreateArraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer);
1183
1184bool isArrayBuffer = false;
1185OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer);
1186
1187JSVM_Value result;
1188OH_JSVM_CreateTypedarray(env, JSVM_TypedarrayType::JSVM_INT32_ARRAY, typedArrayLength, arrayBuffer, 0, &result);
1189
1190bool isTypedArray = false;
1191OH_JSVM_IsTypedarray(env, result, &isTypedArray);
1192
1193
1194JSVM_TypedarrayType type;
1195size_t length = 0;
1196void *data = nullptr;
1197JSVM_Value retArrayBuffer;
1198size_t byteOffset = -1;
1199OH_JSVM_GetTypedarrayInfo(env, result, &type, &length, &data, &retArrayBuffer, &byteOffset);
1200
1201
1202bool retIsArrayBuffer = false;
1203OH_JSVM_IsArraybuffer(env, retArrayBuffer, &retIsArrayBuffer);
1204void *tmpArrayBufferPtr = nullptr;
1205size_t arrayBufferLength = 0;
1206OH_JSVM_GetArraybufferInfo(env, retArrayBuffer, &tmpArrayBufferPtr, &arrayBufferLength);
1207```
1208
1209Create a JS string object from a UTF8-encoded C string and obtain the C string.
1210
1211```c++
1212const char *testStringStr = "testString";
1213JSVM_Value testString = nullptr;
1214OH_JSVM_CreateStringUtf8(env, testStringStr, strlen(testStringStr), &testString);
1215
1216char buffer[128];
1217size_t bufferSize = 128;
1218size_t copied;
1219
1220OH_JSVM_GetValueStringUtf8(env, testString, buffer, bufferSize, &copied);
1221```
1222
1223### Working with JS Values and Abstract Operations
1224
1225#### When to Use
1226
1227Perform abstract operations on JS values.
1228
1229#### Available APIs
1230| API| Description|
1231| -------- | -------- |
1232|OH_JSVM_CoerceToBool | Converts a JS value to an object of the Boolean type.|
1233|OH_JSVM_CoerceToNumber | Converts a JS value to an object of the number type.|
1234|OH_JSVM_CoerceToObject | Converts a JS value to an object of the object type.|
1235|OH_JSVM_CoerceToString | Converts a JS value to an object of the string type.|
1236|OH_JSVM_CoerceToBigInt | Converts a JS value to an object of the BigInt type.|
1237|OH_JSVM_Typeof | Returns the type of a JS object.|
1238|OH_JSVM_Instanceof | Checks whether an object is an instance of a constructor.|
1239|OH_JSVM_IsArray | Checks whether a JS object is an array.|
1240|OH_JSVM_IsArraybuffer | Checks whether a JS object is an array buffer.|
1241|OH_JSVM_IsDate | Checks whether a JS object is a **Date** object.|
1242|OH_JSVM_IsTypedarray | Checks whether a JS object is a **TypedArray** object.|
1243|OH_JSVM_IsDataview | Checks whether a JS object is a **DataView** object.|
1244|OH_JSVM_IsUndefined | Checks whether the value passed in is **Undefined**. This API is equivalent to executing JS code **value === undefined**.|
1245|OH_JSVM_IsNull | Checks whether the value passed in is a **Null** object. This API is equivalent to executing JS code **value === null**.|
1246|OH_JSVM_IsNullOrUndefined | Checks whether the value passed in is **Null** or **Undefined**. This API is equivalent to executing JS code **value == null**.|
1247|OH_JSVM_IsBoolean | Checks whether the value passed in is a Boolean value. This API is equivalent to executing JS code **typeof value ==='boolean'**.|
1248|OH_JSVM_IsNumber | Checks whether the value passed in is a number. This API is equivalent to executing JS code **typeof value === 'number'**.|
1249|OH_JSVM_IsString | Checks whether the value passed in is a string. This API is equivalent to executing JS code **typeof value === 'string'**.|
1250|OH_JSVM_IsSymbol | Checks whether the value passed in is a symbol. This API is equivalent to executing JS code **typeof value === 'symbol'**.|
1251|OH_JSVM_IsFunction | Checks whether the value passed in is a function. This API is equivalent to executing JS code **typeof value === 'function'**.|
1252|OH_JSVM_IsObject | Checks whether the value passed in is an object .|
1253|OH_JSVM_IsBigInt | Checks whether the value passed in is a BigInt. This API is equivalent to executing JS code **typeof value === 'bigint'**.|
1254|OH_JSVM_IsConstructor | Checks whether the value passed in is a constructor.|
1255|OH_JSVM_IsMap | Checks whether the value passed in is a map.|
1256|OH_JSVM_IsSet | Checks whether the value passed in is a **set()** instance.|
1257|OH_JSVM_IsRegExp | Checks whether the value passed in is a regular expression.|
1258|OH_JSVM_StrictEquals | Checks whether two **JSVM_Value** objects are strictly equal.|
1259|OH_JSVM_Equals | Checks whether two **JSVM_Value** objects are roughly equal.|
1260|OH_JSVM_DetachArraybuffer | Calls the **Detach()** operation of an **ArrayBuffer** object.|
1261|OH_JSVM_IsDetachedArraybuffer | Checks whether an **ArrayBuffer** object has been detached.|
1262
1263#### Example
1264
1265Check whether a JS value is of the array type.
1266
1267```c++
1268JSVM_Value array = nullptr;
1269OH_JSVM_CreateArray(env, &array);
1270bool isArray = false;
1271OH_JSVM_IsArray(env, array, &isArray);
1272```
1273
1274Convert a JS int32 value to a string.
1275
1276```c++
1277int32_t num = 123;
1278JSVM_Value intValue;
1279OH_JSVM_CreateInt32(env, num, &intValue);
1280JSVM_Value stringValue;
1281OH_JSVM_CoerceToString(env, intValue, &stringValue);
1282
1283char buffer[128];
1284size_t bufferSize = 128;
1285size_t copied = 0;
1286
1287OH_JSVM_GetValueStringUtf8(env, stringValue, buffer, bufferSize, &copied);
1288// buffer:"123";
1289```
1290
1291Convert a JS boolean value to a bigint.
1292
1293```c++
1294JSVM_Value boolValue;
1295OH_JSVM_GetBoolean(env, false, &boolValue);
1296JSVM_Value bigIntValue;
1297OH_JSVM_CoerceToBigInt(env, boolValue, &bigIntValue);
1298```
1299
1300Check whether two JS values are strictly equal as follows: Compare the operand types first. If the operand types are different, the values are different. If the operand types are the same, compare the two values. If the values are the same, **true** is returned.
1301
1302```c++
1303JSVM_Value value = nullptr;
1304JSVM_Value value1 = nullptr;
1305OH_JSVM_CreateArray(env, &value);
1306
1307OH_JSVM_CreateInt32(env, 10, &value1);
1308bool isArray = true;
1309OH_JSVM_StrictEquals(env, value, value, &isArray);
1310```
1311
1312Check whether two JS values are roughly equal as follows: Compare the operand types first. If the operand types are different but can be converted to the same type, convert the operand types to the same type and check whether the values are strictly equal. If the values are the same, **true** is returned. **false** is returned in other cases.
1313
1314```c++
1315JSVM_HandleScope handleScope;
1316OH_JSVM_OpenHandleScope(env, &handleScope);
1317const char testStr[] = "1";
1318JSVM_Value lhs = nullptr;
1319OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &lhs);
1320JSVM_Value rhs;
1321OH_JSVM_CreateInt32(env, 1, &rhs);
1322bool isEquals = false;
1323OH_JSVM_Equals(env, lhs, rhs, &isEquals); // The value of isEquals is true.
1324OH_JSVM_CloseHandleScope(env, handleScope);
1325```
1326
1327Check whether the JS value is a constructor.
1328
1329```c++
1330JSVM_Value SayHello(JSVM_Env env, JSVM_CallbackInfo info)
1331{
1332    return nullptr;
1333}
1334JSVM_Value value = nullptr;
1335JSVM_CallbackStruct param;
1336param.data = nullptr;
1337param.callback = SayHello;
1338OH_JSVM_CreateFunction(env, "func", JSVM_AUTO_LENGTH, &param, &value);
1339bool isConstructor = false;
1340OH_JSVM_IsConstructor(env, value, &isConstructor); // The value of isConstructor is true.
1341```
1342
1343Check whether the JS value is of the map type.
1344
1345```c++
1346JSVM_Value value = nullptr;
1347OH_JSVM_CreateMap(env, &value);
1348bool isMap = false;
1349OH_JSVM_IsMap(env, value, &isMap); // The value of isMap is true.
1350```
1351
1352Check whether the JS value is a **Set()** instance.
1353
1354```c++
1355JSVM_Value value;
1356OH_JSVM_CreateSet(env, &value);
1357bool isSet = false;
1358OH_JSVM_IsSet(env, value, &isSet); // The value of isSet is true.
1359```
1360
1361Check whether the JS value is a regular expression.
1362
1363```c++
1364JSVM_Value value = nullptr;
1365const char testStr[] = "ab+c";
1366OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &value);
1367JSVM_Value result = nullptr;
1368OH_JSVM_CreateRegExp(env, value, JSVM_RegExpFlags::JSVM_REGEXP_GLOBAL, &result);
1369bool isRegExp = false;
1370OH_JSVM_IsRegExp(env, result, &isRegExp);
1371```
1372
1373### Working with JS Properties
1374
1375#### When to Use
1376
1377Set, get, delete, and check properties of JS objects.
1378
1379#### Available APIs
1380| API| Description|
1381| -------- | -------- |
1382|OH_JSVM_GetPropertyNames | Obtains the names of all enumerable properties of a JS object as a JS array.|
1383|OH_JSVM_GetAllPropertyNames | Obtains the names of all available properties of a JS object as a JS array.|
1384|OH_JSVM_SetProperty | Sets a property for a JS object.|
1385|OH_JSVM_GetProperty | Obtains the requested property from a JS object.|
1386|OH_JSVM_HasProperty | Checks whether a JS object has the specified property.|
1387|OH_JSVM_DeleteProperty | Deletes a property from a JS object.|
1388|OH_JSVM_HasOwnProperty | Checks whether a JS object has the specified own property.|
1389|OH_JSVM_SetNamedProperty | Sets a property with the given property name for a JS object. This API is equivalent to calling **OH_JSVM_SetProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
1390|OH_JSVM_GetNamedProperty | Obtains the property from a JS object with the given property name. This API is equivalent to calling **OH_JSVM_GetProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
1391|OH_JSVM_HasNamedProperty | Checks whether a JS object has the specified property. This API is equivalent to calling **OH_JSVM_HasProperty** using a **JSVM_Value** created from the string passed in as **utf8Name**.|
1392|OH_JSVM_SetElement | Sets an element at the specified index for a JS object.|
1393|OH_JSVM_GetElement | Obtains the element at the specified index of a JS object.|
1394|OH_JSVM_HasElement | Checks whether a JS object has an element at the specified index.|
1395|OH_JSVM_DeleteElement | Deletes the element at the specified index from a JS object.|
1396|OH_JSVM_DefineProperties |  Defines multiple properties for a JS object.|
1397|OH_JSVM_ObjectFreeze | Freeze a JS object. Once a JS object is frozen, new properties cannot be added to it, existing properties cannot be removed, the enumerability, configurability, or writability of existing properties cannot be changed, and the values of existing properties cannot be changed.|
1398|OH_JSVM_ObjectSeal | Seals a JS object. Once a JS object is sealed, new properties cannot be added to it and all existing properties are marked as unconfigurable.|
1399|OH_JSVM_ObjectSetPrototypeOf | Sets a prototype for a given object.|
1400|OH_JSVM_ObjectGetPrototypeOf | Obtains the prototype of a JS object.|
1401
1402#### Example
1403
1404Set, get, delete, and check properties of a JS object.
1405
1406```c++
1407// Create an empty object.
1408JSVM_Value myObject = nullptr;
1409OH_JSVM_CreateObject(env, &myObject);
1410
1411// Set properties.
1412const char *testNameStr = "John Doe";
1413JSVM_Value propValue = nullptr;
1414JSVM_Value key;
1415OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &key);
1416OH_JSVM_CreateStringUtf8(env, testNameStr, strlen(testNameStr), &propValue);
1417OH_JSVM_SetProperty(env, myObject, key, propValue);
1418
1419// Obtain properties.
1420JSVM_Value propResult = nullptr;
1421OH_JSVM_GetProperty(env, myObject, key, &propResult);
1422
1423// Check whether a property exists.
1424bool hasProperty = false;
1425OH_JSVM_HasNamedProperty(env, myObject, "name", &hasProperty);
1426    // The property exists. Perform subsequent processing accordingly.
1427    if (hasProperty)
1428    {
1429        // Obtain all property names of the object.
1430        JSVM_Value propNames = nullptr;
1431        OH_JSVM_GetPropertyNames(env, myObject, &propNames);
1432
1433        bool isArray = false;
1434        OH_JSVM_IsArray(env, propNames, &isArray);
1435
1436        uint32_t arrayLength = 0;
1437        OH_JSVM_GetArrayLength(env, propNames, &arrayLength);
1438        // Traverse property elements.
1439        for (uint32_t i = 0; i < arrayLength; i++)
1440        {
1441            bool hasElement = false;
1442            OH_JSVM_HasElement(env, propNames, i, &hasElement);
1443
1444            JSVM_Value propName = nullptr;
1445            OH_JSVM_GetElement(env, propNames, i, &propName);
1446
1447            bool hasProp = false;
1448            OH_JSVM_HasProperty(env, myObject, propName, &hasProp);
1449
1450            JSVM_Value propValue = nullptr;
1451            OH_JSVM_GetProperty(env, myObject, propName, &propValue);
1452        }
1453    }
1454
1455// Delete a property.
1456OH_JSVM_DeleteProperty(env, myObject, key, &hasProperty);
1457
1458// Set the object prototype.
1459JSVM_Value value;
1460OH_JSVM_CreateSet(env, &value);
1461OH_JSVM_ObjectSetPrototypeOf(env, myObject, value);
1462
1463// Obtain the object prototype.
1464JSVM_Value proto;
1465OH_JSVM_ObjectGetPrototypeOf(env, myObject, &proto);
1466```
1467
1468### Working with JS Functions
1469
1470#### When to Use
1471
1472Call back JS code into native code and call JS functions from native code.
1473
1474#### Available APIs
1475| API| Description|
1476| -------- | -------- |
1477|OH_JSVM_CallFunction | Calls a JS function from a C/C++ addon.|
1478|OH_JSVM_CreateFunction | Creates a JS function object in native code, which allows calling into the native code from JS.|
1479|OH_JSVM_GetCbInfo | Obtains detailed information about the call, such as the parameters and **this** pointer, from the given callback information.|
1480|OH_JSVM_GetNewTarget | Obtains the **new.target** of the constructor call.|
1481|OH_JSVM_NewInstance | Creates an instance based on the given constructor.|
1482|OH_JSVM_CreateFunctionWithScript | Creates a JS function object based on the given function body and parameter list.|
1483
1484#### Example
1485
1486Create a JS function.
1487
1488```c++
1489JSVM_Value SayHello(JSVM_Env env, JSVM_CallbackInfo info)
1490{
1491    printf("Hello\n");
1492    JSVM_Value ret;
1493    OH_JSVM_CreateInt32(env, 2, &ret);
1494    return ret;
1495}
1496
1497static JSVM_Value JsvmCreateFunction(JSVM_Env env, JSVM_CallbackInfo info)
1498{
1499    JSVM_CallbackStruct param;
1500    param.data = nullptr;
1501    param.callback = SayHello;
1502
1503    JSVM_Value funcValue = nullptr;
1504    JSVM_Status status = OH_JSVM_CreateFunction(env, "func", JSVM_AUTO_LENGTH, &param, &funcValue);
1505    return funcValue;
1506}
1507```
1508
1509Obtain and call the JS function from C/C++.
1510
1511```c++
1512static JSVM_Value CallFunction(JSVM_Env env, JSVM_CallbackInfo info)
1513{
1514    size_t argc = 1;
1515    JSVM_Value args[1];
1516    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1517
1518    JSVM_ASSERT(env, argc >= 1, "Wrong number of arguments");
1519
1520    JSVM_ValueType valuetype;
1521    JSVM_CALL(env, OH_JSVM_Typeof(env, args[0], &valuetype));
1522    JSVM_ASSERT(env, valuetype == JSVM_ValueType::JSVM_FUNCTION, "Wrong type of argment. Expects a string.");
1523
1524    JSVM_Value global;
1525    JSVM_CALL(env, OH_JSVM_GetGlobal(env, &global));
1526
1527    JSVM_Value ret;
1528    JSVM_CALL(env, OH_JSVM_CallFunction(env, global, args[0], 0, nullptr, &ret));
1529    return ret;
1530}
1531```
1532
1533Create a function.
1534
1535```c++
1536JSVM_Value script;
1537OH_JSVM_CreateStringUtf8(env, "return a + b;", JSVM_AUTO_LENGTH, &script);
1538JSVM_Value param1;
1539JSVM_Value param2;
1540OH_JSVM_CreateStringUtf8(env, "a", JSVM_AUTO_LENGTH, &param1);
1541OH_JSVM_CreateStringUtf8(env, "b", JSVM_AUTO_LENGTH, &param2);
1542JSVM_Value argus[] = {param1, param2};
1543JSVM_Value func;
1544OH_JSVM_CreateFunctionWithScript(env, "add", JSVM_AUTO_LENGTH, 2, argus, script, &func);
1545```
1546
1547### Wrapping Objects
1548
1549#### When to Use
1550
1551Wrap native classes and instances so that the class constructor and methods can be called from JS.
1552
1553#### Available APIs
1554| API| Description|
1555| -------- | -------- |
1556|OH_JSVM_DefineClass| Defines a JS class and associated functions within a C/C++ addon. It allows you to define a constructor, methods, and properties that can be accessed from JS.|
1557|OH_JSVM_Wrap| Wraps a native instance in a JS object. You can use **OH_JSVM_Unwrap()** to retrieve the native instance later.|
1558|OH_JSVM_Unwrap | Retrieves a native instance from a JS object.|
1559|OH_JSVM_RemoveWrap | Retrieves a native instance previously wrapped in a JS object and removes the wrapping.|
1560|OH_JSVM_TypeTagObject | Associates the value of the **type_tag** pointer with a JS object or an external object.|
1561|OH_JSVM_CheckObjectTypeTag | Check whether a tag matches the tag type of an object.|
1562|OH_JSVM_AddFinalizer | Add a **JSVM_Finalize** callback to a JS object. The callback will be invoked to release the native object when the JS object is garbage-collected.|
1563|OH_JSVM_DefineClassWithPropertyHandler | Defines a JS class with the given class name, constructor, property, and callback handler, and calls it as a function callback. The property operations include getter, setter, deleter, and enumerator.|
1564
1565#### Example
1566
1567Wrap a native object in a JS object.
1568
1569```c++
1570static JSVM_Value AssertEqual(JSVM_Env env, JSVM_CallbackInfo info)
1571{
1572    size_t argc = 2;
1573    JSVM_Value args[2];
1574    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1575
1576    bool isStrictEquals = false;
1577    OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
1578    return nullptr;
1579}
1580
1581static napi_value TestWrap(napi_env env1, napi_callback_info info)
1582{
1583    OH_LOG_ERROR(LOG_APP, "testWrap start");
1584    JSVM_InitOptions init_options;
1585    memset(&init_options, 0, sizeof(init_options));
1586    init_options.externalReferences = externals;
1587    if (aa == 0) {
1588        OH_JSVM_Init(&init_options);
1589        aa++;
1590    }
1591    JSVM_VM vm;
1592    JSVM_CreateVMOptions options;
1593    memset(&options, 0, sizeof(options));
1594    OH_JSVM_CreateVM(&options, &vm);
1595    JSVM_VMScope vm_scope;
1596    OH_JSVM_OpenVMScope(vm, &vm_scope);
1597    JSVM_Env env;
1598    JSVM_CallbackStruct param[1];
1599    param[0].data = nullptr;
1600    param[0].callback = AssertEqual;
1601    JSVM_PropertyDescriptor descriptor[] = {
1602        {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1603    };
1604    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1605    JSVM_EnvScope envScope;
1606    OH_JSVM_OpenEnvScope(env, &envScope);
1607    JSVM_HandleScope handlescope;
1608    OH_JSVM_OpenHandleScope(env, &handlescope);
1609    JSVM_Value testClass = nullptr;
1610    JSVM_CallbackStruct param1;
1611    param1.data = nullptr;
1612    param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1613        JSVM_Value thisVar = nullptr;
1614        OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1615
1616        return thisVar;
1617    };
1618    OH_JSVM_DefineClass(env, "TestClass", JSVM_AUTO_LENGTH, &param1, 0, nullptr, &testClass);
1619
1620    JSVM_Value instanceValue = nullptr;
1621    OH_JSVM_NewInstance(env, testClass, 0, nullptr, &instanceValue);
1622
1623    const char *testStr = "test";
1624    OH_JSVM_Wrap(
1625        env, instanceValue, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, nullptr, nullptr);
1626    const char *tmpTestStr = nullptr;
1627    OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr);
1628    const char *tmpTestStr1 = nullptr;
1629    OH_JSVM_RemoveWrap(env, instanceValue, (void **)&tmpTestStr1);
1630    OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr1);
1631    OH_JSVM_CloseHandleScope(env, handlescope);
1632    OH_JSVM_CloseEnvScope(env, envScope);
1633    OH_JSVM_DestroyEnv(env);
1634    OH_JSVM_CloseVMScope(vm, vm_scope);
1635    OH_JSVM_DestroyVM(vm);
1636    OH_LOG_ERROR(LOG_APP, "testWrap pass");
1637    return nullptr;
1638}
1639```
1640
1641
1642Wrap a native object and register a listener for property access operations.
1643
1644```c++
1645static int aa = 0;
1646static JSVM_Value hello(JSVM_Env env, JSVM_CallbackInfo info) {
1647    JSVM_Value output;
1648    void *data = nullptr;
1649    OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
1650    OH_JSVM_CreateStringUtf8(env, (char *)data, strlen((char *)data), &output);
1651    return output;
1652}
1653
1654static JSVM_CallbackStruct hello_cb = {hello, (void *)"Hello"};
1655static intptr_t externals[] = {
1656    (intptr_t)&hello_cb,
1657    0,
1658};
1659
1660static void test1() { OH_LOG_INFO(LOG_APP, "test1 called"); }
1661
1662struct Test {
1663    void *ptr1;
1664    void *ptr2;
1665};
1666
1667static JSVM_Value assertEqual(JSVM_Env env, JSVM_CallbackInfo info) {
1668    size_t argc = 2;
1669    JSVM_Value args[2];
1670    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1671
1672    bool isStrictEquals = false;
1673    OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
1674    return nullptr;
1675}
1676
1677static JSVM_Value GetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
1678    // This callback is triggered by the getter of the object.
1679    char strValue[100];
1680    size_t size;
1681    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1682    JSVM_Value newResult = nullptr;
1683    char newStr[] = "new return value hahaha from name listening";
1684    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1685    int signBit = 0;
1686    size_t wordCount = 2;
1687    uint64_t wordsOut[2] = {0ULL, 0ULL};
1688    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1689    if (status == JSVM_OK) {
1690        OH_LOG_INFO(LOG_APP, "GetPropertyCbInfo wordCount is %{public}zu", wordCount);
1691        auto test = reinterpret_cast<Test *>(wordsOut);
1692        typedef void (*callTest1)();
1693        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1694        callTe();
1695    }
1696    return nullptr;
1697}
1698
1699static JSVM_Value SetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
1700    // This callback is triggered by the setter of the object.
1701    char strValue[100];
1702    size_t size;
1703    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1704    JSVM_Value newResult = nullptr;
1705    char newStr[] = "new return value hahaha from name listening";
1706    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1707    int signBit = 0;
1708    size_t wordCount = 2;
1709    uint64_t wordsOut[2] = {0ULL, 0ULL};
1710    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1711    if (status == JSVM_OK) {
1712        OH_LOG_INFO(LOG_APP, "SetPropertyCbInfo wordCount is %{public}zu", wordCount);
1713        auto test = reinterpret_cast<Test *>(wordsOut);
1714        typedef void (*callTest1)();
1715        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1716        callTe();
1717    }
1718    return nullptr;
1719}
1720
1721static JSVM_Value DeleterPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
1722    // This callback is triggered by the deleter of the object.
1723    char strValue[100];
1724    size_t size;
1725    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1726    JSVM_Value newResult = nullptr;
1727    bool returnValue = false;
1728    OH_JSVM_GetBoolean(env, returnValue, &newResult);
1729    int signBit = 0;
1730    size_t wordCount = 2;
1731    uint64_t wordsOut[2] = {0ULL, 0ULL};
1732    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1733    if (status == JSVM_OK) {
1734        OH_LOG_INFO(LOG_APP, "DeleterPropertyCbInfo wordCount is %{public}zu", wordCount);
1735        auto test = reinterpret_cast<Test *>(wordsOut);
1736        typedef void (*callTest1)();
1737        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1738        callTe();
1739    }
1740    return nullptr;
1741}
1742
1743static JSVM_Value EnumeratorPropertyCbInfo(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
1744    // This callback is triggered by the enumerator of an object.
1745    JSVM_Value testArray = nullptr;
1746    OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
1747    JSVM_Value name1 = nullptr;
1748    char newStr1[] = "hahaha";
1749    OH_JSVM_CreateStringUtf8(env, newStr1, strlen(newStr1), &name1);
1750    JSVM_Value name2 = nullptr;
1751    char newStr2[] = "heheheh";
1752    OH_JSVM_CreateStringUtf8(env, newStr2, strlen(newStr2), &name2);
1753
1754    OH_JSVM_SetElement(env, testArray, 0, name1);
1755    OH_JSVM_SetElement(env, testArray, 1, name2);
1756    int signBit = 0;
1757    size_t wordCount = 2;
1758    uint64_t wordsOut[2] = {0ULL, 0ULL};
1759    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1760    if (status == JSVM_OK) {
1761        OH_LOG_INFO(LOG_APP, "EnumeratorPropertyCbInfo wordCount is %{public}zu", wordCount);
1762        auto test = reinterpret_cast<Test *>(wordsOut);
1763        typedef void (*callTest1)();
1764        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1765        callTe();
1766    }
1767    return nullptr;
1768}
1769
1770static JSVM_Value IndexedPropertyGet(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
1771    // This callback is triggered by the indexed getter.
1772    uint32_t value;
1773    OH_JSVM_GetValueUint32(env, index, &value);
1774
1775    JSVM_Value newResult = nullptr;
1776    char newStr[] = "new return value hahaha from index listening";
1777    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1778    int signBit = 0;
1779    size_t wordCount = 2;
1780    uint64_t wordsOut[2] = {0ULL, 0ULL};
1781    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1782    if (status == JSVM_OK) {
1783        OH_LOG_INFO(LOG_APP, "IndexedPropertyGet wordCount is %{public}zu", wordCount);
1784        auto test = reinterpret_cast<Test *>(wordsOut);
1785        typedef void (*callTest1)();
1786        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1787        callTe();
1788    }
1789    return nullptr;
1790}
1791
1792static JSVM_Value IndexedPropertySet(JSVM_Env env, JSVM_Value index, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
1793    // This callback is triggered by the indexed setter.
1794    uint32_t value;
1795    OH_JSVM_GetValueUint32(env, index, &value);
1796    char str[100];
1797    size_t size;
1798    OH_JSVM_GetValueStringUtf8(env, property, str, 100, &size);
1799    JSVM_Value newResult = nullptr;
1800    char newStr[] = "new return value hahaha from name listening";
1801    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1802    int signBit = 0;
1803    size_t wordCount = 2;
1804    uint64_t wordsOut[2] = {0ULL, 0ULL};
1805    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1806    if (status == JSVM_OK) {
1807        OH_LOG_INFO(LOG_APP, "IndexedPropertySet wordCount is %{public}zu", wordCount);
1808        auto test = reinterpret_cast<Test *>(wordsOut);
1809        typedef void (*callTest1)();
1810        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1811        callTe();
1812    }
1813    return nullptr;
1814}
1815
1816static JSVM_Value IndexedPropertyDeleter(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
1817    // This callback is triggered by the indexed deleter.
1818    uint32_t value;
1819    OH_JSVM_GetValueUint32(env, index, &value);
1820    JSVM_Value newResult = nullptr;
1821    bool returnValue = false;
1822    OH_JSVM_GetBoolean(env, returnValue, &newResult);
1823    int signBit = 0;
1824    size_t wordCount = 2;
1825    uint64_t wordsOut[2] = {0ULL, 0ULL};
1826    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1827    if (status == JSVM_OK) {
1828        OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
1829        auto test = reinterpret_cast<Test *>(wordsOut);
1830        typedef void (*callTest1)();
1831        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1832        callTe();
1833    }
1834    return nullptr;
1835}
1836
1837static JSVM_Value IndexedPropertyEnumerator(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
1838    // This callback is triggered by the indexed enumerator.
1839    JSVM_Value testArray = nullptr;
1840    OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
1841    JSVM_Value index1 = nullptr;
1842    OH_JSVM_CreateUint32(env, 1, &index1);
1843    JSVM_Value index2 = nullptr;
1844    OH_JSVM_CreateUint32(env, 2, &index2);
1845    OH_JSVM_SetElement(env, testArray, 0, index1);
1846    OH_JSVM_SetElement(env, testArray, 1, index2);
1847    int signBit = 0;
1848    size_t wordCount = 2;
1849    uint64_t wordsOut[2] = {0ULL, 0ULL};
1850    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1851    if (status == JSVM_OK) {
1852        OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
1853        auto test = reinterpret_cast<Test *>(wordsOut);
1854        typedef void (*callTest1)();
1855        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1856        callTe();
1857    }
1858    return nullptr;
1859}
1860
1861static napi_value TestDefineClassWithProperty(napi_env env1, napi_callback_info info) {
1862    OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty start");
1863    JSVM_InitOptions init_options;
1864    memset(&init_options, 0, sizeof(init_options));
1865    init_options.externalReferences = externals;
1866    if (aa == 0) {
1867        OH_JSVM_Init(&init_options);
1868        aa++;
1869    }
1870    JSVM_VM vm;
1871    JSVM_CreateVMOptions options;
1872    memset(&options, 0, sizeof(options));
1873    OH_JSVM_CreateVM(&options, &vm);
1874    JSVM_VMScope vm_scope;
1875    OH_JSVM_OpenVMScope(vm, &vm_scope);
1876    JSVM_Env env;
1877    JSVM_CallbackStruct param[1];
1878    param[0].data = nullptr;
1879    param[0].callback = assertEqual;
1880    JSVM_PropertyDescriptor descriptor[] = {
1881        {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1882    };
1883    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1884    JSVM_EnvScope envScope;
1885    OH_JSVM_OpenEnvScope(env, &envScope);
1886    JSVM_HandleScope handlescope;
1887    OH_JSVM_OpenHandleScope(env, &handlescope);
1888
1889
1890    JSVM_CallbackStruct param1;
1891    param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1892        JSVM_Value thisVar = nullptr;
1893        OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1894        return thisVar;
1895    };
1896    param1.data = nullptr;
1897
1898    JSVM_Value res = nullptr;
1899    Test *test = new Test();
1900    test->ptr1 = (void *)test1;
1901    test->ptr2 = (void *)test1;
1902    OH_LOG_INFO(LOG_APP, "OH_JSVM_CreateBigintWords 111 word count %{public}d",
1903                sizeof(*test) / sizeof(uint64_t));
1904    JSVM_Status status = OH_JSVM_CreateBigintWords(env, 1, 2, reinterpret_cast<const uint64_t *>(test), &res);
1905
1906    // Initialize propertyCfg.
1907    JSVM_PropertyHandlerConfigurationStruct propertyCfg;
1908    propertyCfg.genericNamedPropertyGetterCallback = GetPropertyCbInfo;
1909    propertyCfg.genericNamedPropertySetterCallback = SetPropertyCbInfo;
1910    propertyCfg.genericNamedPropertyDeleterCallback = DeleterPropertyCbInfo;
1911    propertyCfg.genericNamedPropertyEnumeratorCallback = EnumeratorPropertyCbInfo;
1912    propertyCfg.genericIndexedPropertyGetterCallback = IndexedPropertyGet;
1913    propertyCfg.genericIndexedPropertySetterCallback = IndexedPropertySet;
1914    propertyCfg.genericIndexedPropertyDeleterCallback = IndexedPropertyDeleter;
1915    propertyCfg.genericIndexedPropertyEnumeratorCallback = IndexedPropertyEnumerator;
1916    propertyCfg.namedPropertyData = res;
1917    propertyCfg.indexedPropertyData = res;
1918
1919    JSVM_CallbackStruct callbackStruct;
1920    callbackStruct.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1921        OH_LOG_INFO(LOG_APP, "call as a function called");
1922        JSVM_Value thisVar = nullptr;
1923        void *innerData;
1924        size_t argc = 1;
1925        JSVM_Value args[1];
1926        OH_JSVM_GetCbInfo(env, info, &argc, args, &thisVar, &innerData);
1927        OH_LOG_INFO(LOG_APP, "function call as function result is %{public}s", reinterpret_cast<char *>(innerData));
1928        uint32_t ret = 0;
1929        OH_JSVM_GetValueUint32(env, args[0], &ret);
1930        const char testStr[] = "hello world 111111";
1931        JSVM_Value setvalueName = nullptr;
1932        JSVM_CALL(env, OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName));
1933        return setvalueName;
1934    };
1935    char data[100] = "1111 hello world";
1936    callbackStruct.data = data;
1937    JSVM_Value testWrapClass = nullptr;
1938
1939    // Register a property access listener in propertyCfg.
1940    OH_JSVM_DefineClassWithPropertyHandler(env, "TestWrapClass", NAPI_AUTO_LENGTH, &param1, 0, nullptr, &propertyCfg,
1941                                           &callbackStruct, &testWrapClass);
1942    JSVM_Value instanceValue = nullptr;
1943    OH_JSVM_NewInstance(env, testWrapClass, 0, nullptr, &instanceValue);
1944    const char testStr[] = "hello world";
1945    JSVM_Value setvalueName = nullptr;
1946    OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName);
1947
1948    // 1. Callbacks for properties.
1949    // Set properties.
1950    OH_JSVM_SetNamedProperty(env, instanceValue, "str11", setvalueName);
1951    OH_JSVM_SetNamedProperty(env, instanceValue, "str123", setvalueName);
1952
1953    // Obtain a property.
1954    JSVM_Value valueName = nullptr;
1955    OH_JSVM_GetNamedProperty(env, instanceValue, "str11", &valueName);
1956    char str[100];
1957    size_t size;
1958    OH_JSVM_GetValueStringUtf8(env, valueName, str, 100, &size);
1959
1960    // Obtain all property names.
1961    JSVM_Value allPropertyNames = nullptr;
1962    OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
1963                                static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
1964                                JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames);
1965    uint32_t nameSize = 0;
1966    OH_JSVM_GetArrayLength(env, allPropertyNames, &nameSize);
1967    JSVM_Value propertyName = nullptr;
1968    for (uint32_t i = 0; i < nameSize; ++i) {
1969        OH_JSVM_GetElement(env, allPropertyNames, i, &propertyName);
1970        char str[100];
1971        size_t size;
1972        OH_JSVM_GetValueStringUtf8(env, propertyName, str, 100, &size);
1973    }
1974
1975    // Delete a property.
1976    bool result = false;
1977    propertyName = nullptr;
1978    char propertyChar[] = "str11";
1979    OH_JSVM_CreateStringUtf8(env, propertyChar, strlen(propertyChar), &propertyName);
1980    OH_JSVM_DeleteProperty(env, instanceValue, propertyName, &result);
1981
1982    // 2. Callbacks for index properties.
1983    // Set properties.
1984    JSVM_Value jsIndex = nullptr;
1985    uint32_t index = 0;
1986    OH_JSVM_CreateUint32(env, index, &jsIndex);
1987    OH_JSVM_SetProperty(env, instanceValue, jsIndex, setvalueName);
1988    JSVM_Value jsIndex1 = nullptr;
1989    index = 1;
1990    OH_JSVM_CreateUint32(env, index, &jsIndex1);
1991    OH_JSVM_SetProperty(env, instanceValue, jsIndex1, setvalueName);
1992
1993    // Obtain a property.
1994    JSVM_Value valueName1 = nullptr;
1995    OH_JSVM_GetProperty(env, instanceValue, jsIndex, &valueName1);
1996    char str1[100];
1997    size_t size1;
1998    OH_JSVM_GetValueStringUtf8(env, valueName1, str1, 100, &size1);
1999
2000    // Obtain all property names.
2001    JSVM_Value allPropertyNames1 = nullptr;
2002    OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
2003                                static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
2004                                JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames1);
2005    uint32_t nameSize1 = 0;
2006    OH_JSVM_GetArrayLength(env, allPropertyNames1, &nameSize);
2007    JSVM_Value propertyName1 = nullptr;
2008    for (uint32_t i = 0; i < nameSize1; ++i) {
2009        OH_JSVM_GetElement(env, allPropertyNames1, i, &propertyName1);
2010        char str[100];
2011        size_t size;
2012        OH_JSVM_GetValueStringUtf8(env, propertyName1, str, 100, &size);
2013    }
2014
2015    // Delete a property.
2016    bool result1 = false;
2017    OH_JSVM_DeleteProperty(env, instanceValue, jsIndex, &result1);
2018
2019    // 3. Callback of a function.
2020    JSVM_Value gloablObj = nullptr;
2021    OH_JSVM_GetGlobal(env, &gloablObj);
2022    OH_JSVM_SetNamedProperty(env, gloablObj, "myTestInstance", instanceValue);
2023    OH_LOG_INFO(LOG_APP, "set property on global object");
2024    std::string innerSourcecodestr = R"(
2025    {
2026        let res = myTestInstance(12);
2027    })";
2028    JSVM_Value innerSourcecodevalue;
2029    OH_JSVM_CreateStringUtf8(env, innerSourcecodestr.c_str(), innerSourcecodestr.size(), &innerSourcecodevalue);
2030    JSVM_Script innerscript;
2031    OH_JSVM_CompileScript(env, innerSourcecodevalue, nullptr, 0, true, nullptr, &innerscript);
2032    JSVM_Value innerResult;
2033    OH_JSVM_RunScript(env, innerscript, &innerResult);
2034
2035    OH_JSVM_CloseHandleScope(env, handlescope);
2036    OH_JSVM_CloseEnvScope(env, envScope);
2037    OH_JSVM_DestroyEnv(env);
2038    OH_JSVM_CloseVMScope(vm, vm_scope);
2039    OH_JSVM_DestroyVM(vm);
2040    OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty pass");
2041    return nullptr;
2042}
2043```
2044
2045### Version Management
2046
2047#### When to Use
2048
2049Obtain version information.
2050
2051#### Available APIs
2052| API| Description|
2053| -------- | -------- |
2054|OH_JSVM_GetVersion| Obtains the latest JSVM API version supported by the JSVM runtime.|
2055|OH_JSVM_GetVMInfo| Obtains the VM information.|
2056
2057#### Example
2058
2059Obtain version information.
2060
2061```c++
2062JSVM_VMInfo result;
2063OH_JSVM_GetVMInfo(&result);
2064uint32_t versionId = 0;
2065OH_JSVM_GetVersion(env, &versionId);
2066```
2067
2068### Memory Management
2069
2070#### When to Use
2071
2072Perform memory management.
2073
2074#### Available APIs
2075| API                                         | Description                                                                                                  |
2076| ------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
2077| OH_JSVM_AdjustExternalMemory                | Adjusts the amount of registered external memory used to give the JSVM an indication of the amount of externally allocated memory that is kept alive by JS objects. The JSVM then determines whether to perform global GC. Increasing the externally allocated memory will increase the probability of triggering global.|
2078| OH_JSVM_MemoryPressureNotification          | Notifies the VM of the memory pressure level and selectively triggers GC.                                                                            |
2079| OH_JSVM_AllocateArrayBufferBackingStoreData | Allocates memory for a backing store.|
2080| OH_JSVM_FreeArrayBufferBackingStoreData | Releases the backing store memory.|
2081| OH_JSVM_CreateArrayBufferFromBackingStoreData | Creates an array buffer based on the backing store memory allocated.|
2082
2083> Using a backing store is a critical operation. You must ensure correct use of memory and exercise caution when using it. For details, see the following example.
2084
2085#### Example
2086
2087Perform memory management.
2088
2089```c++
2090// Before and after calling OH_JSVM_AdjustExternalMemory, check the memory allocated externally from the perspective of the underlying VM.
2091int64_t result;
2092OH_JSVM_AdjustExternalMemory(env, 0, &result); // The externally allocated memory remains unchanged.
2093OH_LOG_INFO(LOG_APP, "Before AdjustExternalMemory: %{public}lld\n", result); // Obtain the memory value before the adjustment.
2094// Increase the memory usage and notify the VM of the change.
2095int64_t memoryIncrease = 1024 * 1024; // Increase the memory by 1 MB.
2096OH_JSVM_AdjustExternalMemory(env, memoryIncrease, &result);
2097OH_LOG_INFO(LOG_APP, "After AdjustExternalMemory: %{public}lld\n", result); // Obtain the memory value after the adjustment.
2098```
2099```c++
2100// Open a handle scope and apply for a large amount of memory within the scope to test the function.
2101// Check the memory status after the memory is allocated, after the scope is closed, and after OH_JSVM_MemoryPressureNotification is called.
2102JSVM_HandleScope tmpscope;
2103OH_JSVM_OpenHandleScope(env, &tmpscope);
2104for (int i = 0; i < 1000000; ++i) {
2105    JSVM_Value obj;
2106    OH_JSVM_CreateObject(env, &obj);
2107}
2108JSVM_HeapStatistics mem;
2109OH_JSVM_GetHeapStatistics(vm, &mem); // Obtain the heap statistics of the VM.
2110OH_LOG_INFO(LOG_APP, " %{public}zu\n", mem.usedHeapSize); // After the requested memory is allocated, the memory is of the maximum size.
2111OH_JSVM_CloseHandleScope (env, tmpscope); // Close the handle scope.
2112
2113OH_JSVM_GetHeapStatistics(vm, &mem);
2114OH_LOG_INFO(LOG_APP, " %{public}zu\n", mem.usedHeapSize); // After the scope is closed, GC is not performed immediately.
2115
2116// Notify the VM of the memory pressure level and selectively trigger GC.
2117OH_JSVM_MemoryPressureNotification(env, JSVM_MEMORY_PRESSURE_LEVEL_CRITICAL); // The memory pressure is in the critical state.
2118
2119OH_JSVM_GetHeapStatistics(vm, &mem);
2120OH_LOG_INFO(LOG_APP, " %{public}zu\n", mem.usedHeapSize); // After GC is triggered.
2121```
2122
2123**Example**
2124
2125``` c++
2126void *backingStore;
2127JSVM_Value arrayBuffer;
2128
2129// Allocate memory of 100 bytes for a backing store.
2130OH_JSVM_AllocateArrayBufferBackingStoreData(100, JSVM_ZERO_INITIALIZED, &backingStore);
2131
2132// In the allocated memory, create an ArrayBuffer of 20 bytes at 30 bytes away from the start address of the backing store.
2133OH_JSVM_CreateArrayBufferFromBackingStoreData(env, backingStore, 100, 30, 20, &arrayBuffer);
2134
2135// Use the created ArrayBuffer in JS.
2136JSVM_Value js_global;
2137JSVM_Value name;
2138OH_JSVM_GetGlobal(jsvm_env, &js_global);
2139OH_JSVM_CreateStringUtf8(jsvm_env, "buffer", JSVM_AUTO_LENGTH, &name);
2140OH_JSVM_SetProperty(env, js_global, name, arrayBuffer);
2141
2142JSVM_Script script;
2143JSVM_Value scriptString;
2144JSVM_Value result;
2145const char *src = R"JS(
2146function writeBuffer(data) {
2147  let view = new Uint8Array(data);
2148  // Write some values to the ArrayBuffer
2149  for (let i = 0; i < view.length; i++) {
2150    view[i] = i % 256;
2151  }
2152}
2153writeBuffer(buffer)
2154)JS";
2155OH_JSVM_CreateStringUtf8(env, src, JSVM_AUTO_LENGTH, &scriptString);
2156OH_JSVM_CompileScriptWithOptions(env, scriptString, 0, nullptr, &script);
2157OH_JSVM_RunScript(env, script, &result);
2158
2159// Check the ArrayBuffer content.
2160uint8_t *array = static_cast<uint8_t*>(backingStore);
2161for (auto i = 0; i < 100; ++i) {
2162  if (array[i] != i % 25 % 256) {
2163    return false;
2164  }
2165}
2166
2167// Release the ArrayBuffer. Before releasing the backing store, you must
2168// call OH_JSVM_DetachArraybuffer to release all ArrayBuffers created in the backing store.
2169// Otherwise, unpredictable memory problems may occur.
2170OH_JSVM_DetachArraybuffer(env, arrayBuffer);
2171
2172// Release the memory allocated for the backing store.
2173OH_JSVM_FreeArrayBufferBackingStoreData(backingStore);
2174```
2175### Promises
2176
2177#### When to Use
2178
2179Perform operations related to promises.
2180
2181#### Available APIs
2182| API| Description|
2183| -------- | -------- |
2184|OH_JSVM_CreatePromise| Creates a **deferred** object and a JS promise.|
2185|OH_JSVM_ResolveDeferred| Resolves a JS promise by using the **deferred** object associated with it.|
2186|OH_JSVM_RejectDeferred| Rejects a JS promise by using the **deferred** object associated with it.|
2187|OH_JSVM_IsPromise| Checks whether a promise object is a native promise object.|
2188
2189#### Example
2190
2191Perform operations related to promises.
2192
2193```c++
2194JSVM_Deferred deferred;
2195JSVM_Value promise;
2196OH_JSVM_CreatePromise(env, &deferred, &promise);
2197
2198// Perform an asynchronous operation.
2199int result = 42;
2200bool success = true;
2201if (success)
2202{
2203    // Resolve the promise and pass the result.
2204    JSVM_Value value;
2205    OH_JSVM_CreateInt32(env, result, &value);
2206    OH_JSVM_ResolveDeferred(env, deferred, value);
2207} else {
2208    // Reject the promise and pass the error information.
2209    JSVM_Value code = nullptr;
2210    JSVM_Value message = nullptr;
2211    OH_JSVM_CreateStringUtf8(env, "600", JSVM_AUTO_LENGTH, &code);
2212    OH_JSVM_CreateStringUtf8(env, "Async operation failed", JSVM_AUTO_LENGTH, &message);
2213    JSVM_Value error = nullptr;
2214    OH_JSVM_CreateError(env, code, message, &error);
2215    OH_JSVM_RejectDeferred(env, deferred, error);
2216}
2217```
2218
2219### JSON Operations
2220
2221#### When to Use
2222
2223Perform JSON operations.
2224
2225#### Available APIs
2226
2227| API| Description|
2228| -------- | -------- |
2229|OH_JSVM_JsonParse| Parses a JSON string and returns the parsed value.|
2230|OH_JSVM_JsonStringify| Converts a JS object into a JSON string and returns the converted string.|
2231
2232#### Example
2233
2234Parse JSON strings.
2235
2236```c++
2237std::string sourcecodestr = "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}" ;
2238JSVM_Value jsonString;
2239OH_JSVM_CreateStringUtf8(env, sourcecodestr.c_str(), sourcecodestr.size(), &jsonString)
2240JSVM_Value result;
2241OH_JSVM_JsonParse(env, jsonString, &result);
2242```
2243
2244### Creating and Using a VM Startup Snapshot
2245
2246#### When to Use
2247
2248Create and use a VM startup snapshot.
2249
2250#### Available APIs
2251| API| Description|
2252| -------- | -------- |
2253|OH_JSVM_CreateSnapshot| Creates a VM startup snapshot.|
2254|OH_JSVM_CreateEnvFromSnapshot| Creates a JSVM environment from a startup snapshot.|
2255
2256#### Example
2257
2258See [Working with VM Snapshots Using JSVM-API](use-jsvm-create-snapshot.md).
2259
2260### Checking Input Parameters
2261
2262#### When to Use
2263
2264Check whether the input parameters are callable.
2265
2266#### Available APIs
2267| API| Description|
2268| -------- | -------- |
2269|OH_JSVM_IsCallable| Checks whether the input parameters are callable. |
2270
2271#### Example
2272
2273Check whether input parameters are callable.
2274
2275```c++
2276static JSVM_Value NapiIsCallable(JSVM_Env env, JSVM_CallbackInfo info) {
2277    JSVM_Value value, rst;
2278    size_t argc = 1;
2279    bool isCallable = false;
2280    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, &value, NULL, NULL));
2281    JSVM_CALL(env, OH_JSVM_IsCallable(env, value, &isCallable));
2282    OH_JSVM_GetBoolean(env, isCallable, &rst);
2283    return rst;
2284}
2285
2286static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
2287    std::thread t([]() {
2288        // Create a VM instance and open the VM scope.
2289        JSVM_VM vm;
2290        JSVM_CreateVMOptions options;
2291        memset(&options, 0, sizeof(options));
2292        OH_JSVM_CreateVM(&options, &vm);
2293        JSVM_VMScope vmScope;
2294        OH_JSVM_OpenVMScope(vm, &vmScope);
2295        JSVM_CallbackStruct param[] = {
2296            {.data = nullptr, .callback = NapiIsCallable},
2297        };
2298        JSVM_PropertyDescriptor descriptor[] = {
2299            {"napiIsCallable", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
2300        };
2301        // Create env, register a native method, and open an env scope.
2302        JSVM_Env env;
2303        OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
2304        JSVM_EnvScope envScope;
2305        OH_JSVM_OpenEnvScope(env, &envScope);
2306        // Open a handle scope.
2307        JSVM_HandleScope handleScope;
2308        OH_JSVM_OpenHandleScope(env, &handleScope);
2309        std::string sourceCodeStr = R"JS(
2310        function addNumbers(num1, num2)
2311        {
2312            var rst= num1 + num2;
2313            return rst;
2314        }
2315        let rst = napiIsCallable(addNumbers);
2316        )JS";
2317        // Compile the JS script.
2318        JSVM_Value sourceCodeValue;
2319        OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
2320        JSVM_Script script;
2321        OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
2322        JSVM_Value result;
2323        // Run the JS script.
2324        OH_JSVM_RunScript(env, script, &result);
2325        JSVM_ValueType type;
2326        OH_JSVM_Typeof(env, result, &type);
2327        OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
2328        // Exit the VM and release the memory.
2329        OH_JSVM_CloseHandleScope(env, handleScope);
2330        OH_JSVM_CloseEnvScope(env, envScope);
2331        OH_JSVM_DestroyEnv(env);
2332        OH_JSVM_CloseVMScope(vm, vmScope);
2333        OH_JSVM_DestroyVM(vm);
2334    });
2335    t.detach();
2336    return nullptr;
2337}
2338```
2339
2340### Lock Operations
2341
2342#### When to Use
2343
2344Perform lock operations.
2345
2346#### Available APIs
2347| API| Description|
2348| -------- | -------- |
2349|OH_JSVM_IsLocked| Checks whether the current thread holds a lock of the specified environment.|
2350|OH_JSVM_AcquireLock| Obtains a lock.|
2351|OH_JSVM_ReleaseLock| Releases a lock.|
2352
2353#### Example
2354
2355Obtain and release a lock.
2356
2357```c++
2358class LockWrapper {
2359 public:
2360  LockWrapper(JSVM_Env env) : env(env) {
2361    OH_JSVM_IsLocked(env, &isLocked);
2362    if (!isLocked) {
2363      OH_JSVM_AcquireLock(env);
2364      OH_JSVM_GetVM(env, &vm);
2365      OH_JSVM_OpenVMScope(vm, &vmScope);
2366      OH_JSVM_OpenEnvScope(env, &envScope);
2367    }
2368  }
2369
2370  ~LockWrapper() {
2371    if (!isLocked) {
2372      OH_JSVM_CloseEnvScope(env, envScope);
2373      OH_JSVM_CloseVMScope(vm, vmScope);
2374      OH_JSVM_ReleaseLock(env);
2375    }
2376  }
2377
2378  LockWrapper(const LockWrapper&) = delete;
2379  LockWrapper& operator=(const LockWrapper&) = delete;
2380  LockWrapper(LockWrapper&&) = delete;
2381  void* operator new(size_t) = delete;
2382  void* operator new[](size_t) = delete;
2383
2384 private:
2385  JSVM_Env env;
2386  JSVM_EnvScope envScope;
2387  JSVM_VMScope vmScope;
2388  JSVM_VM vm;
2389  bool isLocked;
2390};
2391
2392static napi_value Add([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
2393    static JSVM_VM vm;
2394    static JSVM_Env env;
2395    if (aa == 0) {
2396        OH_JSVM_Init(nullptr);
2397        aa++;
2398        // create vm
2399        JSVM_CreateVMOptions options;
2400        memset(&options, 0, sizeof(options));
2401        OH_JSVM_CreateVM(&options, &vm);
2402        // create env
2403        OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
2404    }
2405
2406    std::thread t1([]() {
2407        LockWrapper lock(env);
2408        JSVM_HandleScope handleScope;
2409        OH_JSVM_OpenHandleScope(env, &handleScope);
2410        JSVM_Value value;
2411        JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
2412        if (rst == JSVM_OK) {
2413            OH_LOG_INFO(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 suc");
2414        } else {
2415            OH_LOG_ERROR(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 fail");
2416        }
2417        int32_t num1;
2418        OH_JSVM_GetValueInt32(env, value, &num1);
2419        OH_LOG_INFO(LOG_APP, "JSVM:t1 num1 = %{public}d", num1);
2420        OH_JSVM_CloseHandleScope(env, handleScope);
2421    });
2422    std::thread t2([]() {
2423        LockWrapper lock(env);
2424        JSVM_HandleScope handleScope;
2425        OH_JSVM_OpenHandleScope(env, &handleScope);
2426        JSVM_Value value;
2427        JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
2428        if (rst == JSVM_OK) {
2429            OH_LOG_INFO(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 suc");
2430        } else {
2431            OH_LOG_ERROR(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 fail");
2432        }
2433        int32_t num1;
2434        OH_JSVM_GetValueInt32(env, value, &num1);
2435        OH_LOG_INFO(LOG_APP, "JSVM:t2 num1 = %{public}d", num1);
2436        OH_JSVM_CloseHandleScope(env, handleScope);
2437    });
2438    t1.detach();
2439    t2.detach();
2440    return nullptr;
2441}
2442```
2443
2444### Setting and Obtaining Data Associated with a JSVM Instance
2445
2446#### When to Use
2447
2448Set and obtain the data associated with a JSVM instance.
2449
2450#### Available APIs
2451| API| Description|
2452| -------- | -------- |
2453|OH_JSVM_SetInstanceData| Sets data to be associated with a JSVM instance.|
2454|OH_JSVM_GetInstanceData| Obtains the data associated with a JSVM instance.|
2455
2456#### Example
2457
2458Set and obtain the data associated with a JSVM instance.
2459
2460```c++
2461JSVM_VM vm;
2462JSVM_CreateVMOptions options;
2463JSVM_VMScope vm_scope;
2464JSVM_Env env;
2465JSVM_EnvScope envScope;
2466JSVM_HandleScope handlescope;
2467
2468static int aa = 0;
2469struct InstanceData {
2470    int32_t value;
2471};
2472
2473// Initialize the VM and create a JSVM instance.
2474void init_JSVM_environment(){
2475    JSVM_InitOptions init_options;
2476    memset(&init_options, 0, sizeof(init_options));
2477    if (aa == 0) {
2478        OH_JSVM_Init(&init_options);
2479        aa++;
2480    }
2481    memset(&options, 0, sizeof(options));
2482    OH_JSVM_CreateVM(&options, &vm);
2483    OH_JSVM_OpenVMScope(vm, &vm_scope);
2484    OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
2485    OH_JSVM_OpenEnvScope(env, &envScope);
2486    OH_JSVM_OpenHandleScope(env, &handlescope);
2487}
2488
2489// Exit the VM and release the running environment.
2490napi_value close_JSVM_environment(napi_env env1, napi_callback_info info)
2491{
2492    OH_JSVM_CloseHandleScope(env, handlescope);
2493    OH_JSVM_CloseEnvScope(env, envScope);
2494    OH_JSVM_DestroyEnv(env);
2495    OH_JSVM_CloseVMScope(vm, vm_scope);
2496    OH_JSVM_DestroyVM(vm);
2497    napi_value result;
2498    char* s = "ok";
2499    napi_create_string_latin1(env1, s, strlen(s), &result);
2500    return result;
2501}
2502
2503// Clear and release the memory used by the instance.
2504void InstanceFinalizeCallback(JSVM_Env env, void *finalizeData, void *finalizeHint)
2505{
2506    if (finalizeData) {
2507        InstanceData *data = reinterpret_cast<InstanceData *>(finalizeData);
2508        free(data);
2509        *(InstanceData **)finalizeData = nullptr;
2510    }
2511}
2512
2513static napi_value GetInstanceData(napi_env env1, napi_callback_info info)
2514{
2515    InstanceData *instanceData = reinterpret_cast<InstanceData *>(malloc(sizeof(InstanceData)));
2516    if (instanceData == nullptr) {
2517        printf("Memory allocation failed!\n");
2518        return nullptr;
2519    }
2520    size_t argc = 1;
2521    napi_value args[1] = {nullptr};
2522    // Obtain the callback function parameters.
2523    napi_get_cb_info(env1, info, &argc, args , nullptr, nullptr);
2524    napi_valuetype valuetype0;
2525    napi_typeof(env1, args[0], &valuetype0);
2526    int32_t tmp = 0;
2527    napi_get_value_int32(env1, args[0], &tmp);
2528    instanceData->value = tmp;
2529    // Associate the obtained parameters with the current JSVM environment.
2530    OH_JSVM_SetInstanceData(env, instanceData, InstanceFinalizeCallback, nullptr);
2531    InstanceData *resData = nullptr;
2532    // Obtain the data associated with the JSVM instance.
2533    OH_JSVM_GetInstanceData(env, (void **)&resData);
2534    napi_value result;
2535    napi_create_uint32(env1, resData->value, &result);
2536    return result;
2537}
2538```
2539
2540### Task Queue
2541
2542#### When to Use
2543
2544Start the running of a task queue in a JSVM and check whether there are micro tasks waiting in the queue. The task queue can be executed cyclically by external events.
2545
2546#### Available APIs
2547| API| Description|
2548| -------- | -------- |
2549|OH_JSVM_PumpMessageLoop| Starts running a task queue.|
2550|OH_JSVM_PerformMicrotaskCheckpoint| Executes micro tasks in a task queue.|
2551
2552#### Example
2553
2554See [Working with Task Queues Using JSVM-API](use-jsvm-execute_tasks.md).