7761922b创建于 2025年9月26日历史提交

Working with BigInt Using JSVM-API

Introduction

BigInt 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.

Basic Concepts

Before using JSVM-API to operate BigInt values, you need to understand the following basic concepts:

  • BigInt: a data type used to represent integers of any precision in JS. Unlike the Number type, BigInt can accurately represent very large integers without losing precision or causing overflows.
  • 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++.
  • 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.

Available APIs

API Description
OH_JSVM_CreateBigintInt64 Creates a JS BigInt object from a C int64_t object.
OH_JSVM_CreateBigintUint64 Creates a JS BigInt object from a C uint64_t object.
OH_JSVM_CreateBigintWords Creates a JS BigInt object from a C uint64_t array.
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.
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.
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.

Example

If you are just starting out with JSVM-API, see JSVM-API Development Process. The following demonstrates only the C++ code and ArkTS code involved in related APIs.

OH_JSVM_GetValueBigintWords

Use OH_JSVM_GetValueBigintWords to obtain the underlying data of a given JS BigInt object, that is, the word representation of BigInt data.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>
#include <fstream>

// Define OH_JSVM_GetValueBigintWords.
static JSVM_Value GetValueBigintWords(JSVM_Env env, JSVM_CallbackInfo info) {
    size_t argc = 1;
    JSVM_Value args[1] = {nullptr};
    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    int signBit = 0;
    size_t wordCount = 0;
    uint64_t* words{nullptr};
    // Call OH_JSVM_GetValueBigintWords to obtain wordCount.
    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, args[0], nullptr, &wordCount, nullptr);
    OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords wordCount:%{public}d.", wordCount);
    words = (uint64_t*)malloc(wordCount*sizeof(uint64_t));
    if (words == nullptr) {
        OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords malloc failed.");
        return nullptr;
    }
    // Call OH_JSVM_GetValueBigintWords to obtain BigInt information, such as whether the value passed by signBit is a positive or negative number.
    status = OH_JSVM_GetValueBigintWords(env, args[0], &signBit, &wordCount, words);
    free(words);
    words = nullptr;
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords fail, status:%{public}d.", status);
    } else {
        OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords signBit: %{public}d.", signBit);
    }
    // Convert the sign bit into a value of Int type and pass it.
    JSVM_Value returnValue = nullptr;
    OH_JSVM_CreateInt32(env, signBit, &returnValue);
    return returnValue;
}
// Register the GetValueBigintWords callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetValueBigintWords},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named getValueBigintWords and associate it with a callback. This allows the GetValueBigintWords callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"getValueBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Call the C++ code from JS.
const char* srcCallNative = R"JS(getValueBigintWords(BigInt(5555555555555555)))JS";

Expected result:

OH_JSVM_GetValueBigintWords wordCount:1.
OH_JSVM_GetValueBigintWords signBit: 0.

OH_JSVM_CreateBigintWords

Use OH_JSVM_GetValueBigintWords to create a JS BigInt object from a C uint64_t array.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>
// Define OH_JSVM_CreateBigintWords.
static int DIFF_VALUE_THREE = 3;
static JSVM_Value CreateBigintWords(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Call OH_JSVM_CreateBigintWords to create a BigInt object.
    int signBit = 0;
    size_t wordCount = DIFF_VALUE_THREE;
    uint64_t words[] = {12ULL, 34ULL, 56ULL};
    JSVM_Value returnValue = nullptr;
    JSVM_Status status = OH_JSVM_CreateBigintWords(env, signBit, wordCount, words, &returnValue);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintWords fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintWords success");
    }
    return returnValue;
}
// Register the CreateBigintWords callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = CreateBigintWords},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named createBigintWords and associate it with a callback. This allows the CreateBigintWords callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"createBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Call the C++ code from JS.
const char* srcCallNative = R"JS(createBigintWords())JS";

Expected result:

JSVM OH_JSVM_CreateBigintWords success

OH_JSVM_CreateBigintUint64

