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++ and ArkTS code involved in the APIs for 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// Register the GetValueUint32 callback.
44static JSVM_CallbackStruct param[] = {
45    {.data = nullptr, .callback = GetValueUint32},
46};
47static JSVM_CallbackStruct *method = param;
48// Set a property descriptor named getValueUint and associate it with a callback. This allows the GetValueUint callback to be called from JS.
49static JSVM_PropertyDescriptor descriptor[] = {
50    {"getValueUint32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
51};
52// Define OH_JSVM_GetValueUint32.
53static JSVM_Value GetValueUint32(JSVM_Env env, JSVM_CallbackInfo info)
54{
55    // Obtain the parameter of the Number type.
56    size_t argc = 1;
57    JSVM_Value argv[1] = {nullptr};
58    // Parse the input parameter.
59    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
60    uint32_t number = 0;
61    // Obtain a 32-bit unsigned integer from the input parameter.
62    JSVM_Status status = OH_JSVM_GetValueUint32(env, argv[0], &number);
63    if (status != JSVM_OK) {
64        OH_LOG_ERROR(LOG_APP, "JSVM GetValueUint32 fail");
65    } else {
66        OH_LOG_INFO(LOG_APP, "JSVM GetValueUint32 success: %{public}d", number);
67    }
68    return argv[0];
69}
70```
71
72ArkTS code:
73
74```ts
75import hilog from "@ohos.hilog"
76// Import the native APIs.
77import napitest from "libentry.so"
78let num = 123;
79let script: string = `
80   function testGetValueUint32(num) {
81       return getValueUint32(num);
82   }
83   testGetValueUint32(${num})
84   `;
85try {
86  let result = napitest.runJsVm(script);
87  hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetValueUint32: %{public}s', result);
88} catch (error) {
89  hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetValueUint32 error: %{public}s', error.message);
90}
91```
92
93### OH_JSVM_GetValueInt32
94
95Use **OH_JSVM_GetValueInt32** to obtain a C int32 value from a JS number.
96
97CPP code:
98
99```cpp
100// hello.cpp
101#include "napi/native_api.h"
102#include "ark_runtime/jsvm.h"
103#include <hilog/log.h>
104// Register the GetValueInt32 callback.
105static JSVM_CallbackStruct param[] = {
106    {.data = nullptr, .callback = GetValueInt32},
107};
108static JSVM_CallbackStruct *method = param;
109// Set a property descriptor named getValueInt32 and associate it with a callback. This allows the GetValueInt32 callback to be called from JS.
110static JSVM_PropertyDescriptor descriptor[] = {
111    {"getValueInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
112};
113// Define OH_JSVM_GetValueInt32.
114static JSVM_Value GetValueInt32(JSVM_Env env, JSVM_CallbackInfo info)
115{
116    size_t argc = 1;
117    JSVM_Value args[1] = {nullptr};
118    int32_t result32 = 0;
119    // Parse the input parameter.
120    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
121    // Convert the input parameter into a C int32 value.
122    JSVM_Status status = OH_JSVM_GetValueInt32(env, args[0], &result32);
123    if (status != JSVM_OK) {
124        return nullptr;
125    }
126    if (status != JSVM_OK) {
127        OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt32 fail");
128    } else {
129        OH_LOG_INFO(LOG_APP, "JSVM GetValueInt32 success: %{public}d", result32);
130    }
131    return args[0];
132}
133```
134
135ArkTS code:
136
137```ts
138import hilog from "@ohos.hilog"
139// Import the native APIs.
140import napitest from "libentry.so"
141let num = -123;
142let script: string = `
143   function testGetValueInt32(num) {
144       return getValueInt32(num);
145   }
146   testGetValueInt32(${num})
147   `;
148try {
149  let result = napitest.runJsVm(script);
150  hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetValueInt32: %{public}s', result);
151} catch (error) {
152  hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetValueInt32 error: %{public}s', error.message);
153}
154```
155
156### OH_JSVM_GetValueInt64
157
158Use **OH_JSVM_GetValueInt64** to obtain a C int64 value from a JS value.
159
160CPP code:
161
162```cpp
163// hello.cpp
164#include "napi/native_api.h"
165#include "ark_runtime/jsvm.h"
166#include <hilog/log.h>
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// Define OH_JSVM_GetValueInt64.
177static JSVM_Value GetValueInt64(JSVM_Env env, JSVM_CallbackInfo info)
178{
179    size_t argc = 1;
180    JSVM_Value args[1] = {nullptr};
181    int64_t result64 = 0;
182    // Parse the input parameter.
183    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
184    // Convert the input parameter into a C int64 value.
185    JSVM_Status status = OH_JSVM_GetValueInt64(env, args[0], &result64);
186    if (status != JSVM_OK) {
187        OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt64 fail");
188    } else {
189        OH_LOG_INFO(LOG_APP, "JSVM GetValueInt64 success: %{public}d", result64);
190    }
191    return args[0];
192}
193```
194
195ArkTS code:
196
197```ts
198import hilog from "@ohos.hilog"
199// Import the native APIs.
200import napitest from "libentry.so"
201let num = -110;
202let script: string = `
203   function testGetValueInt64(num) {
204       return getValueInt64(num);
205   }
206   testGetValueInt64(${num})
207   `;
208try {
209  let result = napitest.runJsVm(script);
210  hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetValueInt64: %{public}s', result);
211} catch (error) {
212  hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetValueInt64 error: %{public}s', error.message);
213}
214```
215
216### OH_JSVM_GetValueDouble
217
218Use **OH_JSVM_GetValueDouble** to obtain a C double value from a JS value.
219
220CPP code:
221
222```cpp
223// hello.cpp
224#include "napi/native_api.h"
225#include "ark_runtime/jsvm.h"
226#include <hilog/log.h>
227// Register the GetDouble callback.
228static JSVM_CallbackStruct param[] = {
229    {.data = nullptr, .callback = GetDouble},
230};
231static JSVM_CallbackStruct *method = param;
232// Set a property descriptor named getDouble and associate it with a callback. This allows the GetDouble callback to be called from JS.
233static JSVM_PropertyDescriptor descriptor[] = {
234    {"getDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
235};
236// Define OH_JSVM_GetValueDouble.
237static JSVM_Value GetDouble(JSVM_Env env, JSVM_CallbackInfo info)
238{
239    size_t argc = 1;
240    JSVM_Value args[1] = {nullptr};
241    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
242    double value;
243    JSVM_Status status = OH_JSVM_GetValueDouble(env, args[0], &value);
244    if (status != JSVM_OK) {
245        OH_LOG_ERROR(LOG_APP, "JSVM GetDouble fail");
246    } else {
247        OH_LOG_INFO(LOG_APP, "JSVM GetDouble success: %{public}f", value);
248    }
249    return args[0];
250}
251```
252
253ArkTS code:
254
255```ts
256import hilog from "@ohos.hilog"
257// Import the native APIs.
258import napitest from "libentry.so"
259let num = -110.0456;
260let script: string = `
261   function testGetDouble(num) {
262       return getDouble(num);
263   }
264   testGetDouble(${num})
265   `;
266try {
267  let result = napitest.runJsVm(script);
268  hilog.info(0x0000, 'testJSVM', 'Test JSVM testGetDouble: %{public}s', result);
269} catch (error) {
270  hilog.error(0x0000, 'testJSVM', 'Test JSVM testGetDouble error: %{public}s', error.message);
271}
272```
273
274### OH_JSVM_CreateInt32
275
276Use **OH_JSVM_CreateInt32** to create a JS number from a 32-bit signed integer.
277
278CPP code:
279
280```cpp
281// hello.cpp
282#include "napi/native_api.h"
283#include "ark_runtime/jsvm.h"
284#include <hilog/log.h>
285// Register the CreateInt32 callback.
286static JSVM_CallbackStruct param[] = {
287    {.data = nullptr, .callback = CreateInt32},
288};
289static JSVM_CallbackStruct *method = param;
290// Set a property descriptor named createInt32 and associate it with a callback. This allows the CreateInt32 callback to be called from JS.
291static JSVM_PropertyDescriptor descriptor[] = {
292    {"createInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
293};
294// Define OH_JSVM_CreateInt32.
295static JSVM_Value CreateInt32(JSVM_Env env, JSVM_CallbackInfo info)
296{
297    // int32_t represents a 32-bit signed integer, ranging from -2^31 to 2^31 - 1, that is, -2147483648 to 2147483647. 
298    int32_t value = -20;
299    // Create a JS Int32 number.
300    JSVM_Value result = nullptr;
301    JSVM_Status status = OH_JSVM_CreateInt32(env, value, &result);
302    if (status != JSVM_OK) {
303        OH_LOG_ERROR(LOG_APP, "JSVM CreateInt32 fail");
304    } else {
305        int32_t number = 0;
306        OH_JSVM_GetValueInt32(env, result, &number);
307        OH_LOG_INFO(LOG_APP, "JSVM CreateInt32 success: %{public}d", number);
308    }
309    return result;
310}
311```
312
313ArkTS code:
314
315```ts
316import hilog from "@ohos.hilog"
317// Import the native APIs.
318import napitest from "libentry.so"
319let script: string = `
320   function testCreateInt32() {
321       return createInt32();
322   }
323   testCreateInt32()
324   `;
325try {
326  let result = napitest.runJsVm(script);
327  hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateInt32: %{public}s', result);
328} catch (error) {
329  hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateInt32 error: %{public}s', error.message);
330}
331```
332
333### OH_JSVM_CreateUint32
334
335Use **OH_JSVM_CreateUint32** to create a JS number from a 32-bit unsigned integer.
336
337CPP code:
338
339```cpp
340// hello.cpp
341#include "napi/native_api.h"
342#include "ark_runtime/jsvm.h"
343#include <hilog/log.h>
344// Register the CreateUInt32 callback.
345static JSVM_CallbackStruct param[] = {
346    {.data = nullptr, .callback = CreateUInt32},
347};
348static JSVM_CallbackStruct *method = param;
349// Set a property descriptor named createUInt32 and associate it with a callback. This allows the CreateUInt32 callback to be called from JS.
350static JSVM_PropertyDescriptor descriptor[] = {
351    {"createUInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
352};
353// Define OH_JSVM_CreateUint32.
354static JSVM_Value CreateUInt32(JSVM_Env env, JSVM_CallbackInfo info)
355{
356    
357    // 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.
358    // uint32_t represents a 32-bit unsigned integer, ranging from 0 to 2^32 - 1, that is, 0 to 4294967295.     
359    uint32_t value = 26;
360    // Create a JS Uint32 number.
361    JSVM_Value result = nullptr;
362    JSVM_Status status = OH_JSVM_CreateUint32(env, value, &result);
363    if (status != JSVM_OK) {
364        OH_LOG_ERROR(LOG_APP, "JSVM CreateUInt32 fail");
365    } else {
366        uint32_t number = 0;
367        OH_JSVM_GetValueUint32(env, result, &number);
368        OH_LOG_INFO(LOG_APP, "JSVM CreateUInt32 success: %{public}d", number);
369    }
370    return result;
371}
372```
373
374ArkTS code:
375
376```ts
377import hilog from "@ohos.hilog"
378// Import the native APIs.
379import napitest from "libentry.so"
380let script: string = `
381   function testCreateUInt32() {
382       return createUInt32();
383   }
384   testCreateUInt32()
385   `;
386try {
387  let result = napitest.runJsVm(script);
388  hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateUInt32: %{public}s', result);
389} catch (error) {
390  hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateUInt32 error: %{public}s', error.message);
391}
392```
393
394### OH_JSVM_CreateInt64
395
396Use **OH_JSVM_CreateInt64** to create a JS number from a 64-bit signed integer.
397
398CPP code:
399
400```cpp
401// hello.cpp
402#include "napi/native_api.h"
403#include "ark_runtime/jsvm.h"
404#include <hilog/log.h>
405// Register the CreateInt64 callback.
406static JSVM_CallbackStruct param[] = {
407    {.data = nullptr, .callback = CreateInt64},
408};
409static JSVM_CallbackStruct *method = param;
410// Set a property descriptor named createInt64 and associate it with a callback. This allows the CreateInt64 callback to be called from JS.
411static JSVM_PropertyDescriptor descriptor[] = {
412    {"createInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
413};
414// Define OH_JSVM_CreateInt64.
415static JSVM_Value CreateInt64(JSVM_Env env, JSVM_CallbackInfo info)
416{
417    // int64 represents a 64-bit signed integer, ranging from -2^63 to 2^63 - 1, that is, -9223372036854775808 to 9223372036854775807.
418    int64_t value = 2147483648;
419    // Create a JS Int64 number.
420    JSVM_Value result = nullptr;
421    JSVM_Status status = OH_JSVM_CreateInt64(env, value, &result);
422    if (status != JSVM_OK) {
423        OH_LOG_ERROR(LOG_APP, "JSVM CreateInt64 fail");
424    } else {
425        int64_t number = 0;
426        OH_JSVM_GetValueInt64(env, result, &number);
427        OH_LOG_INFO(LOG_APP, "JSVM CreateInt64 success: %{public}ld", value);
428    }
429    return result;
430}
431```
432
433ArkTS code:
434
435```ts
436import hilog from "@ohos.hilog"
437// Import the native APIs.
438import napitest from "libentry.so"
439let script: string = `
440   function testCreateInt64() {
441       return createInt64();
442   }
443   testCreateInt64()
444   `;
445try {
446  let result = napitest.runJsVm(script);
447  hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateInt64: %{public}s', result);
448} catch (error) {
449  hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateInt64 error: %{public}s', error.message);
450}
451```
452
453### OH_JSVM_CreateDouble
454
455Use **OH_JSVM_CreateDouble** to create a JS number from a double-precision floating-point number.
456
457CPP code:
458
459```cpp
460// hello.cpp
461#include "napi/native_api.h"
462#include "ark_runtime/jsvm.h"
463#include <hilog/log.h>
464// Register the CreateDouble callback.
465static JSVM_CallbackStruct param[] = {
466    {.data = nullptr, .callback = CreateDouble},
467};
468static JSVM_CallbackStruct *method = param;
469// Set a property descriptor named createDouble and associate it with a callback. This allows the CreateDouble callback to be called from JS.
470static JSVM_PropertyDescriptor descriptor[] = {
471    {"createDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
472};
473// Define OH_JSVM_CreateDouble.
474static JSVM_Value CreateDouble(JSVM_Env env, JSVM_CallbackInfo info)
475{
476    double value = 1.234;
477    // Create a JS double number.
478    JSVM_Value result = nullptr;
479    JSVM_Status status = OH_JSVM_CreateDouble(env, value, &result);
480    if (status != JSVM_OK) {
481        OH_LOG_ERROR(LOG_APP, "JSVM CreateDouble fail");
482    } else {
483        double number = 0;
484        OH_JSVM_GetValueDouble(env, result, &number);
485        OH_LOG_INFO(LOG_APP, "JSVM CreateDouble success: %{public}f", number);
486    }
487    return result;
488}
489```
490
491ArkTS code:
492
493```ts
494import hilog from "@ohos.hilog"
495// Import the native APIs.
496import napitest from "libentry.so"
497let script: string = `
498   function testCreateDouble() {
499       return createDouble();
500   }
501   testCreateDouble()
502   `;
503try {
504  let result = napitest.runJsVm(script);
505  hilog.info(0x0000, 'testJSVM', 'Test JSVM testCreateDouble: %{public}s', result);
506} catch (error) {
507  hilog.error(0x0000, 'testJSVM', 'Test JSVM testCreateDouble error: %{public}s', error.message);
508}
509```
510