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#include <fstream> 42 43// Define OH_JSVM_GetValueBigintWords. 44static JSVM_Value GetValueBigintWords(JSVM_Env env, JSVM_CallbackInfo info) { 45 size_t argc = 1; 46 JSVM_Value args[1] = {nullptr}; 47 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 48 int signBit = 0; 49 size_t wordCount = 0; 50 uint64_t* words{nullptr}; 51 // Call OH_JSVM_GetValueBigintWords to obtain wordCount. 52 JSVM_Status status = OH_JSVM_GetValueBigintWords(env, args[0], nullptr, &wordCount, nullptr); 53 OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords wordCount:%{public}d.", wordCount); 54 words = (uint64_t*)malloc(wordCount*sizeof(uint64_t)); 55 if (words == nullptr) { 56 OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords malloc failed."); 57 return nullptr; 58 } 59 // Call OH_JSVM_GetValueBigintWords to obtain BigInt information, such as whether the value passed by signBit is a positive or negative number. 60 status = OH_JSVM_GetValueBigintWords(env, args[0], &signBit, &wordCount, words); 61 free(words); 62 words = nullptr; 63 if (status != JSVM_OK) { 64 OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords fail, status:%{public}d.", status); 65 } else { 66 OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords signBit: %{public}d.", signBit); 67 } 68 // Convert the sign bit into a value of Int type and pass it. 69 JSVM_Value returnValue = nullptr; 70 OH_JSVM_CreateInt32(env, signBit, &returnValue); 71 return returnValue; 72} 73// Register the GetValueBigintWords callback. 74static JSVM_CallbackStruct param[] = { 75 {.data = nullptr, .callback = GetValueBigintWords}, 76}; 77static JSVM_CallbackStruct *method = param; 78// Set a property descriptor named getValueBigintWords and associate it with a callback. This allows the GetValueBigintWords callback to be called from JS. 79static JSVM_PropertyDescriptor descriptor[] = { 80 {"getValueBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 81}; 82// Call the C++ code from JS. 83const char* srcCallNative = R"JS(getValueBigintWords(BigInt(5555555555555555)))JS"; 84``` 85 86**Expected output** 87```ts 88OH_JSVM_GetValueBigintWords wordCount:1. 89OH_JSVM_GetValueBigintWords signBit: 0. 90``` 91 92### OH_JSVM_CreateBigintWords 93 94Use **OH_JSVM_GetValueBigintWords** to create a JS BigInt object from a C uint64_t array. 95 96CPP code: 97 98```cpp 99// hello.cpp 100#include "napi/native_api.h" 101#include "ark_runtime/jsvm.h" 102#include <hilog/log.h> 103// Define OH_JSVM_CreateBigintWords. 104static int DIFF_VALUE_THREE = 3; 105static JSVM_Value CreateBigintWords(JSVM_Env env, JSVM_CallbackInfo info) 106{ 107 // Call OH_JSVM_CreateBigintWords to create a BigInt object. 108 int signBit = 0; 109 size_t wordCount = DIFF_VALUE_THREE; 110 uint64_t words[] = {12ULL, 34ULL, 56ULL}; 111 JSVM_Value returnValue = nullptr; 112 JSVM_Status status = OH_JSVM_CreateBigintWords(env, signBit, wordCount, words, &returnValue); 113 if (status != JSVM_OK) { 114 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintWords fail"); 115 } else { 116 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintWords success"); 117 } 118 return returnValue; 119} 120// Register the CreateBigintWords callback. 121static JSVM_CallbackStruct param[] = { 122 {.data = nullptr, .callback = CreateBigintWords}, 123}; 124static JSVM_CallbackStruct *method = param; 125// Set a property descriptor named createBigintWords and associate it with a callback. This allows the CreateBigintWords callback to be called from JS. 126static JSVM_PropertyDescriptor descriptor[] = { 127 {"createBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 128}; 129// Call the C++ code from JS. 130const char* srcCallNative = R"JS(createBigintWords())JS"; 131``` 132 133**Expected output** 134```ts 135JSVM OH_JSVM_CreateBigintWords success 136``` 137 138### OH_JSVM_CreateBigintUint64 139 140Use **OH_JSVM_CreateBigintUint64** to create a JS BigInt object from a C Uint64 object. 141 142CPP code: 143 144```cpp 145// hello.cpp 146#include "napi/native_api.h" 147#include "ark_runtime/jsvm.h" 148#include <hilog/log.h> 149// Declare the variable value of uint64_t. 150static uint64_t TEST_VALUE = 5555555555555555555; 151// Define OH_JSVM_CreateBigintUint64. 152static JSVM_Value CreateBigintUint64(JSVM_Env env, JSVM_CallbackInfo info) 153{ 154 // Convert value to the JSVM_Value type and return the value. 155 JSVM_Value returnValue = nullptr; 156 JSVM_Status status = OH_JSVM_CreateBigintUint64(env, TEST_VALUE, &returnValue); 157 if (status != JSVM_OK) { 158 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 fail"); 159 } else { 160 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 success"); 161 } 162 return returnValue; 163} 164// Define CreateBigintUint64. 165static JSVM_CallbackStruct param[] = { 166 {.data = nullptr, .callback = CreateBigintUint64}, 167}; 168static JSVM_CallbackStruct *method = param; 169// Set a property descriptor named createBigintUint64 and associate it with a callback. This allows the CreateBigintUint64 callback to be called from JS. 170static JSVM_PropertyDescriptor descriptor[] = { 171 {"createBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 172}; 173// Call the C++ code from JS. 174const char* srcCallNative = R"JS(createBigintUint64())JS"; 175``` 176 177**Expected output** 178```ts 179JSVM OH_JSVM_CreateBigintUint64 success 180 181``` 182 183### OH_JSVM_GetValueBigintUint64 184 185Use **OH_JSVM_GetValueBigintUint64** to obtain the C uint64_t primitive equivalent of the given JS BigInt object. 186 187CPP code: 188 189```cpp 190// hello.cpp 191#include "napi/native_api.h" 192#include "ark_runtime/jsvm.h" 193#include <hilog/log.h> 194// Define OH_JSVM_GetValueBigintUint64. 195static JSVM_Value GetValueBigintUint64(JSVM_Env env, JSVM_CallbackInfo info) 196{ 197 size_t argc = 1; 198 JSVM_Value args[1] = {nullptr}; 199 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 200 // Obtain the BigInt value. 201 uint64_t value = 0; 202 bool lossLess = false; 203 OH_JSVM_GetValueBigintUint64(env, args[0], &value, &lossLess); 204 // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown. 205 if (!lossLess) { 206 OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted"); 207 return nullptr; 208 } else { 209 OH_LOG_INFO(LOG_APP, "JSVM GetValueBigintUint64 success:%{public}d", lossLess); 210 } 211 JSVM_Value returnValue = nullptr; 212 OH_JSVM_CreateBigintUint64(env, value, &returnValue); 213 return returnValue; 214} 215// Register the GetValueBigintUint64 callback. 216static JSVM_CallbackStruct param[] = { 217 {.data = nullptr, .callback = GetValueBigintUint64}, 218}; 219static JSVM_CallbackStruct *method = param; 220// Set a property descriptor named getValueBigintUint64 and associate it with a callback. This allows the GetValueBigintUint64 callback to be called from JS. 221static JSVM_PropertyDescriptor descriptor[] = { 222 {"getValueBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 223}; 224// Call the C++ code from JS. 225const char* srcCallNative = R"JS(getValueBigintUint64(BigInt(5555555555555555)))JS"; 226``` 227 228**Expected output** 229```ts 230JSVM GetValueBigintUint64 success:1 231``` 232 233### OH_JSVM_CreateBigintInt64 234 235Creates a JS BigInt object from a C Uint64 object. 236 237CPP code: 238 239```cpp 240// hello.cpp 241#include "napi/native_api.h" 242#include "ark_runtime/jsvm.h" 243#include <hilog/log.h> 244// Declare the variable value of int64_t. 245static int64_t TEST_VALUE_DEMO = -5555555555555555555; 246// Define OH_JSVM_CreateBigintInt64. 247static JSVM_Value CreateBigintInt64(JSVM_Env env, JSVM_CallbackInfo info) 248{ 249 JSVM_Value returnValue = nullptr; 250 JSVM_Status status = OH_JSVM_CreateBigintInt64(env, TEST_VALUE_DEMO, &returnValue); 251 if (status != JSVM_OK) { 252 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 fail"); 253 } else { 254 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 success"); 255 } 256 return returnValue; 257} 258// Register the CreateBigintInt64 callback. 259static JSVM_CallbackStruct param[] = { 260 {.data = nullptr, .callback = CreateBigintInt64}, 261}; 262static JSVM_CallbackStruct *method = param; 263// Set a property descriptor named createBigintInt64 and associate it with a callback. This allows the CreateBigintInt64 callback to be called from JS. 264static JSVM_PropertyDescriptor descriptor[] = { 265 {"createBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 266}; 267// Call the C++ code from JS. 268const char* srcCallNative = R"JS(createBigintInt64())JS"; 269``` 270 271**Expected output** 272```ts 273JSVM OH_JSVM_CreateBigintInt64 success 274``` 275 276### OH_JSVM_GetValueBigintInt64 277 278Use OH_JSVM_GetValueBigintInt64 to obtain the C int64_t primitive equivalent of the given JS BigInt object. 279 280CPP code: 281 282```cpp 283// hello.cpp 284#include "napi/native_api.h" 285#include "ark_runtime/jsvm.h" 286#include <hilog/log.h> 287// Define OH_JSVM_GetValueBigintInt64. 288static JSVM_Value GetBigintInt64(JSVM_Env env, JSVM_CallbackInfo info) 289{ 290 size_t argc = 1; 291 JSVM_Value args[1] = {nullptr}; 292 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 293 // Obtain the 64-bit big integer from the input parameter. 294 int64_t value; 295 bool lossLess; 296 OH_JSVM_GetValueBigintInt64(env, args[0], &value, &lossLess); 297 // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown. 298 if (!lossLess) { 299 OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted"); 300 return nullptr; 301 } else { 302 OH_LOG_INFO(LOG_APP, "JSVM GetBigintInt64 success:%{public}d", lossLess); 303 } 304 JSVM_Value returnValue = nullptr; 305 OH_JSVM_CreateBigintInt64(env, value, &returnValue); 306 return returnValue; 307} 308// Register the GetBigintInt64 callback. 309static JSVM_CallbackStruct param[] = { 310 {.data = nullptr, .callback = GetBigintInt64}, 311}; 312static JSVM_CallbackStruct *method = param; 313// Set a property descriptor named getBigintInt64 and associate it with a callback. This allows the GetBigintInt64 callback to be called from JS. 314static JSVM_PropertyDescriptor descriptor[] = { 315 {"getBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 316}; 317// Call the C++ code from JS. 318const char* srcCallNative = R"JS(getBigintInt64(BigInt(-5555555555555555)))JS"; 319``` 320 321**Expected output** 322```ts 323JSVM GetBigintInt64 success:1 324``` 325