1# Working with Primitives Using JSVM-API
2
3## Introduction
4
5JSVM-API provides APIs for converting data between C/C++ and JavaScript (JS) data types and obtaining the JS object of the specified type.
6
7## Basic Concepts
8
9Before using JSVM-API to operate JS objects, you need to understand the following basic concepts:
10
11- Conversion between JS and C/C primitives: You can use JSVM-API to convert JS values to C/C++ data types, for example, convert a JS value into a C/C++ integer and convert a JS string into a C/C++ string array. You can also convert C/C++ data into a JS value and return the JS value to JS.
12
13## Available APIs
14
15| API                  | Description                                               |
16| ---------------------- | ------------------------------------------------------- |
17| OH_JSVM_CoerceToBool   | Converts a JS value to an object of the Boolean type.  |
18| OH_JSVM_CoerceToNumber | Converts a JS value to an object of the number type.   |
19| OH_JSVM_CoerceToObject | Converts a JS value to an object of the object type.   |
20| OH_JSVM_CoerceToString | Converts a JS value to an object of the string type.   |
21| OH_JSVM_GetBoolean       | Obtains a JS singleton object that is used to represent the given Boolean value.|
22| OH_JSVM_GetValueBool    | Obtains the C Boolean primitive equivalent of the given JS Boolean.|
23| OH_JSVM_GetGlobal      | Obtains the **global** object of the current environment.                                     |
24| OH_JSVM_GetNull          | Obtains the JS **null** object.                                       |
25| OH_JSVM_GetUndefined     | Obtains the JS **undefined** object.                                  |
26
27## Example
28
29If 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 related to primitives.
30
31### OH_JSVM_CoerceToBool
32
33Use **OH_JSVM_CoerceToBool** to forcibly convert a JS value to a JS Boolean value.
34
35CPP code:
36
37```cpp
38// hello.cpp
39#include "napi/native_api.h"
40#include "ark_runtime/jsvm.h"
41#include <hilog/log.h>
42// Register the CoerceToBool callback.
43static JSVM_CallbackStruct param[] = {
44    {.data = nullptr, .callback = CoerceToBool},
45};
46static JSVM_CallbackStruct *method = param;
47// Set a property descriptor named coerceToBool and associate it with a callback. This allows the CoerceToBool callback to be called from JS.
48static JSVM_PropertyDescriptor descriptor[] = {
49    {"coerceToBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
50};
51// Define OH_JSVM_CoerceToBool.
52static JSVM_Value CoerceToBool(JSVM_Env env, JSVM_CallbackInfo info)
53{
54    size_t argc = 1;
55    JSVM_Value args[1] = {nullptr};
56    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
57    JSVM_Value boolean = nullptr;
58    JSVM_Status status = OH_JSVM_CoerceToBool(env, args[0], &boolean);
59    if (status != JSVM_OK) {
60        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToBool failed");
61    } else {
62        bool result = false;
63        OH_JSVM_GetValueBool(env, boolean, &result);
64        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToBool success:%{public}d", result);
65    }
66    return boolean;
67}
68```
69
70ArkTS code:
71
72```ts
73import hilog from "@ohos.hilog"
74// Import the native APIs.
75import napitest from "libentry.so"
76let script: string = `coerceToBool("123")`;
77try {
78  let result = napitest.runJsVm(script);
79  hilog.info(0x0000, 'JSVM', 'CoerceToBool: %{public}s', result);
80} catch (error) {
81  hilog.error(0x0000, 'JSVM', 'CoerceToBool: %{public}s', error.message);
82}
83```
84
85### OH_JSVM_CoerceToNumber
86
87Use **OH_JSVM_CoerceToNumber** to forcibly convert a JS value to a JS number.
88
89CPP code:
90
91```cpp
92// hello.cpp
93#include "napi/native_api.h"
94#include "ark_runtime/jsvm.h"
95#include <hilog/log.h>
96// Register the CoerceToNumber callback.
97static JSVM_CallbackStruct param[] = {
98    {.data = nullptr, .callback = CoerceToNumber},
99};
100static JSVM_CallbackStruct *method = param;
101// Set a property descriptor named coerceToNumber and associate it with a callback. This allows the CoerceToNumber callback to be called from JS.
102static JSVM_PropertyDescriptor descriptor[] = {
103    {"coerceToNumber", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
104};
105// Define OH_JSVM_CoerceToNumber.
106static JSVM_Value CoerceToNumber(JSVM_Env env, JSVM_CallbackInfo info)
107{
108    size_t argc = 1;
109    JSVM_Value args[1] = {nullptr};
110    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
111    JSVM_Value number = nullptr;
112    JSVM_Status status = OH_JSVM_CoerceToNumber(env, args[0], &number);
113    if (status != JSVM_OK) {
114        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToNumber failed");
115    } else {
116        int32_t result = 0;
117        OH_JSVM_GetValueInt32(env, number, &result);
118        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result);
119    }
120    return number;
121}
122```
123
124ArkTS code:
125
126```ts
127import hilog from "@ohos.hilog"
128// Import the native APIs.
129import napitest from "libentry.so"
130let script: string = `coerceToNumber(true)`;
131try {
132  let result = napitest.runJsVm(script);
133  hilog.info(0x0000, 'JSVM', 'CoerceToNumber: %{public}s', result);
134} catch (error) {
135  hilog.error(0x0000, 'JSVM', 'CoerceToNumber: %{public}s', error.message);
136}
137```
138
139### OH_JSVM_CoerceToObject
140
141Use **OH_JSVM_CoerceToObject** to forcibly convert a JS value to a JS object.
142
143CPP code:
144
145```cpp
146// hello.cpp
147#include "napi/native_api.h"
148#include "ark_runtime/jsvm.h"
149#include <hilog/log.h>
150// Register the CoerceToObjec callback.
151static JSVM_CallbackStruct param[] = {
152    {.data = nullptr, .callback = CoerceToObject},
153};
154static JSVM_CallbackStruct *method = param;
155// Set a property descriptor named coerceToObject and associate it with a callback. This allows the CoerceToObject callback to be called from JS.
156static JSVM_PropertyDescriptor descriptor[] = {
157    {"coerceToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
158};
159// Define OH_JSVM_CoerceToObject.
160static JSVM_Value CoerceToObject(JSVM_Env env, JSVM_CallbackInfo info)
161{
162    size_t argc = 1;
163    JSVM_Value args[1] = {nullptr};
164    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
165    JSVM_Value obj = nullptr;
166    JSVM_Status status = OH_JSVM_CoerceToObject(env, args[0], &obj);
167    if (status != JSVM_OK) {
168        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToObject failed");
169        return nullptr;
170    } else {
171        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToObject success");
172    }
173    return obj;
174}
175```
176
177ArkTS code:
178
179```ts
180import hilog from "@ohos.hilog"
181// Import the native APIs.
182import napitest from "libentry.so"
183let script: string = `coerceToObject(123)`;
184try {
185  let result = napitest.runJsVm(script);
186  hilog.info(0x0000, 'JSVM', 'CoerceToObject001: %{public}s', result);
187} catch (error) {
188  hilog.error(0x0000, 'JSVM', 'CoerceToObject001: %{public}s', error.message);
189}
190```
191
192### OH_JSVM_CoerceToString
193
194Use **OH_JSVM_CoerceToString** to forcibly convert a JS value to a JS string.
195
196CPP code:
197
198```cpp
199// hello.cpp
200#include "napi/native_api.h"
201#include "ark_runtime/jsvm.h"
202#include <hilog/log.h>
203// Register the CoerceToString callback.
204static JSVM_CallbackStruct param[] = {
205    {.data = nullptr, .callback = CoerceToString},
206};
207static JSVM_CallbackStruct *method = param;
208// Set a property descriptor named coerceToString and associate it with a callback. This allows the CoerceToString callback to be called from JS.
209static JSVM_PropertyDescriptor descriptor[] = {
210    {"coerceToString", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
211};
212// Define OH_JSVM_CoerceToString.
213static JSVM_Value CoerceToString(JSVM_Env env, JSVM_CallbackInfo info)
214{
215    size_t argc = 1;
216    JSVM_Value args[1] = {nullptr};
217    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
218    JSVM_Value str = nullptr;
219    JSVM_Status status = OH_JSVM_CoerceToString(env, args[0], &str);
220    if (status != JSVM_OK) {
221        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToString fail");
222        return nullptr;
223    } else {
224        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToString success");
225    }
226    return str;
227}
228```
229
230ArkTS code:
231
232```ts
233import hilog from "@ohos.hilog"
234// Import the native APIs.
235import napitest from "libentry.so"
236let script: string = `coerceToString(22222)`;
237try {
238  let result = napitest.runJsVm(script);
239  hilog.info(0x0000, 'JSVM', 'CoerceToString: %{public}s', result);
240} catch (error) {
241  hilog.error(0x0000, 'JSVM', 'CoerceToString: %{public}s', error.message);
242}
243```
244
245### OH_JSVM_GetBoolean
246
247Use **OH_JSVM_GetBoolean** to obtain a JS singleton object that is used to represent the given Boolean value.
248
249CPP code:
250
251```cpp
252// hello.cpp
253#include "napi/native_api.h"
254#include "ark_runtime/jsvm.h"
255#include <hilog/log.h>
256// Register the GetBoolean callback.
257static JSVM_CallbackStruct param[] = {
258    {.data = nullptr, .callback = GetBoolean},
259};
260static JSVM_CallbackStruct *method = param;
261// Set a property descriptor named getBoolean and associate it with a callback. This allows the GetBoolean callback to be called from JS.
262static JSVM_PropertyDescriptor descriptor[] = {
263    {"getBoolean", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
264};
265// Define OH_JSVM_GetBoolean.
266static JSVM_Value GetBoolean(JSVM_Env env, JSVM_CallbackInfo info)
267{
268    // Pass in two parameters and parse them.
269    size_t argc = 2;
270    JSVM_Value argv[2] = {nullptr};
271    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
272    int32_t paramData = 0;
273    OH_JSVM_GetValueInt32(env, argv[0], &paramData);
274    int32_t paramValue = 0;
275    OH_JSVM_GetValueInt32(env, argv[1], &paramValue);
276    JSVM_Value returnValue = nullptr;
277    bool type = false;
278    if (paramData == paramValue) {
279        OH_LOG_INFO(LOG_APP, "JSVM resultType equal");
280        type = true;
281    }
282    JSVM_Status status = OH_JSVM_GetBoolean(env, type, &returnValue);
283    if (status != JSVM_OK) {
284        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToNumber fail");
285    } else {
286        bool result = false;
287        OH_JSVM_GetValueBool(env, returnValue, &result);
288        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result);
289    }
290    // Return the result.
291    return returnValue;
292}
293```
294
295ArkTS code:
296
297```ts
298import hilog from "@ohos.hilog"
299// Import the native APIs.
300import napitest from "libentry.so"
301try {
302  let data = 1;
303  let compareData = 2;
304  let script: string = `getBoolean(${data}, ${compareData})`;
305  let result = napitest.runJsVm(script);
306  hilog.info(0x0000, 'JSVM', 'GetBoolean: %{public}s', result);
307} catch (error) {
308  hilog.error(0x0000, 'JSVM', 'GetBoolean: %{public}s', error.message);
309}
310try {
311  let data = 1;
312  let compareData = 1;
313  let script: string = `getBoolean(${data}, ${compareData})`;
314  let result = napitest.runJsVm(script);
315  hilog.info(0x0000, 'JSVM', 'GetBoolean: %{public}s', result);
316} catch (error) {
317  hilog.error(0x0000, 'JSVM', 'GetBoolean: %{public}s', error.message);
318}
319```
320
321### OH_JSVM_GetValueBool
322
323Use **OH_JSVM_GetValueBool** to obtain the C Boolean primitive equivalent of the given JS Boolean.
324
325CPP code:
326
327```cpp
328// hello.cpp
329#include "napi/native_api.h"
330#include "ark_runtime/jsvm.h"
331#include <hilog/log.h>
332// Register the GetValueBool callback.
333static JSVM_CallbackStruct param[] = {
334    {.data = nullptr, .callback = GetValueBool},
335};
336static JSVM_CallbackStruct *method = param;
337// Set a property descriptor named getValueBool and associate it with a callback. This allows the GetValueBool callback to be called from JS.
338static JSVM_PropertyDescriptor descriptor[] = {
339    {"getValueBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
340};
341// Define OH_JSVM_GetValueBool.
342static JSVM_Value GetValueBool(JSVM_Env env, JSVM_CallbackInfo info)
343{
344    size_t argc = 1;
345    JSVM_Value args[1] = {nullptr};
346    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
347    bool result = false;
348    JSVM_Status status = OH_JSVM_GetValueBool(env, args[0], &result);
349    if (status == JSVM_BOOLEAN_EXPECTED || status != JSVM_OK) {
350        // If OH_JSVM_GetValueBool is successful, JSVM_OK is returned. If a non-Boolean value is passed in, JSVM_BOOLEAN_EXPECTED is returned.
351        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetValueBool fail:%{public}d", status);
352        return nullptr;
353    } else {
354        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetValueBool success:%{public}d", result);
355    }
356    JSVM_Value boolJv = nullptr;
357    OH_JSVM_GetBoolean(env, result, &boolJv);
358    return boolJv;
359}
360```
361
362ArkTS code:
363
364```ts
365import hilog from "@ohos.hilog"
366// Import the native APIs.
367import napitest from "libentry.so"
368// Pass in a Boolean value and a non-Boolean value. After the Boolean value is passed in, the Boolean value is returned. After the non-Boolean value is passed in, undefined is returned.
369try {
370  let data = `"abc"`;
371  let script: string = `getValueBool(${data})`;
372  let result = napitest.runJsVm(script);
373  hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result);
374} catch (error) {
375  hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message);
376}
377try {
378  let data = true;
379  let script: string = `getValueBool(${data})`;
380  let result = napitest.runJsVm(script);
381  hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result);
382} catch (error) {
383  hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message);
384}
385try {
386  let data = false;
387  let script: string = `getValueBool(${data})`;
388  let result = napitest.runJsVm(script);
389  hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result);
390} catch (error) {
391  hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message);
392}
393```
394
395### OH_JSVM_GetGlobal
396
397Use **OH_JSVM_GetGlobal** to obtain a JS **global** object. You can use this API to obtain the **JSVM_Value** that represents a JS global object, so that the JSVM module can interact with the global variables and functions defined in the JS context.
398
399CPP code:
400
401```cpp
402// hello.cpp
403#include "napi/native_api.h"
404#include "ark_runtime/jsvm.h"
405#include <hilog/log.h>
406// Register the GetGlobal callback.
407static JSVM_CallbackStruct param[] = {
408    {.data = nullptr, .callback = GetGlobal},
409};
410static JSVM_CallbackStruct *method = param;
411// Set a property descriptor named getGlobal and associate it with a callback. This allows the GetGlobal callback to be called from JS.
412static JSVM_PropertyDescriptor descriptor[] = {
413    {"getGlobal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
414};
415// Define OH_JSVM_GetGlobal.
416static JSVM_Value GetGlobal(JSVM_Env env, JSVM_CallbackInfo info)
417{
418    // Obtain the global object.
419    JSVM_Value value = nullptr;
420    JSVM_Value global = nullptr;
421    OH_JSVM_CreateInt32(env, 1, &value);
422    JSVM_Status status = OH_JSVM_GetGlobal(env, &global);
423    OH_JSVM_SetNamedProperty(env, global, "Row", value);
424    if (status != JSVM_OK) {
425        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetGlobal fail");
426    } else {
427        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetGlobal success");
428    }
429    return global;
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 = `getGlobal()`
440try {
441  let result = napitest.runJsVm(script);
442  hilog.info(0x0000, 'JSVM', 'GetGlobal: %{public}s', result);
443} catch (error) {
444  hilog.error(0x0000, 'JSVM', 'GetGlobal: %{public}s', error.message);
445}
446```
447
448### OH_JSVM_GetNull
449
450Use **OH_JSVM_GetNull** to obtain a JS **null** object.
451
452CPP code:
453
454```cpp
455// hello.cpp
456#include "napi/native_api.h"
457#include "ark_runtime/jsvm.h"
458#include <hilog/log.h>
459// Register the GetNull callback.
460static JSVM_CallbackStruct param[] = {
461    {.data = nullptr, .callback = GetNull},
462};
463static JSVM_CallbackStruct *method = param;
464// Set a property descriptor named getNull and associate it with a callback. This allows the GetNull callback to be called from JS.
465static JSVM_PropertyDescriptor descriptor[] = {
466    {"getNull", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
467};
468// Define OH_JSVM_GetNull.
469static JSVM_Value GetNull(JSVM_Env env, JSVM_CallbackInfo info) {
470    JSVM_Value nullValue = nullptr;
471    JSVM_Status status = OH_JSVM_GetNull(env, &nullValue);
472    if (status != JSVM_OK) {
473        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetNull fail");
474    } else {
475        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNull success");
476    }
477    return nullValue;
478}
479```
480
481ArkTS code:
482
483```ts
484import hilog from "@ohos.hilog"
485// Import the native APIs.
486import napitest from "libentry.so"
487try {
488  let script: string = `getNull()`;
489  let result = napitest.runJsVm(script);
490  hilog.info(0x0000, 'JSVM', 'GetNull: %{public}s', result);
491} catch (error) {
492  hilog.error(0x0000, 'JSVM', 'GetNull: %{public}s', error.message);
493}
494```
495
496### OH_JSVM_GetUndefined
497
498Use **OH_JSVM_GetUndefined** to obtain a JS **undefined** object.
499
500CPP code:
501
502```cpp
503// hello.cpp
504#include "napi/native_api.h"
505#include "ark_runtime/jsvm.h"
506#include <hilog/log.h>
507// Register the GetUndefined callback.
508static JSVM_CallbackStruct param[] = {
509    {.data = nullptr, .callback = GetUndefined},
510};
511static JSVM_CallbackStruct *method = param;
512// Set a property descriptor named getUndefined and associate it with a callback. This allows the GetUndefined callback to be called from JS.
513static JSVM_PropertyDescriptor descriptor[] = {
514    {"getUndefined", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
515};
516// Define OH_JSVM_GetUndefined.
517static JSVM_Value GetUndefined(JSVM_Env env, JSVM_CallbackInfo info)
518{
519    //Obtain and parse the input parameters.
520    size_t argc = 1;
521    JSVM_Value args[1] = {nullptr};
522    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
523    // Create the value 'undefined'.
524    JSVM_Value value = nullptr;
525    JSVM_Status status = OH_JSVM_GetUndefined(env, &value);
526    if (status != JSVM_OK) {
527        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetUndefined failed");
528    } else {
529        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetUndefined success");
530    }
531    return value;
532}
533```
534
535API declaration:
536
537ArkTS code:
538
539```ts
540import hilog from "@ohos.hilog"
541// Import the native APIs.
542import napitest from "libentry.so"
543try {
544  let script: string = `getUndefined()`;
545  let result = napitest.runJsVm(script);
546  hilog.info(0x0000, 'JSVM', 'GetUndefined: %{public}s', result);
547} catch (error) {
548  hilog.error(0x0000, 'JSVM', 'GetUndefined: %{public}s', error.message);
549}
550```
551