1# Creating and Calling JS Functions Using JSVM-API
2
3## Introduction
4
5JSVM-API provides APIs for calling JavaScript (JS) functions and passing parameters or creating JS methods in C/C++.
6
7## Basic Concepts
8
9Functions are blocks of reusable code that performs specific tasks or operations. You can define functions to implement different operations. Functions provide a way to modularize and structure code, helping make your code more organized, reusable, and maintainable.
10
11## Available APIs
12
13| API                      | Description                      |
14|----------------------------|--------------------------------|
15| OH_JSVM_GetCbInfo          | Obtains detailed information about the call, such as the parameters and **this** pointer, from the given callback information.|
16| OH_JSVM_CallFunction       | Calls a JS function from a C/C++ addon.|
17| OH_JSVM_IsFunction         | Checks whether an object is a function object.|
18| OH_JSVM_CreateFunction     | Creates a JS function to call a C/C++ function in JS environment. The function can be called only after it is set in a JS object.|
19
20## Example
21
22If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in creating and calling functions.
23
24### OH_JSVM function Test
25
26Full code for the CPP test. The entry is **TEST_FUNC**.
27``` cpp
28#include "hilog/log.h"
29#include "ark_runtime/jsvm.h"
30
31#define LOG_DOMAIN 0x3200
32#define LOG_TAG "APP"
33
34#define CHECK_RET(cond) \
35  if ((cond)) { \
36    const JSVM_ExtendedErrorInfo* info; \
37    OH_JSVM_GetLastErrorInfo(env, &info); \
38    OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", __FILE__, __LINE__, cond, info != nullptr ? info->errorMessage : ""); \
39    return -1;   \
40  }
41
42#define CHECK(cond) \
43  if (!(cond)) { \
44     OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d", __FILE__, __LINE__, cond); \
45     return -1;   \
46  }
47
48JSVM_Value NativeCreateFunctionTest(JSVM_Env env, JSVM_CallbackInfo info) {
49    void *data;
50    size_t argc = 1;
51    JSVM_Value argv[1] = {nullptr};
52    JSVM_Value thisArg;
53    // Obtain the callback parameters.
54    JSVM_Status ret = OH_JSVM_GetCbInfo(env, info, &argc, &argv[0], &thisArg, &data);
55    if (ret != JSVM_OK) {
56      const JSVM_ExtendedErrorInfo* info;
57      OH_JSVM_GetLastErrorInfo(env, &info);
58      OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d ret = %{public}d message = %{public}s", __FILE__, __LINE__, ret, info != nullptr ? info->errorMessage : "");
59      return nullptr;
60    }
61    char message[256];
62    OH_JSVM_GetValueStringLatin1(env, argv[0], message, 256, nullptr);
63    if (data == nullptr) {
64        OH_LOG_ERROR(LOG_APP, "jsvm: %{public}s; callback data null", message);
65    } else {
66        OH_LOG_INFO(LOG_APP, "jsvm: %{public}s; %{public}s", message, (char*)data);
67    }
68    return nullptr;
69}
70
71static int32_t TEST_FUNC() {
72    JSVM_InitOptions initOptions{};
73    JSVM_VM vm;
74    JSVM_Env env = nullptr;
75    JSVM_VMScope vmScope;
76    JSVM_EnvScope envScope;
77    JSVM_HandleScope handleScope;
78    JSVM_Value result;
79    static bool isVMInit = false;
80    if (!isVMInit) {
81        isVMInit = true;
82        // A single process needs to be initialized only once.
83        OH_JSVM_Init(&initOptions);
84    }
85    CHECK_RET(OH_JSVM_CreateVM(nullptr, &vm));
86    CHECK_RET(OH_JSVM_CreateEnv(vm, 0, nullptr, &env));
87    CHECK_RET(OH_JSVM_OpenVMScope(vm, &vmScope));
88    CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope));
89    CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope));
90
91    // Create a function and check it.
92    char hello[] = "Hello World!";
93    JSVM_CallbackStruct cb = {NativeCreateFunctionTest, (void*)hello};
94    JSVM_Value func;
95    CHECK_RET(OH_JSVM_CreateFunction(env, "", JSVM_AUTO_LENGTH, &cb, &func));
96    bool isFunction = false;
97    CHECK_RET(OH_JSVM_IsFunction(env, func, &isFunction));
98    CHECK(isFunction);
99
100    // Set the function to a global object.
101    JSVM_Value global;
102    CHECK_RET(OH_JSVM_GetGlobal(env, &global));
103    JSVM_Value key;
104    CHECK_RET(OH_JSVM_CreateStringUtf8(env, "NativeFunc", JSVM_AUTO_LENGTH, &key));
105    CHECK_RET(OH_JSVM_SetProperty(env, global, key, func));
106
107    // Call the function through OH_JSVM_CallFunction.
108    JSVM_Value argv[1] = {nullptr};
109    OH_JSVM_CreateStringUtf8(env, "jsvm api call funtion", JSVM_AUTO_LENGTH, &argv[0]);
110    CHECK_RET(OH_JSVM_CallFunction(env, global, func, 1, argv, &result));
111
112    // Call the function through the script.
113    JSVM_Script script;
114    JSVM_Value jsSrc;
115    const char* srcCallNative = R"JS(NativeFunc('js source call funtion');)JS";
116    CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc));
117    CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
118    CHECK_RET(OH_JSVM_RunScript(env, script, &result));
119
120    CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope));
121    CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope));
122    CHECK_RET(OH_JSVM_CloseVMScope(vm, vmScope));
123    CHECK_RET(OH_JSVM_DestroyEnv(env));
124    CHECK_RET(OH_JSVM_DestroyVM(vm));
125    return 0;
126}
127```
128**Expected output**
129```
130jsvm: jsvm api call funtion; Hello World!
131jsvm: js source call funtion; Hello World!
132```
133