目录

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.

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. The following only demonstrates the C++ and ArkTS code for object management APIs.

[h2]OH_JSVM_GetPrototype

Call OH_JSVM_GetPrototype to obtain the prototype of a JS object.

CPP code:

#include "napi/native_api.h"
#include "hilog/log.h"
#include "ark_runtime/jsvm.h"
// ...

// Sample method for OH_JSVM_GetPrototype
static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info)
{
    size_t argc = 1;
    JSVM_Value argv[1] = {nullptr};
    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    JSVM_Value result{nullptr};
    JSVM_Status status = OH_JSVM_GetPrototype(env, argv[0], &result);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success");
    }
    return result;
}
// Register the GetPrototype callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetPrototype},
};
static JSVM_CallbackStruct *method = param;
// Alias of the GetPrototype method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(const myObject = {};
    const proto = getPrototype(myObject);
    console.info(proto === Object.prototype);)JS";

Expected result:

JSVM GetPrototype success

[h2]OH_JSVM_CreateObject

Call OH_JSVM_CreateObject to create a default JS object.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

// Sample method for 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 property of the object
    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 OH_JSVM_CreateObject!"
    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;
}
// Register the CreateObject callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = CreateObject},
};
static JSVM_CallbackStruct *method = param;
// Alias of the CreateObject method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(createObject())JS";

Expected result:

JSVM CreateObject success

[h2]OH_JSVM_ObjectFreeze

Call 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.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

// Sample method for OH_JSVM_ObjectFreeze
const int FREEZE_TEST_VALUE = 111111;
static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Accept an object passed from the JavaScript side
    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 passed object
    JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]);
    if (status == JSVM_OK) {
        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success");
    }
    // Test whether the property of the frozen object can be modified
    JSVM_Value value = nullptr;
    OH_JSVM_CreateInt32(env, FREEZE_TEST_VALUE, &value);
    OH_JSVM_SetNamedProperty(env, argv[0], "data", value);
    // Return the modified property of the frozen object to the JavaScript side
    return argv[0];
}
// Register the ObjectFreeze callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = ObjectFreeze},
};
static JSVM_CallbackStruct *method = param;
// Alias of the ObjectFreeze method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(let obj = { data: 55, message: "hello world"};
  objectFreeze(obj))JS";

Expected result:

Test JSVM OH_JSVM_ObjectFreeze success

[h2]OH_JSVM_ObjectSeal

Call 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.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

// Sample method for OH_JSVM_ObjectSeal
const int TEST_VALUE = 111111;
static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Accept an object passed from the JavaScript side
    size_t argc = 1;
    JSVM_Value argv[1] = {nullptr};
    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    // Call the OH_JSVM_ObjectSeal API to seal the passed object so that new properties cannot be added.
    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 properties of the sealed object can be modified, deleted, or added.
    // Modify the sealed object.
    JSVM_Value changeValue = nullptr;
    OH_JSVM_CreateInt32(env, TEST_VALUE, &changeValue);
    OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue);
    // Delete 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_ERROR(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed");
    }
    // Add 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 sealed object to the JavaScript side.
    return argv[0];
}
// Register the ObjectSeal callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = ObjectSeal},
};
static JSVM_CallbackStruct *method = param;
// Alias of the ObjectSeal method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"objectSeal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS( let obj = { data: 55, message: "hello world"};
  objectSeal(obj))JS";

Expected result:

Test JSVM OH_JSVM_ObjectSeal success

[h2]OH_JSVM_Typeof

Call OH_JSVM_Typeof to return the type of a JS object.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

// Sample method for 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;
}
// Register the GetTypeof callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetTypeof},
};
static JSVM_CallbackStruct *method = param;
// Alias of the GetTypeof method for TS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(getTypeof(true);)JS";

Expected result:

JSVM Input type is boolean

[h2]OH_JSVM_Instanceof

Call OH_JSVM_Instanceof to check whether an object is an instance of a constructor.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

// Sample method for OH_JSVM_Instanceof
static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Obtain two parameters passed from the JavaScript side
    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;
}
// Register the InstanceOf callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = InstanceOf},
};
static JSVM_CallbackStruct *method = param;
// Alias of the InstanceOf method for TS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(class Person {
        name;
        age;
        constructor(name, age) {
          this.name = name;
          this.age = age;
        }
      }
     instanceOf(new Person('Alice', 30), Person);
     ;)JS";

Expected result:

JSVM InstanceOf: 1

[h2]OH_JSVM_TypeTagObject

Call 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.

[h2]OH_JSVM_CheckObjectTypeTag

Call OH_JSVM_CheckObjectTypeTag to check whether a tag matches the tag type of an object.

CPP code:

