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