鸿蒙5.0&next开辟【JSVM-API 支持的数据范例和接口】利用JSVM-API实现JS与C ...

打印 上一主题 下一主题

主题 1798|帖子 1798|积分 5394

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
JSVM-API 支持的数据范例和接口

JSVM-API 的数据范例

JSVM_Status

  1. 是一个枚举数据类型,表示 JSVM-API 接口返回的状态信息。
  2. 每当调用一个 JSVM-API 函数,都会返回该值,表示操作成功与否的相关信息。
复制代码
  1.     typedef enum {
  2.         JSVM_OK,                              /* 成功状态 */
  3.         JSVM_INVALID_ARG,                     /* 无效的状态 */
  4.         JSVM_OBJECT_EXPECTED,                 /* 期待传入对象类型 */
  5.         JSVM_STRING_EXPECTED,                 /* 期待传入字符串类型 */
  6.         JSVM_NAME_EXPECTED,                   /* 期待传入名字 */
  7.         JSVM_FUNCTION_EXPECTED,               /* 期待传入函数类型 */
  8.         JSVM_NUMBER_EXPECTED,                 /* 期待传入数字类型 */
  9.         JSVM_BOOL_EXPECTED,                   /* 期待传入布尔类型 */
  10.         JSVM_ARRAY_EXPECTED,                  /* 期待传入数组类型 */
  11.         JSVM_GENERIC_FAILURE,                 /* 泛型失败状态 */
  12.         JSVM_PENDING_EXCEPTION,               /* 挂起异常状态 */
  13.         JSVM_CANCELLED,                       /* 取消状态 */
  14.         JSVM_ESCAPE_CALLED_TWICE,             /* 转义调用了2次 */
  15.         JSVM_HANDLE_SCOPE_MISMATCH,           /* 句柄作用域不匹配 */
  16.         JSVM_CALLBACK_SCOPE_MISMATCH,         /* 回调作用域不匹配 */
  17.         JSVM_QUEUE_FULL,                      /* 队列满 */
  18.         JSVM_CLOSING,                         /* 关闭中 */
  19.         JSVM_BIGINT_EXPECTED,                 /* 期望传入Bigint类型 */
  20.         JSVM_DATE_EXPECTED,                   /* 期望传入日期类型 */
  21.         JSVM_ARRAYBUFFER_EXPECTED,            /* 期望传入ArrayBuffer类型 */
  22.         JSVM_DETACHABLE_ARRAYBUFFER_EXPECTED, /* 可分离的数组缓冲区预期状态 */
  23.         JSVM_WOULD_DEADLOCK,                  /* 将死锁状态 */
  24.         JSVM_NO_EXTERNAL_BUFFERS_ALLOWED,     /* 不允许外部缓冲区 */
  25.         JSVM_CANNOT_RUN_JS,                   /* 不能执行JS */
  26.         JSVM_JIT_MODE_EXPECTD,                /* 期望在JIT模式下执行 */
  27.     } JSVM_Status;
  28. c++
复制代码
JSVM_ExtendedErrorInfo

一个结构体,在调用函数不乐成时存储了较为详细的错误信息。
  1. typedef struct {
  2.     const char* errorMessage;
  3.     void* engineReserved;
  4.     uint32_t engineErrorCode;
  5.     JSVM_Status errorCode;
  6. } JSVM_ExtendedErrorInfo;
  7. c++
复制代码
JSVM_Value

在C++代码中,表示一个JavaScript值。
JSVM_Env



  • 用于表示JSVM-API执行时的上下文,Native侧函数入参,并传递给函数中的JSVM-API接口。
  • 退出Native侧插件时,JSVM_Env将失效,该事件通过回调传递给OH_JSVM_SetInstanceData。
  • 克制缓存JSVM_Env,克制在差别Worker中传递JSVM_Env。
  • 在差别线程间共享JSVM_Env时,要保证在线程切换时在前一个线程中关闭env scope并在新的线程中打开新的env scope,以保证threadlocal变量的线程隔离。
JSVM_ValueType

JSVM_Value的范例。包含了ECMAScript语言规范中定义的范例,其中JSVM_EXTERNAL表示外部数据范例。
  1. typedef enum {
  2.     JSVM_UNDEFINED,
  3.     JSVM_NULL,
  4.     JSVM_BOOLEAN,
  5.     JSVM_NUMBER,
  6.     JSVM_STRING,
  7.     JSVM_SYMBOL,
  8.     JSVM_OBJECT,
  9.     JSVM_FUNCTION,
  10.     JSVM_EXTERNAL,
  11.     JSVM_BIGINT,
  12. } JSVM_ValueType;
  13. c++
复制代码
JSVM_TypedarrayType

TypedArray的根本二进制标量数据范例。
  1. typedef enum {
  2.     JSVM_INT8_ARRAY,
  3.     JSVM_UINT8_ARRAY,
  4.     JSVM_UINT8_CLAMPED_ARRAY,
  5.     JSVM_INT16_ARRAY,
  6.     JSVM_UINT16_ARRAY,
  7.     JSVM_INT32_ARRAY,
  8.     JSVM_UINT32_ARRAY,
  9.     JSVM_FLOAT32_ARRAY,
  10.     JSVM_FLOAT64_ARRAY,
  11.     JSVM_BIGINT64_ARRAY,
  12.     JSVM_BIGUINT64_ARRAY,
  13. } JSVM_TypedarrayType;
  14. c++
复制代码
JSVM_RegExpFlags

正则表达式标志位。
  1. typedef enum {
  2.     JSVM_REGEXP_NONE = 0,
  3.     JSVM_REGEXP_GLOBAL = 1 << 0,
  4.     JSVM_REGEXP_IGNORE_CASE = 1 << 1,
  5.     JSVM_REGEXP_MULTILINE = 1 << 2,
  6.     JSVM_REGEXP_STICKY = 1 << 3,
  7.     JSVM_REGEXP_UNICODE = 1 << 4,
  8.     JSVM_REGEXP_DOT_ALL = 1 << 5,
  9.     JSVM_REGEXP_LINEAR = 1 << 6,
  10.     JSVM_REGEXP_HAS_INDICES = 1 << 7,
  11.     JSVM_REGEXP_UNICODE_SETS = 1 << 8,
  12. } JSVM_RegExpFlags;
  13. c++
复制代码
编译选项干系范例

JSVM_CompileOptions

共同编译接口 OH_JSVM_CompileScriptWithOptions 利用,是其参数中 options 数组的元素范例。
其中:


  • id 代表这个编译选项的范例。
  • content 代表编译选项的内容。
id 的值和 content 的范例需要对应利用,详细对应关系参考下面对各个选项范例的介绍。
  1. typedef struct {
  2.     /** compile option id. */
  3.     JSVM_CompileOptionId id;
  4.     /** option content. */
  5.     union {
  6.       /** ptr type. */
  7.       void *ptr;
  8.       /** int type. */
  9.       int num;
  10.       /** bool type. */
  11.       _Bool boolean;
  12.     } content;
  13. } JSVM_CompileOptions;
  14. c
复制代码
JSVM_CompileOptionId

JSVM_CompileOptions 中的 id 对应范例, 每个值都有其对应的 content 范例, 其中 JSVM_COMPILE_ENABLE_SOURCE_MAP 对应的范例为 bool,当同时传入的 JSVM_ScriptOrigin 中 sourceMapUrl 不为空时生效。
  1. typedef enum {
  2.     /** compile mode. */
  3.     JSVM_COMPILE_MODE,
  4.     /** code cache content. */
  5.     JSVM_COMPILE_CODE_CACHE,
  6.     /** script origin. */
  7.     JSVM_COMPILE_SCRIPT_ORIGIN,
  8.     /** compile profile content. */
  9.     JSVM_COMPILE_COMPILE_PROFILE,
  10.     /** switch for source map support. */
  11.     JSVM_COMPILE_ENABLE_SOURCE_MAP,
  12. } JSVM_CompileOptionId;
  13. c
复制代码
JSVM_CompileMode

当 id 为 JSVM_COMPILE_MODE,content 的范例,每个值代表一种编译模式:


  • JSVM_COMPILE_MODE_DEFAULT : 默认的编译选项。
  • JSVM_COMPILE_MODE_CONSUME_CODE_CACHE : 斲丧 codecache 举行编译。
  • JSVM_COMPILE_MODE_EAGER_COMPILE : 举行全量编译,不再举行 lazy compile。
  • JSVM_COMPILE_MODE_PRODUCE_COMPILE_PROFILE/JSVM_COMPILE_MODE_CONSUME_COMPILE_PROFILE : 当前暂无效果,请等待后续更新。
  1. typedef enum {
  2.     /** default mode. */
  3.     JSVM_COMPILE_MODE_DEFAULT,
  4.     /** consume code cache. */
  5.     JSVM_COMPILE_MODE_CONSUME_CODE_CACHE,
  6.     /** apply eager compile. */
  7.     JSVM_COMPILE_MODE_EAGER_COMPILE,
  8.     /** preset for compile profile. */
  9.     JSVM_COMPILE_MODE_PRODUCE_COMPILE_PROFILE,
  10.     /** consume compile profile. */
  11.     JSVM_COMPILE_MODE_CONSUME_COMPILE_PROFILE,
  12. } JSVM_CompileMode;
  13. c
复制代码
JSVM_CodeCache

当 id 为 JSVM_COMPILE_CODE_CACHE 时,content 的范例:


  • cache : 指向 code cache 的指针。
  • length : code cache 的大小。
  1. typedef struct {
  2.     /** cache pointer. */
  3.     uint8_t *cache;
  4.     /** length. */
  5.     size_t length;
  6. } JSVM_CodeCache;
  7. c
复制代码
JSVM_ScriptOrigin

当 id 为 JSVM_COMPILE_SCRIPT_ORIGIN 时,content 的范例,存放待编译脚本的源码信息:


  • sourceMapUrl : sourceMap 的路径,当前仅支持运行设备上的当地路径,可以为空。
  • resourceName : 待编译的 js script 的名字。
  1. typedef struct {
  2.     /** Sourcemap url. */
  3.     const char* sourceMapUrl;
  4.     /** Resource name. */
  5.     const char* resourceName;
  6.     /** Resource line offset. */
  7.     size_t resourceLineOffset;
  8.     /** Resource column offset. */
  9.     size_t resourceColumnOffset;
  10. } JSVM_ScriptOrigin;
  11. c
复制代码
JSVM

内存管理范例

JSVM-API包含以下内存管理范例:
JSVM_HandleScope
JSVM_HandleScope数据范例是用来管理JavaScript对象的生命周期的。它允许JavaScript对象在肯定范围内保持活动状态,以便在JavaScript代码中利用。在创建JSVM_HandleScope时,全部在该范围内创建的JavaScript对象都会保持活动状态,直到竣事。如许可以避免在JavaScript代码中利用已经被释放的对象,从而提高代码的可靠性和性能。
JSVM_EscapableHandleScope


  • 由OH_JSVM_OpenEscapableHandleScope接口创建,由OH_JSVM_CloseEscapableHandleScope接口关闭。
  • 表示一种特殊范例的句柄范围,用于将在JSVM_EscapableHandleScope范围内创建的值返回给父scope。
  • 用于OH_JSVM_EscapeHandle接口,将JSVM_EscapableHandleScope提拔到JavaScript对象,以便在外部作用域利用。
JSVM_Ref
指向JSVM_Value,允许用户管理JavaScript值的生命周期。
JSVM_TypeTag
该结构体定义了一个包含两个无符号64位整数的范例标签,用于标识一个JSVM-API值的范例信息。
  1. typedef struct {
  2.     uint64_t lower;
  3.     uint64_t upper;
  4. } JSVM_TypeTag;
  5. c++
复制代码


  • 存储了两个无符号64位整数的128位值,用它来标志JavaScript对象,确保它们属于某种范例。
  • 比OH_JSVM_Instanceof更强的范例查抄,如果对象的原型被利用,OH_JSVM_Instanceof可能会报告误报。
  • JSVM_TypeTag 在与 OH_JSVM_Wrap 联合利用时最有用,由于它确保从包装对象检索的指针可以安全地转换为与先前应用于JavaScript对象的范例标志相对应的Native范例。
回调范例

JSVM-API包含以下回调范例:
JSVM_CallbackStruct
用户提供的 Native callback 的回调函数指针和数据,JSVM_CallbackStruct 将通过 JSVM-API 袒露给 JavaScript。比方,可以利用 OH_JSVM_CreateFunction 接口创建绑定到 Native callback 的 JS 函数,其中 Native callback 就是通过 JSVM_CallbackStruct 结构定义。除非在对象生命周期管理中有特殊要求,一般不在此 callback 中创建 handle 或者 callback scope。
  1. typedef struct {
  2.   JSVM_Value(*callback)(JSVM_Env env, JSVM_CallbackInfo info);
  3.   void* data;
  4. } JSVM_CallbackStruct;
  5. c++
复制代码
JSVM_Callback
JSVM_CallbackStruct 指针范例的范例别名。
定义如下:
  1. typedef JSVM_CallbackStruct* JSVM_Callback;
  2. c++
复制代码
JSVM_CallbackInfo
用户定义的 Native callback,第一个参数范例是 JSVM_Env,第二个参数范例是 JSVM_CallbackInfo。JSVM_CallbackInfo 表示从 JS 侧调用到 Native 侧时携带的调用信息,如参数列表。在实现 Native callback 时,一般利用 OH_JSVM_GetCbInfo 接口从 JSVM_CallbackInfo 中提取调用信息。
JSVM_Finalize
函数指针,用于传入OH_JSVM_SetInstanceData、OH_JSVM_CreateExternal、OH_JSVM_Wrap等接口。JSVM_Finalize在对象被回收时会被调用,可用于在JavaScript对象被垃圾回收时释放Native对象。
写法如下:
  1. typedef void (*JSVM_Finalize)(JSVM_Env env, void* finalizeData, void* finalizeHint);
  2. c++
