1# Creating Basic Data Types Using JSVM-API
2
3## Introduction
4
5In JavaScript (JS), the integer type represents a number without a decimal point, and the double type represents a number with a fractional part. Due to the limitation of the value storage mode of JS, very large or very small numbers cannot be accurately represented. In this case, you can use JSVM-API to represent large numbers in BigInt format.
6
7## Basic Concepts
8
9Before using JSVM-API to create and obtain numbers, you need to understand the following concepts:
10
11- Number type<br>When using JSVM-API, you may need to convert values of number types between C and JS. When converting the data, pay attention to the data range, signedness (signed or unsigned), and precision (single or double precision).
12- Error handling<br>You also need to use JSVM-API to capture and handle errors that may occur during the conversion. For example, when an integer is created, you may need to capture and handle memory allocation failures or other runtime errors.
13- Interaction between JS and JSVM-API<br>During the development, you need to consider the interaction between JS and JSVM-API, including how to pass the data of the number type and return the correct value.
14
15## Available APIs
16
17| API                 | Description                                       |
18| --------------------- | -----------------------------------------------|
19| OH_JSVM_GetValueUint32 | Obtains the C Uint32 primitive equivalent of the given JS number.  |
20| OH_JSVM_GetValueInt32  | Obtains the C Int32 primitive equivalent of the given JS number.   |
21| OH_JSVM_GetValueInt64  | Obtains the C Int64 primitive equivalent of the given JS number.   |
22| OH_JSVM_GetValueDouble | Obtains the C Double primitive equivalent of the given JS number.  |
23| OH_JSVM_CreateInt32     | Creates a JS number object from a C Int32_t object.|
24| OH_JSVM_CreateUint32    | Creates a JS number object from a C Uint32_t object.|
25| OH_JSVM_CreateInt64     | Creates a JS number object from a C Int64_t object.|
26| OH_JSVM_CreateDouble    | Creates a JS number object from a C Double object. |
27
28## Example
29
30If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in manipulating basic data types.
31
32### OH_JSVM_GetValueUint32
33
34Use **OH_JSVM_GetValueUint32** to obtain a 32-bit unsigned integer from a JS number.
35
36CPP code:
37
38```cpp
39// hello.cpp
40#include "napi/native_api.h"
41#include "ark_runtime/jsvm.h"
42#include <hilog/log.h>
43
44// Define OH_JSVM_GetValueUint32.
45static JSVM_Value GetValueUint32(JSVM_Env env, JSVM_CallbackInfo info)
46{
47    // Obtain the parameter of the Number type.
48    size_t argc = 1;
49    JSVM_Value argv[1] = {nullptr};
50    // Parse the input parameters.
51    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
52    uint32_t number = 0;
53    // Obtain a 32-bit unsigned integer.
54    JSVM_Status status = OH_JSVM_GetValueUint32(env, argv[0], &number);
55    if (status != JSVM_OK) {
56        OH_LOG_ERROR(LOG_APP, "JSVM GetValueUint32 fail");
57    } else {
58        OH_LOG_INFO(LOG_APP, "JSVM GetValueUint32 success: %{public}u", number);
59    }
60    return argv[0];
61}
62
63// Register the GetValueUint32 callback.
64static JSVM_CallbackStruct param[] = {
65    {.data = nullptr, .callback = GetValueUint32},
66};
67static JSVM_CallbackStruct *method = param;
68
69// Set a property descriptor named getValueUint and associate it with a callback. This allows the GetValueUint callback to be called from JS.
70static JSVM_PropertyDescriptor descriptor[] = {
71    {"getValueUint32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
72};
73
74// Call the C++ code from JS.
75const char* srcCallNative = R"JS(getValueUint32(123))JS";
76```
77
78**Expected output**
79
80```
81JSVM GetValueUint32 success: 123
82```
83
84### OH_JSVM_GetValueInt32
85
86Use **OH_JSVM_GetValueInt32** to obtain a C int32 value from a JS value.
87
88CPP code:
89
90```cpp
91// hello.cpp
92#include "napi/native_api.h"
93#include "ark_runtime/jsvm.h"
94#include <hilog/log.h>
95
96// Define OH_JSVM_GetValueInt32.
97static JSVM_Value GetValueInt32(JSVM_Env env, JSVM_CallbackInfo info)
98{
99    size_t argc = 1;
100    JSVM_Value args[1] = {nullptr};
101    int32_t result32 = 0;
102    // Parse the input parameters.
103    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
104    // Convert the parameter into a C int32 value.
105    JSVM_Status status = OH_JSVM_GetValueInt32(env, args[0], &result32);
106    if (status != JSVM_OK) {
107        return nullptr;
108    }
109    if (status != JSVM_OK) {
110        OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt32 fail");
111    } else {
112        OH_LOG_INFO(LOG_APP, "JSVM GetValueInt32 success: %{public}d", result32);
113    }
114    return args[0];
115}
116
117// Register the GetValueInt32 callback.
118static JSVM_CallbackStruct param[] = {
119    {.data = nullptr, .callback = GetValueInt32},
120};
121static JSVM_CallbackStruct *method = param;
122// Set a property descriptor named getValueInt32 and associate it with a callback. This allows the GetValueInt32 callback to be called from JS.
123static JSVM_PropertyDescriptor descriptor[] = {
124    {"getValueInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
125};
126
127// Call the C++ code from JS.
128const char* srcCallNative = R"JS(getValueInt32(-123))JS";
129```
130
131**Expected output**
132
133```
134JSVM GetValueInt32 success: -123
135```
136
137### OH_JSVM_GetValueInt64
138
139Use **OH_JSVM_GetValueInt64** to obtain a C int64 value from a JS value.
140
141CPP code:
142
143```cpp
144// hello.cpp
145#include "napi/native_api.h"
146#include "ark_runtime/jsvm.h"
147#include <hilog/log.h>
148
149// Define OH_JSVM_GetValueInt64.
150static JSVM_Value GetValueInt64(JSVM_Env env, JSVM_CallbackInfo info)
151{
152    size_t argc = 1;
153    JSVM_Value args[1] = {nullptr};
154    int64_t result64 = 0;
155    // Parse the input parameters.
156    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
157    // Convert the input parameters into C int64 values.
158    JSVM_Status status = OH_JSVM_GetValueInt64(env, args[0], &result64);
159    if (status != JSVM_OK) {
160        OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt64 fail");
161    } else {
162        OH_LOG_INFO(LOG_APP, "JSVM GetValueInt64 success: %{public}d", result64);
163    }
164    return args[0];
165}
166
167// Register the GetValueInt64 callback.
168static JSVM_CallbackStruct param[] = {
169    {.data = nullptr, .callback = GetValueInt64},
170};
171static JSVM_CallbackStruct *method = param;
172// Set a property descriptor named getValueInt64 and associate it with a callback. This allows the GetValueInt64 callback to be called from JS.
173static JSVM_PropertyDescriptor descriptor[] = {
174    {"getValueInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
175};
176
177// Call the C++ code from JS.
178const char* srcCallNative = R"JS(getValueInt64(-123))JS";
179```
180
181**Expected output**
182
183```
184JSVM GetValueInt64 success: -123
185```
186
187### OH_JSVM_GetValueDouble
188
189Use **OH_JSVM_GetValueDouble** to obtain a C double value from a JS value.
190
191CPP code:
192
193```cpp
194// hello.cpp
195#include "napi/native_api.h"
196#include "ark_runtime/jsvm.h"
197#include <hilog/log.h>
198
199// Define OH_JSVM_GetValueDouble.
200static JSVM_Value GetDouble(JSVM_Env env, JSVM_CallbackInfo info)
201{
202    size_t argc = 1;
203    JSVM_Value args[1] = {nullptr};
204    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
205    double value;
206    JSVM_Status status = OH_JSVM_GetValueDouble(env, args[0], &value);
207    if (status != JSVM_OK) {
208        OH_LOG_ERROR(LOG_APP, "JSVM GetDouble fail");
209    } else {
210        OH_LOG_INFO(LOG_APP, "JSVM GetDouble success: %{public}f", value);
211    }
212    return args[0];
213}
214
215// Register the GetDouble callback.
216static JSVM_CallbackStruct param[] = {
217    {.data = nullptr, .callback = GetDouble},
218};
219static JSVM_CallbackStruct *method = param;
220// Set a property descriptor named getDouble and associate it with a callback. This allows the GetDouble callback to be called from JS.
221static JSVM_PropertyDescriptor descriptor[] = {
222    {"getDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
223};
224
225// Call the C++ code from JS.
226const char* srcCallNative = R"JS(getDouble(-110.0456))JS";
227```
228
229**Expected output**
230
231```
232JSVM GetDouble success: -110.045600
233```
234
235### OH_JSVM_CreateInt32
236
237Use **OH_JSVM_CreateInt32** to create a JS number of the int32 type.
238
239CPP code:
240
241```cpp
242// hello.cpp
243#include "napi/native_api.h"
244#include "ark_runtime/jsvm.h"
245#include <hilog/log.h>
246
247// Define OH_JSVM_CreateInt32.
248static JSVM_Value CreateInt32(JSVM_Env env, JSVM_CallbackInfo info)
249{
250    int32_t value = -20;
251    // Create a JS Int32 number.
252    JSVM_Value result = nullptr;
253    JSVM_Status status = OH_JSVM_CreateInt32(env, value, &result);
254    if (status != JSVM_OK) {
255        OH_LOG_ERROR(LOG_APP, "JSVM CreateInt32 fail");
256    } else {
257        int32_t number = 0;
258        OH_JSVM_GetValueInt32(env, result, &number);
259        OH_LOG_INFO(LOG_APP, "JSVM CreateInt32 success: %{public}d", number);
260    }
261    return result;
262}
263
264// Register the CreateInt32 callback.
265static JSVM_CallbackStruct param[] = {
266    {.data = nullptr, .callback = CreateInt32},
267};
268static JSVM_CallbackStruct *method = param;
269// Set a property descriptor named createInt32 and associate it with a callback. This allows the CreateInt32 callback to be called from JS.
270static JSVM_PropertyDescriptor descriptor[] = {
271    {"createInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
272};
273
274// Call the C++ code from JS.
275const char* srcCallNative = R"JS(createInt32())JS";
276```
277
278**Expected output**
279
280```
281JSVM CreateInt32 success: -20
282```
283
284### OH_JSVM_CreateUint32
285
286Use **OH_JSVM_CreateUint32** to create a JS number of the uint32 type.
287
288CPP code:
289
290```cpp
291// hello.cpp
292#include "napi/native_api.h"
293#include "ark_runtime/jsvm.h"
294#include <hilog/log.h>
295
296// Define OH_JSVM_CreateUint32.
297static JSVM_Value CreateUInt32(JSVM_Env env, JSVM_CallbackInfo info)
298{
299    //
300    // If the uint32_t type is used to represent -26, overflow occurs. Modulo operation is performed on the result to convert the binary complement of the negative number to a positive number. That is, 4294967270 will be returned.
301    // uint32_t represents a 32-bit unsigned integer, ranging from 0 to 2^32 - 1, that is, 0 to 4294967295.
302    //
303    uint32_t value = 26;
304    // Create a JS Uint32 number.
305    JSVM_Value result = nullptr;
306    JSVM_Status status = OH_JSVM_CreateUint32(env, value, &result);
307    if (status != JSVM_OK) {
308        OH_LOG_ERROR(LOG_APP, "JSVM CreateUInt32 fail");
309    } else {
310        uint32_t number = 0;
311        OH_JSVM_GetValueUint32(env, result, &number);
312        OH_LOG_INFO(LOG_APP, "JSVM CreateUInt32 success: %{public}u", number);
313    }
314    return result;
315}
316
317// Register the CreateUInt32 callback.
318static JSVM_CallbackStruct param[] = {
319    {.data = nullptr, .callback = CreateUInt32},
320};
321static JSVM_CallbackStruct *method = param;
322// Set a property descriptor named createUInt32 and associate it with a callback. This allows the CreateUInt32 callback to be called from JS.
323static JSVM_PropertyDescriptor descriptor[] = {
324    {"createUInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
325};
326
327// Call the C++ code from JS.
328const char* srcCallNative = R"JS(createUInt32())JS";
329```
330
331**Expected output**
332
333```
334JSVM CreateUInt32 success: 26
335```
336
337### OH_JSVM_CreateInt64
338
339Use **OH_JSVM_CreateInt64** to create a JS number of the int64 type.
340
341CPP code:
342
343```cpp
344// hello.cpp
345#include "napi/native_api.h"
346#include "ark_runtime/jsvm.h"
347#include <hilog/log.h>
348
349// Define OH_JSVM_CreateInt64.
350static JSVM_Value CreateInt64(JSVM_Env env, JSVM_CallbackInfo info)
351{
352    // int64 represents a 64-bit signed integer, ranging from -2^63 to 2^63 - 1, that is, -9223372036854775808 to 9223372036854775807.
353    //
354    int64_t value = 2147483648;
355    // Create a JS Int64 number.
356    JSVM_Value result = nullptr;
357    JSVM_Status status = OH_JSVM_CreateInt64(env, value, &result);
358    if (status != JSVM_OK) {
359        OH_LOG_ERROR(LOG_APP, "JSVM CreateInt64 fail");
360    } else {
361        int64_t number = 0;
362        OH_JSVM_GetValueInt64(env, result, &number);
363        OH_LOG_INFO(LOG_APP, "JSVM CreateInt64 success: %{public}ld", number);
364    }
365    return result;
366}
367
368// Register the CreateInt64 callback.
369static JSVM_CallbackStruct param[] = {
370    {.data = nullptr, .callback = CreateInt64},
371};
372static JSVM_CallbackStruct *method = param;
373// Set a property descriptor named createInt64 and associate it with a callback. This allows the CreateInt64 callback to be called from JS.
374static JSVM_PropertyDescriptor descriptor[] = {
375    {"createInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
376};
377
378// Call the C++ code from JS.
379const char* srcCallNative = R"JS(createInt64())JS";
380```
381
382**Expected output**
383
384```
385JSVM CreateInt64 success: 2147483648
386```
387
388### OH_JSVM_CreateDouble
389
390Use **OH_JSVM_CreateDouble** to create a JS number of the double type.
391
392CPP code:
393
394```cpp
395// hello.cpp
396#include "napi/native_api.h"
397#include "ark_runtime/jsvm.h"
398#include <hilog/log.h>
399// register a CreateDouble callback.
400
401// Define OH_JSVM_CreateDouble.
402static JSVM_Value CreateDouble(JSVM_Env env, JSVM_CallbackInfo info)
403{
404    double value = 1.234;
405    // Create a JS double number.
406    JSVM_Value result = nullptr;
407    JSVM_Status status = OH_JSVM_CreateDouble(env, value, &result);
408    if (status != JSVM_OK) {
409        OH_LOG_ERROR(LOG_APP, "JSVM CreateDouble fail");
410    } else {
411        double number = 0;
412        OH_JSVM_GetValueDouble(env, result, &number);
413        OH_LOG_INFO(LOG_APP, "JSVM CreateDouble success: %{public}f", number);
414    }
415    return result;
416}
417
418static JSVM_CallbackStruct param[] = {
419    {.data = nullptr, .callback = CreateDouble},
420};
421static JSVM_CallbackStruct *method = param;
422// Set a property descriptor named createDouble and associate it with a callback. This allows the CreateDouble callback to be called from JS.
423static JSVM_PropertyDescriptor descriptor[] = {
424    {"createDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
425};
426
427// Call the C++ code from JS.
428const char* srcCallNative = R"JS(createDouble())JS";
429```
430
431**Expected output**
432
433```
434JSVM CreateDouble success: 1.234000
435```
436