• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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