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