复制代码
JSVM_PropertyHandlerConfigurationStruct
当执行对象的getter、setter、deleter和enumerator作时,对应的的回调将会触发。
  1. typedef struct {
  2.     JSVM_Value(JSVM_CDECL* genericNamedPropertyGetterCallback)(JSVM_Env env,
  3.                                                                JSVM_Value name,
  4.                                                                JSVM_Value thisArg,
  5.                                                                JSVM_Value namedPropertyData);
  6.     JSVM_Value(JSVM_CDECL* genericNamedPropertySetterCallback)(JSVM_Env env,
  7.                                                                JSVM_Value name,
  8.                                                                JSVM_Value property,
  9.                                                                JSVM_Value thisArg,
  10.                                                                JSVM_Value namedPropertyData);
  11.     JSVM_Value(JSVM_CDECL* genericNamedPropertyDeleterCallback)(JSVM_Env env,
  12.                                                                 JSVM_Value name,
  13.                                                                 JSVM_Value thisArg,
  14.                                                                 JSVM_Value namedPropertyData);
  15.     JSVM_Value(JSVM_CDECL* genericNamedPropertyEnumeratorCallback)(JSVM_Env env,
  16.                                                                    JSVM_Value thisArg,
  17.                                                                    JSVM_Value namedPropertyData);
  18.     JSVM_Value(JSVM_CDECL* genericIndexedPropertyGetterCallback)(JSVM_Env env,
  19.                                                                 JSVM_Value index,
  20.                                                                 JSVM_Value thisArg,
  21.                                                                 JSVM_Value indexedPropertyData);
  22.     JSVM_Value(JSVM_CDECL* genericIndexedPropertySetterCallback)(JSVM_Env env,
  23.                                                                  JSVM_Value index,
  24.                                                                  JSVM_Value property,
  25.                                                                  JSVM_Value thisArg,
  26.                                                                  JSVM_Value indexedPropertyData);
  27.     JSVM_Value(JSVM_CDECL* genericIndexedPropertyDeleterCallback)(JSVM_Env env,
  28.                                                                   JSVM_Value index,
  29.                                                                   JSVM_Value thisArg,
  30.                                                                   JSVM_Value indexedPropertyData);
  31.     JSVM_Value(JSVM_CDECL* genericIndexedPropertyEnumeratorCallback)(JSVM_Env env,
  32.                                                                      JSVM_Value thisArg,
  33.                                                                      JSVM_Value indexedPropertyData);
  34.     JSVM_Value namedPropertyData;
  35.     JSVM_Value indexedPropertyData;
  36. } JSVM_PropertyHandlerConfigurationStruct;
  37. c++
复制代码
JSVM_PropertyHandlerCfg
包含属性监听回调的结构的指针范例。
根本用法如下:
  1. typedef JSVM_PropertyHandlerConfigurationStruct* JSVM_PropertyHandlerCfg;
  2. c++
复制代码
支持的JSVM-API接口

尺度JS引擎的能力通过JSVM-API提供。JSVM-API支持动态链接到差别版本的JS引擎库,从而为开辟者屏蔽掉差别引擎接口的差别。JSVM-API提供引擎生命周期管理、JS context管理、JS代码执行、JS/C++互操作、执行环境快照、codecache等能力,详细可见下文。
利用 JSVM-API 接口创建引擎实例及 JS 执行上下文环境

场景介绍

执行JS代码需要先创建JavaScript VM,创建JS执行的上下文环境。
接口说明

接口功能说明OH_JSVM_Init初始化JavaScript引擎实例OH_JSVM_CreateVM创建JavaScript引擎实例OH_JSVM_DestroyVM销毁JavaScript引擎实例OH_JSVM_OpenVMScope打开一个新的VM scope,引擎实例只能在scope范围内利用,可以保证引擎实例不被销毁OH_JSVM_CloseVMScope关闭VM scopeOH_JSVM_CreateEnv创建一个新的JS执行上下文环境,并注册指定的Native函数OH_JSVM_DestroyEnv销毁一个JS执行上下文环境OH_JSVM_OpenEnvScope打开一个新的Env scope,Env只能在scope范围内利用OH_JSVM_CloseEnvScope关闭Env scopeOH_JSVM_OpenHandleScope打开一个Handle scope,确保scope范围内的JSVM_Value不被GC回收OH_JSVM_CloseHandleScope关闭Handle scope JSVM_InitOptions 的利用描述

通过传入 JSVM_InitOptions 可以初始化具备差别能力的 VM 平台。
场景示例: 常规模式下初始化 VM 平台
  1. static void NormalInit(bool &vmInit) {
  2.     if (!vmInit) {
  3.         // JSVM only need init once
  4.         JSVM_InitOptions initOptions;
  5.         memset(&initOptions, 0, sizeof(initOptions));
  6.         OH_JSVM_Init(&initOptions);
  7.         vmInit = true;
  8.     }
  9. }
  10. c++
复制代码
场景示例: 初始化低内存占用的 VM 平台
  1. static void LowMemoryInit(bool &vmInit) {
  2.     if (!vmInit) {
  3.         // JSVM only need init once
  4.         JSVM_InitOptions initOptions;
  5.         initOptions.argc = 4;
  6.         const char* argv[4];
  7.         argv[1] = "--incremental-marking-hard-trigger=40";
  8.         argv[2] = "--min-semi-space-size=4";
  9.         argv[3] = "--max-semi-space-size=1";
  10.         initOptions.argv = const_cast<char**>(argv);
  11.         OH_JSVM_Init(&initOptions);
  12.         vmInit = true;
  13.     }
  14. }
  15. c++
复制代码
场景示例: 初始化低GC触发频次的 VM 平台
  1. static void LowGCFrequencyInit(bool &vmInit) {
  2.     if (!vmInit) {
  3.         // JSVM only need init once
  4.         JSVM_InitOptions initOptions;
  5.         initOptions.argc = 4;
  6.         const char* argv[4];
  7.         argv[1] = "--incremental-marking-hard-trigger=80";
  8.         argv[2] = "--min-semi-space-size=16";
  9.         argv[3] = "--max-semi-space-size=16";
  10.         initOptions.argv = const_cast<char**>(argv);
  11.         OH_JSVM_Init(&initOptions);
  12.         vmInit = true;
  13.     }
  14. }
  15. c++
复制代码
执行结果: 利用以上三个接口可以分别初始化具备差别能力的 VM 平台。初始化之后,可以创建 VM 实例,并执行 JavaScript 脚本。其中, 调用 LowGCFrequencyInit 接口举行 VM 平台初始化执行 JavaScript 脚本,相比调用 NormalInit 接口所触发的 GC 频次更低。调用 LowMemoryInit 接口举行 VM 平台初始化执行 JavaScript 脚本,相比调用 NormalInit 接口所占用内存更少。
创建 VM 实例

场景示例: 创建及销毁JavaScript引擎实例,包含创建及销毁JS执行上下文环境
  1. bool VM_INIT = false;
  2. static JSVM_Value ConsoleInfo(JSVM_Env env, JSVM_CallbackInfo info) {
  3.     size_t argc = 1;
  4.     JSVM_Value args[1];
  5.     char log[256] = "";
  6.     size_t logLength;
  7.     OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
  8.     OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &logLength);
  9.     log[255] = 0;
  10.     OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log);
  11.     return nullptr;
  12. }
  13. static JSVM_Value Add(JSVM_Env env, JSVM_CallbackInfo info) {
  14.     size_t argc = 2;
  15.     JSVM_Value args[2];
  16.     OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
  17.     double num1, num2;
  18.     env, OH_JSVM_GetValueDouble(env, args[0], &num1);
  19.     OH_JSVM_GetValueDouble(env, args[1], &num2);
  20.     JSVM_Value sum = nullptr;
  21.     OH_JSVM_CreateDouble(env, num1 + num2, &sum);
  22.     return sum;
  23. }
  24. static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
  25.     std::thread t([]() {
  26.         // 可以根据不同的业务需求初始化具备不同能力的 VM 平台:
  27.         // 1. 初始化默认的 VM 平台:调用'NormalInit'接口。
  28.         // 2. 初始化低内存占用的 VM 平台:调用'LowMemoryInit'接口。
  29.         // 3. 初始化低 GC 触发频次的 VM 平台:调用'LowGCFrequencyInit'接口。
  30.         NormalInit(VM_INIT);
  31.         // create vm, and open vm scope
  32.         JSVM_VM vm;
  33.         JSVM_CreateVMOptions options;
  34.         memset(&options, 0, sizeof(options));
  35.         OH_JSVM_CreateVM(&options, &vm);
  36.         JSVM_VMScope vmScope;
  37.         OH_JSVM_OpenVMScope(vm, &vmScope);
  38.         JSVM_CallbackStruct param[] = {
  39.             {.data = nullptr, .callback = ConsoleInfo},
  40.             {.data = nullptr, .callback = Add},
  41.         };
  42.         JSVM_PropertyDescriptor descriptor[] = {
  43.             {"consoleinfo", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
  44.             {"add", NULL, &param[1], NULL, NULL, NULL, JSVM_DEFAULT},
  45.         };
  46.         // create env, register native method, and open env scope
  47.         JSVM_Env env;
  48.         OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
  49.         JSVM_EnvScope envScope;
  50.         OH_JSVM_OpenEnvScope(env, &envScope);
  51.         // open handle scope
  52.         JSVM_HandleScope handleScope;
  53.         OH_JSVM_OpenHandleScope(env, &handleScope);
  54.         std::string sourceCodeStr = "\
  55. {\
  56. let value = add(4.96, 5.28);\
  57. consoleinfo('Result is:' + value);\
  58. }\
  59. ";
  60.         // compile js script
  61.         JSVM_Value sourceCodeValue;
  62.         OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
  63.         JSVM_Script script;
  64.         OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
  65.         JSVM_Value result;
  66.         // run js script
  67.         OH_JSVM_RunScript(env, script, &result);
  68.         JSVM_ValueType type;
  69.         OH_JSVM_Typeof(env, result, &type);
  70.         OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
  71.         // exit vm and clean memory
  72.         OH_JSVM_CloseHandleScope(env, handleScope);
  73.         OH_JSVM_CloseEnvScope(env, envScope);
  74.         OH_JSVM_DestroyEnv(env);
  75.         OH_JSVM_CloseVMScope(vm, vmScope);
  76.         OH_JSVM_DestroyVM(vm);
  77.     });
  78.     t.detach();
  79.     return nullptr;
  80. }
  81. c++
复制代码
利用 JSVM-API 接口编译及执行 JS 代码

场景介绍

编译及执行JS代码。
接口说明

