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 involved in primitive-related APIs. 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; 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; 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; 273 OH_JSVM_GetValueInt32(env, argv[0], ¶mData); 274 int32_t paramValue; 275 OH_JSVM_GetValueInt32(env, argv[1], ¶mValue); 276 JSVM_Value returnValue = nullptr; 277 bool type = false; 278 if (paramData == paramValue) 279 { 280 OH_LOG_INFO(LOG_APP, "JSVM resultType equal"); 281 type = true; 282 } 283 JSVM_Status status = OH_JSVM_GetBoolean(env, type, &returnValue); 284 if (status != JSVM_OK) { 285 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToNumber fail"); 286 } else { 287 bool result = false; 288 OH_JSVM_GetValueBool(env, returnValue, &result); 289 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result); 290 } 291 // Return the result. 292 return returnValue; 293} 294``` 295 296ArkTS code: 297 298```ts 299import hilog from "@ohos.hilog" 300// Import the native APIs. 301import napitest from "libentry.so" 302try { 303 let data = 1; 304 let compareData = 2; 305 let script: string = `getBoolean(${data}, ${compareData})`; 306 let result = napitest.runJsVm(script); 307 hilog.info(0x0000, 'JSVM', 'GetBoolean: %{public}s', result); 308} catch (error) { 309 hilog.error(0x0000, 'JSVM', 'GetBoolean: %{public}s', error.message); 310} 311try { 312 let data = 1; 313 let compareData = 1; 314 let script: string = `getBoolean(${data}, ${compareData})`; 315 let result = napitest.runJsVm(script); 316 hilog.info(0x0000, 'JSVM', 'GetBoolean: %{public}s', result); 317} catch (error) { 318 hilog.error(0x0000, 'JSVM', 'GetBoolean: %{public}s', error.message); 319} 320``` 321 322### OH_JSVM_GetValueBool 323 324Use **OH_JSVM_GetValueBool** to obtain the C Boolean equivalent of the given JS Boolean. 325 326CPP code: 327 328```cpp 329// hello.cpp 330#include "napi/native_api.h" 331#include "ark_runtime/jsvm.h" 332#include <hilog/log.h> 333// Register the GetValueBool callback. 334static JSVM_CallbackStruct param[] = { 335 {.data = nullptr, .callback = GetValueBool}, 336}; 337static JSVM_CallbackStruct *method = param; 338// Set a property descriptor named getValueBool and associate it with a callback. This allows the GetValueBool callback to be called from JS. 339static JSVM_PropertyDescriptor descriptor[] = { 340 {"getValueBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 341}; 342// Define OH_JSVM_GetValueBool. 343static JSVM_Value GetValueBool(JSVM_Env env, JSVM_CallbackInfo info) 344{ 345 size_t argc = 1; 346 JSVM_Value args[1] = {nullptr}; 347 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 348 bool result; 349 JSVM_Status status = OH_JSVM_GetValueBool(env, args[0], &result); 350 if (status == JSVM_BOOLEAN_EXPECTED || status != JSVM_OK) { 351 // If OH_JSVM_GetValueBool is successful, JSVM_OK is returned. If a non-Boolean value is passed in, JSVM_BOOLEAN_EXPECTED is returned. 352 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetValueBool fail:%{public}d", status); 353 return nullptr; 354 } else { 355 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetValueBool success:%{public}d", result); 356 } 357 JSVM_Value boolJv; 358 OH_JSVM_GetBoolean(env, result, &boolJv); 359 return boolJv; 360} 361``` 362 363ArkTS code: 364 365```ts 366import hilog from "@ohos.hilog" 367// Import the native APIs. 368import napitest from "libentry.so" 369// 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. 370try { 371 let data = `"abc"`; 372 let script: string = `getValueBool(${data})`; 373 let result = napitest.runJsVm(script); 374 hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result); 375} catch (error) { 376 hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message); 377} 378try { 379 let data = true; 380 let script: string = `getValueBool(${data})`; 381 let result = napitest.runJsVm(script); 382 hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result); 383} catch (error) { 384 hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message); 385} 386try { 387 let data = false; 388 let script: string = `getValueBool(${data})`; 389 let result = napitest.runJsVm(script); 390 hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result); 391} catch (error) { 392 hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message); 393} 394``` 395 396### OH_JSVM_GetGlobal 397 398Use **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. 399 400CPP code: 401 402```cpp 403// hello.cpp 404#include "napi/native_api.h" 405#include "ark_runtime/jsvm.h" 406#include <hilog/log.h> 407// Register the GetGlobal callback. 408static JSVM_CallbackStruct param[] = { 409 {.data = nullptr, .callback = GetGlobal}, 410}; 411static JSVM_CallbackStruct *method = param; 412// Set a property descriptor named getGlobal and associate it with a callback. This allows the GetGlobal callback to be called from JS. 413static JSVM_PropertyDescriptor descriptor[] = { 414 {"getGlobal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 415}; 416// Define OH_JSVM_GetGlobal. 417static JSVM_Value GetGlobal(JSVM_Env env, JSVM_CallbackInfo info) 418{ 419 // Obtain the global object. 420 JSVM_Value value = nullptr; 421 JSVM_Value global; 422 OH_JSVM_CreateInt32(env, 1, &value); 423 JSVM_Status status = OH_JSVM_GetGlobal(env, &global); 424 OH_JSVM_SetNamedProperty(env, global, "Row", value); 425 if (status != JSVM_OK) { 426 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetGlobal fail"); 427 } else { 428 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetGlobal success"); 429 } 430 return global; 431} 432``` 433 434ArkTS code: 435 436```ts 437import hilog from "@ohos.hilog" 438// Import the native APIs. 439import napitest from "libentry.so" 440let script: string = `getGlobal()` 441try { 442 let result = napitest.runJsVm(script); 443 hilog.info(0x0000, 'JSVM', 'GetGlobal: %{public}s', result); 444} catch (error) { 445 hilog.error(0x0000, 'JSVM', 'GetGlobal: %{public}s', error.message); 446} 447``` 448 449### OH_JSVM_GetNull 450 451Use **OH_JSVM_GetNull** to obtain a JS **null** object. 452 453CPP code: 454 455```cpp 456// hello.cpp 457#include "napi/native_api.h" 458#include "ark_runtime/jsvm.h" 459#include <hilog/log.h> 460// Register the GetNull callback. 461static JSVM_CallbackStruct param[] = { 462 {.data = nullptr, .callback = GetNull}, 463}; 464static JSVM_CallbackStruct *method = param; 465// Set a property descriptor named getNull and associate it with a callback. This allows the GetNull callback to be called from JS. 466static JSVM_PropertyDescriptor descriptor[] = { 467 {"getNull", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 468}; 469// Define OH_JSVM_GetNull. 470static JSVM_Value GetNull(JSVM_Env env, JSVM_CallbackInfo info) { 471 JSVM_Value nullValue; 472 JSVM_Status status = OH_JSVM_GetNull(env, &nullValue); 473 if (status != JSVM_OK) { 474 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetNull fail"); 475 } else { 476 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNull success"); 477 } 478 return nullValue; 479} 480``` 481 482ArkTS code: 483 484```ts 485import hilog from "@ohos.hilog" 486// Import the native APIs. 487import napitest from "libentry.so" 488try { 489 let script: string = `getNull()`; 490 let result = napitest.runJsVm(script); 491 hilog.info(0x0000, 'JSVM', 'GetNull: %{public}s', result); 492} catch (error) { 493 hilog.error(0x0000, 'JSVM', 'GetNull: %{public}s', error.message); 494} 495``` 496 497### OH_JSVM_GetUndefined 498 499Use **OH_JSVM_GetUndefined** to obtain a JS **undefined** object. 500 501CPP code: 502 503```cpp 504// hello.cpp 505#include "napi/native_api.h" 506#include "ark_runtime/jsvm.h" 507#include <hilog/log.h> 508// Register the GetUndefined callback. 509static JSVM_CallbackStruct param[] = { 510 {.data = nullptr, .callback = GetUndefined}, 511}; 512static JSVM_CallbackStruct *method = param; 513// Set a property descriptor named getUndefined and associate it with a callback. This allows the GetUndefined callback to be called from JS. 514static JSVM_PropertyDescriptor descriptor[] = { 515 {"getUndefined", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 516}; 517// Define OH_JSVM_GetUndefined. 518static JSVM_Value GetUndefined(JSVM_Env env, JSVM_CallbackInfo info) 519{ 520 // Obtain and parse the parameters passed in. 521 size_t argc = 1; 522 JSVM_Value args[1] = {nullptr}; 523 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 524 // Create the value 'undefined'. 525 JSVM_Value value; 526 JSVM_Status status = OH_JSVM_GetUndefined(env, &value); 527 if (status != JSVM_OK) { 528 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetUndefined failed"); 529 } else { 530 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetUndefined success"); 531 } 532 return value; 533} 534``` 535 536API declaration: 537 538ArkTS code: 539 540```ts 541import hilog from "@ohos.hilog" 542// Import the native APIs. 543import napitest from "libentry.so" 544try { 545 let script: string = `getUndefined()`; 546 let result = napitest.runJsVm(script); 547 hilog.info(0x0000, 'JSVM', 'GetUndefined: %{public}s', result); 548} catch (error) { 549 hilog.error(0x0000, 'JSVM', 'GetUndefined: %{public}s', error.message); 550} 551``` 552