• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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