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