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