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