1# Working with Objects Using JSVM-API 2 3## Overview 4 5JSVM-API provides APIs for basic JavaScript (JS) object operations, including creating an object, obtaining the prototype of an object, freezing or sealing an object, and checking the object type. You can use these APIs to manage JS objects. 6 7## Basic Concepts 8 9You may need to define and operate objects when using JSVM-API in development. For example, define an API with an object as an input parameter, perform operations on the object, and have a result object returned. In this process, you need to ensure that the API definition is clear and compatible with the properties and methods of the object. 10 11- API: defines the interaction protocol between components. An API includes input parameters, output result, and possible error handling. By calling APIs, components can interact and exchange data with each other without knowing the internal implementation details. 12- Object: a composite data type that allows values of different types to be stored as an independent entity in JS. An object is a collection of properties and methods. A property is a value associated with an object, and a method is an operation that the object can perform. 13 14## Available APIs 15 16| API | Description | 17| -------------------------- | -------------------------------------------- | 18| OH_JSVM_GetPrototype | Obtains the prototype of a JS object. | 19| OH_JSVM_CreateObject | Creates a default JS object. | 20| OH_JSVM_ObjectFreeze | Freezes a JS object. Once a JS object is frozen, new properties cannot be added to it, existing properties cannot be removed, the enumerability, configurability, or writability of existing properties cannot be changed, and the values of existing properties cannot be changed. | 21| OH_JSVM_ObjectSeal | Seals a JS object. Once a JS object is sealed, new properties cannot be added to it and all existing properties are marked as unconfigurable. | 22| OH_JSVM_Typeof | Returns the type of a JS object. | 23| OH_JSVM_Instanceof | Checks whether an object is an instance of a constructor. | 24| OH_JSVM_TypeTagObject | Associates the value of the **type_tag** pointer with a JS object or an external object. | 25| OH_JSVM_CheckObjectTypeTag | Checks whether a tag matches the tag type of an object.| 26| OH_JSVM_CreateSymbol | Creates a symbol object based on the given descriptor. | 27|OH_JSVM_SymbolFor | Searches for a symbol with the given key in a global (runtime-wide) symbol registry. If a match is found, the symbol will be returned. Otherwise, a symbol will be created in the registry.| 28| OH_JSVM_CreateExternal | Creates a JS object that wraps an external pointer. | 29| OH_JSVM_GetValueExternal | Obtains the external data pointer previously passed to **OH_JSVM_CreateExternal**. | 30 31## Example 32 33If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following only demonstrates the C++ and ArkTS code for object management APIs. 34 35### OH_JSVM_GetPrototype 36 37Call **OH_JSVM_GetPrototype** to obtain the prototype of a JS object. 38 39CPP code: 40 41```cpp 42// hello.cpp 43#include "napi/native_api.h" 44#include "ark_runtime/jsvm.h" 45#include <hilog/log.h> 46#include <fstream> 47#include <string> 48// Register the GetPrototype callback. 49// Define OH_JSVM_GetPrototype. 50static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info) 51{ 52 size_t argc = 1; 53 JSVM_Value argv[1] = {nullptr}; 54 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 55 JSVM_Value result{nullptr}; 56 JSVM_Status status = OH_JSVM_GetPrototype(env, argv[0], &result); 57 if (status != JSVM_OK) { 58 OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail"); 59 } else { 60 OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success"); 61 } 62 return result; 63} 64static JSVM_CallbackStruct param[] = { 65 {.data = nullptr, .callback = GetPrototype}, 66}; 67static JSVM_CallbackStruct *method = param; 68// Alias for the getPrototype method to be called from JS. 69static JSVM_PropertyDescriptor descriptor[] = { 70 {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 71}; 72// Call the C++ code from JS. 73const char* srcCallNative = R"JS(const myObject = {}; 74 const proto = getPrototype(myObject); 75 console.log(proto === Object.prototype);)JS"; 76``` 77 78**Expected output** 79```ts 80JSVM GetPrototype success 81``` 82 83### OH_JSVM_CreateObject 84 85Call **OH_JSVM_CreateObject** to create a default JS object. 86 87CPP code: 88 89```cpp 90// hello.cpp 91#include "napi/native_api.h" 92#include "ark_runtime/jsvm.h" 93#include <hilog/log.h> 94#include <fstream> 95// Define OH_JSVM_CreateObject. 96static JSVM_Value CreateObject(JSVM_Env env, JSVM_CallbackInfo info) 97{ 98 JSVM_Value object = nullptr; 99 // Create an empty object. 100 JSVM_Status status = OH_JSVM_CreateObject(env, &object); 101 if (status != JSVM_OK) { 102 OH_LOG_ERROR(LOG_APP, "JSVM CreateObject fail"); 103 } else { 104 OH_LOG_INFO(LOG_APP, "JSVM CreateObject success"); 105 } 106 // Set the object property. 107 JSVM_Value name = nullptr; 108 // Set the property name to "name". 109 OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &name); 110 JSVM_Value value = nullptr; 111 // Set the property value to "Hello from N-API!" 112 OH_JSVM_CreateStringUtf8(env, "Hello OH_JSVM_CreateObject!", JSVM_AUTO_LENGTH, &value); 113 // Set the property on the object. 114 OH_JSVM_SetProperty(env, object, name, value); 115 return object; 116} 117// Register the CreateObject callback. 118static JSVM_CallbackStruct param[] = { 119 {.data = nullptr, .callback = CreateObject}, 120}; 121static JSVM_CallbackStruct *method = param; 122// Alias for the createObject method to be called from JS. 123static JSVM_PropertyDescriptor descriptor[] = { 124 {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 125}; 126// Call the C++ code from JS. 127const char* srcCallNative = R"JS(createObject())JS"; 128``` 129 130**Expected output** 131```ts 132JSVM CreateObject success 133``` 134 135### OH_JSVM_ObjectFreeze 136 137Call **OH_JSVM_ObjectFreeze** to freeze a JS object. Once a JS object is frozen, new properties cannot be added to it, existing properties cannot be removed, the enumerability, configurability, or writability of existing properties cannot be changed, and the values of existing properties cannot be changed. 138 139CPP code: 140 141```cpp 142// hello.cpp 143#include "napi/native_api.h" 144#include "ark_runtime/jsvm.h" 145#include <hilog/log.h> 146// Define OH_JSVM_ObjectFreeze. 147static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info) 148{ 149 // Accept an object passed in from JS. 150 size_t argc = 1; 151 JSVM_Value argv[1] = {nullptr}; 152 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 153 // Call OH_JSVM_ObjectFreeze to freeze the object passed in. 154 JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]); 155 if (status == JSVM_OK) { 156 OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success"); 157 } 158 // Check whether the properties of the frozen object can be modified. 159 JSVM_Value value = nullptr; 160 OH_JSVM_CreateInt32(env, 111111, &value); 161 OH_JSVM_SetNamedProperty(env, argv[0], "data", value); 162 // Return the properties modified after the freezing to JS. 163 return argv[0]; 164} 165// Register the ObjectFreeze callback. 166static JSVM_CallbackStruct param[] = { 167 {.data = nullptr, .callback = ObjectFreeze}, 168}; 169static JSVM_CallbackStruct *method = param; 170// Alias for the ObjectFreeze method to be called from JS. 171static JSVM_PropertyDescriptor descriptor[] = { 172 {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 173}; 174// Call the C++ code from JS. 175const char* srcCallNative = R"JS(let obj = { data: 55, message: "hello world"}; 176 objectFreeze(obj))JS"; 177``` 178 179**Expected output** 180```ts 181Test JSVM OH_JSVM_ObjectFreeze success 182``` 183 184### OH_JSVM_ObjectSeal 185 186Call **OH_JSVM_ObjectSeal** to seal a JS object. Once a JS object is sealed, new properties cannot be added to it and all existing properties are marked as unconfigurable. 187 188CPP code: 189 190```cpp 191// hello.cpp 192#include "napi/native_api.h" 193#include "ark_runtime/jsvm.h" 194#include <hilog/log.h> 195// Define OH_JSVM_ObjectSeal. 196static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info) 197{ 198 // Accept an object passed in from JS. 199 size_t argc = 1; 200 JSVM_Value argv[1] = {nullptr}; 201 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 202 // Call OH_JSVM_ObjectSeal to seal the object passed in. 203 JSVM_Status status = OH_JSVM_ObjectSeal(env, argv[0]); 204 if (status == JSVM_OK) { 205 OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal success"); 206 } 207 // Check whether the properties of the sealed object can be modified, deleted, or added. 208 // Modify a property of the sealed object. 209 JSVM_Value changeValue = nullptr; 210 OH_JSVM_CreateInt32(env, 111111, &changeValue); 211 OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue); 212 // Delete a property from the sealed object. 213 JSVM_Value deleteProperty = nullptr; 214 OH_JSVM_CreateStringUtf8(env, "message", JSVM_AUTO_LENGTH, &deleteProperty); 215 bool result = false; 216 OH_JSVM_DeleteProperty(env, argv[0], deleteProperty, &result); 217 if (result) { 218 OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed"); 219 } 220 // Add a property to the sealed object. 221 JSVM_Value addValue = nullptr; 222 OH_JSVM_CreateStringUtf8(env, "addValue", JSVM_AUTO_LENGTH, &addValue); 223 OH_JSVM_SetNamedProperty(env, argv[0], "newProperty", addValue); 224 // Return the modified object to JS. 225 return argv[0]; 226} 227// Register the ObjectSeal callback. 228static JSVM_CallbackStruct param[] = { 229 {.data = nullptr, .callback = ObjectSeal}, 230}; 231static JSVM_CallbackStruct *method = param; 232// Alias for the ObjectSeal method to be called from JS. 233static JSVM_PropertyDescriptor descriptor[] = { 234 {"objectSeal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 235}; 236// Call the C++ code from JS. 237const char* srcCallNative = R"JS( let obj = { data: 55, message: "hello world"}; 238 objectSeal(obj))JS"; 239``` 240 241**Expected output** 242```ts 243Test JSVM OH_JSVM_ObjectSeal success 244``` 245 246### OH_JSVM_Typeof 247 248Call **OH_JSVM_Typeof** to return the type of a JS object. 249 250CPP code: 251 252```cpp 253// hello.cpp 254#include "napi/native_api.h" 255#include "ark_runtime/jsvm.h" 256#include <hilog/log.h> 257// Define OH_JSVM_Typeof. 258static JSVM_Value GetTypeof(JSVM_Env env, JSVM_CallbackInfo info) { 259 size_t argc = 1; 260 JSVM_Value args[1] = {nullptr}; 261 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 262 JSVM_ValueType valueType; 263 OH_JSVM_Typeof(env, args[0], &valueType); 264 JSVM_Value type = nullptr; 265 switch (valueType) { 266 case JSVM_UNDEFINED: 267 OH_LOG_INFO(LOG_APP, "JSVM Input type is undefined"); 268 OH_JSVM_CreateStringUtf8(env, "Input type is undefined", JSVM_AUTO_LENGTH, &type); 269 break; 270 case JSVM_NULL: 271 OH_LOG_INFO(LOG_APP, "JSVM Input type is null"); 272 OH_JSVM_CreateStringUtf8(env, "Input type is null", JSVM_AUTO_LENGTH, &type); 273 break; 274 case JSVM_BOOLEAN: 275 OH_LOG_INFO(LOG_APP, "JSVM Input type is boolean"); 276 OH_JSVM_CreateStringUtf8(env, "Input type is boolean", JSVM_AUTO_LENGTH, &type); 277 break; 278 case JSVM_NUMBER: 279 OH_LOG_INFO(LOG_APP, "JSVM Input type is number"); 280 OH_JSVM_CreateStringUtf8(env, "Input type is number", JSVM_AUTO_LENGTH, &type); 281 break; 282 case JSVM_STRING: 283 OH_LOG_INFO(LOG_APP, "JSVM Input type is string"); 284 OH_JSVM_CreateStringUtf8(env, "Input type is string", JSVM_AUTO_LENGTH, &type); 285 break; 286 case JSVM_SYMBOL: 287 OH_LOG_INFO(LOG_APP, "JSVM Input type is symbol"); 288 OH_JSVM_CreateStringUtf8(env, "Input type is symbol", JSVM_AUTO_LENGTH, &type); 289 break; 290 case JSVM_OBJECT: 291 OH_LOG_INFO(LOG_APP, "JSVM Input type is object"); 292 OH_JSVM_CreateStringUtf8(env, "Input type is object", JSVM_AUTO_LENGTH, &type); 293 break; 294 case JSVM_FUNCTION: 295 OH_LOG_INFO(LOG_APP, "JSVM Input type is function"); 296 OH_JSVM_CreateStringUtf8(env, "Input type is function", JSVM_AUTO_LENGTH, &type); 297 break; 298 case JSVM_EXTERNAL: 299 OH_LOG_INFO(LOG_APP, "JSVM Input type is external"); 300 OH_JSVM_CreateStringUtf8(env, "Input type is external", JSVM_AUTO_LENGTH, &type); 301 break; 302 case JSVM_BIGINT: 303 OH_LOG_INFO(LOG_APP, "JSVM Input type is bigint"); 304 OH_JSVM_CreateStringUtf8(env, "Input type is bigint", JSVM_AUTO_LENGTH, &type); 305 break; 306 default: 307 OH_LOG_INFO(LOG_APP, "JSVM Input type does not match any"); 308 OH_JSVM_CreateStringUtf8(env, " ", JSVM_AUTO_LENGTH, &type); 309 break; 310 } 311 return type; 312} 313// Register the GetTypeof callback. 314static JSVM_CallbackStruct param[] = { 315 {.data = nullptr, .callback = GetTypeof}, 316}; 317static JSVM_CallbackStruct *method = param; 318// Alias for the GetTypeof method to be called from JS. 319static JSVM_PropertyDescriptor descriptor[] = { 320 {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 321}; 322// Call the C++ code from JS. 323const char* srcCallNative = R"JS(getTypeof(true);)JS"; 324``` 325 326**Expected output** 327```ts 328JSVM Input type is boolean 329``` 330 331### OH_JSVM_Instanceof 332 333Call **OH_JSVM_Instanceof** to check whether an object is an instance of a constructor. 334 335CPP code: 336 337```cpp 338// hello.cpp 339#include "napi/native_api.h" 340#include "ark_runtime/jsvm.h" 341#include <hilog/log.h> 342// Define OH_JSVM_Instanceof. 343static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info) 344{ 345 // Obtain the two parameters passed from JS. 346 size_t argc = 2; 347 JSVM_Value args[2] = {nullptr}; 348 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 349 bool result = false; 350 JSVM_Status status = OH_JSVM_Instanceof(env, args[0], args[1], &result); 351 if (status != JSVM_OK) { 352 OH_LOG_ERROR(LOG_APP, "JSVM InstanceOf fail"); 353 } else { 354 OH_LOG_INFO(LOG_APP, "JSVM InstanceOf: %{public}d", result); 355 } 356 JSVM_Value returnValue = nullptr; 357 OH_JSVM_GetBoolean(env, result, &returnValue); 358 return returnValue; 359} 360// Register the InstanceOf callback. 361static JSVM_CallbackStruct param[] = { 362 {.data = nullptr, .callback = InstanceOf}, 363}; 364static JSVM_CallbackStruct *method = param; 365// Alias for the InstanceOf method to be called from JS. 366static JSVM_PropertyDescriptor descriptor[] = { 367 {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 368}; 369// Call the C++ code from JS. 370const char* srcCallNative = R"JS(class Person { 371 name; 372 age; 373 constructor(name, age) { 374 this.name = name; 375 this.age = age; 376 } 377 } 378 instanceOf(new Person('Alice', 30), Person); 379 ;)JS"; 380``` 381 382**Expected output** 383```ts 384JSVM InstanceOf: 1 385``` 386 387### OH_JSVM_TypeTagObject 388 389Call **OH_JSVM_TypeTagObject** to associate the value of the **type_tag** pointer with a JS object so that the object can be identified more accurately. 390 391### OH_JSVM_CheckObjectTypeTag 392 393Call **OH_JSVM_CheckObjectTypeTag** to check whether a tag matches the tag type of an object. 394 395CPP code: 396 397```cpp 398// hello.cpp 399#include "napi/native_api.h" 400#include "ark_runtime/jsvm.h" 401#include <hilog/log.h> 402#define NUMBERINT_FOUR 4 403// Define a static constant JSVM_TypeTag array to store type tags. 404static const JSVM_TypeTag TagsData[NUMBERINT_FOUR] = { 405 {0x9e4b2449547061b3, 0x33999f8a6516c499}, 406 {0x1d55a794c53a726d, 0x43633f509f9c944e}, 407 {0, 0}, // Indicates the default tag or no tag. 408 {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0}, 409}; 410// Define OH_JSVM_TypeTagObject. 411static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info) 412{ 413 // Obtain the two parameters passed from JS. 414 size_t argc = 2; 415 JSVM_Value args[2] = {nullptr}; 416 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 417 // Obtain the index number and convert it to JSVM_Value. 418 int32_t index = 0; 419 OH_JSVM_GetValueInt32(env, args[1], &index); 420 // Set the type tag for the parameter (object). 421 JSVM_Status status = OH_JSVM_TypeTagObject(env, args[0], &TagsData[index]); 422 // Convert the bool value to JSVM_Value and return it. 423 JSVM_Value result = nullptr; 424 if (status != JSVM_OK) { 425 OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail"); 426 OH_JSVM_GetBoolean(env, false, &result); 427 } else { 428 OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success"); 429 OH_JSVM_GetBoolean(env, true, &result); 430 } 431 return result; 432} 433// Define OH_JSVM_CheckObjectTypeTag. 434static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info) 435{ 436 // Obtain the two parameters passed from JS. 437 size_t argc = 2; 438 JSVM_Value args[2] = {nullptr}; 439 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 440 // Obtain the index number and convert it to JSVM_Value. 441 int32_t index = 0; 442 OH_JSVM_GetValueInt32(env, args[1], &index); 443 // Check the type tag of the object. 444 bool checkResult = false; 445 JSVM_Status status = OH_JSVM_CheckObjectTypeTag(env, args[0], &TagsData[index], &checkResult); 446 if (status != JSVM_OK) { 447 OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail"); 448 } else { 449 OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject:%{public}d", checkResult); 450 } 451 // Convert the bool value to JSVM_Value and return it. 452 JSVM_Value checked = nullptr; 453 OH_JSVM_GetBoolean(env, checkResult, &checked); 454 return checked; 455} 456// Registers the SetTypeTagToObject and CheckObjectTypeTag callbacks. 457static JSVM_CallbackStruct param[] = { 458 {.data = nullptr, .callback = SetTypeTagToObject}, 459 {.data = nullptr, .callback = CheckObjectTypeTag}, 460}; 461static JSVM_CallbackStruct *method = param; 462// Aliases for the SetTypeTagToObject and CheckObjectTypeTag methods to be called from JS. 463static JSVM_PropertyDescriptor descriptor[] = { 464 {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 465 {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 466}; 467// Call the C++ code from JS. 468const char* srcCallNative = R"JS( 469 class Obj { 470 data; 471 message; 472 } 473 let obj= { data: 0, message: "hello world"}; 474 setTypeTagToObject(obj, 0); 475 checkObjectTypeTag(obj,0);)JS"; 476``` 477 478**Expected output** 479```ts 480JSVM SetTypeTagToObject success 481JSVM SetTypeTagToObject:1 482``` 483 484### OH_JSVM_CreateExternal 485 486Call **OH_JSVM_CreateExternal** to create a JS object that wraps an external pointer. 487> **NOTE**<br>When a JS object is garbage-collected, the content pointed to by the wrapped external pointer is not directly managed by GC. Only the function corresponding to the third input parameter (if it is not nullptr) is called. 488 489CPP code: 490 491```cpp 492// hello.cpp 493#include "napi/native_api.h" 494#include "ark_runtime/jsvm.h" 495#include <hilog/log.h> 496#include <fstream> 497// Define OH_JSVM_CreateExternal. 498static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info) 499{ 500 size_t dataSize = 10; 501 void *data = malloc(dataSize); 502 if (data == nullptr) { 503 OH_LOG_ERROR(LOG_APP, "JSVM Failed to malloc."); 504 return nullptr; 505 } 506 memset(data, 0, dataSize); 507 const char* testStr = "test"; 508 JSVM_Value external = nullptr; 509 JSVM_Status status = OH_JSVM_CreateExternal( 510 env, data, [](JSVM_Env env, void *data, void *hint) {free(data);}, (void *)testStr, &external); 511 if (status != JSVM_OK) { 512 OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status); 513 free(data); 514 data = nullptr; 515 return nullptr; 516 } else { 517 OH_LOG_INFO(LOG_APP, "JSVM CreateExternal success"); 518 } 519 return external; 520} 521// Register the CreateExternal callback. 522static JSVM_CallbackStruct param[] = { 523 {.data = nullptr, .callback = CreateExternal}, 524}; 525static JSVM_CallbackStruct *method = param; 526// Alias for the CreateExternal method to be called from JS. 527static JSVM_PropertyDescriptor descriptor[] = { 528 {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 529}; 530// Call the C++ code from JS. 531const char* srcCallNative = R"JS(createExternal())JS"; 532``` 533 534**Expected output** 535```ts 536JSVM CreateExternal success 537``` 538 539### OH_JSVM_GetValueExternal 540 541Call **OH_JSVM_CreateExternal** to create a JS object that wraps a custom C/C++ object, and call **OH_JSVM_GetValueExternal** to obtain the pointer to the external object wrapped by **OH_JSVM_CreateExternal**. 542 543CPP code: 544 545```cpp 546// hello.cpp 547#include "napi/native_api.h" 548#include "ark_runtime/jsvm.h" 549#include <hilog/log.h> 550// Define OH_JSVM_GetValueExternal. 551static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info) 552{ 553 static int data = 0x12345; 554 JSVM_Value externalValue = nullptr; 555 JSVM_Status status = OH_JSVM_CreateExternal(env, (void*)&data, nullptr, nullptr, &externalValue); 556 if (status != JSVM_OK) { 557 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail"); 558 } else { 559 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateExternal success"); 560 } 561 void *data_value; 562 status = OH_JSVM_GetValueExternal(env, externalValue, &data_value); 563 if (status != JSVM_OK) { 564 OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail"); 565 } else { 566 OH_LOG_INFO(LOG_APP, "JSVM GetValueExternal success"); 567 } 568 // Convert the sign bit into a value of int type and pass it. 569 JSVM_Value returnValue = nullptr; 570 int retData = *static_cast<int *>(data_value); 571 OH_JSVM_CreateInt32(env, retData, &returnValue); 572 return returnValue; 573} 574// Register the GetValueExternal callback. 575static JSVM_CallbackStruct param[] = { 576 {.data = nullptr, .callback = GetValueExternal}, 577}; 578static JSVM_CallbackStruct *method = param; 579// Alias for the GetValueExternal method to be called from JS. 580static JSVM_PropertyDescriptor descriptor[] = { 581 {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 582}; 583// Call the C++ code from JS. 584const char* srcCallNative = R"JS(getValueExternal())JS"; 585``` 586 587**Expected output** 588```ts 589JSVM OH_JSVM_CreateExternal success 590JSVM GetValueExternal success 591``` 592 593### OH_JSVM_CreateSymbol 594 595Call **OH_JSVM_CreateSymbol** to create a symbol. Symbol is a special data type used to indicate a unique identifier. Unlike strings or numbers, the value of a symbol is unique. Even if two symbols have the same description, they are not equal. Symbols are often used as keys for object properties to ensure property uniqueness. 596 597CPP code: 598 599```cpp 600// hello.cpp 601#include "napi/native_api.h" 602#include "ark_runtime/jsvm.h" 603#include <hilog/log.h> 604// Define OH_JSVM_CreateSymbol. 605static JSVM_Value CreateSymbol(JSVM_Env env, JSVM_CallbackInfo info) 606{ 607 JSVM_Value result = nullptr; 608 const char *des = "only"; 609 OH_JSVM_CreateStringUtf8(env, des, JSVM_AUTO_LENGTH, &result); 610 JSVM_Value returnSymbol = nullptr; 611 OH_JSVM_CreateSymbol(env, result, &returnSymbol); 612 JSVM_ValueType valuetypeSymbol; 613 OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol); 614 if (valuetypeSymbol == JSVM_SYMBOL) { 615 OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success"); 616 } else { 617 OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol fail"); 618 } 619 return returnSymbol; 620} 621// Register the CreateSymbol callback. 622static JSVM_CallbackStruct param[] = { 623 {.data = nullptr, .callback = CreateSymbol}, 624}; 625static JSVM_CallbackStruct *method = param; 626// Alias for the CreateSymbol method to be called from JS. 627static JSVM_PropertyDescriptor descriptor[] = { 628 {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 629}; 630// Call the C++ code from JS. 631const char* srcCallNative = R"JS(createSymbol())JS"; 632``` 633 634**Expected output** 635```ts 636JSVM CreateSymbol Success 637``` 638 639### OH_JSVM_SymbolFor 640 641Call **OH_JSVM_SymbolFor** to search for a symbol with the given key in a global (runtime-wide) symbol registry. If a match is found, the symbol will be returned. Otherwise, a symbol will be created in the Registry. 642 643CPP code: 644 645```cpp 646// hello.cpp 647#include "napi/native_api.h" 648#include "ark_runtime/jsvm.h" 649#include <hilog/log.h> 650// Define a constant to store the maximum length of a string. 651static const int MAX_BUFFER_SIZE = 128; 652// Define OH_JSVM_SymbolFor. 653static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info) 654{ 655 JSVM_Value description = nullptr; 656 OH_JSVM_CreateStringUtf8(env, "test_demo", 9, &description); 657 char buffer[MAX_BUFFER_SIZE]; 658 size_t bufferSize = MAX_BUFFER_SIZE; 659 size_t copied = 0; 660 OH_JSVM_GetValueStringUtf8(env, description, buffer, bufferSize, &copied); 661 JSVM_Value symbol = nullptr; 662 OH_JSVM_CreateSymbol(env, description, &symbol); 663 JSVM_Value result_symbol = nullptr; 664 JSVM_Status status = OH_JSVM_SymbolFor(env, buffer, copied, &result_symbol); 665 JSVM_ValueType valuetypeSymbol; 666 OH_JSVM_Typeof(env, result_symbol, &valuetypeSymbol); 667 if (valuetypeSymbol == JSVM_SYMBOL && status == JSVM_OK) { 668 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SymbolFor success"); 669 } 670 // Return the result. 671 return result_symbol; 672} 673// Register the SymbolFor callback. 674static JSVM_CallbackStruct param[] = { 675 {.data = nullptr, .callback = SymbolFor}, 676}; 677static JSVM_CallbackStruct *method = param; 678// Alias for the SymbolFor method to be called from JS. 679static JSVM_PropertyDescriptor descriptor[] = { 680 {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 681}; 682// Call the C++ code from JS. 683const char* srcCallNative = R"JS(symbolFor())JS"; 684``` 685 686**Expected output** 687```ts 688JSVM OH_JSVM_SymbolFor success 689``` 690