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