接口功能说明OH_JSVM_CompileScript编译JavaScript代码并返回绑定到当前环境的编译脚本OH_JSVM_CompileScriptWithOrigin编译JavaScript代码并返回绑定到当前环境的编译脚本,同时传入包罗 sourceMapUrl 和源文件名在内的源代码信息,用于处理 source map 信息OH_JSVM_CompileScriptWithOptions通用的编译接口,通过传入 option 数组完成前面的 compile 接口全部功能,同时支持后续选项扩展OH_JSVM_CreateCodeCache为编译脚本创建code cacheOH_JSVM_RunScript执行编译脚本 场景示例: 编译及执行JS代码(创建vm,注册function,执行js,销毁vm)。
  1. #include <cstring>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. // 依赖libjsvm.so
  6. #include "ark_runtime/jsvm.h"
  7. using namespace std;
  8. static JSVM_Value Hello(JSVM_Env env, JSVM_CallbackInfo info) {
  9.     JSVM_Value output;
  10.     void* data = nullptr;
  11.     OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
  12.     OH_JSVM_CreateStringUtf8(env, (char*)data, strlen((char*)data), &output);
  13.     return output;
  14. }
  15. static JSVM_CallbackStruct hello_cb = { Hello, (void*)"Hello" };
  16. static string srcGlobal = R"JS(
  17. const concat = (...args) => args.reduce((a, b) => a + b);
  18. )JS";
  19. static void RunScriptWithOption(JSVM_Env env, string& src,
  20.                                                                 uint8_t** dataPtr = nullptr,
  21.                                                                 size_t* lengthPtr = nullptr) {
  22.     JSVM_HandleScope handleScope;
  23.     OH_JSVM_OpenHandleScope(env, &handleScope);
  24.     JSVM_Value jsSrc;
  25.     OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
  26.     uint8_t* data = dataPtr ? *dataPtr : nullptr;
  27.     auto compilMode = data ? JSVM_COMPILE_MODE_CONSUME_CODE_CACHE :  JSVM_COMPILE_MODE_DEFAULT;
  28.     size_t length = lengthPtr ? *lengthPtr : 0;
  29.     JSVM_Script script;
  30.     // 编译js代码
  31.         JSVM_ScriptOrigin origin {
  32.             // 以包名 helloworld 为例, 假如存在对应的 sourcemap, source map 的的路径可以是 /data/app/el2/100/base/com.example.helloworld/files/index.js.map
  33.             .sourceMapUrl = "/data/app/el2/100/base/com.example.helloworld/files/index.js.map",
  34.             // 源文件名字
  35.             .resourceName = "index.js",
  36.             // scirpt 在源文件中的起始行列号
  37.             .resourceLineOffset = 0,
  38.             .resourceColumnOffset = 0,
  39.         };
  40.         JSVM_CompileOptions option[3];
  41.         option[0] = {
  42.                 .id = JSVM_COMPILE_MODE,
  43.                 .content = { .num = compilMode }
  44.         };
  45.         JSVM_CodeCache codeCache = {
  46.                 .cache = data,
  47.                 .length = length
  48.         };
  49.         option[1] = {
  50.                 .id = JSVM_COMPILE_CODE_CACHE,
  51.                 .content = { .ptr = &codeCache }
  52.         };
  53.         // JSVM_COMPILE_ENABLE_SOURCE_MAP 选项默认值为 false,若为 true 那么对应的 sourceMapUrl 必须不为空
  54.         option[2] = {
  55.                 .id = JSVM_COMPILE_ENABLE_SOURCE_MAP,
  56.                 .content = { .boolean = true }
  57.         };
  58.         OH_JSVM_CompileScriptWithOptions(env, jsSrc, 3, option, &script);
  59.     JSVM_Value result;
  60.     // 执行js代码
  61.     OH_JSVM_RunScript(env, script, &result);
  62.     char resultStr[128];
  63.     size_t size;
  64.     OH_JSVM_GetValueStringUtf8(env, result, resultStr, 128, &size);
  65.     printf("%s\n", resultStr);
  66.     if (dataPtr && lengthPtr && *dataPtr == nullptr) {
  67.         // 将js源码编译出的脚本保存到cache,可以避免重复编译,带来性能提升
  68.         OH_JSVM_CreateCodeCache(env, script, (const uint8_t**)dataPtr, lengthPtr);
  69.         printf("Code cache created with length = %ld\n", *lengthPtr);
  70.     }
  71.     OH_JSVM_CloseHandleScope(env, handleScope);
  72. }
  73. static void RunScript(JSVM_Env env, string& src,
  74.                        bool withOrigin = false,
  75.                        uint8_t** dataPtr = nullptr,
  76.                        size_t* lengthPtr = nullptr) {
  77.     JSVM_HandleScope handleScope;
  78.     OH_JSVM_OpenHandleScope(env, &handleScope);
  79.     JSVM_Value jsSrc;
  80.     OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
  81.     uint8_t* data = dataPtr ? *dataPtr : nullptr;
  82.     size_t length = lengthPtr ? *lengthPtr : 0;
  83.     bool cacheRejected = true;
  84.     JSVM_Script script;
  85.     // 编译js代码
  86.     if (withOrigin) {
  87.             JSVM_ScriptOrigin origin {
  88.                 // 以包名 helloworld 为例, 假如存在对应的 sourcemap, source map 的的路径可以是 /data/app/el2/100/base/com.example.helloworld/files/index.js.map
  89.                     .sourceMapUrl = "/data/app/el2/100/base/com.example.helloworld/files/index.js.map",
  90.                     // 源文件名字
  91.                     .resourceName = "index.js",
  92.                     // scirpt 在源文件中的起始行列号
  93.                     .resourceLineOffset = 0,
  94.                     .resourceColumnOffset = 0,
  95.             };
  96.                 OH_JSVM_CompileScriptWithOrigin(env, jsSrc, data, length, true, &cacheRejected, &origin, &script);
  97.     } else {
  98.             OH_JSVM_CompileScript(env, jsSrc, data, length, true, &cacheRejected, &script);
  99.     }
  100.     printf("Code cache is %s\n", cacheRejected ? "rejected" : "used");
  101.     JSVM_Value result;
  102.     // 执行js代码
  103.     OH_JSVM_RunScript(env, script, &result);
  104.     char resultStr[128];
  105.     size_t size;
  106.     OH_JSVM_GetValueStringUtf8(env, result, resultStr, 128, &size);
  107.     printf("%s\n", resultStr);
  108.     if (dataPtr && lengthPtr && *dataPtr == nullptr) {
  109.         // 将js源码编译出的脚本保存到cache,可以避免重复编译,带来性能提升
  110.         OH_JSVM_CreateCodeCache(env, script, (const uint8_t**)dataPtr, lengthPtr);
  111.         printf("Code cache created with length = %ld\n", *lengthPtr);
  112.     }
  113.     OH_JSVM_CloseHandleScope(env, handleScope);
  114. }
  115. static void CreateSnapshot() {
  116.     JSVM_VM vm;
  117.     JSVM_CreateVMOptions options;
  118.     memset(&options, 0, sizeof(options));
  119.     options.isForSnapshotting = true;
  120.     OH_JSVM_CreateVM(&options, &vm);
  121.     JSVM_VMScope vmScope;
  122.     OH_JSVM_OpenVMScope(vm, &vmScope);
  123.     JSVM_Env env;
  124.     // 将native函数注册成js可调用的方法,hello_cb中记录该native方法的指针和参数等信息
  125.     JSVM_PropertyDescriptor descriptors[] = {
  126.         { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT }
  127.     };
  128.     OH_JSVM_CreateEnv(vm, 1, descriptors, &env);
  129.     JSVM_EnvScope envScope;
  130.     OH_JSVM_OpenEnvScope(env, &envScope);
  131.     // 执行js源码src,src中可以包含任何js语法。也可以调用已注册的native方法。
  132.     string src = srcGlobal + "concat(hello(), ', ', 'World from CreateSnapshot!');";
  133.     RunScript(env, src, true);
  134.     // 创建snapshot,将当前的env保存到字符串,可以在某个时机通过该字符串还原出env,避免重复定义该env中的属性,带来性能提升。
  135.     const char* blobData = nullptr;
  136.     size_t blobSize = 0;
  137.     JSVM_Env envs[1] = { env };
  138.     OH_JSVM_CreateSnapshot(vm, 1, envs, &blobData, &blobSize);
  139.     printf("Snapshot blob size = %ld\n", blobSize);
  140.     // 如果将snapshot保存到文件中,需要考虑应用中的文件读写权限
  141.     ofstream file("/data/storage/el2/base/files/blob.bin", ios::out | ios::binary | ios::trunc);
  142.     file.write(blobData, blobSize);
  143.     file.close();
  144.     OH_JSVM_CloseEnvScope(env, envScope);
  145.     OH_JSVM_DestroyEnv(env);
  146.     OH_JSVM_CloseVMScope(vm, vmScope);
  147.     OH_JSVM_DestroyVM(vm);
  148. }
  149. void RunWithoutSnapshot(uint8_t** dataPtr, size_t* lengthPtr) {
  150.     // 创建虚拟机实例
  151.     JSVM_VM vm;
  152.     OH_JSVM_CreateVM(nullptr, &vm);
  153.     JSVM_VMScope vmScope;
  154.     OH_JSVM_OpenVMScope(vm, &vmScope);
  155.     JSVM_Env env;
  156.     // 将native函数注册成js可调用的方法,hello_cb中记录该native方法的指针和参数等信息
  157.     JSVM_PropertyDescriptor descriptors[] = {
  158.         { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT }
  159.     };
  160.     OH_JSVM_CreateEnv(vm, 1, descriptors, &env);
  161.     JSVM_EnvScope envScope;
  162.     OH_JSVM_OpenEnvScope(env, &envScope);
  163.     // 执行js源码src,src中可以包含任何js语法。也可以调用已注册的native方法。
  164.     auto src = srcGlobal + "concat(hello(), ', ', 'World', ' from RunWithoutSnapshot!')";
  165.     // 其中使用新增接口,可以覆盖原有 Compile 系列接口的功能且具有拓展性
  166.     RunScriptWithOption(env, src, dataPtr, lengthPtr);
  167.     OH_JSVM_CloseEnvScope(env, envScope);
  168.     OH_JSVM_DestroyEnv(env);
  169.     OH_JSVM_CloseVMScope(vm, vmScope);
  170.     OH_JSVM_DestroyVM(vm);
  171. }
  172. void RunWithSnapshot(uint8_t **dataPtr, size_t *lengthPtr) {
  173.     // The lifetime of blobData must not be shorter than that of the vm.
  174.     // 如果从文件中读取snapshot,需要考虑应用中的文件读写权限
  175.     vector<char> blobData;
  176.     ifstream file("/data/storage/el2/base/files/blob.bin", ios::in | ios::binary | ios::ate);
  177.     size_t blobSize = file.tellg();
  178.     blobData.resize(blobSize);
  179.     file.seekg(0, ios::beg);
  180.     file.read(blobData.data(), blobSize);
  181.     file.close();
  182.     // 创建虚拟机实例
  183.     JSVM_VM vm;
  184.     JSVM_CreateVMOptions options;
  185.     memset(&options, 0, sizeof(options));
  186.     options.snapshotBlobData = blobData.data();
  187.     options.snapshotBlobSize = blobSize;
  188.     OH_JSVM_CreateVM(&options, &vm);
  189.     JSVM_VMScope vmScope;
  190.     OH_JSVM_OpenVMScope(vm, &vmScope);
  191.     // 从快照中创建env
  192.     JSVM_Env env;
  193.     OH_JSVM_CreateEnvFromSnapshot(vm, 0, &env);
  194.     JSVM_EnvScope envScope;
  195.     OH_JSVM_OpenEnvScope(env, &envScope);
  196.     // 执行js脚本,因为快照记录的env中定义了hello(),所以无需重新定义。dataPtr中如果保存了编译后的js脚本,就能直接执行js脚本,避免从源码重复编译。
  197.     string src = "concat(hello(), ', ', 'World', ' from RunWithSnapshot!')";
  198.     RunScript(env, src, true, dataPtr, lengthPtr);
  199.     OH_JSVM_CloseEnvScope(env, envScope);
  200.     OH_JSVM_DestroyEnv(env);
  201.     OH_JSVM_CloseVMScope(vm, vmScope);
  202.     OH_JSVM_DestroyVM(vm);
  203. }
  204. void PrintVmInfo() {
  205.     JSVM_VMInfo vmInfo;
  206.     OH_JSVM_GetVMInfo(&vmInfo);
  207.     printf("apiVersion: %d\n", vmInfo.apiVersion);
  208.     printf("engine: %s\n", vmInfo.engine);
  209.     printf("version: %s\n", vmInfo.version);
  210.     printf("cachedDataVersionTag: 0x%x\n", vmInfo.cachedDataVersionTag);
  211. }
  212. static intptr_t externals[] = {
  213.     (intptr_t)&hello_cb,
  214.     0,
  215. };
  216. int main(int argc, char *argv[]) {
  217.     if (argc <= 1) {
  218.         printf("Usage: %s gen-snapshot|use-snapshot|no-snapshot\n", argv[0]);
  219.         return 0;
  220.     }
  221.     JSVM_InitOptions initOptions;
  222.     memset(&initOptions, 0, sizeof(initOptions));
  223.     initOptions.externalReferences = externals;
  224.     // 初始化引擎,一个进程中只能初始化一次
  225.     OH_JSVM_Init(&initOptions);
  226.     PrintVmInfo();
  227.     if (argv[1] == string("gen-snapshot")) {
  228.         CreateSnapshot();
  229.         return 0;
  230.     }
  231.     // snapshot可以记录下某个时间的js执行环境,可以跨进程通过snapshot快速还原出js执行上下文环境,前提是保证snapshot数据的生命周期。
  232.     const auto useSnapshot = argv[1] == string("use-snapshot");
  233.     const auto run = useSnapshot ? RunWithSnapshot : RunWithoutSnapshot;
  234.     uint8_t* data = nullptr;
  235.     size_t length = 0;
  236.     run(&data, &length);
  237.     run(&data, &length);
  238.     delete[] data;
  239.     return 0;
  240. }
  241. c++
复制代码
利用 JSVM-API WebAssembly 接口编译 wasm module

场景介绍

JSVM-API WebAssembly 接口提供了 wasm 字节码编译、wasm 函数优化、wasm cache 序列化和反序列化的能力。
接口说明

接口功能说明OH_JSVM_CompileWasmModule将 wasm 字节码同步编译为 wasm module。如果提供了 cache 参数,先尝试将 cache 反序列为 wasm module,反序列化失败时再执行编译。OH_JSVM_CompileWasmFunction将 wasm module 中指定编号的函数编译为优化后的机器码,现在只使能了最高的优化品级,函数编号的正当性由接口调用者保证。OH_JSVM_IsWasmModuleObject判断传入的值是否是一个 wasm module。OH_JSVM_CreateWasmCache将 wasm module 中的机器码序列化为 wasm cache,如果 wasm module 不包含机器码,则会序列化失败。OH_JSVM_ReleaseCache释放由 JSVM 接口生成的 cache。传入的 cacheType 和 cacheData 必须匹配,否则会产生未定义行为。 场景示例

异常处理

场景介绍

获取、抛出、清算JS异常
接口说明

接口功能说明OH_JSVM_Throw抛出一个JS值OH_JSVM_ThrowTypeError抛出一个JS TypeErrorOH_JSVM_ThrowRangeError抛出一个JS RangeErrorOH_JSVM_IsError判断JS值是否为JS异常OH_JSVM_CreateError创建一个JS异常OH_JSVM_CreateTypeError创建一个JS TypeError并返回OH_JSVM_CreateRangeError创建一个JS RangeError并返回OH_JSVM_ThrowError抛出一个JS异常OH_JSVM_GetAndClearLastException清算并返回最后一个JS异常OH_JSVM_IsExceptionPending判断当前是否有异常OH_JSVM_GetLastErrorInfo获取最后一个异常的信息OH_JSVM_ThrowSyntaxError抛出一个JS SyntaxErrorOH_JSVM_CreateSyntaxError创建一个JS SyntaxError并返回 场景示例: 以TypeError为例。创建,判断,并抛出JS TypeError。
  1. JSVM_Value code = nullptr;
  2. JSVM_Value message = nullptr;
  3. OH_JSVM_CreateStringUtf8(env, "500", JSVM_AUTO_LENGTH, &code);
  4. OH_JSVM_CreateStringUtf8(env, "type error 500", JSVM_AUTO_LENGTH, &message);
  5. JSVM_Value error = nullptr;
  6. OH_JSVM_CreateTypeError(env, code, message, &error);
  7. bool isError = false;
  8. OH_JSVM_IsError(env, error, &isError);
  9. OH_JSVM_ThrowTypeError(env, nullptr, "type error1");
  10. c++
复制代码
利用OH_JSVM_GetAndClearLastException后将异常信息以字符串形式打印
  1. if (status != JSVM_OK) // 当执行失败出现异常时
  2. {
  3.     bool isPending = false;
  4.     if (JSVM_OK == OH_JSVM_IsExceptionPending((env), &isPending) && isPending)
  5.     {
  6.         JSVM_Value error;
  7.         if (JSVM_OK == OH_JSVM_GetAndClearLastException((env), &error))
  8.         {
  9.             // 获取异常堆栈
  10.             JSVM_Value stack;
  11.             OH_JSVM_GetNamedProperty((env), error, "stack", &stack);
  12.             JSVM_Value message;
  13.             OH_JSVM_GetNamedProperty((env), error, "message", &message);
  14.             char stackstr[256];
  15.             OH_JSVM_GetValueStringUtf8(env, stack, stackstr, 256, nullptr);
  16.             OH_LOG_INFO(LOG_APP, "JSVM error stack: %{public}s", stackstr);
  17.             char messagestr[256];
  18.             OH_JSVM_GetValueStringUtf8(env, message, messagestr, 256, nullptr);
  19.             OH_LOG_INFO(LOG_APP, "JSVM error message: %{public}s", messagestr);
  20.         }
  21.     }
  22. }
  23. c++
复制代码
对象生命周期管理

在调用JSVM-API接口时,底层VM堆中的对象可能会作为JSVM_Values返回句柄。这些句柄必须在Native方法退出或自动释放掉前,使其关联的对象处于“活动”状态,防止被引擎回收掉。
当对象句柄被返回时,它们与一个“scope”干系联。默认作用域的生命周期与本机方法调用的生命周期干系联,这些句柄及关联的对象将在Native方法的生命周期内保持活动状态。
然而,在很多环境下,句柄必须保持有用的时间范围并不与Native方法的生命周期相同。下面将介绍可用于更改句柄的生命周期的JSVM-API方法。
对象生命周期管理接口说明

