1# Creating Basic Data Types Using JSVM-API 2 3## Introduction 4 5In JavaScript (JS), the Integer type represents a number without a decimal point, and the Double type represents a number with a fractional part. Due to the limitation of the value storage mode of JS, very large or very small numbers cannot be accurately represented. In this case, you can use JSVM-API to represent large numbers in BigInt format. 6 7## Basic Concepts 8 9Before using JSVM-API to create and obtain numbers, you need to understand the following concepts: 10 11- Number type<br>When using JSVM-API, you may need to convert values of number types between C and JS. When converting the data, pay attention to the data range, signedness (signed or unsigned), and precision (single or double precision). 12- Error handling<br>You also need to use JSVM-API to capture and handle errors that may occur during the conversion. For example, when an integer is created, you may need to capture and handle memory allocation failures or other runtime errors. 13- Interaction between JS and JSVM-API<br>During the development, you need to consider the interaction between JS and JSVM-API, including how to pass the data of the number type and return the correct value. 14 15## Available APIs 16 17| API | Description | 18| --------------------- | -----------------------------------------------| 19| OH_JSVM_GetValueUint32 | Obtains the C Uint32 primitive equivalent of the given JS number. | 20| OH_JSVM_GetValueInt32 | Obtains the C Int32 primitive equivalent of the given JS number. | 21| OH_JSVM_GetValueInt64 | Obtains the C Int64 primitive equivalent of the given JS number. | 22| OH_JSVM_GetValueDouble | Obtains the C Double primitive equivalent of the given JS number. | 23| OH_JSVM_CreateInt32 | Creates a JS number object from a C Int32_t object. | 24| OH_JSVM_CreateUint32 | Creates a JS number object from a C Uint32_t object.| 25| OH_JSVM_CreateInt64 | Creates a JS number object from a C Int64_t object. | 26| OH_JSVM_CreateDouble | Creates a JS number object from a C Double object. | 27 28## Example 29 30If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ and ArkTS code involved in the APIs for manipulating basic data types. 31 32### OH_JSVM_GetValueUint32 33 34Use **OH_JSVM_GetValueUint32** to obtain a 32-bit unsigned integer from a JS number. 35 36CPP code: 37 38```cpp 39// hello.cpp 40#include "napi/native_api.h" 41#include "ark_runtime/jsvm.h" 42#include <hilog/log.h> 43// Register the GetValueUint32 callback. 44static JSVM_CallbackStruct param[] = { 45 {.data = nullptr, .callback = GetValueUint32}, 46}; 47static JSVM_CallbackStruct *method = param; 48// Set a property descriptor named getValueUint and associate it with a callback. This allows the GetValueUint callback to be called from JS. 49static JSVM_PropertyDescriptor descriptor[] = { 50 {"getValueUint32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 51}; 52// Define OH_JSVM_GetValueUint32. 53static JSVM_Value GetValueUint32(JSVM_Env env, JSVM_CallbackInfo info) 54{ 55 // Obtain the parameter of the Number type. 56 size_t argc = 1; 57 JSVM_Value argv[1] = {nullptr}; 58 // Parse the input parameter. 59 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 60 uint32_t number = 0; 61 // Obtain a 32-bit unsigned integer from the input parameter. 62 JSVM_Status status = OH_JSVM_GetValueUint32(env, argv[0], &number); 63 if (status != JSVM_OK) { 64 OH_LOG_ERROR(LOG_APP, "JSVM GetValueUint32 fail"); 65 } else { 66 OH_LOG_INFO(LOG_APP, "JSVM GetValueUint32 success: %{public}d", number); 67 } 68 return argv[0]; 69} 70``` 71 72ArkTS code: 73 74```ts 75import hilog from "@ohos.hilog" 76// Import the native APIs. 77import napitest from "libentry.so" 78let num = 123; 79let script: string = ` 80 function testGetValueUint32(num) { 81 return getValueUint32(num); 82 } 83 testGetValueUint32(${num}) 84 `; 85try { 86 let result = napitest.runJsVm(script); 87 hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetValueUint32: %{public}s', result); 88} catch (error) { 89 hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetValueUint32 error: %{public}s', error.message); 90} 91``` 92 93### OH_JSVM_GetValueInt32 94 95Use **OH_JSVM_GetValueInt32** to obtain a C int32 value from a JS number. 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// Register the GetValueInt32 callback. 105static JSVM_CallbackStruct param[] = { 106 {.data = nullptr, .callback = GetValueInt32}, 107}; 108static JSVM_CallbackStruct *method = param; 109// Set a property descriptor named getValueInt32 and associate it with a callback. This allows the GetValueInt32 callback to be called from JS. 110static JSVM_PropertyDescriptor descriptor[] = { 111 {"getValueInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 112}; 113// Define OH_JSVM_GetValueInt32. 114static JSVM_Value GetValueInt32(JSVM_Env env, JSVM_CallbackInfo info) 115{ 116 size_t argc = 1; 117 JSVM_Value args[1] = {nullptr}; 118 int32_t result32 = 0; 119 // Parse the input parameter. 120 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 121 // Convert the input parameter into a C int32 value. 122 JSVM_Status status = OH_JSVM_GetValueInt32(env, args[0], &result32); 123 if (status != JSVM_OK) { 124 return nullptr; 125 } 126 if (status != JSVM_OK) { 127 OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt32 fail"); 128 } else { 129 OH_LOG_INFO(LOG_APP, "JSVM GetValueInt32 success: %{public}d", result32); 130 } 131 return args[0]; 132} 133``` 134 135ArkTS code: 136 137```ts 138import hilog from "@ohos.hilog" 139// Import the native APIs. 140import napitest from "libentry.so" 141let num = -123; 142let script: string = ` 143 function testGetValueInt32(num) { 144 return getValueInt32(num); 145 } 146 testGetValueInt32(${num}) 147 `; 148try { 149 let result = napitest.runJsVm(script); 150 hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetValueInt32: %{public}s', result); 151} catch (error) { 152 hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetValueInt32 error: %{public}s', error.message); 153} 154``` 155 156### OH_JSVM_GetValueInt64 157 158Use **OH_JSVM_GetValueInt64** to obtain a C int64 value from a JS value. 159 160CPP code: 161 162```cpp 163// hello.cpp 164#include "napi/native_api.h" 165#include "ark_runtime/jsvm.h" 166#include <hilog/log.h> 167// Register the GetValueInt64 callback. 168static JSVM_CallbackStruct param[] = { 169 {.data = nullptr, .callback = GetValueInt64}, 170}; 171static JSVM_CallbackStruct *method = param; 172// Set a property descriptor named getValueInt64 and associate it with a callback. This allows the GetValueInt64 callback to be called from JS. 173static JSVM_PropertyDescriptor descriptor[] = { 174 {"getValueInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 175}; 176// Define OH_JSVM_GetValueInt64. 177static JSVM_Value GetValueInt64(JSVM_Env env, JSVM_CallbackInfo info) 178{ 179 size_t argc = 1; 180 JSVM_Value args[1] = {nullptr}; 181 int64_t result64 = 0; 182 // Parse the input parameter. 183 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 184 // Convert the input parameter into a C int64 value. 185 JSVM_Status status = OH_JSVM_GetValueInt64(env, args[0], &result64); 186 if (status != JSVM_OK) { 187 OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt64 fail"); 188 } else { 189 OH_LOG_INFO(LOG_APP, "JSVM GetValueInt64 success: %{public}d", result64); 190 } 191 return args[0]; 192} 193``` 194 195ArkTS code: 196 197```ts 198import hilog from "@ohos.hilog" 199// Import the native APIs. 200import napitest from "libentry.so" 201let num = -110; 202let script: string = ` 203 function testGetValueInt64(num) { 204 return getValueInt64(num); 205 } 206 testGetValueInt64(${num}) 207 `; 208try { 209 let result = napitest.runJsVm(script); 210 hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetValueInt64: %{public}s', result); 211} catch (error) { 212 hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetValueInt64 error: %{public}s', error.message); 213} 214``` 215 216### OH_JSVM_GetValueDouble 217 218Use **OH_JSVM_GetValueDouble** to obtain a C double value from a JS value. 219 220CPP code: 221 222```cpp 223// hello.cpp 224#include "napi/native_api.h" 225#include "ark_runtime/jsvm.h" 226#include <hilog/log.h> 227// Register the GetDouble callback. 228static JSVM_CallbackStruct param[] = { 229 {.data = nullptr, .callback = GetDouble}, 230}; 231static JSVM_CallbackStruct *method = param; 232// Set a property descriptor named getDouble and associate it with a callback. This allows the GetDouble callback to be called from JS. 233static JSVM_PropertyDescriptor descriptor[] = { 234 {"getDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 235}; 236// Define OH_JSVM_GetValueDouble. 237static JSVM_Value GetDouble(JSVM_Env env, JSVM_CallbackInfo info) 238{ 239 size_t argc = 1; 240 JSVM_Value args[1] = {nullptr}; 241 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 242 double value; 243 JSVM_Status status = OH_JSVM_GetValueDouble(env, args[0], &value); 244 if (status != JSVM_OK) { 245 OH_LOG_ERROR(LOG_APP, "JSVM GetDouble fail"); 246 } else { 247 OH_LOG_INFO(LOG_APP, "JSVM GetDouble success: %{public}f", value); 248 } 249 return args[0]; 250} 251``` 252 253ArkTS code: 254 255```ts 256import hilog from "@ohos.hilog" 257// Import the native APIs. 258import napitest from "libentry.so" 259let num = -110.0456; 260let script: string = ` 261 function testGetDouble(num) { 262 return getDouble(num); 263 } 264 testGetDouble(${num}) 265 `; 266try { 267 let result = napitest.runJsVm(script); 268 hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetDouble: %{public}s', result); 269} catch (error) { 270 hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetDouble error: %{public}s', error.message); 271} 272``` 273 274### OH_JSVM_CreateInt32 275 276Use **OH_JSVM_CreateInt32** to create a JS number from a 32-bit signed integer. 277 278CPP code: 279 280```cpp 281// hello.cpp 282#include "napi/native_api.h" 283#include "ark_runtime/jsvm.h" 284#include <hilog/log.h> 285// Register the CreateInt32 callback. 286static JSVM_CallbackStruct param[] = { 287 {.data = nullptr, .callback = CreateInt32}, 288}; 289static JSVM_CallbackStruct *method = param; 290// Set a property descriptor named createInt32 and associate it with a callback. This allows the CreateInt32 callback to be called from JS. 291static JSVM_PropertyDescriptor descriptor[] = { 292 {"createInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 293}; 294// Define OH_JSVM_CreateInt32. 295static JSVM_Value CreateInt32(JSVM_Env env, JSVM_CallbackInfo info) 296{ 297 // int32_t represents a 32-bit signed integer, ranging from -2^31 to 2^31 - 1, that is, -2147483648 to 2147483647. 298 int32_t value = -20; 299 // Create a JS Int32 number. 300 JSVM_Value result = nullptr; 301 JSVM_Status status = OH_JSVM_CreateInt32(env, value, &result); 302 if (status != JSVM_OK) { 303 OH_LOG_ERROR(LOG_APP, "JSVM CreateInt32 fail"); 304 } else { 305 int32_t number = 0; 306 OH_JSVM_GetValueInt32(env, result, &number); 307 OH_LOG_INFO(LOG_APP, "JSVM CreateInt32 success: %{public}d", number); 308 } 309 return result; 310} 311``` 312 313ArkTS code: 314 315```ts 316import hilog from "@ohos.hilog" 317// Import the native APIs. 318import napitest from "libentry.so" 319let script: string = ` 320 function testCreateInt32() { 321 return createInt32(); 322 } 323 testCreateInt32() 324 `; 325try { 326 let result = napitest.runJsVm(script); 327 hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateInt32: %{public}s', result); 328} catch (error) { 329 hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateInt32 error: %{public}s', error.message); 330} 331``` 332 333### OH_JSVM_CreateUint32 334 335Use **OH_JSVM_CreateUint32** to create a JS number from a 32-bit unsigned integer. 336 337CPP code: 338 339```cpp 340// hello.cpp 341#include "napi/native_api.h" 342#include "ark_runtime/jsvm.h" 343#include <hilog/log.h> 344// Register the CreateUInt32 callback. 345static JSVM_CallbackStruct param[] = { 346 {.data = nullptr, .callback = CreateUInt32}, 347}; 348static JSVM_CallbackStruct *method = param; 349// Set a property descriptor named createUInt32 and associate it with a callback. This allows the CreateUInt32 callback to be called from JS. 350static JSVM_PropertyDescriptor descriptor[] = { 351 {"createUInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 352}; 353// Define OH_JSVM_CreateUint32. 354static JSVM_Value CreateUInt32(JSVM_Env env, JSVM_CallbackInfo info) 355{ 356 357 // If the uint32_t type is used to represent -26, overflow occurs. Modulo operation is performed on the result to convert the binary complement of the negative number to a positive number. That is, 4294967270 will be returned. 358 // uint32_t represents a 32-bit unsigned integer, ranging from 0 to 2^32 - 1, that is, 0 to 4294967295. 359 uint32_t value = 26; 360 // Create a JS Uint32 number. 361 JSVM_Value result = nullptr; 362 JSVM_Status status = OH_JSVM_CreateUint32(env, value, &result); 363 if (status != JSVM_OK) { 364 OH_LOG_ERROR(LOG_APP, "JSVM CreateUInt32 fail"); 365 } else { 366 uint32_t number = 0; 367 OH_JSVM_GetValueUint32(env, result, &number); 368 OH_LOG_INFO(LOG_APP, "JSVM CreateUInt32 success: %{public}d", number); 369 } 370 return result; 371} 372``` 373 374ArkTS code: 375 376```ts 377import hilog from "@ohos.hilog" 378// Import the native APIs. 379import napitest from "libentry.so" 380let script: string = ` 381 function testCreateUInt32() { 382 return createUInt32(); 383 } 384 testCreateUInt32() 385 `; 386try { 387 let result = napitest.runJsVm(script); 388 hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateUInt32: %{public}s', result); 389} catch (error) { 390 hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateUInt32 error: %{public}s', error.message); 391} 392``` 393 394### OH_JSVM_CreateInt64 395 396Use **OH_JSVM_CreateInt64** to create a JS number from a 64-bit signed integer. 397 398CPP code: 399 400```cpp 401// hello.cpp 402#include "napi/native_api.h" 403#include "ark_runtime/jsvm.h" 404#include <hilog/log.h> 405// Register the CreateInt64 callback. 406static JSVM_CallbackStruct param[] = { 407 {.data = nullptr, .callback = CreateInt64}, 408}; 409static JSVM_CallbackStruct *method = param; 410// Set a property descriptor named createInt64 and associate it with a callback. This allows the CreateInt64 callback to be called from JS. 411static JSVM_PropertyDescriptor descriptor[] = { 412 {"createInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 413}; 414// Define OH_JSVM_CreateInt64. 415static JSVM_Value CreateInt64(JSVM_Env env, JSVM_CallbackInfo info) 416{ 417 // int64 represents a 64-bit signed integer, ranging from -2^63 to 2^63 - 1, that is, -9223372036854775808 to 9223372036854775807. 418 int64_t value = 2147483648; 419 // Create a JS Int64 number. 420 JSVM_Value result = nullptr; 421 JSVM_Status status = OH_JSVM_CreateInt64(env, value, &result); 422 if (status != JSVM_OK) { 423 OH_LOG_ERROR(LOG_APP, "JSVM CreateInt64 fail"); 424 } else { 425 int64_t number = 0; 426 OH_JSVM_GetValueInt64(env, result, &number); 427 OH_LOG_INFO(LOG_APP, "JSVM CreateInt64 success: %{public}ld", value); 428 } 429 return result; 430} 431``` 432 433ArkTS code: 434 435```ts 436import hilog from "@ohos.hilog" 437// Import the native APIs. 438import napitest from "libentry.so" 439let script: string = ` 440 function testCreateInt64() { 441 return createInt64(); 442 } 443 testCreateInt64() 444 `; 445try { 446 let result = napitest.runJsVm(script); 447 hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateInt64: %{public}s', result); 448} catch (error) { 449 hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateInt64 error: %{public}s', error.message); 450} 451``` 452 453### OH_JSVM_CreateDouble 454 455Use **OH_JSVM_CreateDouble** to create a JS number from a double-precision floating-point number. 456 457CPP code: 458 459```cpp 460// hello.cpp 461#include "napi/native_api.h" 462#include "ark_runtime/jsvm.h" 463#include <hilog/log.h> 464// Register the CreateDouble callback. 465static JSVM_CallbackStruct param[] = { 466 {.data = nullptr, .callback = CreateDouble}, 467}; 468static JSVM_CallbackStruct *method = param; 469// Set a property descriptor named createDouble and associate it with a callback. This allows the CreateDouble callback to be called from JS. 470static JSVM_PropertyDescriptor descriptor[] = { 471 {"createDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 472}; 473// Define OH_JSVM_CreateDouble. 474static JSVM_Value CreateDouble(JSVM_Env env, JSVM_CallbackInfo info) 475{ 476 double value = 1.234; 477 // Create a JS double number. 478 JSVM_Value result = nullptr; 479 JSVM_Status status = OH_JSVM_CreateDouble(env, value, &result); 480 if (status != JSVM_OK) { 481 OH_LOG_ERROR(LOG_APP, "JSVM CreateDouble fail"); 482 } else { 483 double number = 0; 484 OH_JSVM_GetValueDouble(env, result, &number); 485 OH_LOG_INFO(LOG_APP, "JSVM CreateDouble success: %{public}f", number); 486 } 487 return result; 488} 489``` 490 491ArkTS code: 492 493```ts 494import hilog from "@ohos.hilog" 495// Import the native APIs. 496import napitest from "libentry.so" 497let script: string = ` 498 function testCreateDouble() { 499 return createDouble(); 500 } 501 testCreateDouble() 502 `; 503try { 504 let result = napitest.runJsVm(script); 505 hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateDouble: %{public}s', result); 506} catch (error) { 507 hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateDouble error: %{public}s', error.message); 508} 509``` 510