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, ¶m[0], NULL, NULL, NULL, JSVM_DEFAULT}, 504 {"add", NULL, ¶m[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, ¶m, &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, ¶m, &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, ¶m1); 1488OH_JSVM_CreateStringUtf8(env, "b", JSVM_AUTO_LENGTH, ¶m2); 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, ¶m[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, ¶m1, 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, ¶m[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, ¶m1, 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, ¶m[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).