• 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|OH_JSVM_DefineClassWithOptions | Defines a JS class with the given class name, constructor, properties, callback handler, and parent class. The **DefineClassOptions** parameter specifies whether to set a property proxy for the defined class, reserve the internal-field slot, and set a callback when the class is called as a function. |
1565
1566#### Example
1567
1568Wrap a native object in a JS object.
1569
1570```c++
1571static JSVM_Value AssertEqual(JSVM_Env env, JSVM_CallbackInfo info)
1572{
1573    size_t argc = 2;
1574    JSVM_Value args[2];
1575    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1576
1577    bool isStrictEquals = false;
1578    OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
1579    return nullptr;
1580}
1581
1582static napi_value TestWrap(napi_env env1, napi_callback_info info)
1583{
1584    OH_LOG_ERROR(LOG_APP, "testWrap start");
1585    JSVM_InitOptions init_options;
1586    memset(&init_options, 0, sizeof(init_options));
1587    init_options.externalReferences = externals;
1588    if (aa == 0) {
1589        OH_JSVM_Init(&init_options);
1590        aa++;
1591    }
1592    JSVM_VM vm;
1593    JSVM_CreateVMOptions options;
1594    memset(&options, 0, sizeof(options));
1595    OH_JSVM_CreateVM(&options, &vm);
1596    JSVM_VMScope vm_scope;
1597    OH_JSVM_OpenVMScope(vm, &vm_scope);
1598    JSVM_Env env;
1599    JSVM_CallbackStruct param[1];
1600    param[0].data = nullptr;
1601    param[0].callback = AssertEqual;
1602    JSVM_PropertyDescriptor descriptor[] = {
1603        {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1604    };
1605    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1606    JSVM_EnvScope envScope;
1607    OH_JSVM_OpenEnvScope(env, &envScope);
1608    JSVM_HandleScope handlescope;
1609    OH_JSVM_OpenHandleScope(env, &handlescope);
1610    JSVM_Value testClass = nullptr;
1611    JSVM_CallbackStruct param1;
1612    param1.data = nullptr;
1613    param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1614        JSVM_Value thisVar = nullptr;
1615        OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1616
1617        return thisVar;
1618    };
1619    OH_JSVM_DefineClass(env, "TestClass", JSVM_AUTO_LENGTH, &param1, 0, nullptr, &testClass);
1620
1621    JSVM_Value instanceValue = nullptr;
1622    OH_JSVM_NewInstance(env, testClass, 0, nullptr, &instanceValue);
1623
1624    const char *testStr = "test";
1625    OH_JSVM_Wrap(
1626        env, instanceValue, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, nullptr, nullptr);
1627    const char *tmpTestStr = nullptr;
1628    OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr);
1629    const char *tmpTestStr1 = nullptr;
1630    OH_JSVM_RemoveWrap(env, instanceValue, (void **)&tmpTestStr1);
1631    OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr1);
1632    OH_JSVM_CloseHandleScope(env, handlescope);
1633    OH_JSVM_CloseEnvScope(env, envScope);
1634    OH_JSVM_DestroyEnv(env);
1635    OH_JSVM_CloseVMScope(vm, vm_scope);
1636    OH_JSVM_DestroyVM(vm);
1637    OH_LOG_ERROR(LOG_APP, "testWrap pass");
1638    return nullptr;
1639}
1640```
1641
1642
1643Wrap a native object and register a listener for property access operations.
1644
1645```c++
1646static int aa = 0;
1647static JSVM_Value hello(JSVM_Env env, JSVM_CallbackInfo info) {
1648    JSVM_Value output;
1649    void *data = nullptr;
1650    OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
1651    OH_JSVM_CreateStringUtf8(env, (char *)data, strlen((char *)data), &output);
1652    return output;
1653}
1654
1655static JSVM_CallbackStruct hello_cb = {hello, (void *)"Hello"};
1656static intptr_t externals[] = {
1657    (intptr_t)&hello_cb,
1658    0,
1659};
1660
1661static void test1() { OH_LOG_INFO(LOG_APP, "test1 called"); }
1662
1663struct Test {
1664    void *ptr1;
1665    void *ptr2;
1666};
1667
1668static JSVM_Value assertEqual(JSVM_Env env, JSVM_CallbackInfo info) {
1669    size_t argc = 2;
1670    JSVM_Value args[2];
1671    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1672
1673    bool isStrictEquals = false;
1674    OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
1675    return nullptr;
1676}
1677
1678static JSVM_Value GetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
1679    // This callback is triggered by the getter of the object.
1680    char strValue[100];
1681    size_t size;
1682    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1683    JSVM_Value newResult = nullptr;
1684    char newStr[] = "new return value hahaha from name listening";
1685    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1686    int signBit = 0;
1687    size_t wordCount = 2;
1688    uint64_t wordsOut[2] = {0ULL, 0ULL};
1689    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1690    if (status == JSVM_OK) {
1691        OH_LOG_INFO(LOG_APP, "GetPropertyCbInfo wordCount is %{public}zu", wordCount);
1692        auto test = reinterpret_cast<Test *>(wordsOut);
1693        typedef void (*callTest1)();
1694        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1695        callTe();
1696    }
1697    return nullptr;
1698}
1699
1700static JSVM_Value SetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
1701    // This callback is triggered by the setter of the object.
1702    char strValue[100];
1703    size_t size;
1704    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1705    JSVM_Value newResult = nullptr;
1706    char newStr[] = "new return value hahaha from name listening";
1707    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1708    int signBit = 0;
1709    size_t wordCount = 2;
1710    uint64_t wordsOut[2] = {0ULL, 0ULL};
1711    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1712    if (status == JSVM_OK) {
1713        OH_LOG_INFO(LOG_APP, "SetPropertyCbInfo wordCount is %{public}zu", wordCount);
1714        auto test = reinterpret_cast<Test *>(wordsOut);
1715        typedef void (*callTest1)();
1716        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1717        callTe();
1718    }
1719    return nullptr;
1720}
1721
1722static JSVM_Value DeleterPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
1723    // This callback is triggered by the deleter of the object.
1724    char strValue[100];
1725    size_t size;
1726    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1727    JSVM_Value newResult = nullptr;
1728    bool returnValue = false;
1729    OH_JSVM_GetBoolean(env, returnValue, &newResult);
1730    int signBit = 0;
1731    size_t wordCount = 2;
1732    uint64_t wordsOut[2] = {0ULL, 0ULL};
1733    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1734    if (status == JSVM_OK) {
1735        OH_LOG_INFO(LOG_APP, "DeleterPropertyCbInfo wordCount is %{public}zu", wordCount);
1736        auto test = reinterpret_cast<Test *>(wordsOut);
1737        typedef void (*callTest1)();
1738        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1739        callTe();
1740    }
1741    return nullptr;
1742}
1743
1744static JSVM_Value EnumeratorPropertyCbInfo(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
1745    // This callback is triggered by the enumerator of an object.
1746    JSVM_Value testArray = nullptr;
1747    OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
1748    JSVM_Value name1 = nullptr;
1749    char newStr1[] = "hahaha";
1750    OH_JSVM_CreateStringUtf8(env, newStr1, strlen(newStr1), &name1);
1751    JSVM_Value name2 = nullptr;
1752    char newStr2[] = "heheheh";
1753    OH_JSVM_CreateStringUtf8(env, newStr2, strlen(newStr2), &name2);
1754
1755    OH_JSVM_SetElement(env, testArray, 0, name1);
1756    OH_JSVM_SetElement(env, testArray, 1, name2);
1757    int signBit = 0;
1758    size_t wordCount = 2;
1759    uint64_t wordsOut[2] = {0ULL, 0ULL};
1760    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1761    if (status == JSVM_OK) {
1762        OH_LOG_INFO(LOG_APP, "EnumeratorPropertyCbInfo wordCount is %{public}zu", wordCount);
1763        auto test = reinterpret_cast<Test *>(wordsOut);
1764        typedef void (*callTest1)();
1765        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1766        callTe();
1767    }
1768    return nullptr;
1769}
1770
1771static JSVM_Value IndexedPropertyGet(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
1772    // This callback is triggered by the indexed getter.
1773    uint32_t value;
1774    OH_JSVM_GetValueUint32(env, index, &value);
1775
1776    JSVM_Value newResult = nullptr;
1777    char newStr[] = "new return value hahaha from index listening";
1778    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1779    int signBit = 0;
1780    size_t wordCount = 2;
1781    uint64_t wordsOut[2] = {0ULL, 0ULL};
1782    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1783    if (status == JSVM_OK) {
1784        OH_LOG_INFO(LOG_APP, "IndexedPropertyGet wordCount is %{public}zu", wordCount);
1785        auto test = reinterpret_cast<Test *>(wordsOut);
1786        typedef void (*callTest1)();
1787        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1788        callTe();
1789    }
1790    return nullptr;
1791}
1792
1793static JSVM_Value IndexedPropertySet(JSVM_Env env, JSVM_Value index, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
1794    // This callback is triggered by the indexed setter.
1795    uint32_t value;
1796    OH_JSVM_GetValueUint32(env, index, &value);
1797    char str[100];
1798    size_t size;
1799    OH_JSVM_GetValueStringUtf8(env, property, str, 100, &size);
1800    JSVM_Value newResult = nullptr;
1801    char newStr[] = "new return value hahaha from name listening";
1802    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1803    int signBit = 0;
1804    size_t wordCount = 2;
1805    uint64_t wordsOut[2] = {0ULL, 0ULL};
1806    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1807    if (status == JSVM_OK) {
1808        OH_LOG_INFO(LOG_APP, "IndexedPropertySet wordCount is %{public}zu", wordCount);
1809        auto test = reinterpret_cast<Test *>(wordsOut);
1810        typedef void (*callTest1)();
1811        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1812        callTe();
1813    }
1814    return nullptr;
1815}
1816
1817static JSVM_Value IndexedPropertyDeleter(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
1818    // This callback is triggered by the indexed deleter.
1819    uint32_t value;
1820    OH_JSVM_GetValueUint32(env, index, &value);
1821    JSVM_Value newResult = nullptr;
1822    bool returnValue = false;
1823    OH_JSVM_GetBoolean(env, returnValue, &newResult);
1824    int signBit = 0;
1825    size_t wordCount = 2;
1826    uint64_t wordsOut[2] = {0ULL, 0ULL};
1827    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1828    if (status == JSVM_OK) {
1829        OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
1830        auto test = reinterpret_cast<Test *>(wordsOut);
1831        typedef void (*callTest1)();
1832        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1833        callTe();
1834    }
1835    return nullptr;
1836}
1837
1838static JSVM_Value IndexedPropertyEnumerator(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
1839    // This callback is triggered by the indexed enumerator.
1840    JSVM_Value testArray = nullptr;
1841    OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
1842    JSVM_Value index1 = nullptr;
1843    OH_JSVM_CreateUint32(env, 1, &index1);
1844    JSVM_Value index2 = nullptr;
1845    OH_JSVM_CreateUint32(env, 2, &index2);
1846    OH_JSVM_SetElement(env, testArray, 0, index1);
1847    OH_JSVM_SetElement(env, testArray, 1, index2);
1848    int signBit = 0;
1849    size_t wordCount = 2;
1850    uint64_t wordsOut[2] = {0ULL, 0ULL};
1851    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1852    if (status == JSVM_OK) {
1853        OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
1854        auto test = reinterpret_cast<Test *>(wordsOut);
1855        typedef void (*callTest1)();
1856        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1857        callTe();
1858    }
1859    return nullptr;
1860}
1861
1862static napi_value TestDefineClassWithProperty(napi_env env1, napi_callback_info info) {
1863    OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty start");
1864    JSVM_InitOptions init_options;
1865    memset(&init_options, 0, sizeof(init_options));
1866    init_options.externalReferences = externals;
1867    if (aa == 0) {
1868        OH_JSVM_Init(&init_options);
1869        aa++;
1870    }
1871    JSVM_VM vm;
1872    JSVM_CreateVMOptions options;
1873    memset(&options, 0, sizeof(options));
1874    OH_JSVM_CreateVM(&options, &vm);
1875    JSVM_VMScope vm_scope;
1876    OH_JSVM_OpenVMScope(vm, &vm_scope);
1877    JSVM_Env env;
1878    JSVM_CallbackStruct param[1];
1879    param[0].data = nullptr;
1880    param[0].callback = assertEqual;
1881    JSVM_PropertyDescriptor descriptor[] = {
1882        {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1883    };
1884    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1885    JSVM_EnvScope envScope;
1886    OH_JSVM_OpenEnvScope(env, &envScope);
1887    JSVM_HandleScope handlescope;
1888    OH_JSVM_OpenHandleScope(env, &handlescope);
1889
1890
1891    JSVM_CallbackStruct param1;
1892    param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1893        JSVM_Value thisVar = nullptr;
1894        OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1895        return thisVar;
1896    };
1897    param1.data = nullptr;
1898
1899    JSVM_Value res = nullptr;
1900    Test *test = new Test();
1901    test->ptr1 = (void *)test1;
1902    test->ptr2 = (void *)test1;
1903    OH_LOG_INFO(LOG_APP, "OH_JSVM_CreateBigintWords 111 word count %{public}d",
1904                sizeof(*test) / sizeof(uint64_t));
1905    JSVM_Status status = OH_JSVM_CreateBigintWords(env, 1, 2, reinterpret_cast<const uint64_t *>(test), &res);
1906
1907    // Initialize propertyCfg.
1908    JSVM_PropertyHandlerConfigurationStruct propertyCfg;
1909    propertyCfg.genericNamedPropertyGetterCallback = GetPropertyCbInfo;
1910    propertyCfg.genericNamedPropertySetterCallback = SetPropertyCbInfo;
1911    propertyCfg.genericNamedPropertyDeleterCallback = DeleterPropertyCbInfo;
1912    propertyCfg.genericNamedPropertyEnumeratorCallback = EnumeratorPropertyCbInfo;
1913    propertyCfg.genericIndexedPropertyGetterCallback = IndexedPropertyGet;
1914    propertyCfg.genericIndexedPropertySetterCallback = IndexedPropertySet;
1915    propertyCfg.genericIndexedPropertyDeleterCallback = IndexedPropertyDeleter;
1916    propertyCfg.genericIndexedPropertyEnumeratorCallback = IndexedPropertyEnumerator;
1917    propertyCfg.namedPropertyData = res;
1918    propertyCfg.indexedPropertyData = res;
1919
1920    JSVM_CallbackStruct callbackStruct;
1921    callbackStruct.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1922        OH_LOG_INFO(LOG_APP, "call as a function called");
1923        JSVM_Value thisVar = nullptr;
1924        void *innerData;
1925        size_t argc = 1;
1926        JSVM_Value args[1];
1927        OH_JSVM_GetCbInfo(env, info, &argc, args, &thisVar, &innerData);
1928        OH_LOG_INFO(LOG_APP, "function call as function result is %{public}s", reinterpret_cast<char *>(innerData));
1929        uint32_t ret = 0;
1930        OH_JSVM_GetValueUint32(env, args[0], &ret);
1931        const char testStr[] = "hello world 111111";
1932        JSVM_Value setvalueName = nullptr;
1933        JSVM_CALL(env, OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName));
1934        return setvalueName;
1935    };
1936    char data[100] = "1111 hello world";
1937    callbackStruct.data = data;
1938    JSVM_Value testWrapClass = nullptr;
1939
1940    // Register a property access listener in propertyCfg.
1941    OH_JSVM_DefineClassWithPropertyHandler(env, "TestWrapClass", NAPI_AUTO_LENGTH, &param1, 0, nullptr, &propertyCfg,
1942                                           &callbackStruct, &testWrapClass);
1943    JSVM_Value instanceValue = nullptr;
1944    OH_JSVM_NewInstance(env, testWrapClass, 0, nullptr, &instanceValue);
1945    const char testStr[] = "hello world";
1946    JSVM_Value setvalueName = nullptr;
1947    OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName);
1948
1949    // 1. Callbacks for properties.
1950    // Set properties.
1951    OH_JSVM_SetNamedProperty(env, instanceValue, "str11", setvalueName);
1952    OH_JSVM_SetNamedProperty(env, instanceValue, "str123", setvalueName);
1953
1954    // Obtain a property.
1955    JSVM_Value valueName = nullptr;
1956    OH_JSVM_GetNamedProperty(env, instanceValue, "str11", &valueName);
1957    char str[100];
1958    size_t size;
1959    OH_JSVM_GetValueStringUtf8(env, valueName, str, 100, &size);
1960
1961    // Obtain all property names.
1962    JSVM_Value allPropertyNames = nullptr;
1963    OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
1964                                static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
1965                                JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames);
1966    uint32_t nameSize = 0;
1967    OH_JSVM_GetArrayLength(env, allPropertyNames, &nameSize);
1968    JSVM_Value propertyName = nullptr;
1969    for (uint32_t i = 0; i < nameSize; ++i) {
1970        OH_JSVM_GetElement(env, allPropertyNames, i, &propertyName);
1971        char str[100];
1972        size_t size;
1973        OH_JSVM_GetValueStringUtf8(env, propertyName, str, 100, &size);
1974    }
1975
1976    // Delete a property.
1977    bool result = false;
1978    propertyName = nullptr;
1979    char propertyChar[] = "str11";
1980    OH_JSVM_CreateStringUtf8(env, propertyChar, strlen(propertyChar), &propertyName);
1981    OH_JSVM_DeleteProperty(env, instanceValue, propertyName, &result);
1982
1983    // 2. Callbacks for index properties.
1984    // Set properties.
1985    JSVM_Value jsIndex = nullptr;
1986    uint32_t index = 0;
1987    OH_JSVM_CreateUint32(env, index, &jsIndex);
1988    OH_JSVM_SetProperty(env, instanceValue, jsIndex, setvalueName);
1989    JSVM_Value jsIndex1 = nullptr;
1990    index = 1;
1991    OH_JSVM_CreateUint32(env, index, &jsIndex1);
1992    OH_JSVM_SetProperty(env, instanceValue, jsIndex1, setvalueName);
1993
1994    // Obtain a property.
1995    JSVM_Value valueName1 = nullptr;
1996    OH_JSVM_GetProperty(env, instanceValue, jsIndex, &valueName1);
1997    char str1[100];
1998    size_t size1;
1999    OH_JSVM_GetValueStringUtf8(env, valueName1, str1, 100, &size1);
2000
2001    // Obtain all property names.
2002    JSVM_Value allPropertyNames1 = nullptr;
2003    OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
2004                                static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
2005                                JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames1);
2006    uint32_t nameSize1 = 0;
2007    OH_JSVM_GetArrayLength(env, allPropertyNames1, &nameSize);
2008    JSVM_Value propertyName1 = nullptr;
2009    for (uint32_t i = 0; i < nameSize1; ++i) {
2010        OH_JSVM_GetElement(env, allPropertyNames1, i, &propertyName1);
2011        char str[100];
2012        size_t size;
2013        OH_JSVM_GetValueStringUtf8(env, propertyName1, str, 100, &size);
2014    }
2015
2016    // Delete a property.
2017    bool result1 = false;
2018    OH_JSVM_DeleteProperty(env, instanceValue, jsIndex, &result1);
2019
2020    // 3. Callback of a function.
2021    JSVM_Value gloablObj = nullptr;
2022    OH_JSVM_GetGlobal(env, &gloablObj);
2023    OH_JSVM_SetNamedProperty(env, gloablObj, "myTestInstance", instanceValue);
2024    OH_LOG_INFO(LOG_APP, "set property on global object");
2025    std::string innerSourcecodestr = R"(
2026    {
2027        let res = myTestInstance(12);
2028    })";
2029    JSVM_Value innerSourcecodevalue;
2030    OH_JSVM_CreateStringUtf8(env, innerSourcecodestr.c_str(), innerSourcecodestr.size(), &innerSourcecodevalue);
2031    JSVM_Script innerscript;
2032    OH_JSVM_CompileScript(env, innerSourcecodevalue, nullptr, 0, true, nullptr, &innerscript);
2033    JSVM_Value innerResult;
2034    OH_JSVM_RunScript(env, innerscript, &innerResult);
2035
2036    OH_JSVM_CloseHandleScope(env, handlescope);
2037    OH_JSVM_CloseEnvScope(env, envScope);
2038    OH_JSVM_DestroyEnv(env);
2039    OH_JSVM_CloseVMScope(vm, vm_scope);
2040    OH_JSVM_DestroyVM(vm);
2041    OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty pass");
2042    return nullptr;
2043}
2044```
2045Set a parent class and register a listener for property access operations.
2046
2047See [Working with Classes Using JSVM-API](use-jsvm-about-class.md).
2048
2049### Version Management
2050
2051#### When to Use
2052
2053Obtain version information.
2054
2055#### Available APIs
2056| API| Description|
2057| -------- | -------- |
2058|OH_JSVM_GetVersion| Obtains the latest JSVM API version supported by the JSVM runtime.|
2059|OH_JSVM_GetVMInfo| Obtains the VM information.|
2060
2061#### Example
2062
2063Obtain version information.
2064
2065```c++
2066JSVM_VMInfo result;
2067OH_JSVM_GetVMInfo(&result);
2068uint32_t versionId = 0;
2069OH_JSVM_GetVersion(env, &versionId);
2070```
2071
2072### Memory Management
2073
2074#### When to Use
2075
2076Perform memory management.
2077
2078#### Available APIs
2079| API                                         | Description                                                                                                  |
2080| ------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
2081| 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.|
2082| OH_JSVM_MemoryPressureNotification          | Notifies the VM of the memory pressure level and selectively triggers GC.                                                                            |
2083| OH_JSVM_AllocateArrayBufferBackingStoreData | Allocates memory for a backing store.|
2084| OH_JSVM_FreeArrayBufferBackingStoreData | Releases the backing store memory.|
2085| OH_JSVM_CreateArrayBufferFromBackingStoreData | Creates an array buffer based on the backing store memory allocated.|
2086
2087> 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.
2088
2089#### Example
2090
2091Perform memory management.
2092
2093```c++
2094// Before and after calling OH_JSVM_AdjustExternalMemory, check the memory allocated externally from the perspective of the underlying VM.
2095int64_t result;
2096OH_JSVM_AdjustExternalMemory(env, 0, &result); // The externally allocated memory remains unchanged.
2097OH_LOG_INFO(LOG_APP, "Before AdjustExternalMemory: %{public}lld\n", result); // Obtain the memory value before the adjustment.
2098// Increase the memory usage and notify the VM of the change.
2099int64_t memoryIncrease = 1024 * 1024; // Increase the memory by 1 MB.
2100OH_JSVM_AdjustExternalMemory(env, memoryIncrease, &result);
2101OH_LOG_INFO(LOG_APP, "After AdjustExternalMemory: %{public}lld\n", result); // Obtain the memory value after the adjustment.
2102```
2103```c++
2104// Open a handle scope and apply for a large amount of memory within the scope to test the function.
2105// Check the memory status after the memory is allocated, after the scope is closed, and after OH_JSVM_MemoryPressureNotification is called.
2106JSVM_HandleScope tmpscope;
2107OH_JSVM_OpenHandleScope(env, &tmpscope);
2108for (int i = 0; i < 1000000; ++i) {
2109    JSVM_Value obj;
2110    OH_JSVM_CreateObject(env, &obj);
2111}
2112JSVM_HeapStatistics mem;
2113OH_JSVM_GetHeapStatistics(vm, &mem); // Obtain the heap statistics of the VM.
2114OH_LOG_INFO(LOG_APP, " %{public}zu\n", mem.usedHeapSize); // After the requested memory is allocated, the memory is of the maximum size.
2115OH_JSVM_CloseHandleScope (env, tmpscope); // Close the handle scope.
2116
2117OH_JSVM_GetHeapStatistics(vm, &mem);
2118OH_LOG_INFO(LOG_APP, " %{public}zu\n", mem.usedHeapSize); // After the scope is closed, GC is not performed immediately.
2119
2120// Notify the VM of the memory pressure level and selectively trigger GC.
2121OH_JSVM_MemoryPressureNotification(env, JSVM_MEMORY_PRESSURE_LEVEL_CRITICAL); // The memory pressure is in the critical state.
2122
2123OH_JSVM_GetHeapStatistics(vm, &mem);
2124OH_LOG_INFO(LOG_APP, " %{public}zu\n", mem.usedHeapSize); // After GC is triggered.
2125```
2126
2127Example
2128``` c++
2129void *backingStore;
2130JSVM_Value arrayBuffer;
2131
2132// Allocate memory of 100 bytes for a backing store.
2133OH_JSVM_AllocateArrayBufferBackingStoreData(100, JSVM_ZERO_INITIALIZED, &backingStore);
2134
2135// In the allocated memory, create an ArrayBuffer of 20 bytes at 30 bytes away from the start address of the backing store.
2136OH_JSVM_CreateArrayBufferFromBackingStoreData(env, backingStore, 100, 30, 20, &arrayBuffer);
2137
2138// Use the created ArrayBuffer in JS.
2139JSVM_Value js_global;
2140JSVM_Value name;
2141OH_JSVM_GetGlobal(jsvm_env, &js_global);
2142OH_JSVM_CreateStringUtf8(jsvm_env, "buffer", JSVM_AUTO_LENGTH, &name);
2143OH_JSVM_SetProperty(env, js_global, name, arrayBuffer);
2144
2145JSVM_Script script;
2146JSVM_Value scriptString;
2147JSVM_Value result;
2148const char *src = R"JS(
2149function writeBuffer(data) {
2150  let view = new Uint8Array(data);
2151  // Write some values to the ArrayBuffer
2152  for (let i = 0; i < view.length; i++) {
2153    view[i] = i % 256;
2154  }
2155}
2156writeBuffer(buffer)
2157)JS";
2158OH_JSVM_CreateStringUtf8(env, src, JSVM_AUTO_LENGTH, &scriptString);
2159OH_JSVM_CompileScriptWithOptions(env, scriptString, 0, nullptr, &script);
2160OH_JSVM_RunScript(env, script, &result);
2161
2162// Check the ArrayBuffer content.
2163uint8_t *array = static_cast<uint8_t*>(backingStore);
2164for (auto i = 0; i < 100; ++i) {
2165  if (array[i] != i % 25 % 256) {
2166    return false;
2167  }
2168}
2169
2170// Release the ArrayBuffer. Before releasing the backing store, you must
2171// call OH_JSVM_DetachArraybuffer to release all ArrayBuffers created in the backing store.
2172// Otherwise, unpredictable memory problems may occur.
2173OH_JSVM_DetachArraybuffer(env, arrayBuffer);
2174
2175// Release the memory allocated for the backing store.
2176OH_JSVM_FreeArrayBufferBackingStoreData(backingStore);
2177```
2178### Promises
2179
2180#### When to Use
2181
2182Perform operations related to promises.
2183
2184#### Available APIs
2185| API| Description|
2186| -------- | -------- |
2187|OH_JSVM_CreatePromise| Creates a **deferred** object and a JS promise.|
2188|OH_JSVM_ResolveDeferred| Resolves a JS promise by using the **deferred** object associated with it.|
2189|OH_JSVM_RejectDeferred| Rejects a JS promise by using the **deferred** object associated with it.|
2190|OH_JSVM_IsPromise| Checks whether a promise object is a native promise object.|
2191
2192#### Example
2193
2194Perform operations related to promises.
2195
2196```c++
2197JSVM_Deferred deferred;
2198JSVM_Value promise;
2199OH_JSVM_CreatePromise(env, &deferred, &promise);
2200
2201// Perform an asynchronous operation.
2202int result = 42;
2203bool success = true;
2204if (success)
2205{
2206    // Resolve the promise and pass the result.
2207    JSVM_Value value;
2208    OH_JSVM_CreateInt32(env, result, &value);
2209    OH_JSVM_ResolveDeferred(env, deferred, value);
2210} else {
2211    // Reject the promise and pass the error information.
2212    JSVM_Value code = nullptr;
2213    JSVM_Value message = nullptr;
2214    OH_JSVM_CreateStringUtf8(env, "600", JSVM_AUTO_LENGTH, &code);
2215    OH_JSVM_CreateStringUtf8(env, "Async operation failed", JSVM_AUTO_LENGTH, &message);
2216    JSVM_Value error = nullptr;
2217    OH_JSVM_CreateError(env, code, message, &error);
2218    OH_JSVM_RejectDeferred(env, deferred, error);
2219}
2220```
2221
2222### JSON Operations
2223
2224#### When to Use
2225
2226Perform JSON operations.
2227
2228#### Available APIs
2229
2230| API| Description|
2231| -------- | -------- |
2232|OH_JSVM_JsonParse| Parses a JSON string and returns the parsed value.|
2233|OH_JSVM_JsonStringify| Converts a JS object into a JSON string and returns the converted string.|
2234
2235#### Example
2236
2237Parse JSON strings.
2238
2239```c++
2240std::string sourcecodestr = "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}" ;
2241JSVM_Value jsonString;
2242OH_JSVM_CreateStringUtf8(env, sourcecodestr.c_str(), sourcecodestr.size(), &jsonString)
2243JSVM_Value result;
2244OH_JSVM_JsonParse(env, jsonString, &result);
2245```
2246
2247### Creating and Using a VM Startup Snapshot
2248
2249#### When to Use
2250
2251Create and use a VM startup snapshot.
2252
2253#### Available APIs
2254| API| Description|
2255| -------- | -------- |
2256|OH_JSVM_CreateSnapshot| Creates a VM startup snapshot.|
2257|OH_JSVM_CreateEnvFromSnapshot| Creates a JSVM environment from a startup snapshot.|
2258
2259#### Example
2260
2261See [Working with VM Snapshots Using JSVM-API](use-jsvm-create-snapshot.md).
2262
2263### Checking Input Parameters
2264
2265#### When to Use
2266
2267Check whether the input parameters are callable.
2268
2269#### Available APIs
2270| API| Description|
2271| -------- | -------- |
2272|OH_JSVM_IsCallable| Checks whether the input parameters are callable. |
2273
2274#### Example
2275
2276Check whether input parameters are callable.
2277
2278```c++
2279static JSVM_Value NapiIsCallable(JSVM_Env env, JSVM_CallbackInfo info) {
2280    JSVM_Value value, rst;
2281    size_t argc = 1;
2282    bool isCallable = false;
2283    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, &value, NULL, NULL));
2284    JSVM_CALL(env, OH_JSVM_IsCallable(env, value, &isCallable));
2285    OH_JSVM_GetBoolean(env, isCallable, &rst);
2286    return rst;
2287}
2288
2289static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
2290    std::thread t([]() {
2291        // Create a VM instance and open the VM scope.
2292        JSVM_VM vm;
2293        JSVM_CreateVMOptions options;
2294        memset(&options, 0, sizeof(options));
2295        OH_JSVM_CreateVM(&options, &vm);
2296        JSVM_VMScope vmScope;
2297        OH_JSVM_OpenVMScope(vm, &vmScope);
2298        JSVM_CallbackStruct param[] = {
2299            {.data = nullptr, .callback = NapiIsCallable},
2300        };
2301        JSVM_PropertyDescriptor descriptor[] = {
2302            {"napiIsCallable", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
2303        };
2304        // Create env, register a native method, and open an env scope.
2305        JSVM_Env env;
2306        OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
2307        JSVM_EnvScope envScope;
2308        OH_JSVM_OpenEnvScope(env, &envScope);
2309        // Open a handle scope.
2310        JSVM_HandleScope handleScope;
2311        OH_JSVM_OpenHandleScope(env, &handleScope);
2312        std::string sourceCodeStr = R"JS(
2313        function addNumbers(num1, num2)
2314        {
2315            var rst= num1 + num2;
2316            return rst;
2317        }
2318        let rst = napiIsCallable(addNumbers);
2319        )JS";
2320        // Compile the JS script.
2321        JSVM_Value sourceCodeValue;
2322        OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
2323        JSVM_Script script;
2324        OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
2325        JSVM_Value result;
2326        // Run the JS script.
2327        OH_JSVM_RunScript(env, script, &result);
2328        JSVM_ValueType type;
2329        OH_JSVM_Typeof(env, result, &type);
2330        OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
2331        // Exit the VM and release the memory.
2332        OH_JSVM_CloseHandleScope(env, handleScope);
2333        OH_JSVM_CloseEnvScope(env, envScope);
2334        OH_JSVM_DestroyEnv(env);
2335        OH_JSVM_CloseVMScope(vm, vmScope);
2336        OH_JSVM_DestroyVM(vm);
2337    });
2338    t.detach();
2339    return nullptr;
2340}
2341```
2342
2343### Lock Operations
2344
2345#### When to Use
2346
2347Perform lock operations.
2348
2349#### Available APIs
2350| API| Description|
2351| -------- | -------- |
2352|OH_JSVM_IsLocked| Checks whether the current thread holds a lock of the specified environment.|
2353|OH_JSVM_AcquireLock| Obtains a lock.|
2354|OH_JSVM_ReleaseLock| Releases a lock.|
2355
2356#### Example
2357
2358Obtain and release a lock.
2359
2360```c++
2361class LockWrapper {
2362 public:
2363  LockWrapper(JSVM_Env env) : env(env) {
2364    OH_JSVM_IsLocked(env, &isLocked);
2365    if (!isLocked) {
2366      OH_JSVM_AcquireLock(env);
2367      OH_JSVM_GetVM(env, &vm);
2368      OH_JSVM_OpenVMScope(vm, &vmScope);
2369      OH_JSVM_OpenEnvScope(env, &envScope);
2370    }
2371  }
2372
2373  ~LockWrapper() {
2374    if (!isLocked) {
2375      OH_JSVM_CloseEnvScope(env, envScope);
2376      OH_JSVM_CloseVMScope(vm, vmScope);
2377      OH_JSVM_ReleaseLock(env);
2378    }
2379  }
2380
2381  LockWrapper(const LockWrapper&) = delete;
2382  LockWrapper& operator=(const LockWrapper&) = delete;
2383  LockWrapper(LockWrapper&&) = delete;
2384  void* operator new(size_t) = delete;
2385  void* operator new[](size_t) = delete;
2386
2387 private:
2388  JSVM_Env env;
2389  JSVM_EnvScope envScope;
2390  JSVM_VMScope vmScope;
2391  JSVM_VM vm;
2392  bool isLocked;
2393};
2394
2395static napi_value Add([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
2396    static JSVM_VM vm;
2397    static JSVM_Env env;
2398    if (aa == 0) {
2399        OH_JSVM_Init(nullptr);
2400        aa++;
2401        // create vm
2402        JSVM_CreateVMOptions options;
2403        memset(&options, 0, sizeof(options));
2404        OH_JSVM_CreateVM(&options, &vm);
2405        // create env
2406        OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
2407    }
2408
2409    std::thread t1([]() {
2410        LockWrapper lock(env);
2411        JSVM_HandleScope handleScope;
2412        OH_JSVM_OpenHandleScope(env, &handleScope);
2413        JSVM_Value value;
2414        JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
2415        if (rst == JSVM_OK) {
2416            OH_LOG_INFO(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 suc");
2417        } else {
2418            OH_LOG_ERROR(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 fail");
2419        }
2420        int32_t num1;
2421        OH_JSVM_GetValueInt32(env, value, &num1);
2422        OH_LOG_INFO(LOG_APP, "JSVM:t1 num1 = %{public}d", num1);
2423        OH_JSVM_CloseHandleScope(env, handleScope);
2424    });
2425    std::thread t2([]() {
2426        LockWrapper lock(env);
2427        JSVM_HandleScope handleScope;
2428        OH_JSVM_OpenHandleScope(env, &handleScope);
2429        JSVM_Value value;
2430        JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
2431        if (rst == JSVM_OK) {
2432            OH_LOG_INFO(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 suc");
2433        } else {
2434            OH_LOG_ERROR(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 fail");
2435        }
2436        int32_t num1;
2437        OH_JSVM_GetValueInt32(env, value, &num1);
2438        OH_LOG_INFO(LOG_APP, "JSVM:t2 num1 = %{public}d", num1);
2439        OH_JSVM_CloseHandleScope(env, handleScope);
2440    });
2441    t1.detach();
2442    t2.detach();
2443    return nullptr;
2444}
2445```
2446
2447### Setting and Obtaining Data Associated with a JSVM Instance
2448
2449#### When to Use
2450
2451Set and obtain the data associated with a JSVM instance.
2452
2453#### Available APIs
2454| API| Description|
2455| -------- | -------- |
2456|OH_JSVM_SetInstanceData| Sets data to be associated with a JSVM instance.|
2457|OH_JSVM_GetInstanceData| Obtains the data associated with a JSVM instance.|
2458
2459#### Example
2460
2461Set and obtain the data associated with a JSVM instance.
2462
2463```c++
2464JSVM_VM vm;
2465JSVM_CreateVMOptions options;
2466JSVM_VMScope vm_scope;
2467JSVM_Env env;
2468JSVM_EnvScope envScope;
2469JSVM_HandleScope handlescope;
2470
2471static int aa = 0;
2472struct InstanceData {
2473    int32_t value;
2474};
2475
2476// Initialize the VM and create a JSVM instance.
2477void init_JSVM_environment(){
2478    JSVM_InitOptions init_options;
2479    memset(&init_options, 0, sizeof(init_options));
2480    if (aa == 0) {
2481        OH_JSVM_Init(&init_options);
2482        aa++;
2483    }
2484    memset(&options, 0, sizeof(options));
2485    OH_JSVM_CreateVM(&options, &vm);
2486    OH_JSVM_OpenVMScope(vm, &vm_scope);
2487    OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
2488    OH_JSVM_OpenEnvScope(env, &envScope);
2489    OH_JSVM_OpenHandleScope(env, &handlescope);
2490}
2491
2492// Exit the VM and release the running environment.
2493napi_value close_JSVM_environment(napi_env env1, napi_callback_info info)
2494{
2495    OH_JSVM_CloseHandleScope(env, handlescope);
2496    OH_JSVM_CloseEnvScope(env, envScope);
2497    OH_JSVM_DestroyEnv(env);
2498    OH_JSVM_CloseVMScope(vm, vm_scope);
2499    OH_JSVM_DestroyVM(vm);
2500    napi_value result;
2501    char* s = "ok";
2502    napi_create_string_latin1(env1, s, strlen(s), &result);
2503    return result;
2504}
2505
2506// Clear and release the memory used by the instance.
2507void InstanceFinalizeCallback(JSVM_Env env, void *finalizeData, void *finalizeHint)
2508{
2509    if (finalizeData) {
2510        InstanceData *data = reinterpret_cast<InstanceData *>(finalizeData);
2511        free(data);
2512        *(InstanceData **)finalizeData = nullptr;
2513    }
2514}
2515
2516static napi_value GetInstanceData(napi_env env1, napi_callback_info info)
2517{
2518    InstanceData *instanceData = reinterpret_cast<InstanceData *>(malloc(sizeof(InstanceData)));
2519    if (instanceData == nullptr) {
2520        printf("Memory allocation failed!\n");
2521        return nullptr;
2522    }
2523    size_t argc = 1;
2524    napi_value args[1] = {nullptr};
2525    // Obtain the callback function parameters.
2526    napi_get_cb_info(env1, info, &argc, args , nullptr, nullptr);
2527    napi_valuetype valuetype0;
2528    napi_typeof(env1, args[0], &valuetype0);
2529    int32_t tmp = 0;
2530    napi_get_value_int32(env1, args[0], &tmp);
2531    instanceData->value = tmp;
2532    // Associate the obtained parameters with the current JSVM environment.
2533    OH_JSVM_SetInstanceData(env, instanceData, InstanceFinalizeCallback, nullptr);
2534    InstanceData *resData = nullptr;
2535    // Obtain the data associated with the JSVM instance.
2536    OH_JSVM_GetInstanceData(env, (void **)&resData);
2537    napi_value result;
2538    napi_create_uint32(env1, resData->value, &result);
2539    return result;
2540}
2541```
2542
2543### Task Queue
2544
2545#### When to Use
2546
2547Start 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.
2548
2549#### Available APIs
2550| API| Description|
2551| -------- | -------- |
2552|OH_JSVM_PumpMessageLoop| Starts running a task queue.|
2553|OH_JSVM_PerformMicrotaskCheckpoint| Executes micro tasks in a task queue.|
2554
2555#### Example
2556
2557See [Working with Task Queues Using JSVM-API](use-jsvm-execute_tasks.md).