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++ code involved in 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 44// Define OH_JSVM_GetValueUint32. 45static JSVM_Value GetValueUint32(JSVM_Env env, JSVM_CallbackInfo info) 46{ 47 // Obtain the parameter of the Number type. 48 size_t argc = 1; 49 JSVM_Value argv[1] = {nullptr}; 50 // Parse the input parameters. 51 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 52 uint32_t number = 0; 53 // Obtain a 32-bit unsigned integer. 54 JSVM_Status status = OH_JSVM_GetValueUint32(env, argv[0], &number); 55 if (status != JSVM_OK) { 56 OH_LOG_ERROR(LOG_APP, "JSVM GetValueUint32 fail"); 57 } else { 58 OH_LOG_INFO(LOG_APP, "JSVM GetValueUint32 success: %{public}u", number); 59 } 60 return argv[0]; 61} 62 63// Register the GetValueUint32 callback. 64static JSVM_CallbackStruct param[] = { 65 {.data = nullptr, .callback = GetValueUint32}, 66}; 67static JSVM_CallbackStruct *method = param; 68 69// Set a property descriptor named getValueUint and associate it with a callback. This allows the GetValueUint callback to be called from JS. 70static JSVM_PropertyDescriptor descriptor[] = { 71 {"getValueUint32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 72}; 73 74// Call the C++ code from JS. 75const char* srcCallNative = R"JS(getValueUint32(123))JS"; 76``` 77 78**Expected output** 79 80``` 81JSVM GetValueUint32 success: 123 82``` 83 84### OH_JSVM_GetValueInt32 85 86Use **OH_JSVM_GetValueInt32** to obtain a C int32 value from a JS value. 87 88CPP code: 89 90```cpp 91// hello.cpp 92#include "napi/native_api.h" 93#include "ark_runtime/jsvm.h" 94#include <hilog/log.h> 95 96// Define OH_JSVM_GetValueInt32. 97static JSVM_Value GetValueInt32(JSVM_Env env, JSVM_CallbackInfo info) 98{ 99 size_t argc = 1; 100 JSVM_Value args[1] = {nullptr}; 101 int32_t result32 = 0; 102 // Parse the input parameters. 103 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 104 // Convert the parameter into a C int32 value. 105 JSVM_Status status = OH_JSVM_GetValueInt32(env, args[0], &result32); 106 if (status != JSVM_OK) { 107 return nullptr; 108 } 109 if (status != JSVM_OK) { 110 OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt32 fail"); 111 } else { 112 OH_LOG_INFO(LOG_APP, "JSVM GetValueInt32 success: %{public}d", result32); 113 } 114 return args[0]; 115} 116 117// Register the GetValueInt32 callback. 118static JSVM_CallbackStruct param[] = { 119 {.data = nullptr, .callback = GetValueInt32}, 120}; 121static JSVM_CallbackStruct *method = param; 122// Set a property descriptor named getValueInt32 and associate it with a callback. This allows the GetValueInt32 callback to be called from JS. 123static JSVM_PropertyDescriptor descriptor[] = { 124 {"getValueInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 125}; 126 127// Call the C++ code from JS. 128const char* srcCallNative = R"JS(getValueInt32(-123))JS"; 129``` 130 131**Expected output** 132 133``` 134JSVM GetValueInt32 success: -123 135``` 136 137### OH_JSVM_GetValueInt64 138 139Use **OH_JSVM_GetValueInt64** to obtain a C int64 value from a JS value. 140 141CPP code: 142 143```cpp 144// hello.cpp 145#include "napi/native_api.h" 146#include "ark_runtime/jsvm.h" 147#include <hilog/log.h> 148 149// Define OH_JSVM_GetValueInt64. 150static JSVM_Value GetValueInt64(JSVM_Env env, JSVM_CallbackInfo info) 151{ 152 size_t argc = 1; 153 JSVM_Value args[1] = {nullptr}; 154 int64_t result64 = 0; 155 // Parse the input parameters. 156 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 157 // Convert the input parameters into C int64 values. 158 JSVM_Status status = OH_JSVM_GetValueInt64(env, args[0], &result64); 159 if (status != JSVM_OK) { 160 OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt64 fail"); 161 } else { 162 OH_LOG_INFO(LOG_APP, "JSVM GetValueInt64 success: %{public}d", result64); 163 } 164 return args[0]; 165} 166 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 177// Call the C++ code from JS. 178const char* srcCallNative = R"JS(getValueInt64(-123))JS"; 179``` 180 181**Expected output** 182 183``` 184JSVM GetValueInt64 success: -123 185``` 186 187### OH_JSVM_GetValueDouble 188 189Use **OH_JSVM_GetValueDouble** to obtain a C double value from a JS value. 190 191CPP code: 192 193```cpp 194// hello.cpp 195#include "napi/native_api.h" 196#include "ark_runtime/jsvm.h" 197#include <hilog/log.h> 198 199// Define OH_JSVM_GetValueDouble. 200static JSVM_Value GetDouble(JSVM_Env env, JSVM_CallbackInfo info) 201{ 202 size_t argc = 1; 203 JSVM_Value args[1] = {nullptr}; 204 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 205 double value; 206 JSVM_Status status = OH_JSVM_GetValueDouble(env, args[0], &value); 207 if (status != JSVM_OK) { 208 OH_LOG_ERROR(LOG_APP, "JSVM GetDouble fail"); 209 } else { 210 OH_LOG_INFO(LOG_APP, "JSVM GetDouble success: %{public}f", value); 211 } 212 return args[0]; 213} 214 215// Register the GetDouble callback. 216static JSVM_CallbackStruct param[] = { 217 {.data = nullptr, .callback = GetDouble}, 218}; 219static JSVM_CallbackStruct *method = param; 220// Set a property descriptor named getDouble and associate it with a callback. This allows the GetDouble callback to be called from JS. 221static JSVM_PropertyDescriptor descriptor[] = { 222 {"getDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 223}; 224 225// Call the C++ code from JS. 226const char* srcCallNative = R"JS(getDouble(-110.0456))JS"; 227``` 228 229**Expected output** 230 231``` 232JSVM GetDouble success: -110.045600 233``` 234 235### OH_JSVM_CreateInt32 236 237Use **OH_JSVM_CreateInt32** to create a JS number of the int32 type. 238 239CPP code: 240 241```cpp 242// hello.cpp 243#include "napi/native_api.h" 244#include "ark_runtime/jsvm.h" 245#include <hilog/log.h> 246 247// Define OH_JSVM_CreateInt32. 248static JSVM_Value CreateInt32(JSVM_Env env, JSVM_CallbackInfo info) 249{ 250 int32_t value = -20; 251 // Create a JS Int32 number. 252 JSVM_Value result = nullptr; 253 JSVM_Status status = OH_JSVM_CreateInt32(env, value, &result); 254 if (status != JSVM_OK) { 255 OH_LOG_ERROR(LOG_APP, "JSVM CreateInt32 fail"); 256 } else { 257 int32_t number = 0; 258 OH_JSVM_GetValueInt32(env, result, &number); 259 OH_LOG_INFO(LOG_APP, "JSVM CreateInt32 success: %{public}d", number); 260 } 261 return result; 262} 263 264// Register the CreateInt32 callback. 265static JSVM_CallbackStruct param[] = { 266 {.data = nullptr, .callback = CreateInt32}, 267}; 268static JSVM_CallbackStruct *method = param; 269// Set a property descriptor named createInt32 and associate it with a callback. This allows the CreateInt32 callback to be called from JS. 270static JSVM_PropertyDescriptor descriptor[] = { 271 {"createInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 272}; 273 274// Call the C++ code from JS. 275const char* srcCallNative = R"JS(createInt32())JS"; 276``` 277 278**Expected output** 279 280``` 281JSVM CreateInt32 success: -20 282``` 283 284### OH_JSVM_CreateUint32 285 286Use **OH_JSVM_CreateUint32** to create a JS number of the uint32 type. 287 288CPP code: 289 290```cpp 291// hello.cpp 292#include "napi/native_api.h" 293#include "ark_runtime/jsvm.h" 294#include <hilog/log.h> 295 296// Define OH_JSVM_CreateUint32. 297static JSVM_Value CreateUInt32(JSVM_Env env, JSVM_CallbackInfo info) 298{ 299 // 300 // 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. 301 // uint32_t represents a 32-bit unsigned integer, ranging from 0 to 2^32 - 1, that is, 0 to 4294967295. 302 // 303 uint32_t value = 26; 304 // Create a JS Uint32 number. 305 JSVM_Value result = nullptr; 306 JSVM_Status status = OH_JSVM_CreateUint32(env, value, &result); 307 if (status != JSVM_OK) { 308 OH_LOG_ERROR(LOG_APP, "JSVM CreateUInt32 fail"); 309 } else { 310 uint32_t number = 0; 311 OH_JSVM_GetValueUint32(env, result, &number); 312 OH_LOG_INFO(LOG_APP, "JSVM CreateUInt32 success: %{public}u", number); 313 } 314 return result; 315} 316 317// Register the CreateUInt32 callback. 318static JSVM_CallbackStruct param[] = { 319 {.data = nullptr, .callback = CreateUInt32}, 320}; 321static JSVM_CallbackStruct *method = param; 322// Set a property descriptor named createUInt32 and associate it with a callback. This allows the CreateUInt32 callback to be called from JS. 323static JSVM_PropertyDescriptor descriptor[] = { 324 {"createUInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 325}; 326 327// Call the C++ code from JS. 328const char* srcCallNative = R"JS(createUInt32())JS"; 329``` 330 331**Expected output** 332 333``` 334JSVM CreateUInt32 success: 26 335``` 336 337### OH_JSVM_CreateInt64 338 339Use **OH_JSVM_CreateInt64** to create a JS number of the int64 type. 340 341CPP code: 342 343```cpp 344// hello.cpp 345#include "napi/native_api.h" 346#include "ark_runtime/jsvm.h" 347#include <hilog/log.h> 348 349// Define OH_JSVM_CreateInt64. 350static JSVM_Value CreateInt64(JSVM_Env env, JSVM_CallbackInfo info) 351{ 352 // int64 represents a 64-bit signed integer, ranging from -2^63 to 2^63 - 1, that is, -9223372036854775808 to 9223372036854775807. 353 // 354 int64_t value = 2147483648; 355 // Create a JS Int64 number. 356 JSVM_Value result = nullptr; 357 JSVM_Status status = OH_JSVM_CreateInt64(env, value, &result); 358 if (status != JSVM_OK) { 359 OH_LOG_ERROR(LOG_APP, "JSVM CreateInt64 fail"); 360 } else { 361 int64_t number = 0; 362 OH_JSVM_GetValueInt64(env, result, &number); 363 OH_LOG_INFO(LOG_APP, "JSVM CreateInt64 success: %{public}ld", number); 364 } 365 return result; 366} 367 368// Register the CreateInt64 callback. 369static JSVM_CallbackStruct param[] = { 370 {.data = nullptr, .callback = CreateInt64}, 371}; 372static JSVM_CallbackStruct *method = param; 373// Set a property descriptor named createInt64 and associate it with a callback. This allows the CreateInt64 callback to be called from JS. 374static JSVM_PropertyDescriptor descriptor[] = { 375 {"createInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 376}; 377 378// Call the C++ code from JS. 379const char* srcCallNative = R"JS(createInt64())JS"; 380``` 381 382**Expected output** 383 384``` 385JSVM CreateInt64 success: 2147483648 386``` 387 388### OH_JSVM_CreateDouble 389 390Use **OH_JSVM_CreateDouble** to create a JS number of the double type. 391 392CPP code: 393 394```cpp 395// hello.cpp 396#include "napi/native_api.h" 397#include "ark_runtime/jsvm.h" 398#include <hilog/log.h> 399// register a CreateDouble callback. 400 401// Define OH_JSVM_CreateDouble. 402static JSVM_Value CreateDouble(JSVM_Env env, JSVM_CallbackInfo info) 403{ 404 double value = 1.234; 405 // Create a JS double number. 406 JSVM_Value result = nullptr; 407 JSVM_Status status = OH_JSVM_CreateDouble(env, value, &result); 408 if (status != JSVM_OK) { 409 OH_LOG_ERROR(LOG_APP, "JSVM CreateDouble fail"); 410 } else { 411 double number = 0; 412 OH_JSVM_GetValueDouble(env, result, &number); 413 OH_LOG_INFO(LOG_APP, "JSVM CreateDouble success: %{public}f", number); 414 } 415 return result; 416} 417 418static JSVM_CallbackStruct param[] = { 419 {.data = nullptr, .callback = CreateDouble}, 420}; 421static JSVM_CallbackStruct *method = param; 422// Set a property descriptor named createDouble and associate it with a callback. This allows the CreateDouble callback to be called from JS. 423static JSVM_PropertyDescriptor descriptor[] = { 424 {"createDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 425}; 426 427// Call the C++ code from JS. 428const char* srcCallNative = R"JS(createDouble())JS"; 429``` 430 431**Expected output** 432 433``` 434JSVM CreateDouble success: 1.234000 435``` 436