#include "napi/native_api.h"
#include "hilog/log.h"
#include "ark_runtime/jsvm.h"
#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}, // Used to indicate no tag or the default tag
    {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0},
};
// Sample method for OH_JSVM_TypeTagObject
static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Obtain two parameters passed from the JavaScript side
    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]);
    // Convert the bool result to JSVM_Value and return it
    JSVM_Value result = nullptr;
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail");
        OH_JSVM_GetBoolean(env, false, &result);
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success");
        OH_JSVM_GetBoolean(env, true, &result);
    }
    return result;
}
// Sample method for OH_JSVM_CheckObjectTypeTag
static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Obtain two parameters passed from the JavaScript side
    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 CheckObjectTypeTag fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM CheckObjectTypeTag:%{public}d", checkResult);
    }
    // Convert the bool result to JSVM_Value and return it
    JSVM_Value checked = nullptr;
    OH_JSVM_GetBoolean(env, checkResult, &checked);
    return checked;
}
// Register the SetTypeTagToObject and CheckObjectTypeTag callbacks
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = SetTypeTagToObject},
    {.data = nullptr, .callback = CheckObjectTypeTag},
};
static JSVM_CallbackStruct *method = param;
// Aliases of the SetTypeTagToObject and CheckObjectTypeTag methods for TS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"setTypeTagToObject", nullptr, method, nullptr, nullptr, nullptr, JSVM_DEFAULT},
    {"checkObjectTypeTag", nullptr, method+1, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(
         class Obj {
           data;
           message;
         }
         let obj= { data: 0, message: "hello world"};
         setTypeTagToObject(obj, 0);
         checkObjectTypeTag(obj, 0);)JS";

Expected result:

JSVM SetTypeTagToObject success
JSVM CheckObjectTypeTag:1

[h2]OH_JSVM_CreateExternal

Call OH_JSVM_CreateExternal to create a JS object that wraps an external pointer.

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.

CPP code:

#include "napi/native_api.h"
#include "hilog/log.h"
#include "ark_runtime/jsvm.h"
#include <cstdlib>
#include <cstring>
// ...

// Sample method for OH_JSVM_CreateExternal
static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info)
{
    size_t dataSize = 10;
    void *data = malloc(dataSize);
    if (data == nullptr) {
        OH_LOG_ERROR(LOG_APP, "JSVM Failed to malloc.");
        return nullptr;
    }
    memset(data, 0, dataSize);
    const char* testStr = "test";
    JSVM_Value external = nullptr;
    JSVM_Status status = OH_JSVM_CreateExternal(
        env, data, [](JSVM_Env env, void *data, void *hint) {free(data);}, (void *)testStr, &external);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status);
        free(data);
        data = nullptr;
        return nullptr;
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM CreateExternal success");
    }
    return external;
}
// Register the CreateExternal callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = CreateExternal},
};
static JSVM_CallbackStruct *method = param;
// Alias of the CreateExternal method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(createExternal())JS";

Expected result:

JSVM CreateExternal success

[h2]OH_JSVM_GetValueExternal

Call 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.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

// Sample method for OH_JSVM_GetValueExternal
static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info)
{
    static int data = 0x12345;
    JSVM_Value externalValue = nullptr;
    JSVM_Status status = OH_JSVM_CreateExternal(env, (void*)&data, nullptr, nullptr, &externalValue);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateExternal success");
    }
    void *dataValue;
    status = OH_JSVM_GetValueExternal(env, externalValue, &dataValue);
    if (status != JSVM_OK) {
        OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail");
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM GetValueExternal success");
    }
    // Convert the symbol bit to int type and pass it out
    JSVM_Value returnValue = nullptr;
    int retData = *static_cast<int *>(dataValue);
    OH_JSVM_CreateInt32(env, retData, &returnValue);
    return returnValue;
}
// Register the GetValueExternal callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetValueExternal},
};
static JSVM_CallbackStruct *method = param;
// Alias of the GetValueExternal method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(getValueExternal())JS";

Expected result:

JSVM OH_JSVM_CreateExternal success
JSVM GetValueExternal success

[h2]OH_JSVM_CreateSymbol

Call 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.

CPP code:

#include "napi/native_api.h"
#include "hilog/log.h"
#include "ark_runtime/jsvm.h"
// ...

// Sample method for 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_ValueType valuetypeSymbol;
    OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol);
    if (valuetypeSymbol == JSVM_SYMBOL) {
        OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success");
    } else {
        OH_LOG_ERROR(LOG_APP, "JSVM CreateSymbol fail");
    }
    return returnSymbol;
}
// Register the CreateSymbol callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = CreateSymbol},
};
static JSVM_CallbackStruct *method = param;
// Alias of the CreateSymbol method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(createSymbol())JS";

Expected result:

JSVM CreateSymbol Success

[h2]OH_JSVM_SymbolFor

Call 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.

CPP code:

#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include "hilog/log.h"
// ...

static const size_t TESTMO_LENGTH = 9;
// Define a constant to store the maximum string length
static const int MAX_BUFFER_SIZE = 128;
// Sample method for OH_JSVM_SymbolFor
static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info)
{
    JSVM_Value description = nullptr;
    OH_JSVM_CreateStringUtf8(env, "test_demo", TESTMO_LENGTH, &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, buffer, copied, &result_symbol);
    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");
    }
    // Return the result
    return result_symbol;
}
// Register the SymbolFor callback
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = SymbolFor},
};
static JSVM_CallbackStruct *method = param;
// Alias of the SymbolFor method for JS calls
static JSVM_PropertyDescriptor descriptor[] = {
    {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};
// Sample test JS
const char* SRC_CALL_NATIVE = R"JS(symbolFor())JS";

Expected result:

JSVM OH_JSVM_SymbolFor success