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