1# 使用JSVM-API接口操作bigint类型值
2
3## 简介
4
5BigInt是JavaScript中用于表示任意精度整数的数据类型,它能够处理比Number类型更大范围的整数值。通过JSVM-API提供的接口,可以在JSVM模块中创建、获取和操作BigInt类型值,从而实现与BigInt相关的功能扩展。
6
7## 基本概念
8
9在使用JSVM-API接口操作BigInt类型值时,需要理解以下基本概念:
10
11- **BigInt类型:** BigInt是JavaScript中的一种数据类型,用于表示任意精度的整数。与Number类型不同,BigInt类型可以精确表示非常大的整数,而不会丢失精度或溢出。
12- **BigInt创建:** 使用JSVM-API提供的接口,可以通过传递C的int64或uint64数据来创建对应的JavaScript BigInt。这使得在JSVM模块中可以方便地创建BigInt类型值。
13- **BigInt操作:** JSVM-API提供了多个接口用于操作BigInt类型值。通过这些接口,可以获取BigInt的数值,进行数值转换,以及执行常见的算术和位运算操作。
14
15## 接口说明
16
17| 接口                         | 功能说明                                 |
18| ---------------------------- | ---------------------------------------- |
19| OH_JSVM_CreateBigintInt64     | 将C int64_t类型的值转换为JavaScript BigInt类型。|
20| OH_JSVM_CreateBigintUint64    | 将C uint64_t类型的值转换为JavaScript BigInt类型。|
21| OH_JSVM_CreateBigintWords     | 将一组无符号64位字转换为单个BigInt值。|
22| OH_JSVM_GetValueBigintInt64  | 返回给定JavaScript BigInt的C int64_t基础类型等价值。 如果需要,它将截断该值,将lossless设置为false。       |
23| OH_JSVM_GetValueBigintUint64 | 返回给定JavaScript BigInt的C uint64_t基础类型等价值。 如果需要,它将截断该值,将lossless设置为false。      |
24| OH_JSVM_GetValueBigintWords  | 将单个BigInt值转换为一个符号位、一个64位的小端数组和该数组的长度。 signBit和words参数可以都设置为NULL,这种情况下,只获取wordCount。|
25
26## 使用示例
27
28JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
29
30### OH_JSVM_GetValueBigintWords
31
32获取给定JavaScript BigInt对象的底层数据,即BigInt数据的字词表示。
33
34cpp部分代码
35
36```cpp
37// hello.cpp
38#include "napi/native_api.h"
39#include "ark_runtime/jsvm.h"
40#include <hilog/log.h>
41// OH_JSVM_GetValueBigintWords的样例方法
42static JSVM_Value GetValueBigintWords(JSVM_Env env, JSVM_CallbackInfo info) {
43    size_t argc = 1;
44    JSVM_Value args[1] = {nullptr};
45    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
46    int signBit = 0;
47    size_t wordCount = 0;
48    uint64_t* words{nullptr};
49    // 调用OH_JSVM_GetValueBigintWords接口获取wordCount
50    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, args[0], nullptr, &wordCount, nullptr);
51    OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords wordCount:%{public}d.", wordCount);
52    words = (uint64_t*)malloc(wordCount*sizeof(uint64_t));
53    if (words == nullptr) {
54        OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords malloc failed.");
55        return nullptr;
56    }
57    // 调用OH_JSVM_GetValueBigintWords接口获取传入bigInt相关信息,如:signBit传入bigInt正负信息
58    status = OH_JSVM_GetValueBigintWords(env, args[0], &signBit, &wordCount, words);
59    free(words);
60    words = nullptr;
61    if (status != JSVM_OK) {
62        OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords fail, status:%{public}d.", status);
63    } else {
64        OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords signBit: %{public}d.", signBit);
65    }
66    // 将符号位转化为int类型传出去
67    JSVM_Value returnValue = nullptr;
68    OH_JSVM_CreateInt32(env, signBit, &returnValue);
69    return returnValue;
70}
71// GetValueBigintWords注册回调
72static JSVM_CallbackStruct param[] = {
73    {.data = nullptr, .callback = GetValueBigintWords},
74};
75static JSVM_CallbackStruct *method = param;
76// GetValueBigintWords方法别名,供JS调用
77static JSVM_PropertyDescriptor descriptor[] = {
78    {"getValueBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
79};
80// 样例测试js
81const char* srcCallNative = R"JS(getValueBigintWords(BigInt(5555555555555555)))JS";
82```
83
84预期的输出结果
85```ts
86OH_JSVM_GetValueBigintWords wordCount:1.
87OH_JSVM_GetValueBigintWords signBit: 1.
88```
89
90### OH_JSVM_CreateBigintWords
91
92根据给定的Uint64_t数组创建一个JavaScript BigInt对象。
93
94cpp部分代码
95
96```cpp
97// hello.cpp
98#include "napi/native_api.h"
99#include "ark_runtime/jsvm.h"
100#include <hilog/log.h>
101// OH_JSVM_CreateBigintWords的样例方法
102static int DIFF_VALUE_THREE = 3;
103static JSVM_Value CreateBigintWords(JSVM_Env env, JSVM_CallbackInfo info)
104{
105    // 使用OH_JSVM_CreateBigintWords接口创建一个BigInt对象
106    int signBit = 0;
107    size_t wordCount = DIFF_VALUE_THREE;
108    uint64_t words[] = {12ULL, 34ULL, 56ULL};
109    JSVM_Value returnValue = nullptr;
110    JSVM_Status status = OH_JSVM_CreateBigintWords(env, signBit, wordCount, words, &returnValue);
111    if (status != JSVM_OK) {
112        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintWords fail");
113    } else {
114        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintWords success");
115    }
116    return returnValue;
117}
118// CreateBigintWords注册回调
119static JSVM_CallbackStruct param[] = {
120    {.data = nullptr, .callback = CreateBigintWords},
121};
122static JSVM_CallbackStruct *method = param;
123// CreateBigintWords方法别名,供JS调用
124static JSVM_PropertyDescriptor descriptor[] = {
125    {"createBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
126};
127// 样例测试js
128const char* srcCallNative = R"JS(createBigintWords())JS";
129```
130
131预期的输出结果
132```ts
133JSVM OH_JSVM_CreateBigintWords success
134```
135
136### OH_JSVM_CreateBigintUint64
137
138根据Uint64类型对象创建 JavaScript Bigint对象。
139
140cpp部分代码
141
142```cpp
143// hello.cpp
144#include "napi/native_api.h"
145#include "ark_runtime/jsvm.h"
146#include <hilog/log.h>
147// 声明uint64_t的变量value
148static uint64_t TEST_VALUE = 5555555555555555555;
149// OH_JSVM_CreateBigintUint64的样例方法
150static JSVM_Value CreateBigintUint64(JSVM_Env env, JSVM_CallbackInfo info)
151{
152    // 将value转化为JSVM_Value类型返回
153    JSVM_Value returnValue = nullptr;
154    JSVM_Status status = OH_JSVM_CreateBigintUint64(env, TEST_VALUE, &returnValue);
155    if (status != JSVM_OK) {
156        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 fail");
157    } else {
158        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 success");
159    }
160    return returnValue;
161}
162// CreateBigintUint64注册回调
163static JSVM_CallbackStruct param[] = {
164    {.data = nullptr, .callback = CreateBigintUint64},
165};
166static JSVM_CallbackStruct *method = param;
167// CreateBigintUint64方法别名,供JS调用
168static JSVM_PropertyDescriptor descriptor[] = {
169    {"createBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
170};
171// 样例测试js
172const char* srcCallNative = R"JS(createBigintUint64())JS";
173```
174
175预期的输出结果
176```ts
177JSVM OH_JSVM_CreateBigintUint64 success
178
179```
180
181### OH_JSVM_GetValueBigintUint64
182
183获取给定JavaScript BigInt的Uint64_t基础类型值。
184
185cpp部分代码
186
187```cpp
188// hello.cpp
189#include "napi/native_api.h"
190#include "ark_runtime/jsvm.h"
191#include <hilog/log.h>
192// OH_JSVM_GetValueBigintUint64的样例方法
193static JSVM_Value GetValueBigintUint64(JSVM_Env env, JSVM_CallbackInfo info)
194{
195    size_t argc = 1;
196    JSVM_Value args[1] = {nullptr};
197    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
198    // 从参数值中获取BigInt的数值
199    uint64_t value = 0;
200    bool lossLess = false;
201    OH_JSVM_GetValueBigintUint64(env, args[0], &value, &lossLess);
202    // 判断从JS侧获取bigint是否为无损转换,如果不是抛出异常
203    if (!lossLess) {
204        OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted");
205        return nullptr;
206    } else {
207        OH_LOG_INFO(LOG_APP, "JSVM GetValueBigintUint64 success:%{public}d", lossLess);
208    }
209    JSVM_Value returnValue = nullptr;
210    OH_JSVM_CreateBigintUint64(env, value, &returnValue);
211    return returnValue;
212}
213// GetValueBigintUint64注册回调
214static JSVM_CallbackStruct param[] = {
215    {.data = nullptr, .callback = GetValueBigintUint64},
216};
217static JSVM_CallbackStruct *method = param;
218// GetValueBigintUint64方法别名,供JS调用
219static JSVM_PropertyDescriptor descriptor[] = {
220    {"getValueBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
221};
222// 样例测试js
223const char* srcCallNative = R"JS(getValueBigintUint64(BigInt(5555555555555555)))JS";
224```
225
226预期的输出结果
227```ts
228JSVM GetValueBigintUint64 success:1
229```
230
231### OH_JSVM_CreateBigintInt64
232
233根据Uint64类型对象创建JavaScript Bigint对象。
234
235cpp部分代码
236
237```cpp
238// hello.cpp
239#include "napi/native_api.h"
240#include "ark_runtime/jsvm.h"
241#include <hilog/log.h>
242// 声明int64_t的变量value
243static int64_t TEST_VALUE_DEMO = -5555555555555555555;
244// OH_JSVM_CreateBigintInt64的样例方法
245static JSVM_Value CreateBigintInt64(JSVM_Env env, JSVM_CallbackInfo info)
246{
247    JSVM_Value returnValue = nullptr;
248    JSVM_Status status = OH_JSVM_CreateBigintInt64(env, TEST_VALUE_DEMO, &returnValue);
249    if (status != JSVM_OK) {
250        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 fail");
251    } else {
252        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 success");
253    }
254    return returnValue;
255}
256// CreateBigintInt64注册回调
257static JSVM_CallbackStruct param[] = {
258    {.data = nullptr, .callback = CreateBigintInt64},
259};
260static JSVM_CallbackStruct *method = param;
261// CreateBigintInt64方法别名,供JS调用
262static JSVM_PropertyDescriptor descriptor[] = {
263    {"createBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
264};
265// 样例测试js
266const char* srcCallNative = R"JS(createBigintInt64())JS";
267```
268
269预期的输出结果
270```ts
271JSVM OH_JSVM_CreateBigintInt64 success
272```
273
274### OH_JSVM_GetValueBigintInt64
275
276用于从传入的参数中提取64位整数的BigInt数据,以供后续处理。
277
278cpp部分代码
279
280```cpp
281// hello.cpp
282#include "napi/native_api.h"
283#include "ark_runtime/jsvm.h"
284#include <hilog/log.h>
285// OH_JSVM_GetValueBigintInt64的样例方法
286static JSVM_Value GetBigintInt64(JSVM_Env env, JSVM_CallbackInfo info)
287{
288    size_t argc = 1;
289    JSVM_Value args[1] = {nullptr};
290    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
291    // 从传入的参数中提取64位整数的BigInt数据
292    int64_t value;
293    bool lossLess;
294    OH_JSVM_GetValueBigintInt64(env, args[0], &value, &lossLess);
295    // 判断从JS侧获取bigint是否为无损转换,如果不是抛出异常
296    if (!lossLess) {
297        OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted");
298        return nullptr;
299    } else {
300        OH_LOG_INFO(LOG_APP, "JSVM GetBigintInt64 success:%{public}d", lossLess);
301    }
302    JSVM_Value returnValue = nullptr;
303    OH_JSVM_CreateBigintInt64(env, value, &returnValue);
304    return returnValue;
305}
306// GetBigintInt64注册回调
307static JSVM_CallbackStruct param[] = {
308    {.data = nullptr, .callback = GetBigintInt64},
309};
310static JSVM_CallbackStruct *method = param;
311// GetBigintInt64方法别名,供JS调用
312static JSVM_PropertyDescriptor descriptor[] = {
313    {"getBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
314};
315// 样例测试js
316const char* srcCallNative = R"JS(getBigintInt64(BigInt(-5555555555555555)))JS";
317```
318
319预期的输出结果
320```ts
321JSVM GetBigintInt64 success:1
322```
323