Use OH_JSVM_CreateBigintUint64 to create a JavaScript BigInt object from a Uint64 object.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>
// Declare the variable value of uint64_t.
static uint64_t TEST_VALUE = 5555555555555555555;
// Define OH_JSVM_CreateBigintUint64.
static JSVM_Value CreateBigintUint64(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Convert value to the JSVM_Value type and return the value.
    JSVM_Value returnValue = nullptr;
    JSVM_Status status = OH_JSVM_CreateBigintUint64(env, TEST_VALUE, &returnValue);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 success");
    }
    return returnValue;
}
// Define CreateBigintUint64.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = CreateBigintUint64},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named createBigintUint64 and associate it with a callback. This allows the CreateBigintUint64 callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"createBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Call the C++ code from JS.
const char* srcCallNative = R"JS(createBigintUint64())JS";

Expected result:

JSVM OH_JSVM_CreateBigintUint64 success

OH_JSVM_GetValueBigintUint64

Use OH_JSVM_GetValueBigintUint64 to obtain the C uint64_t primitive equivalent of the given JS BigInt object.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>
// Define OH_JSVM_GetValueBigintUint64.
static JSVM_Value GetValueBigintUint64(JSVM_Env env, JSVM_CallbackInfo info)
{
    size_t argc = 1;
    JSVM_Value args[1] = {nullptr};
    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // Obtain the BigInt value.
    uint64_t value = 0;
    bool lossLess = false;
    OH_JSVM_GetValueBigintUint64(env, args[0], &value, &lossLess);
    // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown.
    if (!lossLess) {
        OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted");
        return nullptr;
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM GetValueBigintUint64 success");
    }
    JSVM_Value returnValue = nullptr;
    OH_JSVM_CreateBigintUint64(env, value, &returnValue);
    return returnValue;
}
// Register the GetValueBigintUint64 callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetValueBigintUint64},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named getValueBigintUint64 and associate it with a callback. This allows the GetValueBigintUint64 callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"getValueBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Call the C++ code from JS.
const char* srcCallNative = R"JS(getValueBigintUint64(BigInt(5555555555555555)))JS";

Expected result:

JSVM GetValueBigintUint64 success

OH_JSVM_CreateBigintInt64

Use OH_JSVM_CreateBigintInt64 to create a JavaScript BigInt object from an int64_t object.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>
// Declare the variable value of int64_t.
static int64_t TEST_VALUE_DEMO = -5555555555555555555;
// Define OH_JSVM_CreateBigintInt64.
static JSVM_Value CreateBigintInt64(JSVM_Env env, JSVM_CallbackInfo info)
{
    JSVM_Value returnValue = nullptr;
    JSVM_Status status = OH_JSVM_CreateBigintInt64(env, TEST_VALUE_DEMO, &returnValue);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 success");
    }
    return returnValue;
}
// Register the CreateBigintInt64 callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = CreateBigintInt64},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named createBigintInt64 and associate it with a callback. This allows the CreateBigintInt64 callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"createBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Call the C++ code from JS.
const char* srcCallNative = R"JS(createBigintInt64())JS";

Expected result:

JSVM OH_JSVM_CreateBigintInt64 success

OH_JSVM_GetValueBigintInt64

Use OH_JSVM_GetValueBigintInt64 to obtain the C int64_t primitive equivalent of the given JS BigInt object.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>
// Define OH_JSVM_GetValueBigintInt64.
static JSVM_Value GetBigintInt64(JSVM_Env env, JSVM_CallbackInfo info)
{
    size_t argc = 1;
    JSVM_Value args[1] = {nullptr};
    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // Obtain the 64-bit big integer from the input parameter.
    int64_t value = 0;
    bool lossLess = false;
    OH_JSVM_GetValueBigintInt64(env, args[0], &value, &lossLess);
    // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown.
    if (!lossLess) {
        OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted");
        return nullptr;
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM GetBigintInt64 success");
    }
    JSVM_Value returnValue = nullptr;
    OH_JSVM_CreateBigintInt64(env, value, &returnValue);
    return returnValue;
}
// Register the GetBigintInt64 callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetBigintInt64},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named getBigintInt64 and associate it with a callback. This allows the GetBigintInt64 callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"getBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Call the C++ code from JS.
const char* srcCallNative = R"JS(getBigintInt64(BigInt(-5555555555555555)))JS";

Expected result:

JSVM GetValueBigintUint64 success