接口功能说明OH_JSVM_OpenHandleScope打开一个新的scope,在关闭该scope之前创建的对象在scope范围内不会被GC回收OH_JSVM_CloseHandleScope关闭一个scope,在此scope范围内创建的对象在关闭scope后可以被GC回收OH_JSVM_OpenEscapableHandleScope打开一个新的scope逃逸handle scope,在关闭该scope之前创建的对象与父作用域有相同的生命周期OH_JSVM_CloseEscapableHandleScope关闭一个scope,在此scope范围外创建的对象不受父作用域保护OH_JSVM_EscapeHandle将 JavaScript 对象的句柄提拔到外部作用域,确保在外部作用域中可以持续地利用该对象OH_JSVM_CreateReference以指定的引用计数为JavaScript对象创建一个新的引用,该引用将指向传入的对象,引用允许在差别的上下文中利用和共享对象,并且可以有用地监测对象的生命周期OH_JSVM_DeleteReference释放由 OH_JSVM_CreateReference 创建的引用,确保对象在不再被利用时能够被正确地释放和回收,避免内存泄漏OH_JSVM_ReferenceRef增长由OH_JSVM_CreateReference 创建的引用的引用计数,以确保对象在有引用时不会被提前释放OH_JSVM_ReferenceUnref淘汰由OH_JSVM_CreateReference 创建的引用的引用计数,以确保没有任何引用指向该对象时能正确地释放和回收OH_JSVM_GetReferenceValue返回由 OH_JSVM_CreateReference 创建的引用的对象OH_JSVM_RetainScript持久化生存一个 JSVM_Script, 使其能够跨过当前 scope 利用OH_JSVM_ReleaseScript释放持久化生存过的 JSVM_Script,释放之后 JSVM_Script 不再可用,应当置为空 场景示例: 通过handlescope保护在scope范围内创建的对象在该范围内不被回收。
  1. JSVM_HandleScope scope;
  2. OH_JSVM_OpenHandleScope(env, &scope);
  3. JSVM_Value obj = nullptr;
  4. OH_JSVM_CreateObject(env, &obj);
  5. OH_JSVM_CloseHandleScope(env, scope);
  6. c++
复制代码
通过escapable handlescope保护在scope范围内创建的对象在父作用域范围内不被回收
  1. JSVM_EscapableHandleScope scope;
  2. JSVM_CALL(env, OH_JSVM_OpenEscapableHandleScope(env, &scope));
  3. JSVM_Value output = NULL;
  4. JSVM_Value escapee = NULL;
  5. JSVM_CALL(env, OH_JSVM_CreateObject(env, &output));
  6. JSVM_CALL(env, OH_JSVM_EscapeHandle(env, scope, output, &escapee));
  7. JSVM_CALL(env, OH_JSVM_CloseEscapableHandleScope(env, scope));
  8. return escapee;
  9. c++
复制代码
通过CreateReference创建对象引用和释放
  1. JSVM_Value obj = nullptr;
  2. OH_JSVM_CreateObject(env, &obj);
  3. // 创建引用
  4. JSVM_Ref reference;
  5. OH_JSVM_CreateReference(env, obj, 1, &reference);
  6. // 使用引用
  7. JSVM_Value result;
  8. OH_JSVM_GetReferenceValue(env, reference, &result);
  9. // 释放引用
  10. OH_JSVM_DeleteReference(env, reference);
  11. c++
复制代码
通过 RetainScript 持久化生存 JSVM_Script 并利用
  1. JSVM_HandleScope scope;
  2. OH_JSVM_OpenHandleScope(env, &scope);
  3. JSVM_Script script;
  4. JSVM_Value jsSrc;
  5. std::string src(R"JS(
  6. let a = 37;
  7. a = a * 9;
  8. )JS");
  9. OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc);
  10. OH_JSVM_CompileScriptWithOptions(env, jsSrc, 0, nullptr, &script);
  11. OH_JSVM_RetainScript(env, script);
  12. OH_JSVM_CloseHandleScope(env, scope);
  13. // 使用JSVM_Script
  14. OH_JSVM_OpenHandleScope(env, &scope);
  15. JSVM_Value result;
  16. OH_JSVM_RunScript(env, script, &result);
  17. // 释放JSVM_Script,并置空
  18. OH_JSVM_ReleaseScript(env, script);
  19. script = nullptr;
  20. OH_JSVM_CloseHandleScope(env, scope);
  21. c++
复制代码
创建JS对象范例和根本范例

场景介绍

创建JS对象范例和根本范例
接口说明

接口功能说明OH_JSVM_CreateArray创建一个新的 JavaScript 数组对象OH_JSVM_CreateArrayWithLength创建一个指定长度的 JavaScript 数组对象OH_JSVM_CreateArraybuffer创建一个指定大小的 ArrayBuffer 对象OH_JSVM_CreateDate创建了一个表示给定毫秒数的 Date 对象OH_JSVM_CreateExternal创建一个包装了外部指针的 JavaScript 对象OH_JSVM_CreateObject创建一个默认的JavaScript Object对象OH_JSVM_CreateSymbol根据给定的描述符创建一个 Symbol 对象OH_JSVM_SymbolFor在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新SymbolOH_JSVM_CreateTypedarray在现有的 ArrayBuffer 上创建一个 JavaScript TypedArray 对象,TypedArray 对象在底层数据缓冲区上提供类似数组的视图,其中每个元素都具有相同的底层二进制标量数据范例OH_JSVM_CreateDataview在现有的 ArrayBuffer 上创建一个 JavaScript DataView 对象,DataView 对象在底层数据缓冲区上提供类似数组的视图OH_JSVM_CreateInt32根据 Int32_t 范例对象创建 JavaScript number 对象OH_JSVM_CreateUint32根据 Uint32_t 范例对象创建 JavaScript number 对象OH_JSVM_CreateInt64根据 Int64_t 范例对象创建 JavaScript number 对象OH_JSVM_CreateDouble根据 Double 范例对象创建 JavaScript number 对象OH_JSVM_CreateBigintInt64根据 Int64 范例对象创建 JavaScript Bigint 对象OH_JSVM_CreateBigintUint64根据 Uint64 范例对象创建 JavaScript Bigint 对象OH_JSVM_CreateBigintWords根据给定的 Uint64_t 数组创建一个 JavaScript BigInt 对象OH_JSVM_CreateStringLatin1根据 Latin-1 编码的字符串创建一个 JavaScript string 对象OH_JSVM_CreateStringUtf16根据 Utf16 编码的字符串创建一个 JavaScript string 对象OH_JSVM_CreateStringUtf8根据 Utf8 编码的字符串创建一个 JavaScript string 对象OH_JSVM_CreateMap创建一个新的 JavaScript Map对象OH_JSVM_CreateRegExp根据输入的字符串创建一个JavaScript 正则对象OH_JSVM_CreateSet创建一个新的 JavaScript Set对象 场景示例: 创建指定长度的数组。
  1. size_t arrayLength = 2;
  2. JSVM_Value arr;
  3. OH_JSVM_CreateArrayWithLength(env, arrayLength, &arr);
  4. for (uint32_t i = 0; i < arrayLength; i++)
  5. {
  6.     JSVM_Value element;
  7.     OH_JSVM_CreateUint32(env, i * 2, &element);
  8.     OH_JSVM_SetElement(env, arr, i, element);
  9. }
  10. c++
复制代码
创建typedarray,以Int32Array为例:
  1. JSVM_Value arrayBuffer = nullptr;
  2. void *arrayBufferPtr = nullptr;
  3. size_t arrayBufferSize = 16;
  4. size_t typedArrayLength = 4;
  5. OH_JSVM_CreateArraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer);
  6. void *tmpArrayBufferPtr = nullptr;
  7. size_t arrayBufferLength = 0;
  8. OH_JSVM_GetArraybufferInfo(env, arrayBuffer, &tmpArrayBufferPtr, &arrayBufferLength);
  9. JSVM_Value result;
  10. OH_JSVM_CreateTypedarray(env, JSVM_TypedarrayType::JSVM_INT32_ARRAY, typedArrayLength, arrayBuffer, 0, &result);
  11. return result;
  12. c++
复制代码
创建number和string:
  1. const char *testStringStr = "test";
  2. JSVM_Value testString = nullptr;
  3. OH_JSVM_CreateStringUtf8(env, testStringStr, strlen(testStringStr), &testString);
  4. JSVM_Value testNumber1 = nullptr;
  5. JSVM_Value testNumber2 = nullptr;
  6. OH_JSVM_CreateDouble(env, 10.1, &testNumber1);
  7. OH_JSVM_CreateInt32(env, 10, &testNumber2);
  8. c++
复制代码
创建Map:
  1. JSVM_Value value = nullptr;
  2. OH_JSVM_CreateMap(env, &value);
  3. c++
复制代码
创建RegExp:
  1. JSVM_Value value = nullptr;
  2. const char testStr[] = "ab+c";
  3. OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &value);
  4. JSVM_Value result = nullptr;
  5. OH_JSVM_CreateRegExp(env, value, JSVM_RegExpFlags::JSVM_REGEXP_GLOBAL, &result);
  6. c++
复制代码
创建Set:
  1. JSVM_Value value;
  2. OH_JSVM_CreateSet(env, &value);
  3. c++
复制代码
从JS范例获取C范例&获取JS范例信息

场景介绍

从JS范例获取C范例&获取JS范例信息。
接口说明

接口功能说明OH_JSVM_GetArrayLength返回 Array 对象的长度OH_JSVM_GetArraybufferInfo检索 ArrayBuffer 的底层数据缓冲区及其长度OH_JSVM_GetPrototype获取给定 JavaScript 对象的原型OH_JSVM_GetTypedarrayInfo获取 TypedArray(范例化数组)对象的信息OH_JSVM_GetDataviewInfo获取 Dataview 对象的信息OH_JSVM_GetDateValue获取给定 JavaScript Date 的时间值的 Double 基础范例值OH_JSVM_GetValueBool获取给定 JavaScript Boolean 的 C 布尔基础范例值OH_JSVM_GetValueDouble获取给定 JavaScript number 的 Double 基础范例值OH_JSVM_GetValueBigintInt64获取给定 JavaScript BigInt 的 Int64_t 基础范例值OH_JSVM_GetValueBigintUint64获取给定 JavaScript BigInt 的 Uint64_t 基础范例值OH_JSVM_GetValueBigintWords获取给定 JavaScript BigInt 对象的底层数据,即 BigInt 数据的字词表示OH_JSVM_GetValueExternal获取先前传递给 OH_JSVM_CreateExternal 的外部数据指针OH_JSVM_GetValueInt32获取给定 JavaScript number 的 Int32 基础范例值OH_JSVM_GetValueInt64获取给定 JavaScript number 的 Int64 基础范例值OH_JSVM_GetValueStringLatin1获取给定 JavaScript string 对象的 Latin1 编码字符串OH_JSVM_GetValueStringUtf8获取给定 JavaScript string 对象的 Utf8 编码字符串OH_JSVM_GetValueStringUtf16获取给定 JavaScript string 对象的 Utf16 编码字符串OH_JSVM_GetValueUint32获取给定 JavaScript number 的 Uint32 基础范例值OH_JSVM_GetBoolean返回用于表示给定布尔值的 JavaScript 单例对象OH_JSVM_GetGlobal返回当前环境中的全局 global 对象OH_JSVM_GetNull返回 JavaScript null 对象OH_JSVM_GetUndefined返回 JavaScript Undefined 对象 场景示例: 创建64位的BigInt,并获取64位int值。
  1. int64_t testValue = INT64_MAX;
  2. JSVM_Value result = nullptr;
  3. OH_JSVM_CreateBigintInt64(env, testValue, &result);
  4. int64_t resultValue = 0;
  5. bool flag = false;
  6. OH_JSVM_GetValueBigintInt64(env, result, &resultValue, &flag);
  7. c++
复制代码
创建一个Int32Array,并获取其长度,byteoffset等信息。
  1. JSVM_Value arrayBuffer = nullptr;
  2. void *arrayBufferPtr = nullptr;
  3. size_t arrayBufferSize = 16;
  4. size_t typedArrayLength = 4;
  5. OH_JSVM_CreateArraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer);
  6. bool isArrayBuffer = false;
  7. OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer);
  8. JSVM_Value result;
  9. OH_JSVM_CreateTypedarray(env, JSVM_TypedarrayType::JSVM_INT32_ARRAY, typedArrayLength, arrayBuffer, 0, &result);
  10. bool isTypedArray = false;
  11. OH_JSVM_IsTypedarray(env, result, &isTypedArray);
  12. JSVM_TypedarrayType type;
  13. size_t length = 0;
  14. void *data = nullptr;
  15. JSVM_Value retArrayBuffer;
  16. size_t byteOffset = -1;
  17. OH_JSVM_GetTypedarrayInfo(env, result, &type, &length, &data, &retArrayBuffer, &byteOffset);
  18. bool retIsArrayBuffer = false;
  19. OH_JSVM_IsArraybuffer(env, retArrayBuffer, &retIsArrayBuffer);
  20. void *tmpArrayBufferPtr = nullptr;
  21. size_t arrayBufferLength = 0;
  22. OH_JSVM_GetArraybufferInfo(env, retArrayBuffer, &tmpArrayBufferPtr, &arrayBufferLength);
  23. c++
复制代码
创建utf8范例的String,并获取C字符串。
  1. const char *testStringStr = "testString";
  2. JSVM_Value testString = nullptr;
  3. OH_JSVM_CreateStringUtf8(env, testStringStr, strlen(testStringStr), &testString);
  4. char buffer[128];
  5. size_t bufferSize = 128;
  6. size_t copied;
  7. OH_JSVM_GetValueStringUtf8(env, testString, buffer, bufferSize, &copied);
  8. c++
复制代码
JS值操作和抽象操作

场景介绍

JS值操作和抽象操作。
接口说明

