1# Working with BigInt Using JSVM-API 2 3## Introduction 4 5BigInt is a data type used to represent integers of any precision in JavaScript (JS), with values greater than the value range of the Number type. You can use JSVM-API to create, obtain, and operate JS BigInt values. 6 7## Basic Concepts 8 9Before using JSVM-API to operate BigInt values, you need to understand the following basic concepts: 10 11- BigInt: a data type used to represent integers of any precision in JS. Different from the Number type, BigInt can accurately represent very large integers without losing precision or causing overflows. 12- BigInt creation: You can use JSVM-API to create a JS BigInt object from a C **Int64** or **Uint64** value. This makes it easy to create BigInt values using C/C++. 13- BigInt operation: JSVM-API provides APIs for operating BigInt values. You can use these APIs to obtain and convert BigInt values and perform arithmetic and bitwise operations. 14 15## Available APIs 16 17| API | Description | 18| ---------------------------- | ---------------------------------------- | 19| OH_JSVM_CreateBigintInt64 | Creates a JS BigInt object from a C int64_t object.| 20| OH_JSVM_CreateBigintUint64 | Creates a JS BigInt object from a C uint64_t object.| 21| OH_JSVM_CreateBigintWords | Creates a JS BigInt object from a C uint64_t array.| 22| OH_JSVM_GetValueBigintInt64 | Obtains the C int64_t primitive equivalent of the given JS BigInt. If necessary, it truncates the value and sets **lossless** to **false**. | 23| OH_JSVM_GetValueBigintUint64 | Obtains the C uint64_t primitive equivalent of the given JS BigInt. If necessary, it truncates the value and sets **lossless** to **false**. | 24| OH_JSVM_GetValueBigintWords | Obtains the underlying data (word representation) of a given JS BigInt object. The word representation includes a sign bit, a 64-bit little-endian array, and the length of the array. If **signBit** and **words** are set to **NULL**, only **wordCount** is obtained.| 25 26## Example 27 28If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code related to BigInt operations. 29 30### OH_JSVM_GetValueBigintWords 31 32Use **OH_JSVM_GetValueBigintWords** to obtain the underlying data of a given JS BigInt object, that is, the word representation of BigInt data. 33 34CPP code: 35 36```cpp 37// hello.cpp 38#include "napi/native_api.h" 39#include "ark_runtime/jsvm.h" 40#include <hilog/log.h> 41// Define OH_JSVM_GetValueBigintWords. 42static JSVM_Value GetValueBigintWords(JSVM_Env env, JSVM_CallbackInfo info) 43 { 44 size_t argc = 1; 45 JSVM_Value args[1] = {nullptr}; 46 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 47 int signBit = 0; 48 size_t wordCount = 0; 49 uint64_t* words{nullptr}; 50 // Call OH_JSVM_GetValueBigintWords to obtain wordCount. 51 JSVM_Status status = OH_JSVM_GetValueBigintWords(env, args[0], nullptr, &wordCount, nullptr); 52 OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords wordCount:%{public}d.", wordCount); 53 words = (uint64_t*)malloc(wordCount*sizeof(uint64_t)); 54 if (words == nullptr) { 55 OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords malloc failed."); 56 return nullptr; 57 } 58 // Call OH_JSVM_GetValueBigintWords to obtain BigInt information, such as whether the value passed by signBit is a positive or negative number. 59 status = OH_JSVM_GetValueBigintWords(env, args[0], &signBit, &wordCount, words); 60 free(words); 61 words = nullptr; 62 if (status != JSVM_OK) { 63 OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords fail, status:%{public}d.", status); 64 } else { 65 OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords signBit: %{public}d.", signBit); 66 } 67 // Convert the sign bit into a value of Int type and pass it. 68 JSVM_Value returnValue = nullptr; 69 OH_JSVM_CreateInt32(env, signBit, &returnValue); 70 return returnValue; 71} 72// Register the GetValueBigintWords callback. 73static JSVM_CallbackStruct param[] = { 74 {.data = nullptr, .callback = GetValueBigintWords}, 75}; 76static JSVM_CallbackStruct *method = param; 77// Set a property descriptor named getValueBigintWords and associate it with a callback. This allows the GetValueBigintWords callback to be called from JS. 78static JSVM_PropertyDescriptor descriptor[] = { 79 {"getValueBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 80}; 81// Call the C++ code from JS. 82const char* srcCallNative = R"JS(getValueBigintWords(BigInt(5555555555555555)))JS"; 83``` 84 85**Expected output** 86```ts 87OH_JSVM_GetValueBigintWords wordCount:1. 88OH_JSVM_GetValueBigintWords signBit: 1. 89``` 90 91### OH_JSVM_CreateBigintWords 92 93Use **OH_JSVM_GetValueBigintWords** to create a JS BigInt object from a C uint64_t array. 94 95CPP code: 96 97```cpp 98// hello.cpp 99#include "napi/native_api.h" 100#include "ark_runtime/jsvm.h" 101#include <hilog/log.h> 102// Define OH_JSVM_CreateBigintWords. 103static int DIFF_VALUE_THREE = 3; 104static JSVM_Value CreateBigintWords(JSVM_Env env, JSVM_CallbackInfo info) 105{ 106 // Call OH_JSVM_CreateBigintWords to create a BigInt object. 107 int signBit = 0; 108 size_t wordCount = DIFF_VALUE_THREE; 109 uint64_t words[] = {12ULL, 34ULL, 56ULL}; 110 JSVM_Value returnValue = nullptr; 111 JSVM_Status status = OH_JSVM_CreateBigintWords(env, signBit, wordCount, words, &returnValue); 112 if (status != JSVM_OK) { 113 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintWords fail"); 114 } else { 115 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintWords success"); 116 } 117 return returnValue; 118} 119// Register the CreateBigintWords callback. 120static JSVM_CallbackStruct param[] = { 121 {.data = nullptr, .callback = CreateBigintWords}, 122}; 123static JSVM_CallbackStruct *method = param; 124// Set a property descriptor named createBigintWords and associate it with a callback. This allows the CreateBigintWords callback to be called from JS. 125static JSVM_PropertyDescriptor descriptor[] = { 126 {"createBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 127}; 128// Call the C++ code from JS. 129const char* srcCallNative = R"JS(createBigintWords())JS"; 130``` 131 132**Expected output** 133```ts 134JSVM OH_JSVM_CreateBigintWords success 135``` 136 137### OH_JSVM_CreateBigintUint64 138 139Use **OH_JSVM_CreateBigintUint64** to create a JS BigInt object from a C Uint64 object. 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// Declare the variable value of uint64_t. 149static uint64_t TEST_VALUE = 5555555555555555555; 150// Define OH_JSVM_CreateBigintUint64. 151static JSVM_Value CreateBigintUint64(JSVM_Env env, JSVM_CallbackInfo info) 152{ 153 // Convert value to the JSVM_Value type and return the value. 154 JSVM_Value returnValue = nullptr; 155 JSVM_Status status = OH_JSVM_CreateBigintUint64(env, TEST_VALUE, &returnValue); 156 if (status != JSVM_OK) { 157 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 fail"); 158 } else { 159 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 success"); 160 } 161 return returnValue; 162} 163// Define CreateBigintUint64. 164static JSVM_CallbackStruct param[] = { 165 {.data = nullptr, .callback = CreateBigintUint64}, 166}; 167static JSVM_CallbackStruct *method = param; 168// Set a property descriptor named createBigintUint64 and associate it with a callback. This allows the CreateBigintUint64 callback to be called from JS. 169static JSVM_PropertyDescriptor descriptor[] = { 170 {"createBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 171}; 172// Call the C++ code from JS. 173const char* srcCallNative = R"JS(createBigintUint64())JS"; 174``` 175 176**Expected output** 177```ts 178JSVM OH_JSVM_CreateBigintUint64 success 179 180``` 181 182### OH_JSVM_GetValueBigintUint64 183 184Use **OH_JSVM_GetValueBigintUint64** to obtain the C uint64_t primitive equivalent of the given JS BigInt object. 185 186CPP code: 187 188```cpp 189// hello.cpp 190#include "napi/native_api.h" 191#include "ark_runtime/jsvm.h" 192#include <hilog/log.h> 193// Define OH_JSVM_GetValueBigintUint64. 194static JSVM_Value GetValueBigintUint64(JSVM_Env env, JSVM_CallbackInfo info) 195{ 196 size_t argc = 1; 197 JSVM_Value args[1] = {nullptr}; 198 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 199 // Obtain the BigInt value. 200 uint64_t value = 0; 201 bool lossLess = false; 202 OH_JSVM_GetValueBigintUint64(env, args[0], &value, &lossLess); 203 // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown. 204 if (!lossLess) { 205 OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted"); 206 return nullptr; 207 } else { 208 OH_LOG_INFO(LOG_APP, "JSVM GetValueBigintUint64 success:%{public}d", lossLess); 209 } 210 JSVM_Value returnValue = nullptr; 211 OH_JSVM_CreateBigintUint64(env, value, &returnValue); 212 return returnValue; 213} 214// Register the GetValueBigintUint64 callback. 215static JSVM_CallbackStruct param[] = { 216 {.data = nullptr, .callback = GetValueBigintUint64}, 217}; 218static JSVM_CallbackStruct *method = param; 219// Set a property descriptor named getValueBigintUint64 and associate it with a callback. This allows the GetValueBigintUint64 callback to be called from JS. 220static JSVM_PropertyDescriptor descriptor[] = { 221 {"getValueBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 222}; 223// Call the C++ code from JS. 224const char* srcCallNative = R"JS(getValueBigintUint64(BigInt(5555555555555555)))JS"; 225``` 226 227**Expected output** 228```ts 229JSVM GetValueBigintUint64 success:1 230``` 231 232### OH_JSVM_CreateBigintInt64 233 234Creates a JS BigInt object from a C Uint64 object. 235 236CPP code: 237 238```cpp 239// hello.cpp 240#include "napi/native_api.h" 241#include "ark_runtime/jsvm.h" 242#include <hilog/log.h> 243// Declare the variable value of int64_t. 244static int64_t TEST_VALUE_DEMO = -5555555555555555555; 245// Define OH_JSVM_CreateBigintInt64. 246static JSVM_Value CreateBigintInt64(JSVM_Env env, JSVM_CallbackInfo info) 247{ 248 JSVM_Value returnValue = nullptr; 249 JSVM_Status status = OH_JSVM_CreateBigintInt64(env, TEST_VALUE_DEMO, &returnValue); 250 if (status != JSVM_OK) { 251 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 fail"); 252 } else { 253 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 success"); 254 } 255 return returnValue; 256} 257// Register the CreateBigintInt64 callback. 258static JSVM_CallbackStruct param[] = { 259 {.data = nullptr, .callback = CreateBigintInt64}, 260}; 261static JSVM_CallbackStruct *method = param; 262// Set a property descriptor named createBigintInt64 and associate it with a callback. This allows the CreateBigintInt64 callback to be called from JS. 263static JSVM_PropertyDescriptor descriptor[] = { 264 {"createBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 265}; 266// Call the C++ code from JS. 267const char* srcCallNative = R"JS(createBigintInt64())JS"; 268``` 269 270**Expected output** 271```ts 272JSVM OH_JSVM_CreateBigintInt64 success 273``` 274 275### OH_JSVM_GetValueBigintInt64 276 277Use OH_JSVM_GetValueBigintInt64 to obtain the C int64_t primitive equivalent of the given JS BigInt object. 278 279CPP code: 280 281```cpp 282// hello.cpp 283#include "napi/native_api.h" 284#include "ark_runtime/jsvm.h" 285#include <hilog/log.h> 286// Define OH_JSVM_GetValueBigintInt64. 287static JSVM_Value GetBigintInt64(JSVM_Env env, JSVM_CallbackInfo info) 288{ 289 size_t argc = 1; 290 JSVM_Value args[1] = {nullptr}; 291 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 292 // Obtain the 64-bit big integer from the input parameter. 293 int64_t value; 294 bool lossLess; 295 OH_JSVM_GetValueBigintInt64(env, args[0], &value, &lossLess); 296 // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown. 297 if (!lossLess) { 298 OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted"); 299 return nullptr; 300 } else { 301 OH_LOG_INFO(LOG_APP, "JSVM GetBigintInt64 success:%{public}d", lossLess); 302 } 303 JSVM_Value returnValue = nullptr; 304 OH_JSVM_CreateBigintInt64(env, value, &returnValue); 305 return returnValue; 306} 307// Register the GetBigintInt64 callback. 308static JSVM_CallbackStruct param[] = { 309 {.data = nullptr, .callback = GetBigintInt64}, 310}; 311static JSVM_CallbackStruct *method = param; 312// Set a property descriptor named getBigintInt64 and associate it with a callback. This allows the GetBigintInt64 callback to be called from JS. 313static JSVM_PropertyDescriptor descriptor[] = { 314 {"getBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 315}; 316// Call the C++ code from JS. 317const char* srcCallNative = R"JS(getBigintInt64(BigInt(-5555555555555555)))JS"; 318``` 319 320**Expected output** 321```ts 322JSVM GetBigintInt64 success:1 323``` 324