# Working with Objects Using JSVM-API ## Overview JSVM-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. ## Basic Concepts You 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. - 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. - 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. ## Available APIs | API | Description | | -------------------------- | -------------------------------------------- | | OH_JSVM_GetPrototype | Obtains the prototype of a JS object. | | OH_JSVM_CreateObject | Creates a default JS object. | | 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. | | 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. | | OH_JSVM_Typeof | Returns the type of a JS object. | | OH_JSVM_Instanceof | Checks whether an object is an instance of a constructor. | | OH_JSVM_TypeTagObject | Associates the value of the **type_tag** pointer with a JS object or an external object. | | OH_JSVM_CheckObjectTypeTag | Checks whether a tag matches the tag type of an object. | | OH_JSVM_CreateSymbol | Creates a symbol object based on the given descriptor. | |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. | | OH_JSVM_CreateExternal | Creates a JS object that wraps an external pointer. | | OH_JSVM_GetValueExternal | Obtains the external data pointer previously passed to **OH_JSVM_CreateExternal**. | ## Example If 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. ### OH_JSVM_GetPrototype Obtains the prototype of a JS object. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the GetPrototype callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = GetPrototype}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named getPrototype and associate it with a callback. This allows the GetPrototype callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_GetPrototype. static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info) { // Create an empty object. JSVM_Value obj = nullptr; OH_JSVM_CreateObject(env, &obj); const char *testNameStr = "set and get proto"; JSVM_Value propValue = nullptr; JSVM_Value key = nullptr; OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &key); OH_JSVM_CreateStringUtf8(env, testNameStr, strlen(testNameStr), &propValue); OH_JSVM_SetProperty(env, obj, key, propValue); // Obtain properties. JSVM_Value propResult = nullptr; JSVM_Status status = OH_JSVM_GetProperty(env, obj, key, &propResult); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success"); } return propResult; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = `getPrototype()`; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'testJSVM', 'Test JSVM getPrototype: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM getPrototype error: %{public}s', error.message); } ``` ### OH_JSVM_CreateObject Creates a default JS object. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the CreateObject callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = CreateObject}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named createObject and associate it with a callback. This allows the CreateObject callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_CreateObject. static JSVM_Value CreateObject(JSVM_Env env, JSVM_CallbackInfo info) { JSVM_Value object = nullptr; // Create an empty object. JSVM_Status status = OH_JSVM_CreateObject(env, &object); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM CreateObject fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM CreateObject success"); } // Set the object property. JSVM_Value name = nullptr; // Set the property name to "name". OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &name); JSVM_Value value = nullptr; // Set the property value to "Hello from N-API!" OH_JSVM_CreateStringUtf8(env, "Hello OH_JSVM_CreateObject!", JSVM_AUTO_LENGTH, &value); // Set the property on the object. OH_JSVM_SetProperty(env, object, name, value); return object; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = `createObject()`; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'testJSVM', 'Test JSVM createObject: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM createObject error: %{public}s', error.message); } ``` ### 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. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the ObjectFreeze callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = ObjectFreeze}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named objectFreeze and associate it with a callback. This allows the ObjectFreeze callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_ObjectFreeze. static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info) { // Accept an object passed in from JS. size_t argc = 1; JSVM_Value argv[1] = {nullptr}; OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); // Call OH_JSVM_ObjectFreeze to freeze the object passed in. JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]); if (status == JSVM_OK) { OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success"); } // Check whether the properties of the frozen object can be modified. JSVM_Value value = nullptr; OH_JSVM_CreateInt32(env, 111111, &value); OH_JSVM_SetNamedProperty(env, argv[0], "data", value); // Return the properties modified after the freezing to JS. return argv[0]; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = ` let obj = { data: 55, message: "hello world"}; objectFreeze(obj) ` try { let result = napitest.runJsVm(script); // The property values of the frozen object remain unchanged. hilog.info(0x0000, 'testJSVM', 'Test JSVM objectFreeze: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM objectFreeze error: %{public}s', error.message); } ``` ### 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. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the ObjectSeal callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = ObjectSeal}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named objectSeal and associate it with a callback. This allows the ObjectSeal callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"objectSeal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_ObjectSeal. static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info) { // Accept an object passed in from JS. size_t argc = 1; JSVM_Value argv[1] = {nullptr}; OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); // Call OH_JSVM_ObjectSeal to seal the object passed in. JSVM_Status status = OH_JSVM_ObjectSeal(env, argv[0]); if (status == JSVM_OK) { OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal success"); } // Check whether the properties of the sealed object can be modified, deleted, or added. // Modify a property of the sealed object. JSVM_Value changeValue = nullptr; OH_JSVM_CreateInt32(env, 111111, &changeValue); OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue); // Delete a property from the sealed object. JSVM_Value deleteProperty = nullptr; OH_JSVM_CreateStringUtf8(env, "message", JSVM_AUTO_LENGTH, &deleteProperty); bool result = false; OH_JSVM_DeleteProperty(env, argv[0], deleteProperty, &result); if (result) { OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed"); } // Add a property to the sealed object. JSVM_Value addValue = nullptr; OH_JSVM_CreateStringUtf8(env, "addValue", JSVM_AUTO_LENGTH, &addValue); OH_JSVM_SetNamedProperty(env, argv[0], "newProperty", addValue); // Return the modified object to JS. return argv[0]; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = ` let obj = { data: 55, message: "hello world"}; objectSeal(obj) ` try { let result = napitest.runJsVm(script); // Properties of a sealed object can be modified, but cannot be added or deleted. hilog.info(0x0000, 'testJSVM', 'Test JSVM objectSeal: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM objectSeal error: %{public}s', error.message); } ``` ### OH_JSVM_Typeof Returns the type of a JS object. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the GetTypeof callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = GetTypeof}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named getTypeof and associate it with a callback. This allows the GetTypeof callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_Typeof. static JSVM_Value GetTypeof(JSVM_Env env, JSVM_CallbackInfo info) { size_t argc = 1; JSVM_Value args[1] = {nullptr}; OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); JSVM_ValueType valueType; OH_JSVM_Typeof(env, args[0], &valueType); JSVM_Value type = nullptr; switch (valueType) { case JSVM_UNDEFINED: OH_LOG_INFO(LOG_APP, "JSVM Input type is undefined"); OH_JSVM_CreateStringUtf8(env, "Input type is undefined", JSVM_AUTO_LENGTH, &type); break; case JSVM_NULL: OH_LOG_INFO(LOG_APP, "JSVM Input type is null"); OH_JSVM_CreateStringUtf8(env, "Input type is null", JSVM_AUTO_LENGTH, &type); break; case JSVM_BOOLEAN: OH_LOG_INFO(LOG_APP, "JSVM Input type is boolean"); OH_JSVM_CreateStringUtf8(env, "Input type is boolean", JSVM_AUTO_LENGTH, &type); break; case JSVM_NUMBER: OH_LOG_INFO(LOG_APP, "JSVM Input type is number"); OH_JSVM_CreateStringUtf8(env, "Input type is number", JSVM_AUTO_LENGTH, &type); break; case JSVM_STRING: OH_LOG_INFO(LOG_APP, "JSVM Input type is string"); OH_JSVM_CreateStringUtf8(env, "Input type is string", JSVM_AUTO_LENGTH, &type); break; case JSVM_SYMBOL: OH_LOG_INFO(LOG_APP, "JSVM Input type is symbol"); OH_JSVM_CreateStringUtf8(env, "Input type is symbol", JSVM_AUTO_LENGTH, &type); break; case JSVM_OBJECT: OH_LOG_INFO(LOG_APP, "JSVM Input type is object"); OH_JSVM_CreateStringUtf8(env, "Input type is object", JSVM_AUTO_LENGTH, &type); break; case JSVM_FUNCTION: OH_LOG_INFO(LOG_APP, "JSVM Input type is function"); OH_JSVM_CreateStringUtf8(env, "Input type is function", JSVM_AUTO_LENGTH, &type); break; case JSVM_EXTERNAL: OH_LOG_INFO(LOG_APP, "JSVM Input type is external"); OH_JSVM_CreateStringUtf8(env, "Input type is external", JSVM_AUTO_LENGTH, &type); break; case JSVM_BIGINT: OH_LOG_INFO(LOG_APP, "JSVM Input type is bigint"); OH_JSVM_CreateStringUtf8(env, "Input type is bigint", JSVM_AUTO_LENGTH, &type); break; default: OH_LOG_INFO(LOG_APP, "JSVM Input type does not match any"); OH_JSVM_CreateStringUtf8(env, " ", JSVM_AUTO_LENGTH, &type); break; } return type; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = ` getTypeof(true); `; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'JSVM', 'GetTypeof: %{public}s', result); } catch (error) { hilog.error(0x0000, 'JSVM', 'GetTypeof: %{public}s', error.message); } ``` ### OH_JSVM_Instanceof Checks whether an object is an instance of a constructor. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the InstanceOf callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = InstanceOf}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named instanceOf and associate it with a callback. This allows the InstanceOf callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_Instanceof. static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info) { // Obtain the two parameters passed from JS. size_t argc = 2; JSVM_Value args[2] = {nullptr}; OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); bool result = false; JSVM_Status status = OH_JSVM_Instanceof(env, args[0], args[1], &result); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM InstanceOf fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM InstanceOf: %{public}d", result); } JSVM_Value returnValue = nullptr; OH_JSVM_GetBoolean(env, result, &returnValue); return returnValue; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = ` class Person { name; age; constructor(name, age) { this.name = name; this.age = age; } } instanceOf(new Person('Alice', 30), Person); ; `; try { let result = napitest.runJsVm(script.toString()); hilog.info(0x0000, 'JSVM', 'InstanceOf: %{public}s', result); } catch (error) { hilog.error(0x0000, 'JSVM', 'InstanceOf: %{public}s', error.message); } ``` ### OH_JSVM_TypeTagObject Associate the value of the **type_tag** pointer with a JS object so that the object can be identified more accurately. ### OH_JSVM_CheckObjectTypeTag Checks whether a tag matches the tag type of an object. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Registers the SetTypeTagToObject and CheckObjectTypeTag callbacks. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = SetTypeTagToObject}, {.data = nullptr, .callback = CheckObjectTypeTag}, }; static JSVM_CallbackStruct *method = param; // 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. static JSVM_PropertyDescriptor descriptor[] = { {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; #define NUMBERINT_FOUR 4 // Define a static constant JSVM_TypeTag array to store type tags. static const JSVM_TypeTag TagsData[NUMBERINT_FOUR] = { {0x9e4b2449547061b3, 0x33999f8a6516c499}, {0x1d55a794c53a726d, 0x43633f509f9c944e}, {0, 0}, // Indicates the default tag or no tag. {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0}, }; // Define OH_JSVM_TypeTagObject. static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info) { // Obtain the two parameters passed from JS. size_t argc = 2; JSVM_Value args[2] = {nullptr}; OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); // Obtain the index number and convert it to JSVM_Value. int32_t index = 0; OH_JSVM_GetValueInt32(env, args[1], &index); // Set the type tag for the parameter (object). JSVM_Status status = OH_JSVM_TypeTagObject(env, args[0], &TagsData[index]); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success"); } // Convert the bool value to JSVM_Value and return it. JSVM_Value result = nullptr; OH_JSVM_GetBoolean(env, true, &result); return result; } // Define OH_JSVM_CheckObjectTypeTag. static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info) { // Obtain the two parameters passed from JS. size_t argc = 2; JSVM_Value args[2] = {nullptr}; OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); // Obtain the index number and convert it to JSVM_Value. int32_t index = 0; OH_JSVM_GetValueInt32(env, args[1], &index); // Check the type tag of the object. bool checkResult = false; JSVM_Status status = OH_JSVM_CheckObjectTypeTag(env, args[0], &TagsData[index], &checkResult); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject:%{public}d", checkResult); } // Convert the bool value to JSVM_Value and return it. JSVM_Value checked = nullptr; OH_JSVM_GetBoolean(env, checkResult, &checked); return checked; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = ` class Obj { data; message; } let obj= { data: 0, message: "hello world"}; setTypeTagToObject(obj, 0) ` try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'JSVM', 'SetTypeTagToObject: %{public}s', result); } catch (error) { hilog.error(0x0000, 'JSVM', 'SetTypeTagToObject: %{public}s', error.message); } let script: string = ` class Obj { data; message; } let obj= { data: 0, message: "hello world"}; setTypeTagToObject(obj,0) checkObjectTypeTag(obj,0); ` try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'JSVM', 'CheckObjectTypeTag: %{public}s', result); } catch (error) { hilog.error(0x0000, 'JSVM', 'CheckObjectTypeTag: %{public}s', error.message); } ``` ### OH_JSVM_CreateExternal Creates a JS object that wraps an external pointer. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the CreateExternal callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = CreateExternal}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named createExternal and associate it with a callback. This allows the CreateExternal callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_CreateExternal. static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info) { size_t dataSize = 10; void *data = malloc(dataSize); memset(data, 0, dataSize); const char testStr[] = "test"; JSVM_Value external = nullptr; JSVM_Status status = OH_JSVM_CreateExternal( env, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, (void *)testStr, &external); JSVM_Value returnValue = nullptr; bool type = false; if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status); return nullptr; } else { type = true; OH_LOG_INFO(LOG_APP, "JSVM CreateExternal:%{public}d", type); } OH_JSVM_GetBoolean(env, type, &returnValue); // Return the result. return returnValue; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = `createExternal()`; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'testJSVM', 'Test JSVM createExternal: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM createExternal error: %{public}s', error.message); } ``` ### OH_JSVM_GetValueExternal Use **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**. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the GetValueExternal callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = GetValueExternal}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named getValueExternal and associate it with a callback. This allows the GetValueExternal callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_GetValueExternal. static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info) { void *data = (void *)0x12345; JSVM_Value externalValue = nullptr; JSVM_Status status = OH_JSVM_CreateExternal(env, data, nullptr, nullptr, &externalValue); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail"); } void *data_value; status = OH_JSVM_GetValueExternal(env, externalValue, &data_value); bool type = false; if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail"); } type = true; OH_LOG_INFO(LOG_APP, "JSVM API Get ValueExternal:%{public}p", data_value); // Convert the sign bit into a value of int type and pass it. JSVM_Value returnValue = nullptr; OH_JSVM_CreateInt32(env, 0, &returnValue); return returnValue; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = `getValueExternal()`; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'testJSVM', 'Test JSVM getValueExternal: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM getValueExternal error: %{public}s', error.message); } ``` ### OH_JSVM_CreateSymbol 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. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the CreateSymbol callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = CreateSymbol}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named createSymbol and associate it with a callback. This allows the CreateSymbol callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define OH_JSVM_CreateSymbol. static JSVM_Value CreateSymbol(JSVM_Env env, JSVM_CallbackInfo info) { JSVM_Value result = nullptr; const char *des = "only"; OH_JSVM_CreateStringUtf8(env, des, JSVM_AUTO_LENGTH, &result); JSVM_Value returnSymbol = nullptr; OH_JSVM_CreateSymbol(env, result, &returnSymbol); JSVM_Value returnValue = nullptr; bool type = false; JSVM_ValueType valuetypeSymbol; OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol); if (valuetypeSymbol == JSVM_SYMBOL) { OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success"); type = true; } OH_JSVM_GetBoolean(env, type, &returnValue); return returnValue; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = `createSymbol()`; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'testJSVM', 'Test JSVM createSymbol: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM createSymbol error: %{public}s', error.message); } ``` ### 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. CPP code: ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // Register the SymbolFor callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = SymbolFor}, }; static JSVM_CallbackStruct *method = param; // Set a property descriptor named symbolFor and associate it with a callback. This allows the SymbolFor callback to be called from JS. static JSVM_PropertyDescriptor descriptor[] = { {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // Define a constant to store the maximum length of a string. static const int MAX_BUFFER_SIZE = 128; // Define OH_JSVM_SymbolFor. static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info) { JSVM_Value description = nullptr; OH_JSVM_CreateStringUtf8(env, "test_demo", 9, &description); char buffer[MAX_BUFFER_SIZE]; size_t bufferSize = MAX_BUFFER_SIZE; size_t copied = 0; OH_JSVM_GetValueStringUtf8(env, description, buffer, bufferSize, &copied); JSVM_Value symbol = nullptr; OH_JSVM_CreateSymbol(env, description, &symbol); JSVM_Value result_symbol = nullptr; JSVM_Status status = OH_JSVM_SymbolFor(env, nullptr, 0, &result_symbol); JSVM_Value returnValue = nullptr; bool type = false; JSVM_ValueType valuetypeSymbol; OH_JSVM_Typeof(env, result_symbol, &valuetypeSymbol); if (valuetypeSymbol == JSVM_SYMBOL && status == JSVM_OK) { OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SymbolFor success"); type = true; } OH_JSVM_GetBoolean(env, type, &returnValue); // Return the result. return returnValue; } ``` ArkTS code: ```ts import hilog from "@ohos.hilog" // Import the native APIs. import napitest from "libentry.so" let script: string = `symbolFor()`; try { let result = napitest.runJsVm(script); hilog.info(0x0000, 'testJSVM', 'Test JSVM symbolFor: %{public}s', result); } catch (error) { hilog.error(0x0000, 'testJSVM', 'Test JSVM symbolFor error: %{public}s', error.message); } ```