• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# JSVM-API Data Types and APIs
2
3## Data Types
4
5### JSVM_Status
6
7Enum indicating the execution status of a JSVM-API call.
8
9Each time a JSVM-API function is called, a value of **JSVM_Status** is returned indicating the execution result.
10
11```c++
12typedef enum {
13    JSVM_OK,
14    JSVM_INVALID_ARG,
15    JSVM_OBJECT_EXPECTED,
16    JSVM_STRING_EXPECTED,
17    JSVM_NAME_EXPECTED,
18    JSVM_FUNCTION_EXPECTED,
19    JSVM_NUMBER_EXPECTED,
20    JSVM_BOOL_EXPECTED,
21    JSVM_ARRAY_EXPECTED,
22    JSVM_GENERIC_FAILURE,
23    JSVM_PENDING_EXCEPTION,
24    JSVM_CENCELLED,
25    JSVM_ESCAPE_CALLED_TWICE,
26    JSVM_HANDLE_SCOPE_MISMATCH,
27    JSVM_CALLBACK_SCOPE_MISMATCH,
28    JSVM_QUEUE_FULL,
29    JSVM_CLOSING,
30    JSVM_BIGINT_EXPECTED,
31    JSVM_DATA_EXPECTED,
32    JSVM_CALLBACK_SCOPE_MISMATCH,
33    JSVM_DETACHABLE_ARRAYBUFFER_EXPECTED,
34    JSVM_WOULD_DEADLOCK,  /* unused */
35    JSVM_NO_EXTERNAL_BUFFERS_ALLOWED,
36    JSVM_CANNOT_RUN_JS
37} JSVM_Status;
38```
39
40### JSVM_ExtendedErrorInfo
41
42Struct that holds detailed error information when a JSVM-API call fails.
43
44```c++
45typedef struct {
46    const char* errorMessage;
47    void* engineReserved;
48    uint32_t engineErrorCode;
49    JSVM_Status errorCode;
50} JSVM_ExtendedErrorInfo;
51```
52
53### JSVM_Value
54
55Pointer used to represent a JavaScript (JS) value.
56
57### JSVM_Env
58
59- Context used by the underlying JSVM-API implementation. It is passed to the native functions when they are invoked, and must be passed back when JSVM-API calls are made.
60
61- When a native addon exits, **JSVM_Env** becomes invalid and this event is passed to **OH_JSVM_SetInstanceData** via a callback.
62
63- Avoid caching **JSVM_Env** or passing **JSVM_Env** between different worker threads.
64
65- If **JSVM_Env** is shared between different threads, the **threadlocal** variable must be isolated across threads. For this purpose, close the env scope of the current thread before switching to another thread and open a new env scope in each thread switched to.
66
67### JSVM_ValueType
68
69Enum indicating the type of **JSVM_Value**. The **JSVM_Value** types include the types defined in ECMAScript. **JSVM_EXTERNAL** indicates an external data type.
70
71```c++
72typedef enum {
73    JSVM_UNDEFINED,
74    JSVM_NULL,
75    JSVM_BOOLEAN,
76    JSVM_NUMBER,
77    JSVM_STRING,
78    JSVM_SYMBOL,
79    JSVM_OBJECT,
80    JSVM_FUNCTION,
81    JSVM_EXTERNAL,
82    JSVM_BIGINT,
83} JSVM_ValueType;
84```
85
86### JSVM_TypedarrayType
87
88Enum indicating the data type of the binary **TypedArray** object.
89
90```c++
91typedef enum {
92    JSVM_INT8_ARRAY,
93    JSVM_UINT8_ARRAY,
94    JSVM_UINT8_CLAMPED_ARRAY,
95    JSVM_INT16_ARRAY,
96    JAVM_UINT16_ARRAY,
97    JSVM_INT32_ARRAY,
98    JSVM_UINT32_ARRAY,
99    JSVM_FLOAT32_ARRAY,
100    JSVM_FLOAT64_ARRAY,
101    JSVM_BIGINT64_ARRAY,
102    JSVM_BIGUINT64_ARRAY,
103} JSVM_TypedarrayType;
104```
105
106### Memory Management Types
107
108JSVM-API provides the following memory management types:
109
110**JSVM_HandleScope**
111
112Data 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.
113
114**JSVM_EscapableHandleScope**
115
116- It is created by **OH_JSVM_OpenEscapableHandleScope** and closed by **OH_JSVM_CloseEscapableHandleScope**.
117
118- It is a special type of handle range used to return values created within the scope of **JSVM_EscapableHandleScope** to a parent scope.
119
120- 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.
121
122**JSVM_Ref**
123
124Reference to **JSVM_Value**, which allows you to manage the lifecycle of JS values.
125
126**JSVM_TypeTag**
127
128Struct containing two unsigned 64-bit integers to identify the type of a JSVM-API value.
129
130```c++
131typedef struct {
132    uint64_t lower;
133    uint64_t upper;
134} JSVM_TypeTag;
135```
136
137- 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.
138
139- 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.
140
141- 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.
142
143### Callback Types
144
145JSVM-API provides the following callback types:
146
147**JSVM_CallbackInfo**
148
149User-defined native function, which is exposed to JS via JSVM-API. Generally, no handle or callback scope is created inside this callback.
150
151**JSVM_CallbackStruct**
152
153Function pointer type and data for user-provided native functions, which are to be exposed to JS via JSVM-API.
154
155```c++
156typedef struct {
157  JSVM_Value(*callback)(JSVM_Env env, JSVM_CallbackInfo info);
158  void* data;
159} JSVM_CallbackStruct;
160```
161
162**JSVM_Callback**
163
164User-defined native function exposed to JS. Unless otherwise required in object lifecycle management, no handle or callback scope is created in this callback.
165
166The usage is as follows:
167
168```c++
169typedef JSVM_CallbackStruct* JSVM_Callback;
170```
171
172**JSVM_Finalize**
173
174Function 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.
175
176The format is as follows:
177
178```c++
179typedef void (JSVM_Finalize)(JSVM_Env env, void finalizeData, void* finalizeHint);
180```
181
182**JSVM_PropertyHandlerConfigurationStruct**
183
184Callback to be invoked when the getter(), setter(), deleter(), or enumerator() of an object is executed.
185
186```c++
187typedef struct {
188    JSVM_Value(JSVM_CDECL* genericNamedPropertyGetterCallback)(JSVM_Env env,
189                                                               JSVM_Value name,
190                                                               JSVM_Value thisArg,
191                                                               JSVM_Value namedPropertyData);
192    JSVM_Value(JSVM_CDECL* genericNamedPropertySetterCallback)(JSVM_Env env,
193                                                               JSVM_Value name,
194                                                               JSVM_Value property,
195                                                               JSVM_Value thisArg,
196                                                               JSVM_Value namedPropertyData);
197    JSVM_Value(JSVM_CDECL* genericNamedPropertyDeleterCallback)(JSVM_Env env,
198                                                                JSVM_Value name,
199                                                                JSVM_Value thisArg,
200                                                                JSVM_Value namedPropertyData);
201    JSVM_Value(JSVM_CDECL* genericNamedPropertyEnumeratorCallback)(JSVM_Env env,
202                                                                   JSVM_Value thisArg,
203                                                                   JSVM_Value namedPropertyData);
204    JSVM_Value(JSVM_CDECL* genericIndexedPropertyGetterCallback)(JSVM_Env env,
205                                                                JSVM_Value index,
206                                                                JSVM_Value thisArg,
207                                                                JSVM_Value indexedPropertyData);
208    JSVM_Value(JSVM_CDECL* genericIndexedPropertySetterCallback)(JSVM_Env env,
209                                                                 JSVM_Value index,
210                                                                 JSVM_Value property,
211                                                                 JSVM_Value thisArg,
212                                                                 JSVM_Value indexedPropertyData);
213    JSVM_Value(JSVM_CDECL* genericIndexedPropertyDeleterCallback)(JSVM_Env env,
214                                                                  JSVM_Value index,
215                                                                  JSVM_Value thisArg,
216                                                                  JSVM_Value indexedPropertyData);
217    JSVM_Value(JSVM_CDECL* genericIndexedPropertyEnumeratorCallback)(JSVM_Env env,
218                                                                     JSVM_Value thisArg,
219                                                                     JSVM_Value indexedPropertyData);
220    JSVM_Value namedPropertyData;
221    JSVM_Value indexedPropertyData;
222} JSVM_PropertyHandlerConfigurationStruct;
223```
224
225**JSVM_PropertyHandlerCfg**
226
227Pointer to the struct that contains a callback for property listening.
228
229The usage is as follows:
230
231```c++
232typedef JSVM_PropertyHandlerConfigurationStruct* JSVM_PropertyHandlerCfg;
233```
234
235## APIs
236
237JSVM-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.
238
239### Creating a VM Instance and JS Context
240
241#### When to Use
242
243Before executing JS code, you need to create a JS VM and JS context.
244
245#### Available APIs
246| API| Description|
247| -------- | -------- |
248| OH_JSVM_Init| Initializes a JS engine instance.|
249| OH_JSVM_CreateVM| Creates a JS VM instance.|
250| OH_JSVM_DestroyVM| Destroys a JS VM instance.|
251| 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.|
252| OH_JSVM_CloseVMScope| Closes a VM scope.|
253| OH_JSVM_CreateEnv| Creates a JS context and registers the specified native function.|
254| OH_JSVM_DestroyEnv| Destroys a JS context.|
255| OH_JSVM_OpenEnvScope| Opens a JS context scope. The context can be used only within the scope.|
256| OH_JSVM_CloseEnvScope| Closes a JS context scope.|
257| OH_JSVM_OpenHandleScope| Opens a handle scope. **JSVM_Value** within the scope will not be garbage-collected.|
258| OH_JSVM_CloseHandleScope| Close a handle scope.|
259
260Example:
261Create a JS VM instance and then destroy it.
262
263```c++
264bool VM_INIT = false;
265
266static JSVM_Value ConsoleInfo(JSVM_Env env, JSVM_CallbackInfo info) {
267    size_t argc = 1;
268    JSVM_Value args[1];
269    char log[256] = "";
270    size_t logLength;
271    OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
272
273    OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &logLength);
274    log[255] = 0;
275    OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log);
276    return nullptr;
277}
278
279static JSVM_Value Add(JSVM_Env env, JSVM_CallbackInfo info) {
280    size_t argc = 2;
281    JSVM_Value args[2];
282    OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
283    double num1, num2;
284    env, OH_JSVM_GetValueDouble(env, args[0], &num1);
285    OH_JSVM_GetValueDouble(env, args[1], &num2);
286    JSVM_Value sum = nullptr;
287    OH_JSVM_CreateDouble(env, num1 + num2, &sum);
288    return sum;
289}
290
291static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
292    std::thread t([]() {
293        if (!VM_INIT) {
294            // The JSVM only needs to be initialized once.
295            JSVM_InitOptions initOptions;
296            memset(&initOptions, 0, sizeof(initOptions));
297            OH_JSVM_Init(&initOptions);
298            VM_INIT = true;
299        }
300        // Create a VM instance and open the VM scope.
301        JSVM_VM vm;
302        JSVM_CreateVMOptions options;
303        memset(&options, 0, sizeof(options));
304        OH_JSVM_CreateVM(&options, &vm);
305
306        JSVM_VMScope vmScope;
307        OH_JSVM_OpenVMScope(vm, &vmScope);
308
309        JSVM_CallbackStruct param[] = {
310            {.data = nullptr, .callback = ConsoleInfo},
311            {.data = nullptr, .callback = Add},
312        };
313        JSVM_PropertyDescriptor descriptor[] = {
314            {"consoleinfo", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
315            {"add", NULL, &param[1], NULL, NULL, NULL, JSVM_DEFAULT},
316        };
317        // Create env, register a native method, and open an env scope.
318        JSVM_Env env;
319        OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
320
321        JSVM_EnvScope envScope;
322        OH_JSVM_OpenEnvScope(env, &envScope);
323
324        // Open a handle scope.
325        JSVM_HandleScope handleScope;
326        OH_JSVM_OpenHandleScope(env, &handleScope);
327
328        std::string sourceCodeStr = "\
329{\
330let value = add(4.96, 5.28);\
331consoleinfo('Result is:' + value);\
332}\
333";
334        // Compile the JS script.
335        JSVM_Value sourceCodeValue;
336        OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
337        JSVM_Script script;
338        OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
339        JSVM_Value result;
340        // Run the JS script.
341        OH_JSVM_RunScript(env, script, &result);
342        JSVM_ValueType type;
343        OH_JSVM_Typeof(env, result, &type);
344        OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
345
346        // Exit the VM and release the memory.
347        OH_JSVM_CloseHandleScope(env, handleScope);
348
349        OH_JSVM_CloseEnvScope(env, envScope);
350        OH_JSVM_DestroyEnv(env);
351
352        OH_JSVM_CloseVMScope(vm, vmScope);
353        OH_JSVM_DestroyVM(vm);
354    });
355
356    t.detach();
357
358    return nullptr;
359}
360```
361
362### Compiling and Running JS Code
363
364#### When to Use
365
366Compile and run JS code.
367
368#### Available APIs
369| API| Description|
370| -------- | -------- |
371| OH_JSVM_CompileScript| Compiles JS code and returns the compiled script bound to the current environment.|
372| OH_JSVM_CreateCodeCache| Creates a code cache for the compiled script.|
373| OH_JSVM_RunScript| Runs a JS script.|
374
375Example:
376Compile and run JS code (create a VM, register native functions, execute JS code, and destroy the VM).
377
378```c++
379#include <cstring>
380#include <fstream>
381#include <string>
382#include <vector>
383
384// Add the dependency libjsvm.so.
385#include "ark_runtime/jsvm.h"
386
387using namespace std;
388
389static JSVM_Value Hello(JSVM_Env env, JSVM_CallbackInfo info) {
390    JSVM_Value output;
391    void* data = nullptr;
392    OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
393    OH_JSVM_CreateStringUtf8(env, (char*)data, strlen((char*)data), &output);
394    return output;
395}
396
397static JSVM_CallbackStruct hello_cb = { Hello, (void*)"Hello" };
398
399static string srcGlobal = R"JS(
400const concat = (...args) => args.reduce((a, b) => a + b);
401)JS";
402
403static void RunScript(JSVM_Env env, string& src,
404                       const uint8_t** dataPtr = nullptr,
405                       size_t* lengthPtr = nullptr) {
406    JSVM_HandleScope handleScope;
407    OH_JSVM_OpenHandleScope(env, &handleScope);
408
409    JSVM_Value jsSrc;
410    OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
411
412    const uint8_t* data = dataPtr ? *dataPtr : nullptr;
413    size_t length = lengthPtr ? *lengthPtr : 0;
414    bool cacheRejected = true;
415    JSVM_Script script;
416    // Compile the JS code.
417    OH_JSVM_CompileScript(env, jsSrc, data, length, true, &cacheRejected, &script);
418    printf("Code cache is %s\n", cacheRejected ? "rejected" : "used");
419
420    JSVM_Value result;
421    // Run the JS code.
422    OH_JSVM_RunScript(env, script, &result);
423
424    char resultStr[128];
425    size_t size;
426    OH_JSVM_GetValueStringUtf8(env, result, resultStr, 128, &size);
427    printf("%s\n", resultStr);
428    if (dataPtr && lengthPtr && *dataPtr == nullptr) {
429        // Save the script compiled from the JS source code to the cache to avoid repeated compilation and improve performance.
430        OH_JSVM_CreateCodeCache(env, script, dataPtr, lengthPtr);
431        printf("Code cache created with length = %ld\n", *lengthPtr);
432    }
433
434    OH_JSVM_CloseHandleScope(env, handleScope);
435}
436
437static void CreateSnapshot() {
438    JSVM_VM vm;
439    JSVM_CreateVMOptions options;
440    memset(&options, 0, sizeof(options));
441    options.isForSnapshotting = true;
442    OH_JSVM_CreateVM(&options, &vm);
443    JSVM_VMScope vmScope;
444    OH_JSVM_OpenVMScope(vm, &vmScope);
445
446    JSVM_Env env;
447    // 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.
448    JSVM_PropertyDescriptor descriptors[] = {
449        { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT }
450    };
451    OH_JSVM_CreateEnv(vm, 1, descriptors, &env);
452
453    JSVM_EnvScope envScope;
454    OH_JSVM_OpenEnvScope(env, &envScope);
455    // Execute the JS source code src, which can contain any JS syntax. The registered native function can also be invoked.
456    string src = srcGlobal + "concat(hello(), ', ', 'World from CreateSnapshot!');";
457    RunScript(env, src);
458
459    // Create a snapshot and save the current env to a string. The string can be used to restore the env to avoid repeatedly defining the properties in the env.
460    const char* blobData = nullptr;
461    size_t blobSize = 0;
462    JSVM_Env envs[1] = { env };
463    OH_JSVM_CreateSnapshot(vm, 1, envs, &blobData, &blobSize);
464    printf("Snapshot blob size = %ld\n", blobSize);
465
466    // If you need to save the snapshot to a file, also consider the read/write permissions on the file in the application.
467    ofstream file("/data/storage/el2/base/files/blob.bin", ios::out | ios::binary | ios::trunc);
468    file.write(blobData, blobSize);
469    file.close();
470
471    OH_JSVM_CloseEnvScope(env, envScope);
472    OH_JSVM_DestroyEnv(env);
473    OH_JSVM_CloseVMScope(vm, vmScope);
474    OH_JSVM_DestroyVM(vm);
475}
476
477void RunWithoutSnapshot(const uint8_t** dataPtr, size_t* lengthPtr) {
478    // Create a VM instance.
479    JSVM_VM vm;
480    OH_JSVM_CreateVM(nullptr, &vm);
481    JSVM_VMScope vmScope;
482    OH_JSVM_OpenVMScope(vm, &vmScope);
483
484    JSVM_Env env;
485    // 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.
486    JSVM_PropertyDescriptor descriptors[] = {
487        { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT }
488    };
489    OH_JSVM_CreateEnv(vm, 1, descriptors, &env);
490    JSVM_EnvScope envScope;
491    OH_JSVM_OpenEnvScope(env, &envScope);
492    // Execute the JS source code src, which can contain any JS syntax. The registered native function can also be invoked.
493    auto src = srcGlobal + "concat(hello(), ', ', 'World', ' from RunWithoutSnapshot!')";
494    RunScript(env, src, dataPtr, lengthPtr);
495
496    OH_JSVM_CloseEnvScope(env, envScope);
497    OH_JSVM_DestroyEnv(env);
498    OH_JSVM_CloseVMScope(vm, vmScope);
499    OH_JSVM_DestroyVM(vm);
500}
501
502void RunWithSnapshot(const uint8_t **dataPtr, size_t *lengthPtr) {
503    // The lifetime of blobData must not be shorter than that of the vm.
504    // If the snapshot needs to be read from a file, also consider the read/write permissions on the file in the application.
505    vector<char> blobData;
506    ifstream file("/data/storage/el2/base/files/blob.bin", ios::in | ios::binary | ios::ate);
507    size_t blobSize = file.tellg();
508    blobData.resize(blobSize);
509    file.seekg(0, ios::beg);
510    file.read(blobData.data(), blobSize);
511    file.close();
512
513    // Create a VM instance.
514    JSVM_VM vm;
515    JSVM_CreateVMOptions options;
516    memset(&options, 0, sizeof(options));
517    options.snapshotBlobData = blobData.data();
518    options.snapshotBlobSize = blobSize;
519    OH_JSVM_CreateVM(&options, &vm);
520    JSVM_VMScope vmScope;
521    OH_JSVM_OpenVMScope(vm, &vmScope);
522
523    // Create env from a snapshot.
524    JSVM_Env env;
525    OH_JSVM_CreateEnvFromSnapshot(vm, 0, &env);
526    JSVM_EnvScope envScope;
527    OH_JSVM_OpenEnvScope(env, &envScope);
528
529    // 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.
530    string src = "concat(hello(), ', ', 'World', ' from RunWithSnapshot!')";
531    RunScript(env, src, dataPtr, lengthPtr);
532
533    OH_JSVM_CloseEnvScope(env, envScope);
534    OH_JSVM_DestroyEnv(env);
535    OH_JSVM_CloseVMScope(vm, vmScope);
536    OH_JSVM_DestroyVM(vm);
537}
538
539void PrintVmInfo() {
540    JSVM_VMInfo vmInfo;
541    OH_JSVM_GetVMInfo(&vmInfo);
542    printf("apiVersion: %d\n", vmInfo.apiVersion);
543    printf("engine: %s\n", vmInfo.engine);
544    printf("version: %s\n", vmInfo.version);
545    printf("cachedDataVersionTag: 0x%x\n", vmInfo.cachedDataVersionTag);
546}
547
548static intptr_t externals[] = {
549    (intptr_t)&hello_cb,
550    0,
551};
552
553int main(int argc, char *argv[]) {
554    if (argc <= 1) {
555        printf("Usage: %s gen-snapshot|use-snapshot|no-snapshot\n", argv[0]);
556        return 0;
557    }
558
559    JSVM_InitOptions initOptions;
560    memset(&initOptions, 0, sizeof(initOptions));
561    initOptions.externalReferences = externals;
562    // Initialize the VM, which can be initialized only once in a process.
563    OH_JSVM_Init(&initOptions);
564    PrintVmInfo();
565
566    if (argv[1] == string("gen-snapshot")) {
567        CreateSnapshot();
568        return 0;
569    }
570
571    // The snapshot records the JS context at a certain time and can be used to quickly restore JS context across processes as long as the snapshot is within the lifecycle.
572    const auto useSnapshot = argv[1] == string("use-snapshot");
573    const auto run = useSnapshot ? RunWithSnapshot : RunWithoutSnapshot;
574    const uint8_t* data = nullptr;
575    size_t length = 0;
576    run(&data, &length);
577    run(&data, &length);
578    delete[] data;
579
580    return 0;
581}
582```
583
584### Exception Handling
585
586#### When to Use
587
588Capture, throw, and clear JS exceptions as required.
589
590#### Available APIs
591| API| Description|
592| -------- | -------- |
593| OH_JSVM_Throw| Throws a JS value.|
594| OH_JSVM_ThrowTypeError| Throws a JS type error.|
595| OH_JSVM_ThrowRangeError| Throws a JS range error.|
596| OH_JSVM_IsError| Checks whether a JS value indicates an error.|
597| OH_JSVM_CreateError| Creates a JS error.|
598| OH_JSVM_CreateTypeError| Creates a JS type error and returns it.|
599| OH_JSVM_CreateRangeError| Creates a JS range error and returns it.|
600| OH_JSVM_ThrowError| Throws a JS exception.|
601| OH_JSVM_GetAndClearLastException| Obtains and clears the last JS exception.|
602| OH_JSVM_IsExceptionPending| Checks whether an exception occurs.|
603| OH_JSVM_GetLastErrorInfo| Obtains information about the last exception.|
604| OH_JSVM_ThrowSyntaxError| Throws a JS syntax error.|
605| OH_JSVM_CreateSyntaxError| Creates a JS syntax error and returns it.|
606
607Example:
608The following walks you through on how to Create, judge, and throw a JS type error.
609
610```c++
611JSVM_Value code = nullptr;
612JSVM_Value message = nullptr;
613OH_JSVM_CreateStringUtf8(env, "500", JSVM_AUTO_LENGTH, &code);
614OH_JSVM_CreateStringUtf8(env, "type error 500", JSVM_AUTO_LENGTH, &message);
615JSVM_Value error = nullptr;
616OH_JSVM_CreateTypeError(env, code, message, &error);
617bool isError = false;
618OH_JSVM_IsError(env, error, &isError);
619OH_JSVM_ThrowTypeError(env, nullptr, "type error1");
620```
621
622Call OH_JSVM_GetAndClearLastException to log the exception information as a string to the console.
623
624```c++
625if (status != JSVM_OK) // An exception occurs when the execution fails.
626{
627    bool isPending = false;
628    if (JSVM_OK == OH_JSVM_IsExceptionPending((env), &isPending) && isPending)
629    {
630        JSVM_Value error;
631        if (JSVM_OK == OH_JSVM_GetAndClearLastException((env), &error))
632        {
633            // Obtain the exception stack.
634            JSVM_Value stack;
635            OH_JSVM_GetNamedProperty((env), error, "stack", &stack);
636
637            JSVM_Value message;
638            OH_JSVM_GetNamedProperty((env), error, "message", &message);
639
640            char stackstr[256];
641            OH_JSVM_GetValueStringUtf8(env, stack, stackstr, 256, nullptr);
642            OH_LOG_INFO(LOG_APP, "JSVM error stack: %{public}s", stackstr);
643
644            char messagestr[256];
645            OH_JSVM_GetValueStringUtf8(env, message, messagestr, 256, nullptr);
646            OH_LOG_INFO(LOG_APP, "JSVM error message: %{public}s", messagestr);
647        }
648    }
649}
650```
651
652### Object Lifetime Management
653
654When 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.
655
656 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.
657
658However, 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.
659
660#### Available APIs
661| API| Description|
662| -------- | -------- |
663| OH_JSVM_OpenHandleScope| Opens a handle scope. The object within the scope will not be garbage-collected until the handle scope is closed.|
664| OH_JSVM_CloseHandleScope| Closes a handle scope. The object within the scope will be garbage-collected after the handle scope is closed.|
665| 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.|
666| OH_JSVM_CloseEscapableHandleScope| Closes an escapable handle scope.|
667| OH_JSVM_EscapeHandle| Promotes a handle to a JS object so that it is valid for the lifetime of the outer scope.|
668| OH_JSVM_CreateReference| Creates a new reference with the specified reference count to the value passed in. The reference allows objects to be used and shared in different contexts and effectively tracks the lifecycle of the object.|
669| 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.|
670| OH_JSVM_ReferenceRef| Increments the reference count of the reference created by **OH_JSVM_CreateReference** so that the object referenced will not be released.|
671| 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.|
672| OH_JSVM_GetReferenceValue| Obtains the object referenced by **OH_JSVM_CreateReference**.|
673
674Example:
675Use a handle scope to protect an object created within the scope from being reclaimed.
676
677```c++
678JSVM_HandleScope scope;
679OH_JSVM_OpenHandleScope(env, &scope);
680JSVM_Value obj = nullptr;
681OH_JSVM_CreateObject(env, &obj);
682OH_JSVM_CloseHandleScope(env, scope);
683```
684
685Use an escapable handle scope to protect an object from being reclaimed within its parent scope.
686
687```c++
688JSVM_EscapableHandleScope scope;
689JSVM_CALL(env, OH_JSVM_OpenEscapableHandleScope(env, &scope));
690JSVM_Value output = NULL;
691JSVM_Value escapee = NULL;
692JSVM_CALL(env, OH_JSVM_CreateObject(env, &output));
693JSVM_CALL(env, OH_JSVM_EscapeHandle(env, scope, output, &escapee));
694JSVM_CALL(env, OH_JSVM_CloseEscapableHandleScope(env, scope));
695return escapee;
696```
697
698Reference a JS object and release the reference.
699
700```c++
701JSVM_Value obj = nullptr;
702OH_JSVM_CreateObject(env, &obj);
703// Create a reference.
704JSVM_Ref reference;
705OH_JSVM_CreateReference(env, obj, 1, &reference);
706
707// Create a reference with a JS object.
708JSVM_Value result;
709OH_JSVM_GetReferenceValue(env, reference, &result);
710
711// Release the reference.
712OH_JSVM_DeleteReference(env, reference);
713```
714
715### Creating JS Object Types and Basic Types
716
717#### When to Use
718
719Create JS object types and basic types.
720
721#### Available APIs
722| API| Description|
723| -------- | -------- |
724|OH_JSVM_CreateArray | Creates a JS array object.|
725|OH_JSVM_CreateArrayWithLength | Creates a JS array object of the specified length.|
726|OH_JSVM_CreateArraybuffer | Creates an ArrayBuffer object of the specified size.|
727|OH_JSVM_CreateDate | Creates a **Date** object representing the given number of milliseconds. |
728|OH_JSVM_CreateExternal | Creates a JS object that wraps an external pointer.|
729|OH_JSVM_CreateExternalArraybuffer | Creates a JS object that wraps an external Arraybuffer.|
730|OH_JSVM_CreateObject | Creates a default JS object.|
731|OH_JSVM_CreateSymbol | Creates a symbol object based on the given descriptor.|
732|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.|
733|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.|
734|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.|
735|OH_JSVM_CreateInt32 | Creates a JS number object from a C Int32_t object.|
736|OH_JSVM_CreateUint32 | Creates a JS number object from a C Uint32_t object.|
737|OH_JSVM_CreateInt64 | Creates a JS number object from a C Int64_t object.|
738|OH_JSVM_CreateDouble | Creates a JS number object from a C Double object.|
739|OH_JSVM_CreateBigintInt64 | Creates a JS BigInt object from a C Int64 object.|
740|OH_JSVM_CreateBigintUint64 | Creates a JS BigInt object from a C Uint64 object.|
741|OH_JSVM_CreateBigintWords | Creates a JS BigInt object from a C Uint64_t array.|
742|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.|
743|OH_JSVM_CreateStringUtf16 | Creates a JS string object from a UTF16-encoded C string.|
744|OH_JSVM_CreateStringUtf8 | Creates a JS string object from a UTF8-encoded C string.|
745
746Example:
747Create a JS array of the specified length.
748
749```c++
750size_t arrayLength = 2;
751JSVM_Value arr;
752
753OH_JSVM_CreateArrayWithLength(env, arrayLength, &arr);
754for (uint32_t i = 0; i < arrayLength; i++)
755{
756    JSVM_Value element;
757    OH_JSVM_CreateUint32(env, i * 2, &element);
758    OH_JSVM_SetElement(env, arr, i, element);
759}
760```
761
762Create a JS Int32Array.
763
764```c++
765JSVM_Value arrayBuffer = nullptr;
766void *arrayBufferPtr = nullptr;
767size_t arrayBufferSize = 16;
768size_t typedArrayLength = 4;
769OH_JSVM_CreateArraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer);
770
771void *tmpArrayBufferPtr = nullptr;
772size_t arrayBufferLength = 0;
773OH_JSVM_GetArraybufferInfo(env, arrayBuffer, &tmpArrayBufferPtr, &arrayBufferLength);
774
775JSVM_Value result;
776OH_JSVM_CreateTypedarray(env, JSVM_TypedarrayType::JSVM_INT32_ARRAY, typedArrayLength, arrayBuffer, 0, &result);
777return result;
778```
779
780Create JS numbers and strings.
781
782```c++
783const char *testStringStr = "test";
784JSVM_Value testString = nullptr;
785OH_JSVM_CreateStringUtf8(env, testStringStr, strlen(testStringStr), &testString);
786
787JSVM_Value testNumber1 = nullptr;
788JSVM_Value testNumber2 = nullptr;
789OH_JSVM_CreateDouble(env, 10.1, &testNumber1);
790OH_JSVM_CreateInt32(env, 10, &testNumber2);
791```
792
793### Obtaining C Types or JS Type Information from JS Types
794
795#### When to Use
796
797Obtaining C types or JS type information from JS types.
798
799#### Available APIs
800| API| Description|
801| -------- | -------- |
802|OH_JSVM_GetArrayLength | Obtains the length of an array.|
803|OH_JSVM_GetArraybufferInfo | Obtains the underlying data buffer of an ArrayBuffer and its length.|
804|OH_JSVM_GetPrototype | Obtains the prototype of a JS object.|
805|OH_JSVM_GetTypedarrayInfo | Obtains information about a TypedArray object.|
806|OH_JSVM_GetDataviewInfo | Obtains information about a DataView object.|
807|OH_JSVM_GetDateValue | Obtains the C double primitive of the time value for the given JS **Date** object.|
808|OH_JSVM_GetValueBool | Obtains the C Boolean primitive equivalent of the given JS Boolean.|
809|OH_JSVM_GetValueDouble | Obtains the C Double primitive equivalent of the given JS number.|
810|OH_JSVM_GetValueBigintInt64 | Obtains the C Int64_t primitive equivalent of the given JS BigInt.|
811|OH_JSVM_GetValueBigintUint64 | Obtains the C Uint64_t primitive equivalent of the given JS BigInt.|
812|OH_JSVM_GetValueBigintWords | Obtains the underlying data of a given JS BigInt object, that is, the word representation of BigInt data.|
813|OH_JSVM_GetValueExternal | Obtains the external data pointer previously passed to **OH_JSVM_CreateExternal**.|
814|OH_JSVM_GetValueInt32 | Obtains the C Int32 primitive equivalent of the given JS number.|
815|OH_JSVM_GetValueInt64 | Obtains the C Int64 primitive equivalent of the given JS number.|
816|OH_JSVM_GetValueStringLatin1 | Obtains the ISO-8859-1-encoded string from the given JS string.|
817|OH_JSVM_GetValueStringUtf8 | Obtains the UTF8-encoded string from the given JS string.|
818|OH_JSVM_GetValueStringUtf16 | Obtains the UTF16-encoded string from the given JS string.|
819|OH_JSVM_GetValueUint32 | Obtains the C primitive equivalent (a Uint32) of the given JS number.|
820|OH_JSVM_GetBoolean | Obtains a JS singleton object that is used to represent the given Boolean value.|
821|OH_JSVM_GetGlobal | Obtains the **global** object of the current environment.|
822|OH_JSVM_GetNull | Obtains the JS **null** object.|
823|OH_JSVM_GetUndefined | Obtains the JS **Undefined** object.|
824
825Example:
826Creates a JS BigInt object from a C Int64 object and obtain the C Int64_t primitive equivalent.
827
828```c++
829int64_t testValue = INT64_MAX;
830JSVM_Value result = nullptr;
831OH_JSVM_CreateBigintInt64(env, testValue, &result);
832int64_t resultValue = 0;
833bool flag = false;
834OH_JSVM_GetValueBigintInt64(env, result, &resultValue, &flag);
835```
836
837Create an Int32Array and obtain its information such as the length and byte offset.
838
839```c++
840JSVM_Value arrayBuffer = nullptr;
841void *arrayBufferPtr = nullptr;
842size_t arrayBufferSize = 16;
843size_t typedArrayLength = 4;
844OH_JSVM_CreateArraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer);
845
846bool isArrayBuffer = false;
847OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer);
848
849JSVM_Value result;
850OH_JSVM_CreateTypedarray(env, JSVM_TypedarrayType::JSVM_INT32_ARRAY, typedArrayLength, arrayBuffer, 0, &result);
851
852bool isTypedArray = false;
853OH_JSVM_IsTypedarray(env, result, &isTypedArray);
854
855
856JSVM_TypedarrayType type;
857size_t length = 0;
858void *data = nullptr;
859JSVM_Value retArrayBuffer;
860size_t byteOffset = -1;
861OH_JSVM_GetTypedarrayInfo(env, result, &type, &length, &data, &retArrayBuffer, &byteOffset);
862
863
864bool retIsArrayBuffer = false;
865OH_JSVM_IsArraybuffer(env, retArrayBuffer, &retIsArrayBuffer);
866void *tmpArrayBufferPtr = nullptr;
867size_t arrayBufferLength = 0;
868OH_JSVM_GetArraybufferInfo(env, retArrayBuffer, &tmpArrayBufferPtr, &arrayBufferLength);
869```
870
871Creates a JS string object from a UTF8-encoded C string and obtain the C string.
872
873```c++
874const char *testStringStr = "testString";
875JSVM_Value testString = nullptr;
876OH_JSVM_CreateStringUtf8(env, testStringStr, strlen(testStringStr), &testString);
877
878char buffer[128];
879size_t bufferSize = 128;
880size_t copied;
881
882OH_JSVM_GetValueStringUtf8(env, testString, buffer, bufferSize, &copied);
883```
884
885### Working with JS Values and Abstract Operations
886
887#### When to Use
888
889Perform abstract operations on JS values.
890
891#### Available APIs
892| API| Description|
893| -------- | -------- |
894|OH_JSVM_CoerceToBool | Converts a JS value to an object of the Boolean type.|
895|OH_JSVM_CoerceToNumber | Converts a JS value to an object of the number type.|
896|OH_JSVM_CoerceToObject | Converts a JS value to an object of the object type.|
897|OH_JSVM_CoerceToString | Converts a JS value to an object of the string type.|
898|OH_JSVM_Typeof | Returns the type of a JS object.|
899|OH_JSVM_Instanceof | Checks whether an object is an instance of a constructor.|
900|OH_JSVM_IsArray | Checks whether a JS object is an array.|
901|OH_JSVM_IsArraybuffer | Checks whether a JS object is an array buffer.|
902|OH_JSVM_IsDate | Checks whether a JS object is a date.|
903|OH_JSVM_IsTypedarray | Checks whether a JS object is a typed array.|
904|OH_JSVM_IsDataview | Checks whether a JS object is a **DataView**.|
905|OH_JSVM_IsUndefined | Checks whether the value passed in is **Undefined**. This API is equivalent to executing JS code **value === undefined**.|
906|OH_JSVM_IsNull | Checks whether the value passed in is a **Null** object. This API is equivalent to executing JS code **value === null**.|
907|OH_JSVM_IsNullOrUndefined | Checks whether the value passed in is **Null** or **Undefined**. This API is equivalent to executing JS code **value == null**.|
908|OH_JSVM_IsBoolean | Checks whether the value passed in is a Boolean value. This API is equivalent to executing JS code **typeof value ==='boolean'**.|
909|OH_JSVM_IsNumber | Checks whether the value passed in is a number. This API is equivalent to executing JS code **typeof value === 'number'**.|
910|OH_JSVM_IsString | Checks whether the value passed in is a string. This API is equivalent to executing JS code **typeof value === 'string'**.|
911|OH_JSVM_IsSymbol | Checks whether the value passed in is a symbol. This API is equivalent to executing JS code **typeof value === 'symbol'**.|
912|OH_JSVM_IsFunction | Checks whether the value passed in is a function. This API is equivalent to executing JS code **typeof value === 'function'**.|
913|OH_JSVM_IsObject | Checks whether the value passed in is an object .|
914|OH_JSVM_IsBigInt | Checks whether the value passed in is a BigInt. This API is equivalent to executing JS code **typeof value === 'bigint'**.|
915|OH_JSVM_StrictEquals | Checks whether two **JSVM_Value** objects are strictly equal.|
916|OH_JSVM_Equals | Checks whether two **JSVM_Value** objects are roughly equal.|
917|OH_JSVM_DetachArraybuffer | Calls the **Detach()** operation of an **ArrayBuffer** object.|
918|OH_JSVM_IsDetachedArraybuffer | Checks whether an **ArrayBuffer** object has been detached.|
919
920Example:
921Check whether a JS value is of the array type.
922
923```c++
924JSVM_Value array = nullptr;
925OH_JSVM_CreateArray(env, &array);
926bool isArray = false;
927OH_JSVM_IsArray(env, array, &isArray);
928```
929
930Converts a JS int32 value to a string.
931
932```c++
933int32_t num = 123;
934JSVM_Value intValue;
935OH_JSVM_CreateInt32(env, num, &intValue);
936JSVM_Value stringValue;
937OH_JSVM_CoerceToString(env, intValue, &stringValue);
938
939char buffer[128];
940size_t bufferSize = 128;
941size_t copied = 0;
942
943OH_JSVM_GetValueStringUtf8(env, stringValue, buffer, bufferSize, &copied);
944// buffer:"123";
945```
946
947Check 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.
948
949```c++
950JSVM_Value value = nullptr;
951JSVM_Value value1 = nullptr;
952OH_JSVM_CreateArray(env, &value);
953
954OH_JSVM_CreateInt32(env, 10, &value1);
955bool isArray = true;
956OH_JSVM_StrictEquals(env, value, value, &isArray);
957```
958
959Check 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 other cases.
960
961```c++
962JSVM_HandleScope handleScope;
963OH_JSVM_OpenHandleScope(env, &handleScope);
964const char testStr[] = "1";
965JSVM_Value lhs = nullptr;
966OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &lhs);
967JSVM_Value rhs;
968OH_JSVM_CreateInt32(env, 1, &rhs);
969bool isEquals = false;
970OH_JSVM_Equals(env, lhs, rhs, &isEquals); // The value of isEquals is true.
971OH_JSVM_CloseHandleScope(env, handleScope);
972```
973
974### Working with JS Properties
975
976#### When to Use
977
978Set, get, delete, and check properties of JS objects.
979
980#### Available APIs
981| API| Description|
982| -------- | -------- |
983|OH_JSVM_GetPropertyNames | Obtains the names of all enumerable properties of a JS object as a JS array.|
984|OH_JSVM_GetAllPropertyNames | Obtains the names of all available properties of a JS object as a JS array.|
985|OH_JSVM_SetProperty | Sets a property for a JS object.|
986|OH_JSVM_GetProperty | Obtains the requested property from a JS object.|
987|OH_JSVM_HasProperty | Checks whether a JS object has the named property.|
988|OH_JSVM_DeleteProperty | Deletes a property from a JS object.|
989|OH_JSVM_HasOwnProperty | Checks whether a JS object has the named own property.|
990|OH_JSVM_SetNamedProperty | Sets a property with the given property name for a JS object. This API is equivalent to calling **OH_JSVM_SetNamedProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
991|OH_JSVM_GetNamedProperty | Obtains the property from a JS object with the given property name. This API is equivalent to calling **OH_JSVM_GetNamedProperty** with a **JSVM_Value** created from the string passed in as **utf8Name**.|
992|OH_JSVM_HasNamedProperty | Checks whether a JS object has the named property. This API is equivalent to calling **OH_JSVM_HasProperty** using a **JSVM_Value** created from the string passed in as **utf8Name**.|
993|OH_JSVM_SetElement | Sets an element at the specified index for a JS object.|
994|OH_JSVM_GetElement | Obtains the element at the specified index of a JS object.|
995|OH_JSVM_HasElement | Checks whether a JS object has an element at the specified index.|
996|OH_JSVM_DeleteElement | Deletes the element at the specified index from a JS object.|
997|OH_JSVM_DefineProperties |  Defines multiple properties for a JS object.|
998|OH_JSVM_ObjectFreeze | Freezes 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.|
999|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. |
1000
1001Example:
1002Set, get, delete, and check properties of a JS object.
1003
1004```c++
1005// Create an empty object.
1006JSVM_Value myObject = nullptr;
1007OH_JSVM_CreateObject(env, &myObject);
1008
1009// Set properties.
1010const char *testNameStr = "John Doe";
1011JSVM_Value propValue = nullptr;
1012JSVM_Value key;
1013OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &key);
1014OH_JSVM_CreateStringUtf8(env, testNameStr, strlen(testNameStr), &propValue);
1015OH_JSVM_SetProperty(env, myObject, key, propValue);
1016
1017// Obtain properties.
1018JSVM_Value propResult = nullptr;
1019OH_JSVM_GetProperty(env, myObject, key, &propResult);
1020
1021// Check whether a property exists.
1022bool hasProperty = false;
1023OH_JSVM_HasNamedProperty(env, myObject, "name", &hasProperty);
1024    // The property exists. Perform subsequent processing accordingly.
1025    if (hasProperty)
1026    {
1027        // Obtain all property names of the object.
1028        JSVM_Value propNames = nullptr;
1029        OH_JSVM_GetPropertyNames(env, myObject, &propNames);
1030
1031        bool isArray = false;
1032        OH_JSVM_IsArray(env, propNames, &isArray);
1033
1034        uint32_t arrayLength = 0;
1035        OH_JSVM_GetArrayLength(env, propNames, &arrayLength);
1036        // Traverse property elements.
1037        for (uint32_t i = 0; i < arrayLength; i++)
1038        {
1039            bool hasElement = false;
1040            OH_JSVM_HasElement(env, propNames, i, &hasElement);
1041
1042            JSVM_Value propName = nullptr;
1043            OH_JSVM_GetElement(env, propNames, i, &propName);
1044
1045            bool hasProp = false;
1046            OH_JSVM_HasProperty(env, myObject, propName, &hasProp);
1047
1048            JSVM_Value propValue = nullptr;
1049            OH_JSVM_GetProperty(env, myObject, propName, &propValue);
1050        }
1051    }
1052
1053// Delete a property.
1054OH_JSVM_DeleteProperty(env, myObject, key, &hasProperty);
1055```
1056
1057### Working with JS Functions
1058
1059#### When to Use
1060
1061Call back JS code into native code and call JS functions from native code.
1062
1063#### Available APIs
1064| API| Description|
1065| -------- | -------- |
1066|OH_JSVM_CallFunction | Calls a JS function from a C/C++ addon.|
1067|OH_JSVM_CreateFunction | Creates a JS function object in native code, which allows calling into the native code from JS.|
1068|OH_JSVM_GetCbInfo | Obtains detailed information about the call, such as the parameters and **this** pointer, from the given callback information.|
1069|OH_JSVM_GetNewTarget | Obtains the **new.target** of the constructor call.|
1070|OH_JSVM_NewInstance | Creates an instance based on the given constructor.|
1071
1072Example:
1073Create a JS function.
1074
1075```c++
1076JSVM_Value SayHello(JSVM_Env env, JSVM_CallbackInfo info)
1077{
1078    printf("Hello\n");
1079    JSVM_Value ret;
1080    OH_JSVM_CreateInt32(env, 2, &ret);
1081    return ret;
1082}
1083
1084static JSVM_Value JsvmCreateFunction(JSVM_Env env, JSVM_CallbackInfo info)
1085{
1086    JSVM_CallbackStruct param;
1087    param.data = nullptr;
1088    param.callback = SayHello;
1089
1090    JSVM_Value funcValue = nullptr;
1091    JSVM_Status status = OH_JSVM_CreateFunction(env, "func", JSVM_AUTO_LENGTH, &param, &funcValue);
1092    return funcValue;
1093}
1094```
1095
1096Obtain and call the JS function from C/C++.
1097
1098```c++
1099static JSVM_Value CallFunction(JSVM_Env env, JSVM_CallbackInfo info)
1100{
1101    size_t argc = 1;
1102    JSVM_Value args[1];
1103    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1104
1105    JSVM_ASSERT(env, argc >= 1, "Wrong number of arguments");
1106
1107    JSVM_ValueType valuetype;
1108    JSVM_CALL(env, OH_JSVM_Typeof(env, args[0], &valuetype));
1109    JSVM_ASSERT(env, valuetype == JSVM_ValueType::JSVM_FUNCTION, "Wrong type of argment. Expects a string.");
1110
1111    JSVM_Value global;
1112    JSVM_CALL(env, OH_JSVM_GetGlobal(env, &global));
1113
1114    JSVM_Value ret;
1115    JSVM_CALL(env, OH_JSVM_CallFunction(env, global, args[0], 0, nullptr, &ret));
1116    return ret;
1117}
1118```
1119
1120### Wrapping Objects
1121
1122#### When to Use
1123
1124Wrap native classes and instances so that the class constructor and methods can be called from JS.
1125
1126#### Available APIs
1127| API| Description|
1128| -------- | -------- |
1129|OH_JSVM_DefineClass| Defines a JS class and associated functions within a C/C++ addon. It allows you to define class constructors, methods, and properties that can be accessed from JS.|
1130|OH_JSVM_Wrap| Wraps a native instance in a JS object. You can use **OH_JSVM_Unwrap()** to retrieve the native instance later.|
1131|OH_JSVM_Unwrap | Retrieves a native instance from a JS object.|
1132|OH_JSVM_RemoveWrap | Retrieves a native instance previously wrapped in a JS object and removes the wrapping.|
1133|OH_JSVM_TypeTagObject | Associates the value of the **type_tag** pointer with a JS object or an external object.|
1134|OH_JSVM_CheckObjectTypeTag | Checks whether a tag matches the tag type of an object.|
1135|OH_JSVM_AddFinalizer | Add a **JSVM_Finalize** callback to a JS object. The callback will be invoked to release the native object when the JS object is garbage-collected.|
1136|OH_JSVM_PostFinalizer | Schedules a **JSVM_Finalize** callback to be called asynchronously in the event loop.|
1137|OH_JSVM_DefineClassWithPropertyHandler | Defines a JS class with the given class name, constructor, properties, and callback hander. The property operations include **getter()**, **setter()**, **deleter()**, and **enumerator()** and are called via callbacks.|
1138
1139Example:
1140Wrap a native object in a JS object.
1141
1142```c++
1143static JSVM_Value AssertEqual(JSVM_Env env, JSVM_CallbackInfo info)
1144{
1145    size_t argc = 2;
1146    JSVM_Value args[2];
1147    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1148
1149    bool isStrictEquals = false;
1150    OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
1151    return nullptr;
1152}
1153
1154static napi_value TestWrap(napi_env env1, napi_callback_info info)
1155{
1156    OH_LOG_ERROR(LOG_APP, "testWrap start");
1157    JSVM_InitOptions init_options;
1158    memset(&init_options, 0, sizeof(init_options));
1159    init_options.externalReferences = externals;
1160    if (aa == 0) {
1161        OH_JSVM_Init(&init_options);
1162        aa++;
1163    }
1164    JSVM_VM vm;
1165    JSVM_CreateVMOptions options;
1166    memset(&options, 0, sizeof(options));
1167    OH_JSVM_CreateVM(&options, &vm);
1168    JSVM_VMScope vm_scope;
1169    OH_JSVM_OpenVMScope(vm, &vm_scope);
1170    JSVM_Env env;
1171    JSVM_CallbackStruct param[1];
1172    param[0].data = nullptr;
1173    param[0].callback = AssertEqual;
1174    JSVM_PropertyDescriptor descriptor[] = {
1175        {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1176    };
1177    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1178    JSVM_EnvScope envScope;
1179    OH_JSVM_OpenEnvScope(env, &envScope);
1180    JSVM_HandleScope handlescope;
1181    OH_JSVM_OpenHandleScope(env, &handlescope);
1182    JSVM_Value testClass = nullptr;
1183    JSVM_CallbackStruct param1;
1184    param1.data = nullptr;
1185    param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1186        JSVM_Value thisVar = nullptr;
1187        OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1188
1189        return thisVar;
1190    };
1191    OH_JSVM_DefineClass(env, "TestClass", JSVM_AUTO_LENGTH, &param1, 0, nullptr, &testClass);
1192
1193    JSVM_Value instanceValue = nullptr;
1194    OH_JSVM_NewInstance(env, testClass, 0, nullptr, &instanceValue);
1195
1196    const char *testStr = "test";
1197    OH_JSVM_Wrap(
1198        env, instanceValue, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, nullptr, nullptr);
1199    const char *tmpTestStr = nullptr;
1200    OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr);
1201    const char *tmpTestStr1 = nullptr;
1202    OH_JSVM_RemoveWrap(env, instanceValue, (void **)&tmpTestStr1);
1203    OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr1);
1204    OH_JSVM_CloseHandleScope(env, handlescope);
1205    OH_JSVM_CloseEnvScope(env, envScope);
1206    OH_JSVM_DestroyEnv(env);
1207    OH_JSVM_CloseVMScope(vm, vm_scope);
1208    OH_JSVM_DestroyVM(vm);
1209    OH_LOG_ERROR(LOG_APP, "testWrap pass");
1210    return nullptr;
1211}
1212```
1213
1214Example:
1215Wrap a native object and register a listener for property access operations.
1216
1217```c++
1218static int aa = 0;
1219static JSVM_Value hello(JSVM_Env env, JSVM_CallbackInfo info) {
1220    JSVM_Value output;
1221    void *data = nullptr;
1222    OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
1223    OH_JSVM_CreateStringUtf8(env, (char *)data, strlen((char *)data), &output);
1224    return output;
1225}
1226
1227static JSVM_CallbackStruct hello_cb = {hello, (void *)"Hello"};
1228static intptr_t externals[] = {
1229    (intptr_t)&hello_cb,
1230    0,
1231};
1232
1233static void test1() { OH_LOG_INFO(LOG_APP, "test1 called"); }
1234
1235struct Test {
1236    void *ptr1;
1237    void *ptr2;
1238};
1239
1240static JSVM_Value assertEqual(JSVM_Env env, JSVM_CallbackInfo info) {
1241    size_t argc = 2;
1242    JSVM_Value args[2];
1243    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
1244
1245    bool isStrictEquals = false;
1246    OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
1247    return nullptr;
1248}
1249
1250static JSVM_Value GetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
1251    // This callback is triggered by a request for getting a property from an object.
1252    char strValue[100];
1253    size_t size;
1254    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1255    JSVM_Value newResult = nullptr;
1256    char newStr[] = "new return value hahaha from name listening";
1257    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1258    int signBit = 0;
1259    size_t wordCount = 2;
1260    uint64_t wordsOut[2] = {0ULL, 0ULL};
1261    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1262    if (status == JSVM_OK) {
1263        OH_LOG_INFO(LOG_APP, "GetPropertyCbInfo wordCount is %{public}zu", wordCount);
1264        auto test = reinterpret_cast<Test *>(wordsOut);
1265        typedef void (*callTest1)();
1266        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1267        callTe();
1268    }
1269    return nullptr;
1270}
1271
1272static JSVM_Value SetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
1273    // This callback is triggered by a request for setting a property for an object.
1274    char strValue[100];
1275    size_t size;
1276    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1277    JSVM_Value newResult = nullptr;
1278    char newStr[] = "new return value hahaha from name listening";
1279    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1280    int signBit = 0;
1281    size_t wordCount = 2;
1282    uint64_t wordsOut[2] = {0ULL, 0ULL};
1283    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1284    if (status == JSVM_OK) {
1285        OH_LOG_INFO(LOG_APP, "SetPropertyCbInfo wordCount is %{public}zu", wordCount);
1286        auto test = reinterpret_cast<Test *>(wordsOut);
1287        typedef void (*callTest1)();
1288        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1289        callTe();
1290    }
1291    return nullptr;
1292}
1293
1294static JSVM_Value DeleterPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
1295    // This callback is triggered by a request for deleting a property from an object.
1296    char strValue[100];
1297    size_t size;
1298    OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
1299    JSVM_Value newResult = nullptr;
1300    bool returnValue = false;
1301    OH_JSVM_GetBoolean(env, returnValue, &newResult);
1302    int signBit = 0;
1303    size_t wordCount = 2;
1304    uint64_t wordsOut[2] = {0ULL, 0ULL};
1305    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1306    if (status == JSVM_OK) {
1307        OH_LOG_INFO(LOG_APP, "DeleterPropertyCbInfo wordCount is %{public}zu", wordCount);
1308        auto test = reinterpret_cast<Test *>(wordsOut);
1309        typedef void (*callTest1)();
1310        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1311        callTe();
1312    }
1313    return nullptr;
1314}
1315
1316static JSVM_Value EnumeratorPropertyCbInfo(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
1317    // This callback is triggered by a request for getting all properties of an object.
1318    JSVM_Value testArray = nullptr;
1319    OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
1320    JSVM_Value name1 = nullptr;
1321    char newStr1[] = "hahaha";
1322    OH_JSVM_CreateStringUtf8(env, newStr1, strlen(newStr1), &name1);
1323    JSVM_Value name2 = nullptr;
1324    char newStr2[] = "heheheh";
1325    OH_JSVM_CreateStringUtf8(env, newStr2, strlen(newStr2), &name2);
1326
1327    OH_JSVM_SetElement(env, testArray, 0, name1);
1328    OH_JSVM_SetElement(env, testArray, 1, name2);
1329    int signBit = 0;
1330    size_t wordCount = 2;
1331    uint64_t wordsOut[2] = {0ULL, 0ULL};
1332    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1333    if (status == JSVM_OK) {
1334        OH_LOG_INFO(LOG_APP, "EnumeratorPropertyCbInfo wordCount is %{public}zu", wordCount);
1335        auto test = reinterpret_cast<Test *>(wordsOut);
1336        typedef void (*callTest1)();
1337        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1338        callTe();
1339    }
1340    return nullptr;
1341}
1342
1343static JSVM_Value IndexedPropertyGet(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
1344    // This function is triggered by getting an indexed property of an instance.
1345    uint32_t value;
1346    OH_JSVM_GetValueUint32(env, index, &value);
1347
1348    JSVM_Value newResult = nullptr;
1349    char newStr[] = "new return value hahaha from index listening";
1350    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1351    int signBit = 0;
1352    size_t wordCount = 2;
1353    uint64_t wordsOut[2] = {0ULL, 0ULL};
1354    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1355    if (status == JSVM_OK) {
1356        OH_LOG_INFO(LOG_APP, "IndexedPropertyGet wordCount is %{public}zu", wordCount);
1357        auto test = reinterpret_cast<Test *>(wordsOut);
1358        typedef void (*callTest1)();
1359        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1360        callTe();
1361    }
1362    return nullptr;
1363}
1364
1365static JSVM_Value IndexedPropertySet(JSVM_Env env, JSVM_Value index, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
1366    // This function is triggered by setting an indexed property of an instance.
1367    uint32_t value;
1368    OH_JSVM_GetValueUint32(env, index, &value);
1369    char str[100];
1370    size_t size;
1371    OH_JSVM_GetValueStringUtf8(env, property, str, 100, &size);
1372    JSVM_Value newResult = nullptr;
1373    char newStr[] = "new return value hahaha from name listening";
1374    OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
1375    int signBit = 0;
1376    size_t wordCount = 2;
1377    uint64_t wordsOut[2] = {0ULL, 0ULL};
1378    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1379    if (status == JSVM_OK) {
1380        OH_LOG_INFO(LOG_APP, "IndexedPropertySet wordCount is %{public}zu", wordCount);
1381        auto test = reinterpret_cast<Test *>(wordsOut);
1382        typedef void (*callTest1)();
1383        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1384        callTe();
1385    }
1386    return nullptr;
1387}
1388
1389static JSVM_Value IndexedPropertyDeleter(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
1390    // This function is triggered by deleting an indexed property from an instance.
1391    uint32_t value;
1392    OH_JSVM_GetValueUint32(env, index, &value);
1393    JSVM_Value newResult = nullptr;
1394    bool returnValue = false;
1395    OH_JSVM_GetBoolean(env, returnValue, &newResult);
1396    int signBit = 0;
1397    size_t wordCount = 2;
1398    uint64_t wordsOut[2] = {0ULL, 0ULL};
1399    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1400    if (status == JSVM_OK) {
1401        OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
1402        auto test = reinterpret_cast<Test *>(wordsOut);
1403        typedef void (*callTest1)();
1404        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1405        callTe();
1406    }
1407    return nullptr;
1408}
1409
1410static JSVM_Value IndexedPropertyEnumerator(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
1411    // This function is triggered by getting all indexed properties from an object.
1412    JSVM_Value testArray = nullptr;
1413    OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
1414    JSVM_Value index1 = nullptr;
1415    OH_JSVM_CreateUint32(env, 1, &index1);
1416    JSVM_Value index2 = nullptr;
1417    OH_JSVM_CreateUint32(env, 2, &index2);
1418    OH_JSVM_SetElement(env, testArray, 0, index1);
1419    OH_JSVM_SetElement(env, testArray, 1, index2);
1420    int signBit = 0;
1421    size_t wordCount = 2;
1422    uint64_t wordsOut[2] = {0ULL, 0ULL};
1423    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
1424    if (status == JSVM_OK) {
1425        OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
1426        auto test = reinterpret_cast<Test *>(wordsOut);
1427        typedef void (*callTest1)();
1428        callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
1429        callTe();
1430    }
1431    return nullptr;
1432}
1433
1434static napi_value TestDefineClassWithProperty(napi_env env1, napi_callback_info info) {
1435    OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty start");
1436    JSVM_InitOptions init_options;
1437    memset(&init_options, 0, sizeof(init_options));
1438    init_options.externalReferences = externals;
1439    if (aa == 0) {
1440        OH_JSVM_Init(&init_options);
1441        aa++;
1442    }
1443    JSVM_VM vm;
1444    JSVM_CreateVMOptions options;
1445    memset(&options, 0, sizeof(options));
1446    OH_JSVM_CreateVM(&options, &vm);
1447    JSVM_VMScope vm_scope;
1448    OH_JSVM_OpenVMScope(vm, &vm_scope);
1449    JSVM_Env env;
1450    JSVM_CallbackStruct param[1];
1451    param[0].data = nullptr;
1452    param[0].callback = assertEqual;
1453    JSVM_PropertyDescriptor descriptor[] = {
1454        {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1455    };
1456    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1457    JSVM_EnvScope envScope;
1458    OH_JSVM_OpenEnvScope(env, &envScope);
1459    JSVM_HandleScope handlescope;
1460    OH_JSVM_OpenHandleScope(env, &handlescope);
1461
1462
1463    JSVM_CallbackStruct param1;
1464    param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1465        JSVM_Value thisVar = nullptr;
1466        OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1467        return thisVar;
1468    };
1469    param1.data = nullptr;
1470
1471    JSVM_Value res = nullptr;
1472    Test *test = new Test();
1473    test->ptr1 = (void *)test1;
1474    test->ptr2 = (void *)test1;
1475    OH_LOG_INFO(LOG_APP, "OH_JSVM_CreateBigintWords 111 word count %{public}d",
1476                sizeof(*test) / sizeof(uint64_t));
1477    JSVM_Status status = OH_JSVM_CreateBigintWords(env, 1, 2, reinterpret_cast<const uint64_t *>(test), &res);
1478
1479    // Initialize propertyCfg.
1480    JSVM_PropertyHandlerConfigurationStruct propertyCfg;
1481    propertyCfg.genericNamedPropertyGetterCallback = GetPropertyCbInfo;
1482    propertyCfg.genericNamedPropertySetterCallback = SetPropertyCbInfo;
1483    propertyCfg.genericNamedPropertyDeleterCallback = DeleterPropertyCbInfo;
1484    propertyCfg.genericNamedPropertyEnumeratorCallback = EnumeratorPropertyCbInfo;
1485    propertyCfg.genericIndexedPropertyGetterCallback = IndexedPropertyGet;
1486    propertyCfg.genericIndexedPropertySetterCallback = IndexedPropertySet;
1487    propertyCfg.genericIndexedPropertyDeleterCallback = IndexedPropertyDeleter;
1488    propertyCfg.genericIndexedPropertyEnumeratorCallback = IndexedPropertyEnumerator;
1489    propertyCfg.namedPropertyData = res;
1490    propertyCfg.indexedPropertyData = res;
1491
1492    JSVM_CallbackStruct callbackStruct;
1493    callbackStruct.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1494        OH_LOG_INFO(LOG_APP, "call as a function called");
1495        JSVM_Value thisVar = nullptr;
1496        void *innerData;
1497        size_t argc = 1;
1498        JSVM_Value args[1];
1499        OH_JSVM_GetCbInfo(env, info, &argc, args, &thisVar, &innerData);
1500        OH_LOG_INFO(LOG_APP, "function call as function result is %{public}s", reinterpret_cast<char *>(innerData));
1501        uint32_t ret = 0;
1502        OH_JSVM_GetValueUint32(env, args[0], &ret);
1503        const char testStr[] = "hello world 111111";
1504        JSVM_Value setvalueName = nullptr;
1505        JSVM_CALL(env, OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName));
1506        return setvalueName;
1507    };
1508    char data[100] = "1111 hello world";
1509    callbackStruct.data = data;
1510    JSVM_Value testWrapClass = nullptr;
1511
1512    // Register a property access listener in propertyCfg.
1513    OH_JSVM_DefineClassWithPropertyHandler(env, "TestWrapClass", NAPI_AUTO_LENGTH, &param1, 0, nullptr, &propertyCfg,
1514                                           &callbackStruct, &testWrapClass);
1515    JSVM_Value instanceValue = nullptr;
1516    OH_JSVM_NewInstance(env, testWrapClass, 0, nullptr, &instanceValue);
1517    const char testStr[] = "hello world";
1518    JSVM_Value setvalueName = nullptr;
1519    OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName);
1520
1521    //
1522    // Set a property.
1523    OH_JSVM_SetNamedProperty(env, instanceValue, "str11", setvalueName);
1524    OH_JSVM_SetNamedProperty(env, instanceValue, "str123", setvalueName);
1525
1526    // Get a property.
1527    JSVM_Value valueName = nullptr;
1528    OH_JSVM_GetNamedProperty(env, instanceValue, "str11", &valueName);
1529    char str[100];
1530    size_t size;
1531    OH_JSVM_GetValueStringUtf8(env, valueName, str, 100, &size);
1532
1533    // Get all property names.
1534    JSVM_Value allPropertyNames = nullptr;
1535    OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
1536                                static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
1537                                JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames);
1538    uint32_t nameSize = 0;
1539    OH_JSVM_GetArrayLength(env, allPropertyNames, &nameSize);
1540    JSVM_Value propertyName = nullptr;
1541    for (uint32_t i = 0; i < nameSize; ++i) {
1542        OH_JSVM_GetElement(env, allPropertyNames, i, &propertyName);
1543        char str[100];
1544        size_t size;
1545        OH_JSVM_GetValueStringUtf8(env, propertyName, str, 100, &size);
1546    }
1547
1548    // Delete a property.
1549    bool result = false;
1550    propertyName = nullptr;
1551    char propertyChar[] = "str11";
1552    OH_JSVM_CreateStringUtf8(env, propertyChar, strlen(propertyChar), &propertyName);
1553    OH_JSVM_DeleteProperty(env, instanceValue, propertyName, &result);
1554
1555    //
1556    // Set a property.
1557    JSVM_Value jsIndex = nullptr;
1558    uint32_t index = 0;
1559    OH_JSVM_CreateUint32(env, index, &jsIndex);
1560    OH_JSVM_SetProperty(env, instanceValue, jsIndex, setvalueName);
1561    JSVM_Value jsIndex1 = nullptr;
1562    index = 1;
1563    OH_JSVM_CreateUint32(env, index, &jsIndex1);
1564    OH_JSVM_SetProperty(env, instanceValue, jsIndex1, setvalueName);
1565
1566    // Get a property.
1567    JSVM_Value valueName1 = nullptr;
1568    OH_JSVM_GetProperty(env, instanceValue, jsIndex, &valueName1);
1569    char str1[100];
1570    size_t size1;
1571    OH_JSVM_GetValueStringUtf8(env, valueName1, str1, 100, &size1);
1572
1573    // Get all property names.
1574    JSVM_Value allPropertyNames1 = nullptr;
1575    OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
1576                                static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
1577                                JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames1);
1578    uint32_t nameSize1 = 0;
1579    OH_JSVM_GetArrayLength(env, allPropertyNames1, &nameSize);
1580    JSVM_Value propertyName1 = nullptr;
1581    for (uint32_t i = 0; i < nameSize1; ++i) {
1582        OH_JSVM_GetElement(env, allPropertyNames1, i, &propertyName1);
1583        char str[100];
1584        size_t size;
1585        OH_JSVM_GetValueStringUtf8(env, propertyName1, str, 100, &size);
1586    }
1587
1588    // Delete a property.
1589    bool result1 = false;
1590    OH_JSVM_DeleteProperty(env, instanceValue, jsIndex, &result1);
1591
1592    //
1593    JSVM_Value gloablObj = nullptr;
1594    OH_JSVM_GetGlobal(env, &gloablObj);
1595    OH_JSVM_SetNamedProperty(env, gloablObj, "myTestInstance", instanceValue);
1596    OH_LOG_INFO(LOG_APP, "set property on global object");
1597    std::string innerSourcecodestr = R"(
1598    {
1599        let res = myTestInstance(12);
1600    })";
1601    JSVM_Value innerSourcecodevalue;
1602    OH_JSVM_CreateStringUtf8(env, innerSourcecodestr.c_str(), innerSourcecodestr.size(), &innerSourcecodevalue);
1603    JSVM_Script innerscript;
1604    OH_JSVM_CompileScript(env, innerSourcecodevalue, nullptr, 0, true, nullptr, &innerscript);
1605    JSVM_Value innerResult;
1606    OH_JSVM_RunScript(env, innerscript, &innerResult);
1607
1608    OH_JSVM_CloseHandleScope(env, handlescope);
1609    OH_JSVM_CloseEnvScope(env, envScope);
1610    OH_JSVM_DestroyEnv(env);
1611    OH_JSVM_CloseVMScope(vm, vm_scope);
1612    OH_JSVM_DestroyVM(vm);
1613    OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty pass");
1614    return nullptr;
1615}
1616```
1617
1618### Version Management
1619
1620#### When to Use
1621
1622Obtain version information.
1623
1624#### Available APIs
1625| API| Description|
1626| -------- | -------- |
1627|OH_JSVM_GetVersion| Obtains the latest JSVM API version supported by the JSVM runtime.|
1628|OH_JSVM_GetVMInfo| Obtains the VM information.|
1629
1630Example:
1631Obtain version information.
1632
1633```c++
1634JSVM_VMInfo result;
1635OH_JSVM_GetVMInfo(&result);
1636uint32_t versionId = 0;
1637OH_JSVM_GetVersion(env, &versionId);
1638```
1639
1640### Memory Management
1641
1642#### When to Use
1643
1644Perform memory management.
1645
1646#### Available APIs
1647| API| Description|
1648| -------- | -------- |
1649|OH_JSVM_AdjustExternalMemory| Informs the underlying engine that the VM system memory is insufficient and selectively triggers garbage collection.|
1650|OH_JSVM_MemoryPressureNotification| Creates a deferred object and a JS promise.|
1651
1652Example:
1653Perform memory management.
1654
1655```c++
1656int64_t change = 1024 * 1024; // Allocate 1 MB of memory.
1657int64_t result;
1658OH_JSVM_AdjustExternalMemory(env, change, &result);
1659```
1660
1661### Promises
1662
1663#### When to Use
1664
1665Perform operations related to promises.
1666
1667#### Available APIs
1668| API| Description|
1669| -------- | -------- |
1670|OH_JSVM_CreatePromise| Creates a deferred object and a JS promise.|
1671|OH_JSVM_ResolveDeferred| Resolves a JS promise by using the deferred object associated with it.|
1672|OH_JSVM_RejectDeferred| Rejects a JS promise by using the deferred object associated with it.|
1673|OH_JSVM_IsPromise| Checks whether a promise object is a native promise object.|
1674
1675Example:
1676Perform operations related to promises.
1677
1678```c++
1679JSVM_Deferred deferred;
1680JSVM_Value promise;
1681OH_JSVM_CreatePromise(env, &deferred, &promise);
1682
1683// Perform an asynchronous operation.
1684int result = 42;
1685bool success = true;
1686if (success)
1687{
1688    // Resolve the promise and pass the result.
1689    JSVM_Value value;
1690    OH_JSVM_CreateInt32(env, result, &value);
1691    OH_JSVM_ResolveDeferred(env, deferred, value);
1692} else {
1693    // Reject the promise and pass the error information.
1694    JSVM_Value code = nullptr;
1695    JSVM_Value message = nullptr;
1696    OH_JSVM_CreateStringUtf8(env, "600", JSVM_AUTO_LENGTH, &code);
1697    OH_JSVM_CreateStringUtf8(env, "Async operation failed", JSVM_AUTO_LENGTH, &message);
1698    JSVM_Value error = nullptr;
1699    OH_JSVM_CreateError(env, code, message, &error);
1700    OH_JSVM_RejectDeferred(env, deferred, error);
1701}
1702```
1703
1704### JSON Operations
1705
1706#### When to Use
1707
1708Perform JSON operations.
1709
1710#### Available APIs
1711
1712| API| Description|
1713| -------- | -------- |
1714|OH_JSVM_JsonParse| Parses a JSON string and returns the parsed value.|
1715|OH_JSVM_JsonStringify| Converts a JS object into a JSON string and returns the converted string.|
1716
1717Example:
1718Parse JSON strings.
1719
1720```c++
1721std::string sourcecodestr = "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}" ;
1722JSVM_Value jsonString;
1723OH_JSVM_CreateStringUtf8(env, sourcecodestr.c_str(), sourcecodestr.size(), &jsonString)
1724JSVM_Value result;
1725OH_JSVM_JsonParse(env, jsonString, &result);
1726```
1727
1728### Creating VM Startup Snapshots
1729
1730#### When to Use
1731
1732Create a VM startup snapshot.
1733
1734#### Available APIs
1735| API| Description|
1736| -------- | -------- |
1737|OH_JSVM_CreateSnapshot| Creates a VM startup snapshot.|
1738
1739Example:
1740Create a VM startup snapshot.
1741
1742```c++
1743JSVM_VM vm;
1744JSVM_CreateVMOptions options;
1745memset(&options, 0, sizeof(options));
1746OH_JSVM_CreateVM(&options, &vm);
1747JSVM_Env env;
1748JSVM_CallbackStruct param[1];
1749param[0].data = nullptr;
1750param[0].callback = AssertEqual;
1751JSVM_PropertyDescriptor descriptor[] = {
1752    {"test", nullptr, &param[0], nullptr, nullptr, nullptr, JSVM_DEFAULT},
1753};
1754OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1755const char *blobData = nullptr;
1756size_t blobSize = 0;
1757JSVM_Env envs[1] = {env};
1758OH_JSVM_CreateSnapshot(vm, 1, envs, &blobData, &blobSize);
1759```
1760
1761### Checking Input Parameters
1762
1763#### When to Use
1764
1765Check whether the input parameters are callable.
1766
1767#### Available APIs
1768| API| Description|
1769| -------- | -------- |
1770|OH_JSVM_IsCallable| Checks whether input parameters are callable.|
1771
1772Example:
1773Check whether input parameters are callable.
1774
1775```c++
1776static JSVM_Value NapiIsCallable(JSVM_Env env, JSVM_CallbackInfo info) {
1777    JSVM_Value value, rst;
1778    size_t argc = 1;
1779    bool isCallable = false;
1780    JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, &value, NULL, NULL));
1781    JSVM_CALL(env, OH_JSVM_IsCallable(env, value, &isCallable));
1782    OH_JSVM_GetBoolean(env, isCallable, &rst);
1783    return rst;
1784}
1785
1786static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
1787    std::thread t([]() {
1788        // Create a VM instance and open the VM scope.
1789        JSVM_VM vm;
1790        JSVM_CreateVMOptions options;
1791        memset(&options, 0, sizeof(options));
1792        OH_JSVM_CreateVM(&options, &vm);
1793        JSVM_VMScope vmScope;
1794        OH_JSVM_OpenVMScope(vm, &vmScope);
1795        JSVM_CallbackStruct param[] = {
1796            {.data = nullptr, .callback = NapiIsCallable},
1797        };
1798        JSVM_PropertyDescriptor descriptor[] = {
1799            {"napiIsCallable", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
1800        };
1801        // Create env, register a native method, and open an env scope.
1802        JSVM_Env env;
1803        OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
1804        JSVM_EnvScope envScope;
1805        OH_JSVM_OpenEnvScope(env, &envScope);
1806        // Open a handle scope.
1807        JSVM_HandleScope handleScope;
1808        OH_JSVM_OpenHandleScope(env, &handleScope);
1809        std::string sourceCodeStr = R"JS(
1810        function addNumbers(num1, num2)
1811        {
1812            var rst= num1 + num2;
1813            return rst;
1814        }
1815        let rst = napiIsCallable(addNumbers);
1816        )JS";
1817        // Compile the JS script.
1818        JSVM_Value sourceCodeValue;
1819        OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
1820        JSVM_Script script;
1821        OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
1822        JSVM_Value result;
1823        // Run the JS script.
1824        OH_JSVM_RunScript(env, script, &result);
1825        JSVM_ValueType type;
1826        OH_JSVM_Typeof(env, result, &type);
1827        OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
1828        // Exit the VM and release the memory.
1829        OH_JSVM_CloseHandleScope(env, handleScope);
1830        OH_JSVM_CloseEnvScope(env, envScope);
1831        OH_JSVM_DestroyEnv(env);
1832        OH_JSVM_CloseVMScope(vm, vmScope);
1833        OH_JSVM_DestroyVM(vm);
1834    });
1835    t.detach();
1836    return nullptr;
1837}
1838```
1839
1840### Lock Operations
1841
1842#### When to Use
1843
1844Perform lock operations.
1845
1846#### Available APIs
1847| API| Description|
1848| -------- | -------- |
1849|OH_JSVM_IsLocked| Checks whether the current thread holds a lock of the specified environment.|
1850|OH_JSVM_AcquireLock| Obtains a lock.|
1851|OH_JSVM_ReleaseLock| Releases a lock.|
1852
1853Example:
1854Obtain and release a lock.
1855
1856```c++
1857static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
1858    // Create a VM instance and open the VM scope.
1859    JSVM_VM vm;
1860    JSVM_CreateVMOptions options;
1861    memset(&options, 0, sizeof(options));
1862    OH_JSVM_CreateVM(&options, &vm);
1863    JSVM_VMScope vmScope;
1864    OH_JSVM_OpenVMScope(vm, &vmScope);
1865    // Create env, register a native method, and open an env scope.
1866    JSVM_Env env;
1867    OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
1868    JSVM_EnvScope envScope;
1869    OH_JSVM_OpenEnvScope(env, &envScope);
1870    // Open a handle scope.
1871    JSVM_HandleScope handleScope;
1872    OH_JSVM_OpenHandleScope(env, &handleScope);
1873    std::thread t1([vm, env]() {
1874        bool isLocked = false;
1875        OH_JSVM_IsLocked(env, &isLocked);
1876        if (!isLocked) {
1877            OH_JSVM_AcquireLock(env);
1878        }
1879        JSVM_VMScope vmScope;
1880        OH_JSVM_OpenVMScope(vm, &vmScope);
1881        JSVM_EnvScope envScope;
1882        OH_JSVM_OpenEnvScope(env, &envScope);
1883        JSVM_HandleScope handleScope;
1884        OH_JSVM_OpenHandleScope(env, &handleScope);
1885        JSVM_Value value;
1886        JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
1887        if (rst) {
1888            OH_LOG_INFO(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 suc");
1889        } else {
1890            OH_LOG_ERROR(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 fail");
1891        }
1892        int32_t num1;
1893        OH_JSVM_GetValueInt32(env, value, &num1);
1894        OH_LOG_INFO(LOG_APP, "JSVM:t1 num1 = %{public}d", num1);
1895        OH_JSVM_CloseHandleScope(env, handleScope);
1896        OH_JSVM_CloseEnvScope(env, envScope);
1897        OH_JSVM_DestroyEnv(env);
1898        OH_JSVM_IsLocked(env, &isLocked);
1899        if (isLocked) {
1900            OH_JSVM_ReleaseLock(env);
1901        }
1902    });
1903    std::thread t2([vm, env]() {
1904        bool isLocked = false;
1905        OH_JSVM_IsLocked(env, &isLocked);
1906        if (!isLocked) {
1907            OH_JSVM_AcquireLock(env);
1908        }
1909        JSVM_VMScope vmScope;
1910        OH_JSVM_OpenVMScope(vm, &vmScope);
1911        JSVM_EnvScope envScope;
1912        OH_JSVM_OpenEnvScope(env, &envScope);
1913        JSVM_HandleScope handleScope;
1914        OH_JSVM_OpenHandleScope(env, &handleScope);
1915        JSVM_Value value;
1916        JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
1917        if (rst) {
1918            OH_LOG_INFO(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 suc");
1919        } else {
1920            OH_LOG_ERROR(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 fail");
1921        }
1922        int32_t num1;
1923        OH_JSVM_GetValueInt32(env, value, &num1);
1924        OH_LOG_INFO(LOG_APP, "JSVM:t2 num1 = %{public}d", num1);
1925        OH_JSVM_CloseHandleScope(env, handleScope);
1926        OH_JSVM_CloseEnvScope(env, envScope);
1927        OH_JSVM_DestroyEnv(env);
1928        OH_JSVM_IsLocked(env, &isLocked);
1929        if (isLocked) {
1930            OH_JSVM_ReleaseLock(env);
1931        }
1932    });
1933    t1.detach();
1934    t2.detach();
1935    sleep(10);
1936    // Exit the VM and release the memory.
1937    OH_JSVM_CloseHandleScope(env, handleScope);
1938    OH_JSVM_CloseEnvScope(env, envScope);
1939    OH_JSVM_DestroyEnv(env);
1940    OH_JSVM_CloseVMScope(vm, vmScope);
1941    OH_JSVM_DestroyVM(vm);
1942    return nullptr;
1943}
1944```
1945