1# Working with Arrays Using JSVM-API 2 3## Introduction 4 5JSVM-API provides APIs for directly managing JavaScript (JS) arrays. 6 7## Basic Concepts 8 9JSVM-API can be used to create, access, modify, and traverse arrays. Before using JSVM-API to work with arrays, it's helpful if you understand the following concepts: 10 11- Array creation: You can use **OH_JSVM_CreateArray** to create an array and pass it to the JS layer. 12- Array-related operations: You can use the APIs provides by the JSVM module to obtain the length of a JS array, retrieve the element at the specified index, and set the element value at the specified index. 13- **TypedArray**: A **TypedArray** object in JS is an array-like view of an underlying binary data buffer. It can be simply understood as an array of elements of the specified type. There is no constructor for **TypedArray** objects, but its child class constructor can be used to construct **TypedArray** data. The child classes of **TypedArray** include **Int8Array**, **Uint8Array**, **Uint8ClampedArray**, **Int16Array**, and **Int32Array**. 14- **ArrayBuffer**: **ArrayBuffer** is a data struct used to represent a binary data buffer of fixed length. 15- **DataView**: **DataView** is a JS view that allows a variety of number types to be read and written in an **ArrayBuffer** object. 16 17 18## Available APIs 19 20| API | Description | 21| ---------------------------- | ------------------------------------------ | 22|OH_JSVM_CreateArray | Creates a JS array object.| 23|OH_JSVM_CreateArrayWithLength | Creates a JS array object of the specified length.| 24|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. <br/>The parameters specified must meet the following:<br>(**length** x **size_of_element**) + **byte_offset** ≤ Array size (in bytes)<br>Otherwise, a **RangeError** exception will be thrown.<br>**size_of_element** specifies the size of the data type of the elements in the array. | 25|OH_JSVM_CreateDataview | Creates a JS **DataView** object based on an existing **ArrayBuffer**. The **DataView** object provides an array-like view on the underlying data buffer. The **ArrayBuffer** allows elements of different sizes and types. <br/>The sum of **byte_length** and **byte_offset** must be less than or equal to the array size (in bytes). Otherwise, a **RangeError** exception will be thrown. | 26|OH_JSVM_GetArrayLength | Obtains the length of an array.| 27|OH_JSVM_GetTypedarrayInfo | Obtains information about a **TypedArray** object.| 28|OH_JSVM_GetDataviewInfo | Obtains information of a **DataView** object.| 29|OH_JSVM_IsArray | Checks whether a JS object is an array.| 30|OH_JSVM_SetElement | Sets an element at the specified index for a JS object.| 31|OH_JSVM_GetElement | Obtains the element at the specified index of a JS object.| 32|OH_JSVM_HasElement | Checks whether a JS object has an element at the specified index.| 33|OH_JSVM_DeleteElement | Deletes the element at the specified index from a JS object.| 34|OH_JSVM_IsDataview | Checks whether a JS object is a **DataView** object.| 35|OH_JSVM_IsTypedarray | Checks whether a JS object is a **TypedArray** object.| 36 37## Example 38 39If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in array development. 40 41### OH_JSVM_CreateArray 42 43Use **OH_JSVM_CreateArray** to create a JS array object. 44 45CPP code: 46 47```cpp 48// hello.cpp 49#include "napi/native_api.h" 50#include "ark_runtime/jsvm.h" 51#include <hilog/log.h> 52// Register the CreateArray callback. 53static int DIFF_VALUE_FIVE = 5; 54// Define OH_JSVM_CreateArray. 55static JSVM_Value CreateArray(JSVM_Env env, JSVM_CallbackInfo info) 56{ 57 // Create an empty array. 58 JSVM_Value array = nullptr; 59 JSVM_Status status = OH_JSVM_CreateArray(env, &array); 60 // Assign values to the created array. 61 for (int i = 0; i < DIFF_VALUE_FIVE; i++) { 62 JSVM_Value element; 63 OH_JSVM_CreateInt32(env, i, &element); 64 OH_JSVM_SetElement(env, array, i, element); 65 } 66 if (status != JSVM_OK) { 67 OH_LOG_ERROR(LOG_APP, "JSVM CreateArray fail"); 68 } else { 69 OH_LOG_INFO(LOG_APP, "JSVM CreateArray success"); 70 } 71 return array; 72} 73static JSVM_CallbackStruct param[] = { 74 {.data = nullptr, .callback = CreateArray}, 75}; 76static JSVM_CallbackStruct *method = param; 77// Set a property descriptor named createArray and associate it with a callback. This allows the CreateArray callback to be called from JS. 78static JSVM_PropertyDescriptor descriptor[] = { 79 {"createArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 80}; 81// Call the C++ code from JS. 82const char *srcCallNative = R"JS( 83 function testCreateArray() { 84 return createArray(); 85 } 86 testCreateArray(); 87)JS"; 88``` 89Expected result: 90``` 91JSVM CreateArray success 92``` 93### OH_JSVM_CreateArrayWithLength 94 95Use **OH_JSVM_CreateArrayWithLength** to create a JS array object of the specified length. 96 97CPP code: 98 99```cpp 100// hello.cpp 101#include "napi/native_api.h" 102#include "ark_runtime/jsvm.h" 103#include <hilog/log.h> 104// Define OH_JSVM_CreateArrayWithLength. 105static JSVM_Value CreateArrayWithLength(JSVM_Env env, JSVM_CallbackInfo info) 106{ 107 size_t argc = 1; 108 JSVM_Value argv[1] = {nullptr}; 109 JSVM_Value result = nullptr; 110 // Obtain the callback information. 111 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 112 // Obtain the array length passed. 113 int32_t length; 114 OH_JSVM_GetValueInt32(env, argv[0], &length); 115 // Call OH_JSVM_CreateArrayWithLength to create an array with the specified length. 116 JSVM_Status status = OH_JSVM_CreateArrayWithLength(env, length, &result); 117 if (status == JSVM_OK) { 118 // Set an element in the created array. 119 for (int32_t i = 0; i < length; i++) { 120 JSVM_Value value; 121 OH_JSVM_CreateInt32(env, i, &value); 122 OH_JSVM_SetElement(env, result, i, value); 123 } 124 OH_LOG_INFO(LOG_APP, "JSVM CreateArrayWithLength success"); 125 } else { 126 OH_LOG_ERROR(LOG_APP, "JSVM CreateArrayWithLength fail"); 127 } 128 return result; 129} 130// Register the CreateArrayWithLength callback. 131static JSVM_CallbackStruct param[] = { 132 {.data = nullptr, .callback = CreateArrayWithLength}, 133}; 134static JSVM_CallbackStruct *method = param; 135// Set a property descriptor named createArrayWithLength and associate it with a callback. This allows the CreateArrayWithLength callback to be called from JS. 136static JSVM_PropertyDescriptor descriptor[] = { 137 {"createArrayWithLength", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 138}; 139// Call the C++ code from JS. 140const char *srcCallNative = R"JS( 141let num = 7; 142function testCreateArrayWithLength(num){ 143 return createArrayWithLength(num); 144} 145testCreateArrayWithLength(num); 146)JS"; 147``` 148Expected result: 149``` 150JSVM CreateArrayWithLength success 151``` 152### OH_JSVM_CreateTypedarray 153 154Use **OH_JSVM_CreateTypedarray** to create a JS **TypedArray** object based on 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. 155 156CPP code: 157 158```cpp 159// hello.cpp 160#include "napi/native_api.h" 161#include "ark_runtime/jsvm.h" 162#include <hilog/log.h> 163// Define OH_JSVM_CreateTypedarray. 164static int DIFF_VALUE_THREE = 3; 165static JSVM_Value CreateTypedArray(JSVM_Env env, JSVM_CallbackInfo info) 166{ 167 size_t argc = 1; 168 JSVM_Value args[1] = {nullptr}; 169 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 170 int32_t typeNum; 171 OH_JSVM_GetValueInt32(env, args[0], &typeNum); 172 JSVM_TypedarrayType arrayType; 173 // Set the element size. 174 size_t elementSize = 0; 175 // Convert the value to the JSVM_TypedarrayType type. 176 arrayType = static_cast<JSVM_TypedarrayType>(typeNum); 177 switch (typeNum) { 178 case JSVM_INT8_ARRAY: 179 case JSVM_UINT8_ARRAY: 180 case JSVM_UINT8_CLAMPED_ARRAY: 181 elementSize = sizeof(int8_t); 182 break; 183 case JSVM_INT16_ARRAY: 184 case JSVM_UINT16_ARRAY: 185 elementSize = sizeof(int16_t); 186 break; 187 case JSVM_INT32_ARRAY: 188 case JSVM_UINT32_ARRAY: 189 elementSize = sizeof(int32_t); 190 break; 191 case JSVM_FLOAT32_ARRAY: 192 elementSize = sizeof(float); 193 break; 194 case JSVM_FLOAT64_ARRAY: 195 elementSize = sizeof(double); 196 break; 197 case JSVM_BIGINT64_ARRAY: 198 case JSVM_BIGUINT64_ARRAY: 199 elementSize = sizeof(int64_t); 200 break; 201 default: 202 // By default, an array of the JSVM_INT8_ARRAY type is created. 203 arrayType = JSVM_INT8_ARRAY; 204 elementSize = sizeof(int8_t); 205 break; 206 } 207 size_t length = DIFF_VALUE_THREE; 208 JSVM_Value arrayBuffer = nullptr; 209 JSVM_Value typedArray = nullptr; 210 void *data; 211 // Create an ArrayBuffer object. 212 OH_JSVM_CreateArraybuffer(env, length * elementSize, (void **)&data, &arrayBuffer); 213 // Create a TypedArray object of the specified type. 214 JSVM_Status status = OH_JSVM_CreateTypedarray(env, arrayType, length, arrayBuffer, 0, &typedArray); 215 if (status != JSVM_OK) { 216 OH_LOG_ERROR(LOG_APP, "JSVM CreateTypedArray fail"); 217 } else { 218 OH_LOG_INFO(LOG_APP, "JSVM CreateTypedArray success"); 219 } 220 return typedArray; 221} 222// Register the CreateTypedArray callback. 223static JSVM_CallbackStruct param[] = { 224 {.data = nullptr, .callback = CreateTypedArray}, 225}; 226static JSVM_CallbackStruct *method = param; 227// Set a property descriptor named createTypedArray and associate it with a callback. This allows the CreateTypedArray callback to be called from JS. 228static JSVM_PropertyDescriptor descriptor[] = { 229 {"createTypedArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 230}; 231// Call the C++ code from JS. 232const char *srcCallNative = R"JS( 233const type = { 234 INT8_ARRAY: 0, 235 UINT8_ARRAY: 1, 236 UINT8_CLAMPED_ARRAY: 2, 237 INT16_ARRAY: 3, 238 UINT16_ARRAY: 4, 239 INT32_ARRAY: 5, 240 UINT32_ARRAY: 6, 241 FLOAT32_ARRAY: 7, 242 FLOAT64_ARRAY: 8, 243 BIGINT64_ARRAY: 9, 244 BIGUINT64_ARRAY: 10 245}; 246createTypedArray(type.INT8_ARRAY); 247createTypedArray(type.INT32_ARRAY); 248)JS"; 249``` 250Expected result: 251``` 252JSVM CreateTypedArray success 253JSVM CreateTypedArray success 254``` 255### OH_JSVM_CreateDataview 256 257Use **OH_JSVM_CreateDataview** to create a JS **DataView** object based on an **ArrayBuffer**. The **DataView** object provides an array-like view over an underlying data buffer. 258 259CPP code: 260 261```cpp 262static int DIFF_VALUE_FOUR = 4; 263static int DIFF_VALUE_TWELVE = 12; 264// Define OH_JSVM_CreateDataview. 265static JSVM_Value CreateDataView(JSVM_Env env, JSVM_CallbackInfo info) 266{ 267 // Obtain the two parameters passed from JS. 268 size_t argc = 2; 269 JSVM_Value args[2] = {nullptr}; 270 JSVM_Value arrayBuffer = nullptr; 271 JSVM_Value result = nullptr; 272 // Byte length of DataView. 273 size_t byteLength = DIFF_VALUE_TWELVE; 274 // Offset of the byte. 275 size_t byteOffset = DIFF_VALUE_FOUR; 276 // Obtain the parameters of the callback. 277 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 278 // Convert the parameter into the object type. 279 OH_JSVM_CoerceToObject(env, args[0], &arrayBuffer); 280 // Create a DataView object with the specified byte length and offset. 281 JSVM_Status status = OH_JSVM_CreateDataview(env, byteLength, arrayBuffer, byteOffset, &result); 282 // Obtain the pointer to the DataView object and the length. 283 uint8_t *data = nullptr; 284 size_t length = 0; 285 // Assign values to DataView. 286 for (size_t i = 0; i < length; i++) { 287 data[i] = static_cast<uint8_t>(i + 1); 288 } 289 int32_t infoType; 290 OH_JSVM_GetValueInt32(env, args[1], &infoType); 291 size_t returnLength; 292 JSVM_Value returnArrayBuffer = nullptr; 293 size_t returnOffset; 294 enum InfoType { BYTE_LENGTHE, ARRAY_BUFFERE, BYTE_OFFSET }; 295 // Obtain DataView information. 296 OH_JSVM_GetDataviewInfo(env, result, &returnLength, (void **)&data, &returnArrayBuffer, &returnOffset); 297 JSVM_Value returnResult = nullptr; 298 switch (infoType) { 299 case BYTE_LENGTHE: 300 JSVM_Value len; 301 OH_JSVM_CreateInt32(env, returnLength, &len); 302 returnResult = len; 303 if (status != JSVM_OK) { 304 OH_LOG_ERROR(LOG_APP, "JSVM CreateDataView fail"); 305 } else { 306 OH_LOG_INFO(LOG_APP, "JSVM CreateDataView success, returnLength: %{public}d", returnLength); 307 } 308 break; 309 case ARRAY_BUFFERE: 310 bool isArraybuffer; 311 OH_JSVM_IsArraybuffer(env, returnArrayBuffer, &isArraybuffer); 312 JSVM_Value isArray; 313 OH_JSVM_GetBoolean(env, isArraybuffer, &isArray); 314 returnResult = isArray; 315 if (status != JSVM_OK) { 316 OH_LOG_ERROR(LOG_APP, "JSVM CreateDataView fail"); 317 } else { 318 OH_LOG_INFO(LOG_APP, "JSVM CreateDataView success, isArraybuffer: %{public}d", isArraybuffer); 319 } 320 break; 321 case BYTE_OFFSET: 322 JSVM_Value offset; 323 OH_JSVM_CreateInt32(env, returnOffset, &offset); 324 returnResult = offset; 325 if (status != JSVM_OK) { 326 OH_LOG_ERROR(LOG_APP, "JSVM CreateDataView fail"); 327 } else { 328 OH_LOG_INFO(LOG_APP, "JSVM CreateDataView success, returnOffset: %{public}d", returnOffset); 329 } 330 break; 331 default: 332 break; 333 } 334 return returnResult; 335} 336// Register the CreateDataView callback. 337static JSVM_CallbackStruct param[] = { 338 {.data = nullptr, .callback = CreateDataView}, 339}; 340static JSVM_CallbackStruct *method = param; 341// Set a property descriptor named createDataView and associate it with a callback. This allows the CreateDataView callback to be called from JS. 342static JSVM_PropertyDescriptor descriptor[] = { 343 {"createDataView", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 344}; 345// Call the C++ code from JS. 346const char *srcCallNative = R"JS( 347 let BYTE_LENGTH = 0; 348 createDataView(new ArrayBuffer(16), BYTE_LENGTH); 349 let IS_ARRAYBUFFER = 1; 350 createDataView(new ArrayBuffer(16), IS_ARRAYBUFFER); 351 let BYTE_OFFSET = 2; 352 createDataView(new ArrayBuffer(16), BYTE_OFFSET); 353)JS"; 354``` 355Expected result: 356``` 357CreateDataView success, returnLength: 12 358JSVM CreateDataView success, isArraybuffer: 1 359JSVM CreateDataView success, returnOffset: 4 360``` 361### OH_JSVM_GetArrayLength 362 363Use **OH_JSVM_GetArrayLength** to obtain the length of an array. 364 365CPP code: 366 367```cpp 368// hello.cpp 369#include "napi/native_api.h" 370#include "ark_runtime/jsvm.h" 371#include <hilog/log.h> 372// Define OH_JSVM_GetArrayLength. 373static JSVM_Value GetArrayLength(JSVM_Env env, JSVM_CallbackInfo info) 374{ 375 size_t argc = 1; 376 JSVM_Value args[1] = {nullptr}; 377 JSVM_Value result = nullptr; 378 // Initialize length. 379 uint32_t length = 0; 380 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 381 // Check whether the parameter is an array. 382 bool isArray = false; 383 OH_JSVM_IsArray(env, args[0], &isArray); 384 if (!isArray) { 385 OH_LOG_INFO(LOG_APP, "JSVM Argument must be an array"); 386 return nullptr; 387 } 388 /* 389 * If the array length is successfully obtained, length is assigned to the actual JSArray length, and the API returns the JSVM_OK status code. 390 * If args[0] is not of the JSArray type, for example, args[0] is a proxy object, the length cannot be obtained. 391 * In this case, length remains unchanged, and the JSVM_ARRAY_EXPECTED status code is returned. 392 */ 393 JSVM_Status status = OH_JSVM_GetArrayLength(env, args[0], &length); 394 if (status == JSVM_OK) { 395 // Create a return value. 396 OH_JSVM_CreateInt32(env, length, &result); 397 OH_LOG_INFO(LOG_APP, "JSVM length: %{public}d", length); 398 } 399 return result; 400} 401// Register the GetArrayLength callback. 402static JSVM_CallbackStruct param[] = { 403 {.data = nullptr, .callback = GetArrayLength}, 404}; 405static JSVM_CallbackStruct *method = param; 406// Set a property descriptor named getArrayLength and associate it with a callback. This allows the GetArrayLength callback to be called from JS. 407static JSVM_PropertyDescriptor descriptor[] = { 408 {"getArrayLength", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 409}; 410// Call the C++ code from JS. 411const char *srcCallNative = R"JS( 412let data = [0, 1, 2, 3, 4, 5]; 413getArrayLength(data); 414)JS"; 415``` 416Expected result: 417``` 418JSVM length: 6 419``` 420### OH_JSVM_GetTypedarrayInfo 421 422Use **OH_JSVM_GetTypedarrayInfo** to obtain information about a **TypedArray** object. 423 424CPP code: 425 426```cpp 427// hello.cpp 428#include "napi/native_api.h" 429#include "ark_runtime/jsvm.h" 430#include <hilog/log.h> 431// Define OH_JSVM_GetTypedarrayInfo. 432static JSVM_Value GetTypedArrayInfo(JSVM_Env env, JSVM_CallbackInfo info) 433{ 434 // Obtain and parse the parameters passed to a JS callback within a JSVM. The first parameter is the TypedArray type of the information to obtain, and the second parameter is the enums of the information type to obtain. 435 size_t argc = 2; 436 JSVM_Value args[2] = {nullptr}; 437 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 438 439 // Convert the second parameter to the int32 type for comparison. 440 int32_t infoTypeParam; 441 OH_JSVM_GetValueInt32(env, args[1], &infoTypeParam); 442 // Define the infoType enums in the same sequence as those in ArkTS. 443 enum InfoType { INFO_TYPE, INFO_LENGTH, INFO_ARRAY_BUFFER, INFO_BYTE_OFFSET }; 444 void *data; 445 JSVM_TypedarrayType type; 446 size_t byteOffset, length; 447 JSVM_Value arrayBuffer = nullptr; 448 // Call OH_JSVM_GetTypedarrayInfo to obtain TypedArray information. 449 JSVM_Status status = OH_JSVM_GetTypedarrayInfo(env, args[0], &type, &length, &data, &arrayBuffer, &byteOffset); 450 JSVM_Value result = nullptr; 451 // Return the property value based on the property name. 452 switch (infoTypeParam) { 453 case INFO_TYPE: 454 // If the input parameter is TypedArray data of the int8 type, the value type is JSVM_INT8_ARRAY. 455 JSVM_Value int8_type; 456 OH_JSVM_GetBoolean(env, type == JSVM_INT8_ARRAY, &int8_type); 457 result = int8_type; 458 if (status != JSVM_OK) { 459 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 460 } else { 461 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, JSVM_INT8_ARRAY: %{public}d", type == JSVM_INT8_ARRAY); 462 } 463 break; 464 case INFO_LENGTH: 465 // Number of elements in the TypedArray object. 466 JSVM_Value jsvmLength; 467 OH_JSVM_CreateInt32(env, length, &jsvmLength); 468 result = jsvmLength; 469 if (status != JSVM_OK) { 470 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 471 } else { 472 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, length: %{public}d", length); 473 } 474 break; 475 case INFO_BYTE_OFFSET: 476 // Byte offset of the first TypedArray element in the native array. 477 JSVM_Value jsvmOffset; 478 OH_JSVM_CreateInt32(env, byteOffset, &jsvmOffset); 479 result = jsvmOffset; 480 if (status != JSVM_OK) { 481 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 482 } else { 483 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, byteOffset: %{public}d", byteOffset); 484 } 485 break; 486 case INFO_ARRAY_BUFFER: 487 // ArrayBuffer under TypedArray. 488 bool isArrayBuffer; 489 OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer); 490 JSVM_Value isArray; 491 OH_JSVM_GetBoolean(env, isArrayBuffer, &isArray); 492 result = isArray; 493 if (status != JSVM_OK) { 494 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 495 } else { 496 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, isArrayBuffer: %{public}d", isArrayBuffer); 497 } 498 break; 499 default: 500 break; 501 } 502 return result; 503} 504// Register the GetTypedArrayInfo callback. 505static JSVM_CallbackStruct param[] = { 506 {.data = nullptr, .callback = GetTypedArrayInfo}, 507}; 508static JSVM_CallbackStruct *method = param; 509// Set a property descriptor named getTypedArrayInfo and associate it with a callback. This allows the GetTypedArrayInfo callback to be called from JS. 510static JSVM_PropertyDescriptor descriptor[] = { 511 {"getTypedArrayInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 512}; 513// Call the C++ code from JS. 514const char *srcCallNative = R"JS( 515// is JSVM_INT8_ARRAY 516getTypedArrayInfo(new Int8Array(3), 0); 517// Length 518getTypedArrayInfo(new Int8Array(5), 1); 519// is_arraybuffer 520getTypedArrayInfo(new Int8Array(5), 2); 521// Byte offset. 522getTypedArrayInfo(new Int8Array(1), 3); 523)JS"; 524``` 525Expected result: 526``` 527JSVM GetTypedArrayInfo success, JSVM_INT8_ARRAY: 1 528JSVM GetTypedArrayInfo success, length: 5 529JSVM GetTypedArrayInfo success, isArrayBuffer: 1 530JSVM GetTypedArrayInfo success, byteOffset: 0 531``` 532### OH_JSVM_GetDataviewInfo 533 534Use **OH_JSVM_GetDataviewInfo** to obtain information about a **DataView** object. 535 536CPP code: 537 538```cpp 539// hello.cpp 540#include "napi/native_api.h" 541#include "ark_runtime/jsvm.h" 542#include <hilog/log.h> 543// Define OH_JSVM_GetDataviewInfo. 544static JSVM_Value GetDataViewInfo(JSVM_Env env, JSVM_CallbackInfo info) 545{ 546 // Obtain and parse the parameters passed to a JS callback within a JSVM. The first parameter is the DataView type of the information to obtain, and the second parameter is the enums of the information type to obtain. 547 size_t argc = 2; 548 JSVM_Value args[2] = {nullptr}; 549 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 550 // Convert the second parameter to an int32 number. 551 int32_t infoType; 552 OH_JSVM_GetValueInt32(env, args[1], &infoType); 553 size_t byteLength; 554 void *data; 555 JSVM_Value arrayBuffer = nullptr; 556 size_t byteOffset; 557 // Define the infoType enums in the same sequence as those in ArkTS. 558 enum infoTypeEnum { BYTE_LENGTHE, ARRAY_BUFFERE, BYTE_OFFSET }; 559 // Obtain DataView information. 560 JSVM_Status status = OH_JSVM_GetDataviewInfo(env, args[0], &byteLength, &data, &arrayBuffer, &byteOffset); 561 JSVM_Value result = nullptr; 562 switch (infoType) { 563 case BYTE_LENGTHE: 564 // Return the length of DataView. 565 JSVM_Value len; 566 OH_JSVM_CreateInt32(env, byteLength, &len); 567 result = len; 568 if (status != JSVM_OK) { 569 OH_LOG_ERROR(LOG_APP, "JSVM GetDataViewInfo fail"); 570 } else { 571 OH_LOG_INFO(LOG_APP, "JSVM GetDataViewInfo success, byteLength: %{public}d", byteLength); 572 } 573 break; 574 case ARRAY_BUFFERE: 575 // Check whether data in Info of DataView is an ArrayBuffer object. 576 bool isArrayBuffer; 577 OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer); 578 JSVM_Value isArray; 579 OH_JSVM_GetBoolean(env, isArrayBuffer, &isArray); 580 result = isArray; 581 if (status != JSVM_OK) { 582 OH_LOG_ERROR(LOG_APP, "JSVM GetDataViewInfo fail"); 583 } else { 584 OH_LOG_INFO(LOG_APP, "JSVM GetDataViewInfo success, isArrayBuffer: %{public}d", isArrayBuffer); 585 } 586 break; 587 case BYTE_OFFSET: 588 // Return the offset of DataView. 589 JSVM_Value offset; 590 OH_JSVM_CreateInt32(env, byteOffset, &offset); 591 result = offset; 592 if (status != JSVM_OK) { 593 OH_LOG_ERROR(LOG_APP, "JSVM GetDataViewInfo fail"); 594 } else { 595 OH_LOG_INFO(LOG_APP, "JSVM GetDataViewInfo success, byteOffset: %{public}d", byteOffset); 596 } 597 break; 598 default: 599 break; 600 } 601 return result; 602} 603// Register the GetDataViewInfo callback. 604static JSVM_CallbackStruct param[] = { 605 {.data = nullptr, .callback = GetDataViewInfo}, 606}; 607static JSVM_CallbackStruct *method = param; 608// Set a property descriptor named getDataViewInfo and associate it with a callback. This allows the GetDataViewInfo callback to be called from JS. 609static JSVM_PropertyDescriptor descriptor[] = { 610 {"getDataViewInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 611}; 612// Call the C++ code from JS. 613const char *srcCallNative = R"JS( 614// Byte length. 615getDataViewInfo(new DataView(new Int8Array([2,5]).buffer), 0); 616// Check whether the data is an ArrayBuffer object. 617let data = 'a'; 618let isarraybuffer = 1; 619getDataViewInfo(data, isarraybuffer); 620// Check whether the data is an ArrayBuffer object. 621data = new DataView(new Int8Array([2,5,3]).buffer); 622isarraybuffer = 1; 623getDataViewInfo(data, isarraybuffer); 624// byte_offset 625data = new DataView(new Int8Array([2,5,3]).buffer); 626isarraybuffer = 2; 627getDataViewInfo(data, isarraybuffer); 628)JS"; 629``` 630Expected result: 631``` 632JSVM GetDataViewInfo success, byteLength: 2 633JSVM GetDataViewInfo fail 634JSVM GetDataViewInfo success, isArrayBuffer: 1 635JSVM GetDataViewInfo success, byteOffset: 0 636``` 637### OH_JSVM_IsArray 638 639Use **OH_JSVM_IsArray** to check whether a JS object is an array. 640 641CPP code: 642 643```cpp 644// hello.cpp 645#include "napi/native_api.h" 646#include "ark_runtime/jsvm.h" 647#include <hilog/log.h> 648// Define OH_JSVM_IsArray. 649static JSVM_Value IsArray(JSVM_Env env, JSVM_CallbackInfo info) 650{ 651 size_t argc = 1; 652 JSVM_Value args[1] = {nullptr}; 653 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 654 bool result = false; 655 JSVM_Status status = OH_JSVM_IsArray(env, args[0], &result); 656 JSVM_Value returnValue = nullptr; 657 OH_JSVM_GetBoolean(env, result, &returnValue); 658 if (status != JSVM_OK) { 659 OH_LOG_ERROR(LOG_APP, "JSVM IsArray fail"); 660 } else { 661 OH_LOG_INFO(LOG_APP, "JSVM IsArray success, IsArray: %{public}d", result); 662 } 663 return returnValue; 664} 665// Register the IsArray callback. 666static JSVM_CallbackStruct param[] = { 667 {.data = nullptr, .callback = IsArray}, 668}; 669static JSVM_CallbackStruct *method = param; 670// Set a property descriptor named isArray and associate it with a callback. This allows the IsArray callback to be called from JS. 671static JSVM_PropertyDescriptor descriptor[] = { 672 {"isArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 673}; 674// Call the C++ code from JS. 675const char *srcCallNative = R"JS( 676let data = [1, 2, 3, 4, 5]; 677isArray(data); 678)JS"; 679``` 680Expected result: 681``` 682JSVM IsArray success, IsArray: 1 683``` 684### OH_JSVM_SetElement 685 686Use **OH_JSVM_SetElement** to set an element at the specified index for a JS object. 687 688CPP code: 689 690```cpp 691// hello.cpp 692#include "napi/native_api.h" 693#include "ark_runtime/jsvm.h" 694#include <hilog/log.h> 695// Define OH_JSVM_SetElement. 696static int DIFF_VALUE_THREE = 3; 697static JSVM_Value SetElement(JSVM_Env env, JSVM_CallbackInfo info) { 698 size_t argc = DIFF_VALUE_THREE; 699 JSVM_Value args[3] = {nullptr}; 700 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 701 int32_t index = 0; 702 OH_JSVM_GetValueInt32(env, args[1], &index); 703 JSVM_Status status = OH_JSVM_SetElement(env, args[0], index, args[2]); 704 if (status != JSVM_OK) { 705 OH_LOG_ERROR(LOG_APP, "JSVM SetElement fail"); 706 } else { 707 OH_LOG_INFO(LOG_APP, "JSVM SetElement success"); 708 } 709 return args[0]; 710} 711// Register the SetElement callback. 712static JSVM_CallbackStruct param[] = { 713 {.data = nullptr, .callback = SetElement}, 714}; 715static JSVM_CallbackStruct *method = param; 716// Set a property descriptor named setElement and associate it with a callback. This allows the SetElement callback to be called from JS. 717static JSVM_PropertyDescriptor descriptor[] = { 718 {"setElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 719}; 720// Call the C++ code from JS. 721const char *srcCallNative = R"JS( 722setElement(3); 723)JS"; 724``` 725Expected result: 726``` 727JSVM SetElement success 728``` 729### OH_JSVM_GetElement 730 731Use **OH_JSVM_GetElement** to obtain the element at the specified index of a JS object. 732 733CPP code: 734 735```cpp 736// hello.cpp 737#include "napi/native_api.h" 738#include "ark_runtime/jsvm.h" 739#include <hilog/log.h> 740// Define OH_JSVM_GetElement. 741static JSVM_Value GetElement(JSVM_Env env, JSVM_CallbackInfo info) { 742 // Obtain the two parameters passed from JS. 743 size_t argc = 2; 744 JSVM_Value args[2] = {nullptr}; 745 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 746 // Obtain the index value of the element. 747 uint32_t index; 748 OH_JSVM_GetValueUint32(env, args[1], &index); 749 // Obtain the element value at the index and store it in result. 750 JSVM_Value result = nullptr; 751 JSVM_Status status = OH_JSVM_GetElement(env, args[0], index, &result); 752 if (status != JSVM_OK) { 753 OH_LOG_ERROR(LOG_APP, "JSVM GetElement fail"); 754 } else { 755 OH_LOG_INFO(LOG_APP, "JSVM GetElement success"); 756 } 757 return result; 758} 759// Register the GetElement callback. 760static JSVM_CallbackStruct param[] = { 761 {.data = nullptr, .callback = GetElement}, 762}; 763static JSVM_CallbackStruct *method = param; 764// Set a property descriptor named getElement and associate it with a callback. This allows the GetElement callback to be called from JS. 765static JSVM_PropertyDescriptor descriptor[] = { 766 {"getElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 767}; 768// Call the C++ code from JS. 769const char *srcCallNative = R"JS( 770let arr = [10, 'hello', null, true]; 771getElement(arr, 3); 772)JS"; 773``` 774Expected result: 775``` 776JSVM GetElement success 777``` 778### OH_JSVM_HasElement 779 780Use **OH_JSVM_HasElement** to check whether a JS object has an element at the specified index. 781 782CPP code: 783 784```cpp 785// hello.cpp 786#include "napi/native_api.h" 787#include "ark_runtime/jsvm.h" 788#include <hilog/log.h> 789// Define OH_JSVM_HasElement. 790static JSVM_Value HasElement(JSVM_Env env, JSVM_CallbackInfo info) 791{ 792 // Obtain the two parameters passed from JS. 793 size_t argc = 2; 794 JSVM_Value args[2] = {nullptr}; 795 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 796 // Obtain the index of the element to be checked. 797 uint32_t index; 798 OH_JSVM_GetValueUint32(env, args[1], &index); 799 // Check whether the element exists based on the given index. 800 bool hasElement = true; 801 JSVM_Status status = OH_JSVM_HasElement(env, args[0], index, &hasElement); 802 // Convert the boolean value to JSVM_Value and return it. 803 JSVM_Value result = nullptr; 804 OH_JSVM_GetBoolean(env, hasElement, &result); 805 if (status != JSVM_OK) { 806 OH_LOG_ERROR(LOG_APP, "JSVM hasElement fail"); 807 } else { 808 OH_LOG_INFO(LOG_APP, "JSVM hasElement: %{public}d", hasElement); 809 } 810 return result; 811} 812// Register the HasElement callback. 813static JSVM_CallbackStruct param[] = { 814 {.data = nullptr, .callback = HasElement}, 815}; 816static JSVM_CallbackStruct *method = param; 817// Set a property descriptor named hasElement and associate it with a callback. This allows the HasElement callback to be called from JS. 818static JSVM_PropertyDescriptor descriptor[] = { 819 {"hasElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 820}; 821// Call the C++ code from JS. 822const char *srcCallNative = R"JS( 823let arr = [10, 'hello', null, true]; 824hasElement(arr, 0); 825hasElement(arr, 4); 826)JS"; 827``` 828Expected result: 829``` 830JSVM hasElement: 1 831JSVM hasElement: 0 832``` 833### OH_JSVM_DeleteElement 834 835Use **OH_JSVM_DeleteElement** to delete the element at the specified index from a JS object. 836 837CPP code: 838 839```cpp 840// hello.cpp 841#include "napi/native_api.h" 842#include "ark_runtime/jsvm.h" 843#include <hilog/log.h> 844// Define OH_JSVM_DeleteElement. 845static JSVM_Value DeleteElement(JSVM_Env env, JSVM_CallbackInfo info) { 846 // Obtain the two parameters passed from JS. 847 size_t argc = 2; 848 JSVM_Value args[2] = {nullptr}; 849 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 850 // Obtain the index of the element to delete. 851 uint32_t index; 852 OH_JSVM_GetValueUint32(env, args[1], &index); 853 // Delete the element at the specified index. 854 bool deleted = true; 855 JSVM_Status status = OH_JSVM_DeleteElement(env, args[0], index, &deleted); 856 // Convert the boolean value to JSVM_Value and return it. 857 JSVM_Value result = nullptr; 858 OH_JSVM_GetBoolean(env, deleted, &result); 859 if (status != JSVM_OK) { 860 OH_LOG_ERROR(LOG_APP, "JSVM DeleteElement fail"); 861 } else { 862 OH_LOG_INFO(LOG_APP, "JSVM DeleteElement: %{public}d", deleted); 863 } 864 return result; 865} 866// Register the DeleteElement callback. 867static JSVM_CallbackStruct param[] = { 868 {.data = nullptr, .callback = DeleteElement}, 869}; 870static JSVM_CallbackStruct *method = param; 871// Set a property descriptor named deleteElement and associate it with a callback. This allows the DeleteElement callback to be called from JS. 872static JSVM_PropertyDescriptor descriptor[] = { 873 {"deleteElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 874}; 875// Call the C++ code from JS. 876const char *srcCallNative = R"JS( 877let arr = [10, 'hello', null, true]; 878deleteElement(arr, 0); 879)JS"; 880``` 881Expected result: 882``` 883JSVM DeleteElement: 1 884``` 885### OH_JSVM_IsDataview 886 887Use **OH_JSVM_IsDataview** to check whether a JS object is a **DataView** object. 888 889CPP code: 890 891```cpp 892// hello.cpp 893#include "napi/native_api.h" 894#include "ark_runtime/jsvm.h" 895#include <hilog/log.h> 896// Define OH_JSVM_IsDataview. 897static JSVM_Value IsDataView(JSVM_Env env, JSVM_CallbackInfo info) { 898 size_t argc = 1; 899 JSVM_Value args[1] = {nullptr}; 900 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 901 // Call OH_JSVM_IsDataview to check whether the input parameter is a DataView object. 902 bool result = false; 903 JSVM_Status status = OH_JSVM_IsDataview(env, args[0], &result); 904 JSVM_Value isDateView = nullptr; 905 OH_JSVM_GetBoolean(env, result, &isDateView); 906 if (status != JSVM_OK) { 907 OH_LOG_ERROR(LOG_APP, "JSVM IsDataView fail"); 908 } else { 909 OH_LOG_INFO(LOG_APP, "JSVM IsDataView: %{public}d", result); 910 } 911 return isDateView; 912} 913// Register the IsDataView callback. 914static JSVM_CallbackStruct param[] = { 915 {.data = nullptr, .callback = IsDataView}, 916}; 917static JSVM_CallbackStruct *method = param; 918// Set a property descriptor named isDataView and associate it with a callback. This allows the IsDataView callback to be called from JS. 919static JSVM_PropertyDescriptor descriptor[] = { 920 {"isDataView", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 921}; 922// Call the C++ code from JS. 923const char *srcCallNative = R"JS( 924let buffer = new ArrayBuffer(16); 925let dataView = new DataView(buffer); 926isDataView(dataView); 927)JS"; 928``` 929Expected result: 930``` 931JSVM IsDataView: 1 932``` 933### OH_JSVM_IsTypedarray 934 935Use **OH_JSVM_IsTypedarray** to check whether a JS object is a **TypedArray** object. 936 937CPP code: 938 939```cpp 940// hello.cpp 941#include "napi/native_api.h" 942#include "ark_runtime/jsvm.h" 943#include <hilog/log.h> 944// Define OH_JSVM_IsTypedarray. 945static JSVM_Value IsTypedarray(JSVM_Env env, JSVM_CallbackInfo info) { 946 size_t argc = 1; 947 JSVM_Value args[1] = {nullptr}; 948 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 949 bool result = false; 950 JSVM_Status status = OH_JSVM_IsTypedarray(env, args[0], &result); 951 JSVM_Value isTypedArray = nullptr; 952 OH_JSVM_GetBoolean(env, result, &isTypedArray); 953 if (status != JSVM_OK) { 954 OH_LOG_ERROR(LOG_APP, "JSVM IsTypedarray fail"); 955 } else { 956 OH_LOG_INFO(LOG_APP, "JSVM IsTypedarray: %{public}d", result); 957 } 958 return isTypedArray; 959} 960// Register the IsTypedarray callback. 961static JSVM_CallbackStruct param[] = { 962 {.data = nullptr, .callback = IsTypedarray}, 963}; 964static JSVM_CallbackStruct *method = param; 965// Set a property descriptor named isTypedarray and associate it with a callback. This allows the IsTypedarray callback to be called from JS. 966static JSVM_PropertyDescriptor descriptor[] = { 967 {"isTypedarray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 968}; 969// Call the C++ code from JS. 970const char *srcCallNative = R"JS( 971isTypedarray(new Uint16Array([1, 2, 3, 4])); 972)JS"; 973``` 974Expected result: 975``` 976JSVM IsTypedarray: 1 977``` 978