接口功能说明OH_JSVM_CoerceToBool将目标值转换为 Boolean 范例对象OH_JSVM_CoerceToNumber将目标值转换为 Number 范例对象OH_JSVM_CoerceToObject将目标值转换为 Object 范例对象OH_JSVM_CoerceToString将目标值转换为 String 范例对象OH_JSVM_CoerceToBigInt将目标值转换为 BigInt 范例对象OH_JSVM_Typeof返回 JavaScript 对象的范例OH_JSVM_Instanceof判断一个对象是否是某个构造函数的实例OH_JSVM_IsArray判断一个 JavaScript 对象是否为 Array 范例对象OH_JSVM_IsArraybuffer判断一个 JavaScript 对象是否为 Arraybuffer 范例对象OH_JSVM_IsDate判断一个 JavaScript 对象是否为 Date 范例对象OH_JSVM_IsTypedarray判断一个 JavaScript 对象是否为 Typedarray 范例对象OH_JSVM_IsDataview判断一个 JavaScript 对象是否为 Dataview 范例对象OH_JSVM_IsUndefined此API查抄传入的值是否为Undefined。这相当于JS中的value === undefined。OH_JSVM_IsNull此API查抄传入的值是否为Null对象。这相当于JS中的value === null。OH_JSVM_IsNullOrUndefined此API查抄传入的值是否为Null或Undefined。这相当于JS中的value == null。OH_JSVM_IsBoolean此API查抄传入的值是否为Boolean。这相当于JS中的typeof value === 'boolean'。OH_JSVM_IsNumber此API查抄传入的值是否为Number。这相当于JS中的typeof value === 'number'。OH_JSVM_IsString此API查抄传入的值是否为String。这相当于JS中的typeof value === 'string'。OH_JSVM_IsSymbol此API查抄传入的值是否为Symbol。这相当于JS中的typeof value === 'symbol'。OH_JSVM_IsFunction此API查抄传入的值是否为Function。这相当于JS中的typeof value === 'function'。OH_JSVM_IsObject此API查抄传入的值是否为Object。OH_JSVM_IsBigInt此API查抄传入的值是否为BigInt。这相当于JS中的typeof value === 'bigint'。OH_JSVM_IsConstructor此API查抄传入的值是否为构造函数。OH_JSVM_IsMap此API查抄传入的值是否为Map。OH_JSVM_IsSet此API查抄传入的值是否为Set。OH_JSVM_IsRegExp此API查抄传入的值是否为RegExp。OH_JSVM_StrictEquals判断两个 JSVM_Value 对象是否严酷相称OH_JSVM_Equals判断两个 JSVM_Value 对象是否宽松相称OH_JSVM_DetachArraybuffer调用 ArrayBuffer 对象的Detach操作OH_JSVM_IsDetachedArraybuffer查抄给定的 ArrayBuffer 是否已被分离(detached) 场景示例: 判断JS值是否为数组范例
  1. JSVM_Value array = nullptr;
  2. OH_JSVM_CreateArray(env, &array);
  3. bool isArray = false;
  4. OH_JSVM_IsArray(env, array, &isArray);
  5. c++
复制代码
将int32范例转换为string范例
  1. int32_t num = 123;
  2. JSVM_Value intValue;
  3. OH_JSVM_CreateInt32(env, num, &intValue);
  4. JSVM_Value stringValue;
  5. OH_JSVM_CoerceToString(env, intValue, &stringValue);
  6. char buffer[128];
  7. size_t bufferSize = 128;
  8. size_t copied = 0;
  9. OH_JSVM_GetValueStringUtf8(env, stringValue, buffer, bufferSize, &copied);
  10. // buffer:"123";
  11. c++
复制代码
将boolean范例转换为bigint范例
  1. JSVM_Value boolValue;
  2. OH_JSVM_GetBoolean(env, false, &boolValue);
  3. JSVM_Value bigIntValue;
  4. OH_JSVM_CoerceToBigInt(env, boolValue, &bigIntValue);
  5. c++
复制代码
判断两个JS值范例是否严酷相同:先比力操作数范例,操作数范例差别就是不相称,操作数范例相同时,比力值是否相称,相称才返回true。
  1. JSVM_Value value = nullptr;
  2. JSVM_Value value1 = nullptr;
  3. OH_JSVM_CreateArray(env, &value);
  4. OH_JSVM_CreateInt32(env, 10, &value1);
  5. bool isArray = true;
  6. OH_JSVM_StrictEquals(env, value, value, &isArray);
  7. c++
复制代码
判断两个JS值范例是否宽松相同:判断两个操作数的范例是否相同,若不相同,且可以转换为相同的数据范例,转换为相同的数据范例后,值做严酷相称比力,其他的都返回false。
  1. JSVM_HandleScope handleScope;
  2. OH_JSVM_OpenHandleScope(env, &handleScope);
  3. const char testStr[] = "1";
  4. JSVM_Value lhs = nullptr;
  5. OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &lhs);
  6. JSVM_Value rhs;
  7. OH_JSVM_CreateInt32(env, 1, &rhs);
  8. bool isEquals = false;
  9. OH_JSVM_Equals(env, lhs, rhs, &isEquals); // 这里isEquals的值是true
  10. OH_JSVM_CloseHandleScope(env, handleScope);
  11. c++
复制代码
判断JS值是否为构造函数
  1. JSVM_Value SayHello(JSVM_Env env, JSVM_CallbackInfo info)
  2. {
  3.     return nullptr;
  4. }
  5. JSVM_Value value = nullptr;
  6. JSVM_CallbackStruct param;
  7. param.data = nullptr;
  8. param.callback = SayHello;
  9. OH_JSVM_CreateFunction(env, "func", JSVM_AUTO_LENGTH, &param, &value);
  10. bool isConstructor = false;
  11. OH_JSVM_IsConstructor(env, value, &isConstructor); // 这里isConstructor的值是true
  12. c++
复制代码
判断JS值是否为map范例
  1. JSVM_Value value = nullptr;
  2. OH_JSVM_CreateMap(env, &value);
  3. bool isMap = false;
  4. OH_JSVM_IsMap(env, value, &isMap); // 这里isMap的值是true
  5. c++
复制代码
判断JS值是否为Set范例
  1. JSVM_Value value;
  2. OH_JSVM_CreateSet(env, &value);
  3. bool isSet = false;
  4. OH_JSVM_IsSet(env, value, &isSet); // 这里isSet的值是true
  5. c++
复制代码
判断JS值是否为RegExp范例
  1. JSVM_Value value = nullptr;
  2. const char testStr[] = "ab+c";
  3. OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &value);
  4. JSVM_Value result = nullptr;
  5. OH_JSVM_CreateRegExp(env, value, JSVM_RegExpFlags::JSVM_REGEXP_GLOBAL, &result);
  6. bool isRegExp = false;
  7. OH_JSVM_IsRegExp(env, result, &isRegExp);
  8. c++
复制代码
JS属性操作

场景介绍

JS对象属性的增删获取和判断
接口说明

接口功能说明OH_JSVM_GetPropertyNames获取给定对象的全部可枚举属性名称, 结果变量将存储一个包含全部可枚举属性名称的JavaScript数组。OH_JSVM_GetAllPropertyNames获取给定对象的全部可用属性名称, 结果变量将存储一个包含全部可枚举属性名称的JavaScript数组。OH_JSVM_SetProperty为给定对象设置一个属性。OH_JSVM_GetProperty用给定的属性的名称,检索目标对象的属性。OH_JSVM_HasProperty用给定的属性的名称,查询目标对象是否有此属性。OH_JSVM_DeleteProperty用给定的属性的名称,删除目标对象属性。OH_JSVM_HasOwnProperty查抄目标对象是否具有指定的自有属性。OH_JSVM_SetNamedProperty用给定的属性的名称为目标对象设置属性,此方法等效于利用从作为 utf8Name 传入的字符串创建的 JSVM_Value 调用 OH_JSVM_SetProperty。OH_JSVM_GetNamedProperty用给定的属性的名称,检索目标对象的属性,此方法等效于利用从作为 utf8Name 传入的字符串创建的 JSVM_Value 调用 OH_JSVM_GetProperty。OH_JSVM_HasNamedProperty用给定的属性的名称,查询目标对象是否有此属性,此方法等效于利用从作为 utf8Name 传入的字符串创建的 JSVM_Value 调用 OH_JSVM_HasProperty。OH_JSVM_SetElement在给定对象的指定索引处设置元素。OH_JSVM_GetElement获取给定对象指定索引处的元素。OH_JSVM_HasElement若给定对象的指定索引处拥有属性,获取该元素。OH_JSVM_DeleteElement尝试删除给定对象的指定索引处的元素。OH_JSVM_DefineProperties批量的向给定对象中定义属性。OH_JSVM_ObjectFreeze冻结给定的对象,防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。OH_JSVM_ObjectSeal密封给定的对象。这可以防止向其添加新属性,以及将全部现有属性标志为不可配置。OH_JSVM_ObjectSetPrototypeOf为给定对象设置一个原型。OH_JSVM_ObjectGetPrototypeOf获取给定JavaScript对象的原型。 场景示例: JS对象属性的增删获取和判断
  1. // 创建一个空对象
  2. JSVM_Value myObject = nullptr;
  3. OH_JSVM_CreateObject(env, &myObject);
  4. // 设置属性
  5. const char *testNameStr = "John Doe";
  6. JSVM_Value propValue = nullptr;
  7. JSVM_Value key;
  8. OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &key);
  9. OH_JSVM_CreateStringUtf8(env, testNameStr, strlen(testNameStr), &propValue);
  10. OH_JSVM_SetProperty(env, myObject, key, propValue);
  11. // 获取属性
  12. JSVM_Value propResult = nullptr;
  13. OH_JSVM_GetProperty(env, myObject, key, &propResult);
  14. // 检查属性是否存在
  15. bool hasProperty = false;
  16. OH_JSVM_HasNamedProperty(env, myObject, "name", &hasProperty);
  17.     // 属性存在,做相应处理...
  18.     if (hasProperty)
  19.     {
  20.         // 获取对象的所有属性名
  21.         JSVM_Value propNames = nullptr;
  22.         OH_JSVM_GetPropertyNames(env, myObject, &propNames);
  23.         bool isArray = false;
  24.         OH_JSVM_IsArray(env, propNames, &isArray);
  25.         uint32_t arrayLength = 0;
  26.         OH_JSVM_GetArrayLength(env, propNames, &arrayLength);
  27.         // 遍历属性元素
  28.         for (uint32_t i = 0; i < arrayLength; i++)
  29.         {
  30.             bool hasElement = false;
  31.             OH_JSVM_HasElement(env, propNames, i, &hasElement);
  32.             JSVM_Value propName = nullptr;
  33.             OH_JSVM_GetElement(env, propNames, i, &propName);
  34.             bool hasProp = false;
  35.             OH_JSVM_HasProperty(env, myObject, propName, &hasProp);
  36.             JSVM_Value propValue = nullptr;
  37.             OH_JSVM_GetProperty(env, myObject, propName, &propValue);
  38.         }
  39.     }
  40. // 删除属性
  41. OH_JSVM_DeleteProperty(env, myObject, key, &hasProperty);
  42. // 设置对象原型
  43. JSVM_Value value;
  44. OH_JSVM_CreateSet(env, &value);
  45. OH_JSVM_ObjectSetPrototypeOf(env, myObject, value);
  46. // 获取对象原型
  47. JSVM_Value proto;
  48. OH_JSVM_ObjectGetPrototypeOf(env, myObject, &proto);
  49. c++
复制代码
JS函数操作

场景介绍

JS函数操作。
接口说明

接口功能说明OH_JSVM_CallFunction在C/C++侧调用JS方法OH_JSVM_CreateFunction用于创建JavaScript函数,用于从JavaScript环境中调用C/C++代码中的函数OH_JSVM_GetCbInfo从给定的callback info中获取有关调用的详细信息,如参数和this指针OH_JSVM_GetNewTarget获取构造函数调用的new.targetOH_JSVM_NewInstance通过给定的构造函数,构建一个实例OH_JSVM_CreateFunctionWithScript根据传入的函数体和函数参数列表,创建一个新的 JavaScript Function对象 场景示例: 创建JavaScript函数操作
  1. JSVM_Value SayHello(JSVM_Env env, JSVM_CallbackInfo info)
  2. {
  3.     printf("Hello\n");
  4.     JSVM_Value ret;
  5.     OH_JSVM_CreateInt32(env, 2, &ret);
  6.     return ret;
  7. }
  8. static JSVM_Value JsvmCreateFunction(JSVM_Env env, JSVM_CallbackInfo info)
  9. {
  10.     JSVM_CallbackStruct param;
  11.     param.data = nullptr;
  12.     param.callback = SayHello;
  13.     JSVM_Value funcValue = nullptr;
  14.     JSVM_Status status = OH_JSVM_CreateFunction(env, "func", JSVM_AUTO_LENGTH, &param, &funcValue);
  15.     return funcValue;
  16. }
  17. c++
复制代码
在C/C++侧获取并调用JS方法
  1. static JSVM_Value CallFunction(JSVM_Env env, JSVM_CallbackInfo info)
  2. {
  3.     size_t argc = 1;
  4.     JSVM_Value args[1];
  5.     JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
  6.     JSVM_ASSERT(env, argc >= 1, "Wrong number of arguments");
  7.     JSVM_ValueType valuetype;
  8.     JSVM_CALL(env, OH_JSVM_Typeof(env, args[0], &valuetype));
  9.     JSVM_ASSERT(env, valuetype == JSVM_ValueType::JSVM_FUNCTION, "Wrong type of argment. Expects a string.");
  10.     JSVM_Value global;
  11.     JSVM_CALL(env, OH_JSVM_GetGlobal(env, &global));
  12.     JSVM_Value ret;
  13.     JSVM_CALL(env, OH_JSVM_CallFunction(env, global, args[0], 0, nullptr, &ret));
  14.     return ret;
  15. }
  16. c++
复制代码
创建Function:
  1. JSVM_Value script;
  2. OH_JSVM_CreateStringUtf8(env, "return a + b;", JSVM_AUTO_LENGTH, &script);
  3. JSVM_Value param1;
  4. JSVM_Value param2;
  5. OH_JSVM_CreateStringUtf8(env, "a", JSVM_AUTO_LENGTH, &param1);
  6. OH_JSVM_CreateStringUtf8(env, "b", JSVM_AUTO_LENGTH, &param2);
  7. JSVM_Value argus[] = {param1, param2};
  8. JSVM_Value func;
  9. OH_JSVM_CreateFunctionWithScript(env, "add", JSVM_AUTO_LENGTH, 2, argus, script, &func);
  10. c++
复制代码
对象绑定操作

场景介绍

对象绑定操作。
接口说明

