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++ code involved in primitive development. 30 31### OH_JSVM_CoerceToBool 32 33Call **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// Define OH_JSVM_CoerceToBool. 43static JSVM_Value CoerceToBool(JSVM_Env env, JSVM_CallbackInfo info) 44{ 45 size_t argc = 1; 46 JSVM_Value args[1] = {nullptr}; 47 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 48 JSVM_Value boolean = nullptr; 49 JSVM_Status status = OH_JSVM_CoerceToBool(env, args[0], &boolean); 50 if (status != JSVM_OK) { 51 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToBool failed"); 52 } else { 53 bool result = false; 54 OH_JSVM_GetValueBool(env, boolean, &result); 55 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToBool success:%{public}d", result); 56 } 57 return boolean; 58} 59// Register the CoerceToBool callback. 60static JSVM_CallbackStruct param[] = { 61 {.data = nullptr, .callback = CoerceToBool}, 62}; 63static JSVM_CallbackStruct *method = param; 64// Alias for the CoerceToBool method to be called from JS. 65static JSVM_PropertyDescriptor descriptor[] = { 66 {"coerceToBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 67}; 68// Call C++ code from JS. 69const char *srcCallNative = R"JS(coerceToBool("123"))JS"; 70``` 71 72Expected result: 73``` 74SVM OH_JSVM_CoerceToBool success:1 75``` 76 77### OH_JSVM_CoerceToNumber 78 79Call **OH_JSVM_CoerceToNumber** to forcibly convert a JS value to a JS number. 80 81CPP code: 82 83```cpp 84// hello.cpp 85#include "napi/native_api.h" 86#include "ark_runtime/jsvm.h" 87#include <hilog/log.h> 88// Define OH_JSVM_CoerceToNumber. 89static JSVM_Value CoerceToNumber(JSVM_Env env, JSVM_CallbackInfo info) 90{ 91 size_t argc = 1; 92 JSVM_Value args[1] = {nullptr}; 93 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 94 JSVM_Value number = nullptr; 95 JSVM_Status status = OH_JSVM_CoerceToNumber(env, args[0], &number); 96 if (status != JSVM_OK) { 97 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToNumber failed"); 98 } else { 99 int32_t result = 0; 100 OH_JSVM_GetValueInt32(env, number, &result); 101 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result); 102 } 103 return number; 104} 105// Register the CoerceToNumber callback. 106static JSVM_CallbackStruct param[] = { 107 {.data = nullptr, .callback = CoerceToNumber}, 108}; 109static JSVM_CallbackStruct *method = param; 110// Alias for the CoerceToNumber method to be called from JS. 111static JSVM_PropertyDescriptor descriptor[] = { 112 {"coerceToNumber", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 113}; 114// Call C++ code from JS. 115const char *srcCallNative = R"JS(coerceToNumber(true))JS"; 116``` 117 118Expected result: 119``` 120JSVM OH_JSVM_CoerceToNumber success:1 121``` 122 123### OH_JSVM_CoerceToObject 124 125Call **OH_JSVM_CoerceToObject** to forcibly convert a JS value to a JS object. 126 127CPP code: 128 129```cpp 130// hello.cpp 131#include "napi/native_api.h" 132#include "ark_runtime/jsvm.h" 133#include <hilog/log.h> 134// Define OH_JSVM_CoerceToObject. 135static JSVM_Value CoerceToObject(JSVM_Env env, JSVM_CallbackInfo info) 136{ 137 size_t argc = 1; 138 JSVM_Value args[1] = {nullptr}; 139 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 140 JSVM_Value obj = nullptr; 141 JSVM_Status status = OH_JSVM_CoerceToObject(env, args[0], &obj); 142 if (status != JSVM_OK) { 143 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToObject failed"); 144 return nullptr; 145 } else { 146 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToObject success"); 147 } 148 return obj; 149} 150// Register the CoerceToObject callback. 151static JSVM_CallbackStruct param[] = { 152 {.data = nullptr, .callback = CoerceToObject}, 153}; 154static JSVM_CallbackStruct *method = param; 155// Alias for the CoerceToObject method to be called from JS. 156static JSVM_PropertyDescriptor descriptor[] = { 157 {"coerceToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 158}; 159// Call C++ code from JS. 160const char *srcCallNative = R"JS(coerceToObject(123))JS"; 161``` 162 163Expected result: 164``` 165JSVM OH_JSVM_CoerceToObject success 166``` 167 168### OH_JSVM_CoerceToString 169 170Call **OH_JSVM_CoerceToString** to forcibly convert a JS value to a JS string. 171 172CPP code: 173 174```cpp 175// hello.cpp 176#include "napi/native_api.h" 177#include "ark_runtime/jsvm.h" 178#include <hilog/log.h> 179// Define OH_JSVM_CoerceToString. 180static JSVM_Value CoerceToString(JSVM_Env env, JSVM_CallbackInfo info) 181{ 182 size_t argc = 1; 183 JSVM_Value args[1] = {nullptr}; 184 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 185 JSVM_Value str = nullptr; 186 JSVM_Status status = OH_JSVM_CoerceToString(env, args[0], &str); 187 if (status != JSVM_OK) { 188 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToString fail"); 189 return nullptr; 190 } else { 191 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToString success"); 192 } 193 return str; 194} 195// Register the CoerceToString callback. 196static JSVM_CallbackStruct param[] = { 197 {.data = nullptr, .callback = CoerceToString}, 198}; 199static JSVM_CallbackStruct *method = param; 200// Alias for the CoerceToString method to be called from JS. 201static JSVM_PropertyDescriptor descriptor[] = { 202 {"coerceToString", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 203}; 204// Call C++ code from JS. 205const char *srcCallNative = R"JS(coerceToString(22222))JS"; 206``` 207 208Expected result: 209``` 210JSVM OH_JSVM_CoerceToString success 211``` 212 213### OH_JSVM_GetBoolean 214 215Call **OH_JSVM_GetBoolean** to obtain a JS singleton object that is used to represent the given Boolean value. 216 217CPP code: 218 219```cpp 220// hello.cpp 221#include "napi/native_api.h" 222#include "ark_runtime/jsvm.h" 223#include <hilog/log.h> 224// Define OH_JSVM_GetBoolean. 225static JSVM_Value GetBoolean(JSVM_Env env, JSVM_CallbackInfo info) 226{ 227 // Pass in two parameters and parse them. 228 size_t argc = 2; 229 JSVM_Value argv[2] = {nullptr}; 230 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 231 int32_t paramData = 0; 232 OH_JSVM_GetValueInt32(env, argv[0], ¶mData); 233 int32_t paramValue = 0; 234 OH_JSVM_GetValueInt32(env, argv[1], ¶mValue); 235 JSVM_Value returnValue = nullptr; 236 bool type = false; 237 if (paramData == paramValue) { 238 OH_LOG_INFO(LOG_APP, "JSVM resultType equal"); 239 type = true; 240 } 241 JSVM_Status status = OH_JSVM_GetBoolean(env, type, &returnValue); 242 if (status != JSVM_OK) { 243 OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToNumber fail"); 244 } else { 245 bool result = false; 246 OH_JSVM_GetValueBool(env, returnValue, &result); 247 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result); 248 } 249 // Return the result. 250 return returnValue; 251} 252// Register the GetBoolean callback. 253static JSVM_CallbackStruct param[] = { 254 {.data = nullptr, .callback = GetBoolean}, 255}; 256static JSVM_CallbackStruct *method = param; 257// Alias for the GetBoolean method to be called from JS. 258static JSVM_PropertyDescriptor descriptor[] = { 259 {"getBoolean", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 260}; 261// Call C++ code from JS. 262const char *srcCallNative = R"JS(getBoolean(1, 2); 263 getBoolean(1, 1))JS"; 264``` 265 266Expected result: 267``` 268JSVM OH_JSVM_CoerceToNumber success:0 269JSVM resultType equal 270JSVM OH_JSVM_CoerceToNumber success:1 271``` 272 273### OH_JSVM_GetValueBool 274 275Call **OH_JSVM_GetValueBool** to obtain the C Boolean primitive equivalent of the given JS Boolean. 276 277CPP code: 278 279```cpp 280// hello.cpp 281#include "napi/native_api.h" 282#include "ark_runtime/jsvm.h" 283#include <hilog/log.h> 284// Define OH_JSVM_GetValueBool. 285static JSVM_Value GetValueBool(JSVM_Env env, JSVM_CallbackInfo info) 286{ 287 size_t argc = 1; 288 JSVM_Value args[1] = {nullptr}; 289 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 290 bool result = false; 291 JSVM_Status status = OH_JSVM_GetValueBool(env, args[0], &result); 292 if (status == JSVM_BOOLEAN_EXPECTED || status != JSVM_OK) { 293 // If OH_JSVM_GetValueBool is successful, JSVM_OK is returned. If a non-Boolean value is passed in, JSVM_BOOLEAN_EXPECTED is returned. 294 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetValueBool fail:%{public}d", status); 295 return nullptr; 296 } else { 297 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetValueBool success:%{public}d", result); 298 } 299 JSVM_Value boolJv = nullptr; 300 OH_JSVM_GetBoolean(env, result, &boolJv); 301 return boolJv; 302} 303// Register the GetValueBool callback. 304static JSVM_CallbackStruct param[] = { 305 {.data = nullptr, .callback = GetValueBool}, 306}; 307static JSVM_CallbackStruct *method = param; 308// Alias for the GetValueBool method to be called from JS. 309static JSVM_PropertyDescriptor descriptor[] = { 310 {"getValueBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 311}; 312// Call C++ code from JS. 313const char *srcCallNative = R"JS(getValueBool("abc"); 314 getValueBool(true); 315 getValueBool(false);)JS"; 316``` 317 318Expected result: 319``` 320JSVM OH_JSVM_GetValueBool fail:7 321JSVM OH_JSVM_GetValueBool success:1 322JSVM OH_JSVM_GetValueBool success:0 323``` 324 325### OH_JSVM_GetGlobal 326 327Call **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. 328 329CPP code: 330 331```cpp 332// hello.cpp 333#include "napi/native_api.h" 334#include "ark_runtime/jsvm.h" 335#include <hilog/log.h> 336// Define OH_JSVM_GetGlobal. 337static JSVM_Value GetGlobal(JSVM_Env env, JSVM_CallbackInfo info) 338{ 339 // Obtain the global object. 340 JSVM_Value value = nullptr; 341 JSVM_Value global = nullptr; 342 OH_JSVM_CreateInt32(env, 1, &value); 343 JSVM_Status status = OH_JSVM_GetGlobal(env, &global); 344 OH_JSVM_SetNamedProperty(env, global, "Row", value); 345 if (status != JSVM_OK) { 346 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetGlobal fail"); 347 } else { 348 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetGlobal success"); 349 } 350 return global; 351} 352// Register the GetGlobal callback. 353static JSVM_CallbackStruct param[] = { 354 {.data = nullptr, .callback = GetGlobal}, 355}; 356static JSVM_CallbackStruct *method = param; 357// Alias for the GetGlobal method to be called from JS. 358static JSVM_PropertyDescriptor descriptor[] = { 359 {"getGlobal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 360}; 361// Call C++ code from JS. 362const char *srcCallNative = R"JS(getGlobal())JS"; 363``` 364 365Expected result: 366``` 367JSVM OH_JSVM_GetGlobal success 368``` 369 370### OH_JSVM_GetNull 371 372Call **OH_JSVM_GetNull** to obtain a JS **null** object. 373 374CPP code: 375 376```cpp 377// hello.cpp 378#include "napi/native_api.h" 379#include "ark_runtime/jsvm.h" 380#include <hilog/log.h> 381// Define OH_JSVM_GetNull. 382static JSVM_Value GetNull(JSVM_Env env, JSVM_CallbackInfo info) { 383 JSVM_Value nullValue = nullptr; 384 JSVM_Status status = OH_JSVM_GetNull(env, &nullValue); 385 if (status != JSVM_OK) { 386 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetNull fail"); 387 } else { 388 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNull success"); 389 } 390 return nullValue; 391} 392// Register the GetNull callback. 393static JSVM_CallbackStruct param[] = { 394 {.data = nullptr, .callback = GetNull}, 395}; 396static JSVM_CallbackStruct *method = param; 397// Alias for the GetNull method to be called from JS. 398static JSVM_PropertyDescriptor descriptor[] = { 399 {"getNull", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 400}; 401// Call C++ code from JS. 402const char *srcCallNative = R"JS(getNull())JS"; 403``` 404 405Expected result: 406``` 407JSVM OH_JSVM_GetNull success 408``` 409 410### OH_JSVM_GetUndefined 411 412Call **OH_JSVM_GetUndefined** to obtain a JS **undefined** object. 413 414CPP code: 415 416```cpp 417// hello.cpp 418#include "napi/native_api.h" 419#include "ark_runtime/jsvm.h" 420#include <hilog/log.h> 421// Define OH_JSVM_GetUndefined. 422static JSVM_Value GetUndefined(JSVM_Env env, JSVM_CallbackInfo info) 423{ 424 //Obtain and parse the input parameters. 425 size_t argc = 1; 426 JSVM_Value args[1] = {nullptr}; 427 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 428 // Create the value 'undefined'. 429 JSVM_Value value = nullptr; 430 JSVM_Status status = OH_JSVM_GetUndefined(env, &value); 431 if (status != JSVM_OK) { 432 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetUndefined failed"); 433 } else { 434 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetUndefined success"); 435 } 436 return value; 437} 438// Register the GetUndefined callback. 439static JSVM_CallbackStruct param[] = { 440 {.data = nullptr, .callback = GetUndefined}, 441}; 442static JSVM_CallbackStruct *method = param; 443// Alias for the GetUndefined method to be called from JS. 444static JSVM_PropertyDescriptor descriptor[] = { 445 {"getUndefined", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 446}; 447// Call C++ code from JS. 448const char *srcCallNative = R"JS(getUndefined())JS"; 449``` 450 451Expected result: 452``` 453JSVM OH_JSVM_GetUndefined success 454``` 455