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