接口功能说明OH_JSVM_DefineClass用于在JavaScript中定义一个类,并与对应的C类举行封装和交互。它提供了创建类的构造函数、定义属性和方法的能力,以及在C和JavaScript之间举行数据交互的支持。OH_JSVM_Wrap在 JavaScript 对象中封装原生实例。稍后可以利用 OH_JSVM_Unwrap() 检索原生实例。OH_JSVM_Unwrap利用 OH_JSVM_Wrap() 检索先前封装在 JavaScript 对象中的原生实例。OH_JSVM_RemoveWrap检索先前封装在 JavaScript 对象中的原生实例并移除封装。OH_JSVM_TypeTagObject将 type_tag 指针的值与 JavaScript 对象或外部对象干系联。OH_JSVM_CheckObjectTypeTag查抄给定的范例标签是否与对象上的范例标签匹配。OH_JSVM_AddFinalizer为对象添加 JSVM_Finalize 回调,以便在 JavaScript 对象被垃圾回收时调用来释放原生对象。OH_JSVM_DefineClassWithPropertyHandler定义一个具有给定类名、构造函数、属性和回调处理步伐的JavaScript类,并作为函数回调举行调用。属性操作包罗getter、setter、deleter、enumerator等。 场景示例: 对象绑定操作。
  1. static JSVM_Value AssertEqual(JSVM_Env env, JSVM_CallbackInfo info)
  2. {
  3.     size_t argc = 2;
  4.     JSVM_Value args[2];
  5.     JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
  6.     bool isStrictEquals = false;
  7.     OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
  8.     return nullptr;
  9. }
  10. static napi_value TestWrap(napi_env env1, napi_callback_info info)
  11. {
  12.     OH_LOG_ERROR(LOG_APP, "testWrap start");
  13.     JSVM_InitOptions init_options;
  14.     memset(&init_options, 0, sizeof(init_options));
  15.     init_options.externalReferences = externals;
  16.     if (aa == 0) {
  17.         OH_JSVM_Init(&init_options);
  18.         aa++;
  19.     }
  20.     JSVM_VM vm;
  21.     JSVM_CreateVMOptions options;
  22.     memset(&options, 0, sizeof(options));
  23.     OH_JSVM_CreateVM(&options, &vm);
  24.     JSVM_VMScope vm_scope;
  25.     OH_JSVM_OpenVMScope(vm, &vm_scope);
  26.     JSVM_Env env;
  27.     JSVM_CallbackStruct param[1];
  28.     param[0].data = nullptr;
  29.     param[0].callback = AssertEqual;
  30.     JSVM_PropertyDescriptor descriptor[] = {
  31.         {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
  32.     };
  33.     OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
  34.     JSVM_EnvScope envScope;
  35.     OH_JSVM_OpenEnvScope(env, &envScope);
  36.     JSVM_HandleScope handlescope;
  37.     OH_JSVM_OpenHandleScope(env, &handlescope);
  38.     JSVM_Value testClass = nullptr;
  39.     JSVM_CallbackStruct param1;
  40.     param1.data = nullptr;
  41.     param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
  42.         JSVM_Value thisVar = nullptr;
  43.         OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
  44.         return thisVar;
  45.     };
  46.     OH_JSVM_DefineClass(env, "TestClass", JSVM_AUTO_LENGTH, &param1, 0, nullptr, &testClass);
  47.     JSVM_Value instanceValue = nullptr;
  48.     OH_JSVM_NewInstance(env, testClass, 0, nullptr, &instanceValue);
  49.     const char *testStr = "test";
  50.     OH_JSVM_Wrap(
  51.         env, instanceValue, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, nullptr, nullptr);
  52.     const char *tmpTestStr = nullptr;
  53.     OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr);
  54.     const char *tmpTestStr1 = nullptr;
  55.     OH_JSVM_RemoveWrap(env, instanceValue, (void **)&tmpTestStr1);
  56.     OH_JSVM_Unwrap(env, instanceValue, (void **)&tmpTestStr1);
  57.     OH_JSVM_CloseHandleScope(env, handlescope);
  58.     OH_JSVM_CloseEnvScope(env, envScope);
  59.     OH_JSVM_DestroyEnv(env);
  60.     OH_JSVM_CloseVMScope(vm, vm_scope);
  61.     OH_JSVM_DestroyVM(vm);
  62.     OH_LOG_ERROR(LOG_APP, "testWrap pass");
  63.     return nullptr;
  64. }
  65. c++
复制代码
场景示例: 对象绑定及监听拦截属性操作。
  1. static int aa = 0;
  2. static JSVM_Value hello(JSVM_Env env, JSVM_CallbackInfo info) {
  3.     JSVM_Value output;
  4.     void *data = nullptr;
  5.     OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
  6.     OH_JSVM_CreateStringUtf8(env, (char *)data, strlen((char *)data), &output);
  7.     return output;
  8. }
  9. static JSVM_CallbackStruct hello_cb = {hello, (void *)"Hello"};
  10. static intptr_t externals[] = {
  11.     (intptr_t)&hello_cb,
  12.     0,
  13. };
  14. static void test1() { OH_LOG_INFO(LOG_APP, "test1 called"); }
  15. struct Test {
  16.     void *ptr1;
  17.     void *ptr2;
  18. };
  19. static JSVM_Value assertEqual(JSVM_Env env, JSVM_CallbackInfo info) {
  20.     size_t argc = 2;
  21.     JSVM_Value args[2];
  22.     JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
  23.     bool isStrictEquals = false;
  24.     OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
  25.     return nullptr;
  26. }
  27. static JSVM_Value GetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
  28.     // 该回调是由对象上的获取请求触发的
  29.     char strValue[100];
  30.     size_t size;
  31.     OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
  32.     JSVM_Value newResult = nullptr;
  33.     char newStr[] = "new return value hahaha from name listening";
  34.     OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
  35.     int signBit = 0;
  36.     size_t wordCount = 2;
  37.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  38.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  39.     if (status == JSVM_OK) {
  40.         OH_LOG_INFO(LOG_APP, "GetPropertyCbInfo wordCount is %{public}zu", wordCount);
  41.         auto test = reinterpret_cast<Test *>(wordsOut);
  42.         typedef void (*callTest1)();
  43.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  44.         callTe();
  45.     }
  46.     return nullptr;
  47. }
  48. static JSVM_Value SetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
  49.     // 该回调是由对象上的设置请求触发的
  50.     char strValue[100];
  51.     size_t size;
  52.     OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
  53.     JSVM_Value newResult = nullptr;
  54.     char newStr[] = "new return value hahaha from name listening";
  55.     OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
  56.     int signBit = 0;
  57.     size_t wordCount = 2;
  58.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  59.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  60.     if (status == JSVM_OK) {
  61.         OH_LOG_INFO(LOG_APP, "SetPropertyCbInfo wordCount is %{public}zu", wordCount);
  62.         auto test = reinterpret_cast<Test *>(wordsOut);
  63.         typedef void (*callTest1)();
  64.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  65.         callTe();
  66.     }
  67.     return nullptr;
  68. }
  69. static JSVM_Value DeleterPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) {
  70.     // 该回调是由对象上的删除请求触发的
  71.     char strValue[100];
  72.     size_t size;
  73.     OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size);
  74.     JSVM_Value newResult = nullptr;
  75.     bool returnValue = false;
  76.     OH_JSVM_GetBoolean(env, returnValue, &newResult);
  77.     int signBit = 0;
  78.     size_t wordCount = 2;
  79.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  80.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  81.     if (status == JSVM_OK) {
  82.         OH_LOG_INFO(LOG_APP, "DeleterPropertyCbInfo wordCount is %{public}zu", wordCount);
  83.         auto test = reinterpret_cast<Test *>(wordsOut);
  84.         typedef void (*callTest1)();
  85.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  86.         callTe();
  87.     }
  88.     return nullptr;
  89. }
  90. static JSVM_Value EnumeratorPropertyCbInfo(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
  91.     // 该回调是由获取对象上的所有属性请求触发的
  92.     JSVM_Value testArray = nullptr;
  93.     OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
  94.     JSVM_Value name1 = nullptr;
  95.     char newStr1[] = "hahaha";
  96.     OH_JSVM_CreateStringUtf8(env, newStr1, strlen(newStr1), &name1);
  97.     JSVM_Value name2 = nullptr;
  98.     char newStr2[] = "heheheh";
  99.     OH_JSVM_CreateStringUtf8(env, newStr2, strlen(newStr2), &name2);
  100.     OH_JSVM_SetElement(env, testArray, 0, name1);
  101.     OH_JSVM_SetElement(env, testArray, 1, name2);
  102.     int signBit = 0;
  103.     size_t wordCount = 2;
  104.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  105.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  106.     if (status == JSVM_OK) {
  107.         OH_LOG_INFO(LOG_APP, "EnumeratorPropertyCbInfo wordCount is %{public}zu", wordCount);
  108.         auto test = reinterpret_cast<Test *>(wordsOut);
  109.         typedef void (*callTest1)();
  110.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  111.         callTe();
  112.     }
  113.     return nullptr;
  114. }
  115. static JSVM_Value IndexedPropertyGet(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
  116.     // 该回调是由获取实例对象的索引属性触发的
  117.     uint32_t value;
  118.     OH_JSVM_GetValueUint32(env, index, &value);
  119.     JSVM_Value newResult = nullptr;
  120.     char newStr[] = "new return value hahaha from index listening";
  121.     OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
  122.     int signBit = 0;
  123.     size_t wordCount = 2;
  124.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  125.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  126.     if (status == JSVM_OK) {
  127.         OH_LOG_INFO(LOG_APP, "IndexedPropertyGet wordCount is %{public}zu", wordCount);
  128.         auto test = reinterpret_cast<Test *>(wordsOut);
  129.         typedef void (*callTest1)();
  130.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  131.         callTe();
  132.     }
  133.     return nullptr;
  134. }
  135. static JSVM_Value IndexedPropertySet(JSVM_Env env, JSVM_Value index, JSVM_Value property, JSVM_Value thisArg, JSVM_Value data) {
  136.     // 该回调是由设置实例对象的索引属性触发的
  137.     uint32_t value;
  138.     OH_JSVM_GetValueUint32(env, index, &value);
  139.     char str[100];
  140.     size_t size;
  141.     OH_JSVM_GetValueStringUtf8(env, property, str, 100, &size);
  142.     JSVM_Value newResult = nullptr;
  143.     char newStr[] = "new return value hahaha from name listening";
  144.     OH_JSVM_CreateStringUtf8(env, newStr, strlen(newStr), &newResult);
  145.     int signBit = 0;
  146.     size_t wordCount = 2;
  147.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  148.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  149.     if (status == JSVM_OK) {
  150.         OH_LOG_INFO(LOG_APP, "IndexedPropertySet wordCount is %{public}zu", wordCount);
  151.         auto test = reinterpret_cast<Test *>(wordsOut);
  152.         typedef void (*callTest1)();
  153.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  154.         callTe();
  155.     }
  156.     return nullptr;
  157. }
  158. static JSVM_Value IndexedPropertyDeleter(JSVM_Env env, JSVM_Value index, JSVM_Value thisArg, JSVM_Value data) {
  159.     // 该回调是由删除实例对象的索引属性触发的
  160.     uint32_t value;
  161.     OH_JSVM_GetValueUint32(env, index, &value);
  162.     JSVM_Value newResult = nullptr;
  163.     bool returnValue = false;
  164.     OH_JSVM_GetBoolean(env, returnValue, &newResult);
  165.     int signBit = 0;
  166.     size_t wordCount = 2;
  167.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  168.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  169.     if (status == JSVM_OK) {
  170.         OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
  171.         auto test = reinterpret_cast<Test *>(wordsOut);
  172.         typedef void (*callTest1)();
  173.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  174.         callTe();
  175.     }
  176.     return nullptr;
  177. }
  178. static JSVM_Value IndexedPropertyEnumerator(JSVM_Env env, JSVM_Value thisArg, JSVM_Value data) {
  179.     // 该回调是由获取对象上的所有索引属性请求触发的
  180.     JSVM_Value testArray = nullptr;
  181.     OH_JSVM_CreateArrayWithLength(env, 2, &testArray);
  182.     JSVM_Value index1 = nullptr;
  183.     OH_JSVM_CreateUint32(env, 1, &index1);
  184.     JSVM_Value index2 = nullptr;
  185.     OH_JSVM_CreateUint32(env, 2, &index2);
  186.     OH_JSVM_SetElement(env, testArray, 0, index1);
  187.     OH_JSVM_SetElement(env, testArray, 1, index2);
  188.     int signBit = 0;
  189.     size_t wordCount = 2;
  190.     uint64_t wordsOut[2] = {0ULL, 0ULL};
  191.     JSVM_Status status = OH_JSVM_GetValueBigintWords(env, data, &signBit, &wordCount, wordsOut);
  192.     if (status == JSVM_OK) {
  193.         OH_LOG_INFO(LOG_APP, "IndexedPropertyDeleter wordCount is %{public}zu", wordCount);
  194.         auto test = reinterpret_cast<Test *>(wordsOut);
  195.         typedef void (*callTest1)();
  196.         callTest1 callTe = reinterpret_cast<callTest1>(test->ptr1);
  197.         callTe();
  198.     }
  199.     return nullptr;
  200. }
  201. static napi_value TestDefineClassWithProperty(napi_env env1, napi_callback_info info) {
  202.     OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty start");
  203.     JSVM_InitOptions init_options;
  204.     memset(&init_options, 0, sizeof(init_options));
  205.     init_options.externalReferences = externals;
  206.     if (aa == 0) {
  207.         OH_JSVM_Init(&init_options);
  208.         aa++;
  209.     }
  210.     JSVM_VM vm;
  211.     JSVM_CreateVMOptions options;
  212.     memset(&options, 0, sizeof(options));
  213.     OH_JSVM_CreateVM(&options, &vm);
  214.     JSVM_VMScope vm_scope;
  215.     OH_JSVM_OpenVMScope(vm, &vm_scope);
  216.     JSVM_Env env;
  217.     JSVM_CallbackStruct param[1];
  218.     param[0].data = nullptr;
  219.     param[0].callback = assertEqual;
  220.     JSVM_PropertyDescriptor descriptor[] = {
  221.         {"assertEqual", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
  222.     };
  223.     OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
  224.     JSVM_EnvScope envScope;
  225.     OH_JSVM_OpenEnvScope(env, &envScope);
  226.     JSVM_HandleScope handlescope;
  227.     OH_JSVM_OpenHandleScope(env, &handlescope);
  228.     JSVM_CallbackStruct param1;
  229.     param1.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
  230.         JSVM_Value thisVar = nullptr;
  231.         OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
  232.         return thisVar;
  233.     };
  234.     param1.data = nullptr;
  235.     JSVM_Value res = nullptr;
  236.     Test *test = new Test();
  237.     test->ptr1 = (void *)test1;
  238.     test->ptr2 = (void *)test1;
  239.     OH_LOG_INFO(LOG_APP, "OH_JSVM_CreateBigintWords 111 word count %{public}d",
  240.                 sizeof(*test) / sizeof(uint64_t));
  241.     JSVM_Status status = OH_JSVM_CreateBigintWords(env, 1, 2, reinterpret_cast<const uint64_t *>(test), &res);
  242.     // 初始化propertyCfg
  243.     JSVM_PropertyHandlerConfigurationStruct propertyCfg;
  244.     propertyCfg.genericNamedPropertyGetterCallback = GetPropertyCbInfo;
  245.     propertyCfg.genericNamedPropertySetterCallback = SetPropertyCbInfo;
  246.     propertyCfg.genericNamedPropertyDeleterCallback = DeleterPropertyCbInfo;
  247.     propertyCfg.genericNamedPropertyEnumeratorCallback = EnumeratorPropertyCbInfo;
  248.     propertyCfg.genericIndexedPropertyGetterCallback = IndexedPropertyGet;
  249.     propertyCfg.genericIndexedPropertySetterCallback = IndexedPropertySet;
  250.     propertyCfg.genericIndexedPropertyDeleterCallback = IndexedPropertyDeleter;
  251.     propertyCfg.genericIndexedPropertyEnumeratorCallback = IndexedPropertyEnumerator;
  252.     propertyCfg.namedPropertyData = res;
  253.     propertyCfg.indexedPropertyData = res;
  254.     JSVM_CallbackStruct callbackStruct;
  255.     callbackStruct.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
  256.         OH_LOG_INFO(LOG_APP, "call as a function called");
  257.         JSVM_Value thisVar = nullptr;
  258.         void *innerData;
  259.         size_t argc = 1;
  260.         JSVM_Value args[1];
  261.         OH_JSVM_GetCbInfo(env, info, &argc, args, &thisVar, &innerData);
  262.         OH_LOG_INFO(LOG_APP, "function call as function result is %{public}s", reinterpret_cast<char *>(innerData));
  263.         uint32_t ret = 0;
  264.         OH_JSVM_GetValueUint32(env, args[0], &ret);
  265.         const char testStr[] = "hello world 111111";
  266.         JSVM_Value setvalueName = nullptr;
  267.         JSVM_CALL(env, OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName));
  268.         return setvalueName;
  269.     };
  270.     char data[100] = "1111 hello world";
  271.     callbackStruct.data = data;
  272.     JSVM_Value testWrapClass = nullptr;
  273.     // 将属性的访问监听注册在propertyCfg中
  274.     OH_JSVM_DefineClassWithPropertyHandler(env, "TestWrapClass", NAPI_AUTO_LENGTH, &param1, 0, nullptr, &propertyCfg,
  275.                                            &callbackStruct, &testWrapClass);
  276.     JSVM_Value instanceValue = nullptr;
  277.     OH_JSVM_NewInstance(env, testWrapClass, 0, nullptr, &instanceValue);
  278.     const char testStr[] = "hello world";
  279.     JSVM_Value setvalueName = nullptr;
  280.     OH_JSVM_CreateStringUtf8(env, testStr, strlen(testStr), &setvalueName);
  281.     // 1. 名称属性回调
  282.     // 设置属性
  283.     OH_JSVM_SetNamedProperty(env, instanceValue, "str11", setvalueName);
  284.     OH_JSVM_SetNamedProperty(env, instanceValue, "str123", setvalueName);
  285.     // 获取属性
  286.     JSVM_Value valueName = nullptr;
  287.     OH_JSVM_GetNamedProperty(env, instanceValue, "str11", &valueName);
  288.     char str[100];
  289.     size_t size;
  290.     OH_JSVM_GetValueStringUtf8(env, valueName, str, 100, &size);
  291.     // 获取所有属性的名称
  292.     JSVM_Value allPropertyNames = nullptr;
  293.     OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
  294.                                 static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
  295.                                 JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames);
  296.     uint32_t nameSize = 0;
  297.     OH_JSVM_GetArrayLength(env, allPropertyNames, &nameSize);
  298.     JSVM_Value propertyName = nullptr;
  299.     for (uint32_t i = 0; i < nameSize; ++i) {
  300.         OH_JSVM_GetElement(env, allPropertyNames, i, &propertyName);
  301.         char str[100];
  302.         size_t size;
  303.         OH_JSVM_GetValueStringUtf8(env, propertyName, str, 100, &size);
  304.     }
  305.     // 删除属性
  306.     bool result = false;
  307.     propertyName = nullptr;
  308.     char propertyChar[] = "str11";
  309.     OH_JSVM_CreateStringUtf8(env, propertyChar, strlen(propertyChar), &propertyName);
  310.     OH_JSVM_DeleteProperty(env, instanceValue, propertyName, &result);
  311.     // 2. 索引属性回调
  312.     // 设置属性
  313.     JSVM_Value jsIndex = nullptr;
  314.     uint32_t index = 0;
  315.     OH_JSVM_CreateUint32(env, index, &jsIndex);
  316.     OH_JSVM_SetProperty(env, instanceValue, jsIndex, setvalueName);
  317.     JSVM_Value jsIndex1 = nullptr;
  318.     index = 1;
  319.     OH_JSVM_CreateUint32(env, index, &jsIndex1);
  320.     OH_JSVM_SetProperty(env, instanceValue, jsIndex1, setvalueName);
  321.     // 获取属性
  322.     JSVM_Value valueName1 = nullptr;
  323.     OH_JSVM_GetProperty(env, instanceValue, jsIndex, &valueName1);
  324.     char str1[100];
  325.     size_t size1;
  326.     OH_JSVM_GetValueStringUtf8(env, valueName1, str1, 100, &size1);
  327.     // 获取所有属性的名称
  328.     JSVM_Value allPropertyNames1 = nullptr;
  329.     OH_JSVM_GetAllPropertyNames(env, instanceValue, JSVM_KEY_OWN_ONLY,
  330.                                 static_cast<JSVM_KeyFilter>(JSVM_KEY_ENUMERABLE | JSVM_KEY_SKIP_SYMBOLS),
  331.                                 JSVM_KEY_NUMBERS_TO_STRINGS, &allPropertyNames1);
  332.     uint32_t nameSize1 = 0;
  333.     OH_JSVM_GetArrayLength(env, allPropertyNames1, &nameSize);
  334.     JSVM_Value propertyName1 = nullptr;
  335.     for (uint32_t i = 0; i < nameSize1; ++i) {
  336.         OH_JSVM_GetElement(env, allPropertyNames1, i, &propertyName1);
  337.         char str[100];
  338.         size_t size;
  339.         OH_JSVM_GetValueStringUtf8(env, propertyName1, str, 100, &size);
  340.     }
  341.     // 删除属性
  342.     bool result1 = false;
  343.     OH_JSVM_DeleteProperty(env, instanceValue, jsIndex, &result1);
  344.     // 3. 作为函数的回调
  345.     JSVM_Value gloablObj = nullptr;
  346.     OH_JSVM_GetGlobal(env, &gloablObj);
  347.     OH_JSVM_SetNamedProperty(env, gloablObj, "myTestInstance", instanceValue);
  348.     OH_LOG_INFO(LOG_APP, "set property on global object");
  349.     std::string innerSourcecodestr = R"(
  350.     {
  351.         let res = myTestInstance(12);
  352.     })";
  353.     JSVM_Value innerSourcecodevalue;
  354.     OH_JSVM_CreateStringUtf8(env, innerSourcecodestr.c_str(), innerSourcecodestr.size(), &innerSourcecodevalue);
  355.     JSVM_Script innerscript;
  356.     OH_JSVM_CompileScript(env, innerSourcecodevalue, nullptr, 0, true, nullptr, &innerscript);
  357.     JSVM_Value innerResult;
  358.     OH_JSVM_RunScript(env, innerscript, &innerResult);
  359.     OH_JSVM_CloseHandleScope(env, handlescope);
  360.     OH_JSVM_CloseEnvScope(env, envScope);
  361.     OH_JSVM_DestroyEnv(env);
  362.     OH_JSVM_CloseVMScope(vm, vm_scope);
  363.     OH_JSVM_DestroyVM(vm);
  364.     OH_LOG_ERROR(LOG_APP, "TestDefineClassWithProperty pass");
  365.     return nullptr;
  366. }
  367. c++
