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