• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Creating and Destroying JSVMs Using JSVM-API
2
3## When to Use
4
5Use **createJsCore** to create a JavaScript virtual machine (JSVM), which a runtime environment for executing JS code. The **createJsCore** returns a core ID, which uniquely identifies a VM.
6
7Use **evaluateJS** to run JS code in the VM of the specified core ID and define a promise in the JS code to asynchronously invoke the callback set in TS.
8
9Use **releaseJsCore** to release a JSVM.
10
11## Example
12
131. Declare APIs and configure compile settings.
14
15**Declare the APIs.**
16
17  ```ts
18  // index.d.ts
19  export const createJsCore: (fun: Function) => number;
20  export const releaseJsCore: (a: number) => void;
21  export const evaluateJS: (a: number, str: string) => string;
22  ```
23
24**Configure compile settings.**
25
26  ```
27  // CMakeLists.txt
28  # the minimum version of CMake.
29  cmake_minimum_required(VERSION 3.4.1)
30  project(MyApplication)
31
32  set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
33
34  if(DEFINED PACKAGE_FIND_FILE)
35  include(${PACKAGE_FIND_FILE})
36  endif()
37
38  include_directories(${NATIVERENDER_ROOT_PATH}
39                      ${NATIVERENDER_ROOT_PATH}/include)
40
41  add_library(entry SHARED create_jsvm_runtime.cpp)
42  target_link_libraries(entry PUBLIC libace_napi.z.so libjsvm.so libhilog_ndk.z.so)
43  ```
44
452. Create multiple JS runtime environments and run JS code.
46
47  ```cpp
48  // create_jsvm_runtime.cpp
49  #include "napi/native_api.h"
50  #include "ark_runtime/jsvm.h"
51  #include <bits/alltypes.h>
52  #include <deque>
53  #include <map>
54  #include <unistd.h>
55  #include <hilog/log.h>
56  #include <cstring>
57  #include <string>
58  #include <vector>
59  #include <sstream>
60
61  #define LOG_TAG "TEST_TAG"
62  // Obtain and throw the last error message. Use OH_JSVM_GetLastErrorInfo to obtain error information.
63  // If there is error information and no suspended exception, use OH_JSVM_ThrowError to throw an error.
64  #define GET_AND_THROW_LAST_ERROR(env)                                                                   \
65      do {                                                                                                \
66          const JSVM_ExtendedErrorInfo* errorInfo = nullptr;                                              \
67          OH_JSVM_GetLastErrorInfo((env), &errorInfo);                                                    \
68          bool isPending = false;                                                                         \
69          OH_JSVM_IsExceptionPending((env), &isPending);                                                  \
70              JSVM_Value error;                                                                           \
71          if (isPending && JSVM_OK == OH_JSVM_GetAndClearLastException((env), &error)) {                  \
72                                                                                                          \
73              JSVM_Value stack;                                                                           \
74              OH_JSVM_GetNamedProperty((env), error, "stack", &stack);                                    \
75                                                                                                          \
76              JSVM_Value message;                                                                         \
77              OH_JSVM_GetNamedProperty((env), error, "message", &message);                                \
78                                                                                                          \
79              char stackstr[256];                                                                         \
80              OH_JSVM_GetValueStringUtf8(env, stack, stackstr, 256, nullptr);                             \
81              OH_LOG_INFO(LOG_APP, "JSVM error stack: %{public}s", stackstr);                             \
82              char messagestr[256];                                                                       \
83              OH_JSVM_GetValueStringUtf8(env, message, messagestr, 256, nullptr);                         \
84              OH_LOG_INFO(LOG_APP, "JSVM error message: %{public}s", messagestr);                         \
85          }                                                                                               \
86          if (!isPending && errorInfo != nullptr) {                                                       \
87              const char* errorMessage =                                                                  \
88                  errorInfo->errorMessage != nullptr ? errorInfo->errorMessage : "empty error message";   \
89              OH_JSVM_ThrowError((env), nullptr, errorMessage);                                           \
90          }                                                                                               \
91      } while (0)
92
93  // Call theCall and check whether the return value is JSVM_OK.
94  // If no, call GET_AND_THROW_LAST_ERROR to process the error and return retVal.
95  #define JSVM_CALL_BASE(env, theCall, retVal)                                                            \
96      do {                                                                                                \
97          if ((theCall) != JSVM_OK) {                                                                     \
98              GET_AND_THROW_LAST_ERROR((env));                                                            \
99              return retVal;                                                                              \
100          }                                                                                               \
101      } while (0)
102
103  // Simplified version of JSVM_CALL_BASE. nullptr is returned.
104  #define JSVM_CALL(env, theCall) JSVM_CALL_BASE(env, theCall, nullptr)
105
106  using namespace std;
107  // Define a map to manage each independent VM.
108  static map<int, JSVM_VM*> g_vmMap;
109  static map<int, JSVM_Env*> g_envMap;
110  static map<int, napi_env> g_napiEnvMap;
111  static map<int, napi_ref> g_callBackMap;
112  static map<int, JSVM_CallbackStruct*> g_callBackStructMap;
113  static uint32_t ENVTAG_NUMBER = 0;
114  static std::mutex envMapLock;
115  static int aa = 0;
116
117  class Task {
118  public:
119      virtual ~Task() = default;
120      virtual void Run() = 0;
121  };
122  static map<int, deque<Task *>> g_taskQueueMap;
123
124  // Customize Consoleinfo.
125  static JSVM_Value Consoleinfo(JSVM_Env env, JSVM_CallbackInfo info) {
126      size_t argc = 1;
127      JSVM_Value args[1];
128      char log[256] = "";
129      size_t log_length;
130      OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
131
132      OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &log_length);
133      log[255] = 0;
134      OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log);
135      return nullptr;
136  }
137
138  // Create a promise method, which is used to create a promise in JS code.
139  static JSVM_Value CreatePromise(JSVM_Env env, JSVM_CallbackInfo info) {
140      OH_LOG_INFO(LOG_APP, "JSVM API TEST: CreatePromise start");
141      int envID = 0;
142      // Obtain envID of the current env.
143      for (auto it = g_envMap.begin(); it != g_envMap.end(); ++it) {
144          if (*it->second == env) {
145              envID = it->first;
146              break;
147          }
148      }
149      if (envID == -1) {
150          OH_LOG_INFO(LOG_APP, "JSVM API TEST: CreatePromise envID faild");
151          return nullptr;
152      }
153      JSVM_Value promise;
154      JSVM_Deferred deferred;
155      OH_JSVM_CreatePromise(env, &deferred, &promise);
156      // Define a ReadTask class to add deferred of the promise object to the execution queue.
157      class ReadTask : public Task {
158      public:
159          ReadTask(JSVM_Env env, JSVM_Deferred deferred, int envNum) : env_(env), envID_(envNum), deferred_(deferred) {}
160          void Run() override {
161              //string str = "TEST RUN OH_JSVM_ResolveDeferred";
162              int envID = 0;
163              for (auto it = g_envMap.begin(); it != g_envMap.end(); ++it) {
164                  if (*it->second == env_) {
165                      envID = it->first;
166                      break;
167                  }
168              }
169              OH_LOG_INFO(LOG_APP, "JSVM API TEST: CreatePromise %{public}d", envID);
170              JSVM_Value result;
171              OH_JSVM_CreateInt32(env_, envID, &result);
172              OH_JSVM_ResolveDeferred(env_, deferred_, result);
173          }
174      private:
175          JSVM_Env env_;
176          int envID_;
177          JSVM_Deferred deferred_;
178      };
179      g_taskQueueMap[envID].push_back(new ReadTask(env, deferred, envID));
180      OH_LOG_INFO(LOG_APP, "JSVM API TEST: CreatePromise end");
181      return promise;
182  }
183
184  // Customize the Add method.
185  static JSVM_Value Add(JSVM_Env env, JSVM_CallbackInfo info) {
186      size_t argc = 2;
187      JSVM_Value args[2];
188      OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
189      double num1, num2;
190      OH_JSVM_GetValueDouble(env, args[0], &num1);
191      OH_JSVM_GetValueDouble(env, args[1], &num2);
192      JSVM_Value sum = nullptr;
193      OH_JSVM_CreateDouble(env, num1 + num2, &sum);
194      return sum;
195  }
196
197  // Customize the AssertEqual method.
198  static JSVM_Value AssertEqual(JSVM_Env env, JSVM_CallbackInfo info) {
199      size_t argc = 2;
200      JSVM_Value args[2];
201      JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
202
203      bool isStrictEquals = false;
204      OH_JSVM_StrictEquals(env, args[0], args[1], &isStrictEquals);
205
206      if (isStrictEquals) {
207          OH_LOG_INFO(LOG_APP, "JSVM API TEST RESULT: PASS");
208      } else {
209          OH_LOG_INFO(LOG_APP, "JSVM API TEST RESULT: FAILED");
210      }
211      return nullptr;
212  }
213
214  // Invoke the native callback passed by TS.
215  static JSVM_Value OnJSResultCallback(JSVM_Env env, JSVM_CallbackInfo info) {
216      size_t argc = 3;
217      JSVM_Value args[3];
218      JSVM_CALL(env, OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL));
219      int callId = 0;
220      OH_JSVM_GetValueInt32(env, args[0], &callId);
221      napi_value callArgs[2] = {nullptr, nullptr};
222      size_t size;
223      size_t size1;
224
225      OH_JSVM_GetValueStringUtf8(env, args[1], nullptr, 0, &size);
226      char Str1[size + 1];
227      OH_JSVM_GetValueStringUtf8(env, args[1], Str1, size + 1, &size);
228
229      OH_JSVM_GetValueStringUtf8(env, args[2], nullptr, 0, &size1);
230      char Str2[size1 + 1];
231      OH_JSVM_GetValueStringUtf8(env, args[2], Str2, size1 + 1, &size1);
232
233      napi_create_string_utf8(g_napiEnvMap[callId], Str1, size + 1, &callArgs[0]);
234      napi_create_string_utf8(g_napiEnvMap[callId], Str2, size1 + 1, &callArgs[1]);
235      napi_value callback = nullptr;
236      // Obtain the TS callback, which is passed in when the JSVM is created, based on the call ID.
237      napi_get_reference_value(g_napiEnvMap[callId], g_callBackMap[callId], &callback);
238      napi_value ret;
239      // Execute the TS callback.
240      napi_call_function(g_napiEnvMap[callId], nullptr, callback, 2, callArgs, &ret);
241      char retStr[256];
242      napi_get_value_string_utf8(g_napiEnvMap[callId], ret, retStr, 256, &size);
243
244      JSVM_Value returnVal;
245      OH_JSVM_CreateStringUtf8(env, retStr, JSVM_AUTO_LENGTH, &returnVal);
246      return returnVal;
247  }
248
249  std::string napiValueToString(napi_env env, napi_value nValue) {
250      size_t buffLen = 0;
251      napi_get_value_string_utf8(env, nValue, nullptr, 0, &buffLen);
252      char buffer[buffLen + 1];
253      napi_get_value_string_utf8(env, nValue, buffer, buffLen + 1, &buffLen);
254
255      return buffer;
256  }
257
258  static std::string fromOHStringValue(JSVM_Env &env, JSVM_Value &value) {
259      size_t size;
260      JSVM_Status status;
261      status = OH_JSVM_GetValueStringUtf8(env, value, nullptr, 0, &size);
262      char resultStr[size + 1];
263      status = OH_JSVM_GetValueStringUtf8(env, value, resultStr, size + 1, &size);
264      return resultStr;
265  }
266
267  static void CreateArkJSContext() {
268      JSVM_Status status;
269      JSVM_InitOptions init_options;
270      memset(&init_options, 0, sizeof(init_options));
271      if (aa == 0) {
272          OH_JSVM_Init(&init_options);
273          aa++;
274      }
275
276      // VM instance.
277      g_vmMap[ENVTAG_NUMBER] = new JSVM_VM;
278      JSVM_CreateVMOptions options;
279      memset(&options, 0, sizeof(options));
280      status = OH_JSVM_CreateVM(&options, g_vmMap[ENVTAG_NUMBER]);
281      JSVM_VMScope vmScope;
282      OH_JSVM_OpenVMScope(*g_vmMap[ENVTAG_NUMBER], &vmScope);
283
284      // New environment.
285      g_envMap[ENVTAG_NUMBER] = new JSVM_Env;
286      g_callBackStructMap[ENVTAG_NUMBER] = new JSVM_CallbackStruct[5];
287
288      // Register the pointers to the native callbacks and data provided by the user and expose them to JS code through JSVM-API.
289      for (int i = 0; i < 5; i++) {
290          g_callBackStructMap[ENVTAG_NUMBER][i].data = nullptr;
291      }
292      g_callBackStructMap[ENVTAG_NUMBER][0].callback = Consoleinfo;
293      g_callBackStructMap[ENVTAG_NUMBER][1].callback = Add;
294      g_callBackStructMap[ENVTAG_NUMBER][2].callback = AssertEqual;
295      g_callBackStructMap[ENVTAG_NUMBER][3].callback = OnJSResultCallback;
296      g_callBackStructMap[ENVTAG_NUMBER][4].callback = CreatePromise;
297      JSVM_PropertyDescriptor descriptors[] = {
298          {"consoleinfo", NULL, &g_callBackStructMap[ENVTAG_NUMBER][0], NULL, NULL, NULL, JSVM_DEFAULT},
299          {"add", NULL, &g_callBackStructMap[ENVTAG_NUMBER][1], NULL, NULL, NULL, JSVM_DEFAULT},
300          {"assertEqual", NULL, &g_callBackStructMap[ENVTAG_NUMBER][2], NULL, NULL, NULL, JSVM_DEFAULT},
301          {"onJSResultCallback", NULL, &g_callBackStructMap[ENVTAG_NUMBER][3], NULL, NULL, NULL, JSVM_DEFAULT},
302          {"createPromise", NULL, &g_callBackStructMap[ENVTAG_NUMBER][4], NULL, NULL, NULL, JSVM_DEFAULT},
303      };
304      status = OH_JSVM_CreateEnv(*g_vmMap[ENVTAG_NUMBER], sizeof(descriptors) / sizeof(descriptors[0]), descriptors, g_envMap[ENVTAG_NUMBER]);
305      OH_JSVM_CloseVMScope(*g_vmMap[ENVTAG_NUMBER], vmScope);
306  }
307
308  // Provide an external interface for creating the JSVM and return the unique ID.
309  static napi_value CreateJsCore(napi_env env1, napi_callback_info info) {
310      OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore START");
311      size_t argc = 1;
312      napi_value argv[1];
313      napi_get_cb_info(env1, info, &argc, argv, nullptr, nullptr);
314      if (argc < 1) {
315          OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore the number of params must be one");
316          return nullptr;
317      }
318      g_napiEnvMap[ENVTAG_NUMBER] = env1;
319      g_taskQueueMap[ENVTAG_NUMBER] = deque<Task *>{};
320      // Store the mapping between the callback passed in by TS and env for subsequent calling.
321      napi_ref callFun;
322      napi_create_reference(env1, argv[0], 1, &callFun);
323      g_callBackMap[ENVTAG_NUMBER] = callFun;
324      napi_value coreID = 0;
325      {
326          std::lock_guard<std::mutex> lock_guard(envMapLock);
327          CreateArkJSContext();
328          napi_create_uint32(env1, ENVTAG_NUMBER, &coreID);
329          ENVTAG_NUMBER++;
330      }
331      OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore END");
332      return coreID;
333  }
334
335  // Provide an external interface for releasing the JSVM based on envId.
336  static napi_value ReleaseJsCore(napi_env env1, napi_callback_info info) {
337      OH_LOG_ERROR(LOG_APP, "JSVM ReleaseJsCore START");
338      size_t argc = 1;
339      napi_value argv[1];
340      napi_get_cb_info(env1, info, &argc, argv, nullptr, nullptr);
341      if (argc < 1) {
342          OH_LOG_ERROR(LOG_APP, "JSVM ReleaseJsCore the number of params must be one");
343          return nullptr;
344      }
345
346      uint32_t coreEnvId;
347      napi_status status = napi_get_value_uint32(env1, argv[0], &coreEnvId);
348      if (status != napi_ok) {
349          OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore napi_get_value_uint32 faild");
350          return nullptr;
351      }
352      if (g_envMap.count(coreEnvId) == 0 ) {
353          OH_LOG_ERROR(LOG_APP, "JSVM CreateJsCore not has env ");
354          return nullptr;
355      }
356      if (g_envMap[coreEnvId] != nullptr) {
357          std::lock_guard<std::mutex> lock_guard(envMapLock);
358          OH_JSVM_DestroyEnv(*g_envMap[coreEnvId]);
359          g_envMap[coreEnvId] = nullptr;
360          g_envMap.erase(coreEnvId);
361          OH_JSVM_DestroyVM(*g_vmMap[coreEnvId]);
362          g_vmMap[coreEnvId] = nullptr;
363          g_vmMap.erase(coreEnvId);
364          delete [] g_callBackStructMap[coreEnvId];
365          g_callBackStructMap[coreEnvId] = nullptr;
366          g_callBackStructMap.erase(coreEnvId);
367          napi_delete_reference(env1, g_callBackMap[coreEnvId]);
368          g_callBackMap.erase(coreEnvId);
369          g_taskQueueMap.erase(coreEnvId);
370      }
371      OH_LOG_ERROR(LOG_APP, "JSVM ReleaseJsCore END");
372      return nullptr;
373  }
374
375  static std::mutex mutexLock;
376  // Provide an external interface for running the JS code in the JSVM identified by a core ID.
377  static napi_value EvaluateJS(napi_env env, napi_callback_info info) {
378      OH_LOG_ERROR(LOG_APP, "JSVM EvaluateJS START");
379      size_t argc = 2;
380      napi_value args[2] = {nullptr};
381      napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
382      uint32_t envId;
383      napi_status status = napi_get_value_uint32(env, args[0], &envId);
384      if (status != napi_ok) {
385          OH_LOG_ERROR(LOG_APP, "EvaluateJS first param should be number");
386          return nullptr;
387      }
388
389      if (g_envMap.count(envId) == 0 || g_envMap[envId] == nullptr) {
390          OH_LOG_ERROR(LOG_APP, "EvaluateJS env is null");
391          return nullptr;
392      }
393      std::string dataStr = napiValueToString(env, args[1]);
394      napi_value res = nullptr;
395      std::lock_guard<std::mutex> lock_guard(mutexLock);
396      {
397          // open vm scope
398          JSVM_VMScope vmscope;
399          OH_JSVM_OpenVMScope(*g_vmMap[envId], &vmscope);
400          // open env scope
401          JSVM_EnvScope envscope;
402          OH_JSVM_OpenEnvScope(*g_envMap[envId], &envscope);
403          // open handle scope
404          JSVM_HandleScope handlescope;
405          OH_JSVM_OpenHandleScope(*g_envMap[envId], &handlescope);
406          // Compile the JS script.
407          JSVM_Value sourcecodevalue;
408          OH_JSVM_CreateStringUtf8(*g_envMap[envId], dataStr.c_str(), dataStr.size(), &sourcecodevalue);
409          JSVM_Script script;
410          OH_JSVM_CompileScript(*g_envMap[envId], sourcecodevalue, nullptr, 0, true, nullptr, &script);
411          // Run the JS script.
412          JSVM_Value result;
413          OH_JSVM_RunScript(*g_envMap[envId], script, &result);
414          JSVM_ValueType type;
415          OH_JSVM_Typeof(*g_envMap[envId], result, &type);
416          OH_LOG_INFO(LOG_APP, "JSVM API TEST type: %{public}d", type);
417          // Execute tasks in the current env event queue.
418          while (!g_taskQueueMap[envId].empty()) {
419              auto task = g_taskQueueMap[envId].front();
420              g_taskQueueMap[envId].pop_front();
421              task->Run();
422              delete task;
423          }
424
425          if (type == JSVM_STRING) {
426              std::string stdResult = fromOHStringValue(*g_envMap[envId], result);
427              napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
428          } else if (type == JSVM_BOOLEAN) {
429              bool ret = false;
430              std::string stdResult;
431              OH_JSVM_GetValueBool(*g_envMap[envId], result, &ret);
432              ret ? stdResult = "true" : stdResult = "false";
433              napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
434          } else if (type == JSVM_NUMBER) {
435              int32_t num;
436              OH_JSVM_GetValueInt32(*g_envMap[envId], result, &num);
437              std::string stdResult = std::to_string(num);
438              napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
439          } else if (type == JSVM_OBJECT) {
440              JSVM_Value objResult;
441              OH_JSVM_JsonStringify(*g_envMap[envId], result, &objResult);
442              std::string stdResult = fromOHStringValue(*g_envMap[envId], objResult);
443              napi_create_string_utf8(env, stdResult.c_str(), stdResult.length(), &res);
444      }
445          bool aal = false;
446          OH_JSVM_PumpMessageLoop(*g_vmMap[envId], &aal);
447          OH_JSVM_PerformMicrotaskCheckpoint(*g_vmMap[envId]);
448          OH_JSVM_CloseHandleScope(*g_envMap[envId], handlescope);
449          OH_JSVM_CloseEnvScope(*g_envMap[envId], envscope);
450          OH_JSVM_CloseVMScope(*g_vmMap[envId], vmscope);
451      }
452      OH_LOG_ERROR(LOG_APP, "JSVM EvaluateJS END");
453      return res;
454  }
455  ```
456
457**Register the module.**
458
459  ```cpp
460  // create_jsvm_runtime.cpp
461  EXTERN_C_START
462  static napi_value Init(napi_env env, napi_value exports) {
463      napi_property_descriptor desc[] = {
464          {"createJsCore", nullptr, CreateJsCore, nullptr, nullptr, nullptr, napi_default, nullptr},
465          {"releaseJsCore", nullptr, ReleaseJsCore, nullptr, nullptr, nullptr, napi_default, nullptr},
466          {"evaluateJS", nullptr, EvaluateJS, nullptr, nullptr, nullptr, napi_default, nullptr}
467      };
468
469      napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
470      return exports;
471  }
472  EXTERN_C_END
473
474  static napi_module demoModule = {
475      .nm_version = 1,
476      .nm_flags = 0,
477      .nm_filename = nullptr,
478      .nm_register_func = Init,
479      .nm_modname = "entry",
480      .nm_priv = ((void *)0),
481      .reserved = {0},
482  };
483
484  extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
485  ```
486
487  3. Run ArkTS code.
488
489  ```ts
490  import { hilog } from '@kit.PerformanceAnalysisKit';
491  import testNapi from 'libentry.so';
492
493  function MyCallback(a:string, b:string):string {
494      console.log("TEST MyCallback run: " + a);
495      b = "callback done";
496      console.log("TEST MyCallback run: " + b);
497      return "callback pass";
498  }
499
500  function MyCallback2(a:string, b:string):string {
501    console.log("TEST MyCallback2 start: a =  " + a);
502    console.log("TEST MyCallback2 start: b =  " + b);
503    return "MyCallback2 pass";
504  }
505
506  @Entry
507  @Component
508  struct Index {
509    @State message: string = 'Hello World';
510
511    build() {
512      Row() {
513        Column() {
514          Text(this.message)
515            .fontSize(50)
516            .fontWeight(FontWeight.Bold)
517            .onClick(() => {
518              let sourcecodestr = `{
519            let a = "hello World";
520            consoleinfo(a);
521            const mPromise = createPromise();
522            mPromise.then((result) => {
523            assertEqual(result, 0);
524            onJSResultCallback(result, "abc", "v");
525            });
526            a;
527            };`;
528
529              let sourcecodestr1 = `{
530            let a = "second hello";
531            consoleinfo(a);
532            let b = add(99, 1);
533            assertEqual(100, b);
534            assertEqual(add(99, 1), 100);
535            createPromise().then((result) => {
536            assertEqual(result, 1);
537            consoleinfo(onJSResultCallback(result, '999','666'));
538            });
539            a;
540            };`;
541
542              // Create the first VM and bind the TS callback.
543              const coreId = testNapi.createJsCore(MyCallback);
544              console.log("TEST coreId: " + coreId);
545              // Run JS code in the first VM.
546              console.log("TEST evaluateJS :   " + testNapi.evaluateJS(coreId, sourcecodestr));
547
548              // Create the second VM and bind the TS callback.
549              const coreId1 = testNapi.createJsCore(MyCallback2);
550              console.log("TEST coreId: " + coreId1);
551              // Run JS code in the second VM.
552              console.log("TEST evaluateJS :   " + testNapi.evaluateJS(coreId1, sourcecodestr1));
553
554              // Release the first VM.
555              testNapi.releaseJsCore(coreId);
556              // Release the second VM.
557              testNapi.releaseJsCore(coreId1);
558              hilog.info(0x0000, 'testTag', 'Test NAPI end');
559            })
560        }
561        .width('100%')
562      }
563      .height('100%')
564    }
565  }
566  ```
567