复制代码
版本管理

场景介绍

获取当前版本信息。
接口说明

接口功能说明OH_JSVM_GetVersion返回JSVM运行时支持的最高JSVM API版本OH_JSVM_GetVMInfo返回虚拟机的信息 场景示例: 获取当前版本信息。
  1. JSVM_VMInfo result;
  2. OH_JSVM_GetVMInfo(&result);
  3. uint32_t versionId = 0;
  4. OH_JSVM_GetVersion(env, &versionId);
  5. c++
复制代码
内存管理

场景介绍

内存管理
接口说明

接口功能说明OH_JSVM_AdjustExternalMemory将因JavaScript对象而保持活跃的外部分配的内存大小实时关照给底层虚拟机,虚拟机后续触发GC时,就会综合表里内存状态来判断是否举行全局GC。即增大外部内存分配,则会增大触发全局GC的概率;反之淘汰。OH_JSVM_MemoryPressureNotification关照虚拟机体系内存压力层级,并有选择地触发垃圾回收。OH_JSVM_AllocateArrayBufferBackingStoreData申请一块 BackingStore 内存。OH_JSVM_FreeArrayBufferBackingStoreData释放 BackingStore 内存。OH_JSVM_CreateArrayBufferFromBackingStoreData基于申请的 BackingStore 内存创建 array buffer。   BackingStore 的利用属于高危操作,需要利用者自身保证内存的正确利用,请参考下方的正确示例,审慎利用。
  场景示例: 内存管理。
  1. // 分别在调用OH_JSVM_AdjustExternalMemory前后来查看底层虚拟机视角下外部分配的内存大小
  2. int64_t result;
  3. OH_JSVM_AdjustExternalMemory(env, 0, &result); // 假设外部分配内存的变化不变
  4. OH_LOG_INFO(LOG_APP, "Before AdjustExternalMemory: %{public}lld\n", result); // 得到调整前的数值
  5. // 调整外部分配的内存大小通知给底层虚拟机(此示例假设内存使用量增加)
  6. int64_t memoryIncrease = 1024 * 1024; // 增加 1 MB
  7. OH_JSVM_AdjustExternalMemory(env, memoryIncrease, &result);
  8. OH_LOG_INFO(LOG_APP, "After AdjustExternalMemory: %{public}lld\n", result); // 得到调整后的数值
  9. c++
复制代码
  1. // 打开一个Handle scope,在scope范围内申请大量内存来测试函数功能;
  2. // 分别在“完成申请后”、“关闭scope后”和“调用OH_JSVM_MemoryPressureNotification后”三个节点查看内存状态
  3. JSVM_HandleScope tmpscope;
  4. OH_JSVM_OpenHandleScope(env, &tmpscope);
  5. for (int i = 0; i < 1000000; ++i) {
  6.     JSVM_Value obj;
  7.     OH_JSVM_CreateObject(env, &obj);
  8. }
  9. JSVM_HeapStatistics mem;
  10. OH_JSVM_GetHeapStatistics(vm, &mem); // 获取虚拟机堆的统计数据
  11. OH_LOG_INFO(LOG_APP, "%{public}zu\n", mem.usedHeapSize); // 申请完成后,内存处于最大状态
  12. OH_JSVM_CloseHandleScope(env, tmpscope); // 关闭Handle scope
  13. OH_JSVM_GetHeapStatistics(vm, &mem);
  14. OH_LOG_INFO(LOG_APP, "%{public}zu\n", mem.usedHeapSize); // 关闭scope后,GC并没有立即回收
  15. // 通知虚拟机系统内存压力层级,并有选择地触发垃圾回收
  16. OH_JSVM_MemoryPressureNotification(env, JSVM_MEMORY_PRESSURE_LEVEL_CRITICAL); // 假设内存压力处于临界状态
  17. OH_JSVM_GetHeapStatistics(vm, &mem);
  18. OH_LOG_INFO(LOG_APP, "%{public}zu\n", mem.usedHeapSize); // 触发垃圾回收后
  19. c++
复制代码
BackingStore 正确利用示例
  1. void *backingStore;
  2. JSVM_Value arrayBuffer;
  3. // 申请一块大小为 100 字节的 BackingStore 内存
  4. OH_JSVM_AllocateArrayBufferBackingStoreData(100, JSVM_ZERO_INITIALIZED, &backingStore);
  5. // 在之前申请的 BackingStore 上创建一个 ArrayBuffer,位置为距离 BackingStore 起始地址加 30 字节处,大小为 20 字节
  6. OH_JSVM_CreateArrayBufferFromBackingStoreData(env, backingStore, 100, 30, 20, &arrayBuffer);
  7. // 在 JS 中使用创建的 ArrayBuffer
  8. JSVM_Value js_global;
  9. JSVM_Value name;
  10. OH_JSVM_GetGlobal(jsvm_env, &js_global);
  11. OH_JSVM_CreateStringUtf8(jsvm_env, "buffer", JSVM_AUTO_LENGTH, &name);
  12. OH_JSVM_SetProperty(env, js_global, name, arrayBuffer);
  13. JSVM_Script script;
  14. JSVM_Value scriptString;
  15. JSVM_Value result;
  16. const char *src = R"JS(
  17. function writeBuffer(data) {
  18.   let view = new Uint8Array(data);
  19.   // Write some values to the ArrayBuffer
  20.   for (let i = 0; i < view.length; i++) {
  21.     view[i] = i % 256;
  22.   }
  23. }
  24. writeBuffer(buffer)
  25. )JS";
  26. OH_JSVM_CreateStringUtf8(env, src, JSVM_AUTO_LENGTH, &scriptString);
  27. OH_JSVM_CompileScriptWithOptions(env, scriptString, 0, nullptr, &script);
  28. OH_JSVM_RunScript(env, script, &result);
  29. // 检查 ArrayBuffer 的内容
  30. uint8_t *array = static_cast<uint8_t*>(backingStore);
  31. for (auto i = 0; i < 100; ++i) {
  32.   if (array[i] != i % 25 % 256) {
  33.     return false;
  34.   }
  35. }
  36. // 释放 array buffer. 注意对于这种方式创建的 ArrayBuffer, 在释放对应的 BackingStore 之前,
  37. // 务必使用 OH_JSVM_DetachArraybuffer 将所有使用当前的 BackingStore 创建的 ArrayBuffer 释放
  38. // 否则可能产生不可预测的内存问题,请谨慎使用
  39. OH_JSVM_DetachArraybuffer(env, arrayBuffer);
  40. // 释放申请的 backing store 内存
  41. OH_JSVM_FreeArrayBufferBackingStoreData(backingStore);
  42. c++
复制代码
Promise操作

场景介绍

Promise干系操作。
接口说明

接口功能说明OH_JSVM_CreatePromise创建一个耽误对象和一个JavaScript promiseOH_JSVM_ResolveDeferred通过与之关联的耽误对象来剖析JavaScript promiseOH_JSVM_RejectDeferred通过与之关联的耽误对象来拒绝JavaScript PromiseOH_JSVM_IsPromise查询Promise是否为原生Promise对象 场景示例: Promise干系操作。
  1. JSVM_Deferred deferred;
  2. JSVM_Value promise;
  3. OH_JSVM_CreatePromise(env, &deferred, &promise);
  4. // 模拟异步操作
  5. int result = 42;
  6. bool success = true;
  7. if (success)
  8. {
  9.     // 解析Promise,并传递结果
  10.     JSVM_Value value;
  11.     OH_JSVM_CreateInt32(env, result, &value);
  12.     OH_JSVM_ResolveDeferred(env, deferred, value);
  13. } else {
  14.     // 拒绝Promise,并传递错误信息
  15.     JSVM_Value code = nullptr;
  16.     JSVM_Value message = nullptr;
  17.     OH_JSVM_CreateStringUtf8(env, "600", JSVM_AUTO_LENGTH, &code);
  18.     OH_JSVM_CreateStringUtf8(env, "Async operation failed", JSVM_AUTO_LENGTH, &message);
  19.     JSVM_Value error = nullptr;
  20.     OH_JSVM_CreateError(env, code, message, &error);
  21.     OH_JSVM_RejectDeferred(env, deferred, error);
  22. }
  23. c++
复制代码
JSON操作

场景介绍

JSON操作。
接口说明

接口功能说明OH_JSVM_JsonParse剖析JSON字符串,并返回乐成剖析的值OH_JSVM_JsonStringify将对象字符串化,并返回乐成转换后的字符串 场景示例: 剖析JSON操作。
  1. std::string sourcecodestr = "{"name": "John", "age": 30, "city": "New York"}" ;
  2. JSVM_Value jsonString;
  3. OH_JSVM_CreateStringUtf8(env, sourcecodestr.c_str(), sourcecodestr.size(), &jsonString)
  4. JSVM_Value result;
  5. OH_JSVM_JsonParse(env, jsonString, &result);
  6. c++
复制代码
创建和利用虚拟机的启动快照

场景介绍

创建和利用虚拟机的启动快照
接口说明

接口功能说明OH_JSVM_CreateSnapshot用于创建虚拟机的启动快照OH_JSVM_CreateEnvFromSnapshot基于启动快照创建jsvm环境 查抄传入的值是否可调用

场景介绍

查抄传入的值是否可调用
接口说明

接口功能说明OH_JSVM_IsCallable查抄传入的值是否可调用 场景示例: 查抄传入的值是否可调用
  1. static JSVM_Value NapiIsCallable(JSVM_Env env, JSVM_CallbackInfo info) {
  2.     JSVM_Value value, rst;
  3.     size_t argc = 1;
  4.     bool isCallable = false;
  5.     JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, &value, NULL, NULL));
  6.     JSVM_CALL(env, OH_JSVM_IsCallable(env, value, &isCallable));
  7.     OH_JSVM_GetBoolean(env, isCallable, &rst);
  8.     return rst;
  9. }
  10. static napi_value MyJSVMDemo([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
  11.     std::thread t([]() {
  12.         // create vm, and open vm scope
  13.         JSVM_VM vm;
  14.         JSVM_CreateVMOptions options;
  15.         memset(&options, 0, sizeof(options));
  16.         OH_JSVM_CreateVM(&options, &vm);
  17.         JSVM_VMScope vmScope;
  18.         OH_JSVM_OpenVMScope(vm, &vmScope);
  19.         JSVM_CallbackStruct param[] = {
  20.             {.data = nullptr, .callback = NapiIsCallable},
  21.         };
  22.         JSVM_PropertyDescriptor descriptor[] = {
  23.             {"napiIsCallable", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
  24.         };
  25.         // create env, register native method, and open env scope
  26.         JSVM_Env env;
  27.         OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
  28.         JSVM_EnvScope envScope;
  29.         OH_JSVM_OpenEnvScope(env, &envScope);
  30.         // open handle scope
  31.         JSVM_HandleScope handleScope;
  32.         OH_JSVM_OpenHandleScope(env, &handleScope);
  33.         std::string sourceCodeStr = R"JS(
  34.         function addNumbers(num1, num2)
  35.         {
  36.             var rst= num1 + num2;
  37.             return rst;
  38.         }
  39.         let rst = napiIsCallable(addNumbers);
  40.         )JS";
  41.         // compile js script
  42.         JSVM_Value sourceCodeValue;
  43.         OH_JSVM_CreateStringUtf8(env, sourceCodeStr.c_str(), sourceCodeStr.size(), &sourceCodeValue);
  44.         JSVM_Script script;
  45.         OH_JSVM_CompileScript(env, sourceCodeValue, nullptr, 0, true, nullptr, &script);
  46.         JSVM_Value result;
  47.         // run js script
  48.         OH_JSVM_RunScript(env, script, &result);
  49.         JSVM_ValueType type;
  50.         OH_JSVM_Typeof(env, result, &type);
  51.         OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
  52.         // exit vm and clean memory
  53.         OH_JSVM_CloseHandleScope(env, handleScope);
  54.         OH_JSVM_CloseEnvScope(env, envScope);
  55.         OH_JSVM_DestroyEnv(env);
  56.         OH_JSVM_CloseVMScope(vm, vmScope);
  57.         OH_JSVM_DestroyVM(vm);
  58.     });
  59.     t.detach();
  60.     return nullptr;
  61. }
  62. c++
复制代码
Lock操作

场景介绍

Lock操作
接口说明

接口功能说明OH_JSVM_IsLocked判断当前线程是否持有指定环境的锁OH_JSVM_AcquireLock获取指定环境的锁OH_JSVM_ReleaseLock释放指定环境的锁 场景示例: 加锁解锁操作
  1. class LockWrapper {
  2. public:
  3.   LockWrapper(JSVM_Env env) : env(env) {
  4.     OH_JSVM_IsLocked(env, &isLocked);
  5.     if (!isLocked) {
  6.       OH_JSVM_AcquireLock(env);
  7.       OH_JSVM_GetVM(env, &vm);
  8.       OH_JSVM_OpenVMScope(vm, &vmScope);
  9.       OH_JSVM_OpenEnvScope(env, &envScope);
  10.     }
  11.   }
  12.   ~LockWrapper() {
  13.     if (!isLocked) {
  14.       OH_JSVM_CloseEnvScope(env, envScope);
  15.       OH_JSVM_CloseVMScope(vm, vmScope);
  16.       OH_JSVM_ReleaseLock(env);
  17.     }
  18.   }
  19.   LockWrapper(const LockWrapper&) = delete;
  20.   LockWrapper& operator=(const LockWrapper&) = delete;
  21.   LockWrapper(LockWrapper&&) = delete;
  22.   void* operator new(size_t) = delete;
  23.   void* operator new[](size_t) = delete;
  24. private:
  25.   JSVM_Env env;
  26.   JSVM_EnvScope envScope;
  27.   JSVM_VMScope vmScope;
  28.   JSVM_VM vm;
  29.   bool isLocked;
  30. };
  31. static napi_value Add([[maybe_unused]] napi_env _env, [[maybe_unused]] napi_callback_info _info) {
  32.     static JSVM_VM vm;
  33.     static JSVM_Env env;
  34.     if (aa == 0) {
  35.         OH_JSVM_Init(nullptr);
  36.         aa++;
  37.         // create vm
  38.         JSVM_CreateVMOptions options;
  39.         memset(&options, 0, sizeof(options));
  40.         OH_JSVM_CreateVM(&options, &vm);
  41.         // create env
  42.         OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
  43.     }
  44.     std::thread t1([]() {
  45.         LockWrapper lock(env);
  46.         JSVM_HandleScope handleScope;
  47.         OH_JSVM_OpenHandleScope(env, &handleScope);
  48.         JSVM_Value value;
  49.         JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
  50.         if (rst == JSVM_OK) {
  51.             OH_LOG_INFO(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 suc");
  52.         } else {
  53.             OH_LOG_ERROR(LOG_APP, "JSVM:t1 OH_JSVM_CreateInt32 fail");
  54.         }
  55.         int32_t num1;
  56.         OH_JSVM_GetValueInt32(env, value, &num1);
  57.         OH_LOG_INFO(LOG_APP, "JSVM:t1 num1 = %{public}d", num1);
  58.         OH_JSVM_CloseHandleScope(env, handleScope);
  59.     });
  60.     std::thread t2([]() {
  61.         LockWrapper lock(env);
  62.         JSVM_HandleScope handleScope;
  63.         OH_JSVM_OpenHandleScope(env, &handleScope);
  64.         JSVM_Value value;
  65.         JSVM_Status rst = OH_JSVM_CreateInt32(env, 32, &value); // 32: numerical value
  66.         if (rst == JSVM_OK) {
  67.             OH_LOG_INFO(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 suc");
  68.         } else {
  69.             OH_LOG_ERROR(LOG_APP, "JSVM:t2 OH_JSVM_CreateInt32 fail");
  70.         }
  71.         int32_t num1;
  72.         OH_JSVM_GetValueInt32(env, value, &num1);
  73.         OH_LOG_INFO(LOG_APP, "JSVM:t2 num1 = %{public}d", num1);
  74.         OH_JSVM_CloseHandleScope(env, handleScope);
  75.     });
  76.     t1.detach();
  77.     t2.detach();
  78.     return nullptr;
  79. }
  80. c++
复制代码
设置与获取和当前运行的JSVM环境干系联的数据

场景介绍

检索通过OH_JSVM_SetInstanceData()与当前运行的JSVM环境干系联的数据
接口说明

接口功能说明OH_JSVM_SetInstanceData设置与当前运行的JSVM环境干系联的数据OH_JSVM_GetInstanceData获取与当前运行的JSVM环境干系联的数据 场景示例: 设置并获取与当前运行的JSVM环境干系联的数据。
  1. JSVM_VM vm;
  2. JSVM_CreateVMOptions options;
  3. JSVM_VMScope vm_scope;
  4. JSVM_Env env;
  5. JSVM_EnvScope envScope;
  6. JSVM_HandleScope handlescope;
  7. static int aa = 0;
  8. struct InstanceData {
  9.     int32_t value;
  10. };
  11. // 初始化虚拟机,创建JSVM运行环境
  12. void init_JSVM_environment(){         
  13.     JSVM_InitOptions init_options;
  14.     memset(&init_options, 0, sizeof(init_options));
  15.     if (aa == 0) {
  16.         OH_JSVM_Init(&init_options);
  17.         aa++;
  18.     }
  19.     memset(&options, 0, sizeof(options));
  20.     OH_JSVM_CreateVM(&options, &vm);
  21.     OH_JSVM_OpenVMScope(vm, &vm_scope);
  22.     OH_JSVM_CreateEnv(vm, 0, nullptr, &env);
  23.     OH_JSVM_OpenEnvScope(env, &envScope);
  24.     OH_JSVM_OpenHandleScope(env, &handlescope);
  25. }
  26. // 退出虚拟机,释放对应的环境
  27. napi_value close_JSVM_environment(napi_env env1, napi_callback_info info)
  28. {
  29.     OH_JSVM_CloseHandleScope(env, handlescope);
  30.     OH_JSVM_CloseEnvScope(env, envScope);
  31.     OH_JSVM_DestroyEnv(env);
  32.     OH_JSVM_CloseVMScope(vm, vm_scope);
  33.     OH_JSVM_DestroyVM(vm);
  34.     napi_value result;
  35.     char* s = "ok";
  36.     napi_create_string_latin1(env1, s, strlen(s), &result);
  37.     return result;
  38. }
  39. //清除和释放与实例相关联的内存资源
  40. void InstanceFinalizeCallback(JSVM_Env env, void *finalizeData, void *finalizeHint)
  41. {
  42.     if (finalizeData) {
  43.         InstanceData *data = reinterpret_cast<InstanceData *>(finalizeData);
  44.         free(data);
  45.         *(InstanceData **)finalizeData = nullptr;
  46.     }
  47. }
  48. static napi_value GetInstanceData(napi_env env1, napi_callback_info info)
  49. {
  50.     InstanceData *instanceData = reinterpret_cast<InstanceData *>(malloc(sizeof(InstanceData)));
  51.     if (instanceData == nullptr) {
  52.         printf("Memory allocation failed!\n");
  53.         return nullptr;
  54.     }
  55.     size_t argc = 1;
  56.     napi_value args[1] = {nullptr};
  57.     //用于获取回调函数参数
  58.     napi_get_cb_info(env1, info, &argc, args , nullptr, nullptr);
  59.     napi_valuetype valuetype0;
  60.     napi_typeof(env1, args[0], &valuetype0);
  61.     int32_t tmp = 0;
  62.     napi_get_value_int32(env1, args[0], &tmp);
  63.     instanceData->value = tmp;
  64.     //将获得的参数与当前运行的JSVM环境关联起来
  65.     OH_JSVM_SetInstanceData(env, instanceData, InstanceFinalizeCallback, nullptr);
  66.     InstanceData *resData = nullptr;
  67.     //获取与当前运行的JSVM环境相关联的数据
  68.     OH_JSVM_GetInstanceData(env, (void **)&resData);
  69.     napi_value result;
  70.     napi_create_uint32(env1, resData->value, &result);
  71.     return result;
  72. }
  73. c++
复制代码
使命队列

场景介绍

在虚拟机内部启动使命队列的运行,查抄是否有微使命在队列中等待,这个使命队列可以由外部事件循环执行
接口说明

接口功能说明OH_JSVM_PumpMessageLoop启动使命队列的运行OH_JSVM_PerformMicrotaskCheckpoint执利用命队列里的微使命
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表