1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <chrono>
17 #include <csetjmp>
18 #include <csignal>
19 #include <cstring>
20 #include <deque>
21 #include <fstream>
22 #include <iostream>
23 #include <string>
24 #include <vector>
25
26 #include "jsvm.h"
27 #include "jsvm_types.h"
28 #include "jsvm_utils.h"
29
30 #define JSVM_PARENT_CLASS_DES_COUNT 2
31 #define JSVM_OBJECT_INTERFAIELD_COUNT 3
32 #define JSVM_DEFINE_CLASS_OPTIONS_COUNT 2
33
34 using namespace std;
35 using namespace testing;
36 using namespace testing::ext;
37
38 JSVM_Env jsvm_env = nullptr;
39
40 static string srcProf = R"JS(
41 function sleep(delay) {
42 var start = (new Date()).getTime();
43 while ((new Date()).getTime() - start < delay) {
44 continue;
45 }
46 }
47 function work9() {
48 sleep(100);
49 }
50 function work8() {
51 work9();
52 sleep(100);
53 }
54 function work7() {
55 work8();
56 sleep(100);
57 }
58 function work6() {
59 work7();
60 sleep(100);
61 }
62 function work5() {
63 work6();
64 sleep(100);
65 }
66 function work4() {
67 work5();
68 sleep(100);
69 }
70
71 function work3() {
72 work4();
73 sleep(100);
74 }
75
76 function work2() {
77 work3();
78 sleep(100);
79 }
80
81 function work1() {
82 work2();
83 sleep(100);
84 }
85
86 work1();
87 )JS";
88
hello_fn(JSVM_Env env,JSVM_CallbackInfo info)89 static JSVM_Value hello_fn(JSVM_Env env, JSVM_CallbackInfo info)
90 {
91 JSVM_Value output;
92 void* data = nullptr;
93 OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, nullptr, &data);
94 OH_JSVM_CreateStringUtf8(env, (char*)data, strlen((char*)data), &output);
95 return output;
96 }
97
98 class Task {
99 public:
100 virtual ~Task() = default;
101 virtual void Run() = 0;
102 };
103
104 static deque<Task*> task_queue;
105
read_fn(JSVM_Env env,JSVM_CallbackInfo info)106 static JSVM_Value read_fn(JSVM_Env env, JSVM_CallbackInfo info)
107 {
108 JSVM_Value promise;
109 JSVM_Deferred deferred;
110 OH_JSVM_CreatePromise(env, &deferred, &promise);
111 class ReadTask : public Task {
112 public:
113 ReadTask(JSVM_Env env, JSVM_Deferred deferred) : env_(env), deferred_(deferred) {}
114 void Run() override
115 {
116 string str;
117 getline(cin, str);
118 JSVM_Value result;
119 OH_JSVM_CreateStringUtf8(env_, str.c_str(), str.size(), &result);
120 OH_JSVM_ResolveDeferred(env_, deferred_, result);
121 }
122
123 private:
124 JSVM_Env env_;
125 JSVM_Deferred deferred_;
126 };
127 task_queue.push_back(new ReadTask(env, deferred));
128 return promise;
129 }
130
131 #define BUF_SIZE1 102400
print_fn(JSVM_Env env,JSVM_CallbackInfo info)132 static JSVM_Value print_fn(JSVM_Env env, JSVM_CallbackInfo info)
133 {
134 size_t argc = 1;
135 JSVM_Value argv[1];
136 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
137 if (argc > 0) {
138 char buf[BUF_SIZE1];
139 OH_JSVM_GetValueStringUtf8(env, argv[0], buf, BUF_SIZE1, nullptr);
140 std::cout << buf << std::endl;
141 }
142 return nullptr;
143 }
144
145 static JSVM_CallbackStruct hello_cb = { hello_fn, (void*)"Hello" };
146 static JSVM_CallbackStruct read_cb = { read_fn, nullptr };
147 static JSVM_CallbackStruct print_cb = { print_fn, nullptr };
148
149 static JSVM_PropertyDescriptor property_descriptors[] = {
150 { "hello", NULL, &hello_cb, NULL, NULL, NULL, JSVM_DEFAULT },
151 { "read", NULL, &read_cb, NULL, NULL, NULL, JSVM_DEFAULT },
152 { "print", NULL, &print_cb, NULL, NULL, NULL, JSVM_DEFAULT },
153 };
154
155 class JSVMTest : public testing::Test {
156 public:
SetUpTestCase()157 static void SetUpTestCase()
158 {
159 GTEST_LOG_(INFO) << "JSVMTest SetUpTestCase";
160 JSVM_InitOptions init_options {};
161 OH_JSVM_Init(&init_options);
162 }
163
TearDownTestCase()164 static void TearDownTestCase() {}
165
SetUp()166 void SetUp() override
167 {
168 OH_JSVM_CreateVM(nullptr, &vm);
169 // propertyCount is 3
170 OH_JSVM_CreateEnv(vm, 3, property_descriptors, &env);
171 OH_JSVM_OpenVMScope(vm, &vm_scope);
172 OH_JSVM_OpenEnvScope(env, &env_scope);
173 OH_JSVM_OpenHandleScope(env, &handleScope);
174 jsvm_env = env;
175 }
TearDown()176 void TearDown() override
177 {
178 GTEST_LOG_(INFO) << "JSVMTest TearDown";
179 OH_JSVM_CloseHandleScope(env, handleScope);
180 OH_JSVM_CloseEnvScope(env, env_scope);
181 OH_JSVM_CloseVMScope(vm, vm_scope);
182 OH_JSVM_DestroyEnv(env);
183 OH_JSVM_DestroyVM(vm);
184 }
185
186 protected:
187 JSVM_Env env = nullptr;
188 JSVM_VM vm = nullptr;
189 JSVM_EnvScope env_scope = nullptr;
190 JSVM_VMScope vm_scope = nullptr;
191 JSVM_HandleScope handleScope;
192 };
193
194 HWTEST_F(JSVMTest, JSVMGetVersion001, TestSize.Level1)
195 {
196 uint32_t versionId = 0;
197 JSVMTEST_CALL(OH_JSVM_GetVersion(env, &versionId));
198 ASSERT_EQ(versionId, 9);
199 }
200
201 HWTEST_F(JSVMTest, JSVMEquals001, TestSize.Level1)
202 {
203 JSVM_Value lhs = nullptr;
204 bool x = true;
205 JSVMTEST_CALL(OH_JSVM_GetBoolean(env, x, &lhs));
206 JSVM_Value rhs = nullptr;
207 bool y = true;
208 JSVMTEST_CALL(OH_JSVM_GetBoolean(env, y, &rhs));
209 bool isEquals = false;
210 JSVMTEST_CALL(OH_JSVM_Equals(env, lhs, rhs, &isEquals));
211 ASSERT_TRUE(isEquals);
212 }
213
214 HWTEST_F(JSVMTest, JSVMCreateCodeCache001, TestSize.Level1)
215 {
216 JSVM_Value jsSrc;
217 JSVMTEST_CALL(OH_JSVM_CreateStringUtf8(env, srcProf.c_str(), srcProf.size(), &jsSrc));
218
219 const uint8_t x1 = 34;
220 const uint8_t* x2 = &x1;
221 const uint8_t** dataPtr = &x2;
222 size_t x3 = 1;
223 size_t* lengthPtr = &x3;
224 JSVM_Script script = nullptr;
225 JSVMTEST_CALL(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script));
226 JSVMTEST_CALL(OH_JSVM_CreateCodeCache(env, script, dataPtr, lengthPtr));
227 }
228
229 HWTEST_F(JSVMTest, JSVMAcquire001, TestSize.Level1)
230 {
231 JSVMTEST_CALL(OH_JSVM_AcquireLock(env));
232 }
233
234 HWTEST_F(JSVMTest, JSVMIsObject001, TestSize.Level1)
235 {
236 JSVM_Value obj;
237 JSVMTEST_CALL(OH_JSVM_CreateMap(env, &obj));
238 bool result = false;
239 JSVMTEST_CALL(OH_JSVM_IsObject(env, obj, &result));
240 ASSERT_TRUE(result);
241
242 JSVMTEST_CALL(OH_JSVM_CreateSymbol(env, nullptr, &obj));
243 result = false;
244 JSVMTEST_CALL(OH_JSVM_IsObject(env, obj, &result));
245 ASSERT_FALSE(result);
246 }
247
248 HWTEST_F(JSVMTest, JSVMIsBoolean001, TestSize.Level1)
249 {
250 JSVM_Value obj;
251 JSVMTEST_CALL(OH_JSVM_CreateArray(env, &obj));
252 bool result = false;
253 JSVMTEST_CALL(OH_JSVM_IsBoolean(env, obj, &result));
254 ASSERT_FALSE(result);
255
256 bool boolvalue = true;
257 JSVMTEST_CALL(OH_JSVM_GetBoolean(env, boolvalue, &obj));
258 result = false;
259 JSVMTEST_CALL(OH_JSVM_IsBoolean(env, obj, &result));
260 ASSERT_TRUE(result);
261 }
262
263 HWTEST_F(JSVMTest, JSVMIsString001, TestSize.Level1)
264 {
265 JSVM_Value createString;
266 char str[12] = "hello world";
267 JSVMTEST_CALL(OH_JSVM_CreateStringUtf8(env, str, 12, &createString));
268 bool result = false;
269 JSVMTEST_CALL(OH_JSVM_IsString(env, createString, &result));
270 ASSERT_TRUE(result);
271
272 JSVM_Value obj = nullptr;
273 JSVMTEST_CALL(OH_JSVM_CreateSet(env, &obj));
274 result = false;
275 JSVMTEST_CALL(OH_JSVM_IsString(env, obj, &result));
276 ASSERT_FALSE(result);
277 }
278
279 HWTEST_F(JSVMTest, JSVMIsFunction001, TestSize.Level1)
280 {
281 JSVM_Value function;
282 JSVM_CallbackStruct param;
283 param.data = nullptr;
284 param.callback = nullptr;
285 JSVMTEST_CALL(OH_JSVM_CreateFunction(env, "func", JSVM_AUTO_LENGTH, ¶m, &function));
286 bool result = false;
287 JSVMTEST_CALL(OH_JSVM_IsFunction(env, function, &result));
288 ASSERT_TRUE(result);
289
290 JSVM_Value obj;
291 JSVMTEST_CALL(OH_JSVM_CreateObject(env, &obj));
292 result = false;
293 JSVMTEST_CALL(OH_JSVM_IsFunction(env, obj, &result));
294 ASSERT_FALSE(result);
295 }
296
297 HWTEST_F(JSVMTest, JSVMIsSymbol001, TestSize.Level1)
298 {
299 JSVM_Value obj;
300 JSVMTEST_CALL(OH_JSVM_CreateSymbol(env, nullptr, &obj));
301 bool result = false;
302 JSVMTEST_CALL(OH_JSVM_IsSymbol(env, obj, &result));
303 ASSERT_TRUE(result);
304
305 JSVMTEST_CALL(OH_JSVM_CreateObject(env, &obj));
306 result = false;
307 JSVMTEST_CALL(OH_JSVM_IsSymbol(env, obj, &result));
308 ASSERT_FALSE(result);
309 }
310
311 HWTEST_F(JSVMTest, JSVMIsNumber001, TestSize.Level1)
312 {
313 JSVM_Value obj;
314 JSVMTEST_CALL(OH_JSVM_CreateObject(env, &obj));
315 bool result = false;
316 JSVMTEST_CALL(OH_JSVM_IsNumber(env, obj, &result));
317 ASSERT_FALSE(result);
318
319 JSVM_Value value;
320 int intValue = 2;
321 JSVMTEST_CALL(OH_JSVM_CreateInt32(env, intValue, &value));
322 result = false;
323 JSVMTEST_CALL(OH_JSVM_IsNumber(env, value, &result));
324 ASSERT_TRUE(result);
325 }
326
327 HWTEST_F(JSVMTest, JSVMIsBigInt001, TestSize.Level1)
328 {
329 JSVM_Value obj;
330 JSVMTEST_CALL(OH_JSVM_CreateObject(env, &obj));
331 bool result = false;
332 JSVMTEST_CALL(OH_JSVM_IsBigInt(env, obj, &result));
333 ASSERT_FALSE(result);
334
335 JSVM_Value bigint;
336 int intValue = 2;
337 JSVMTEST_CALL(OH_JSVM_CreateBigintInt64(env, intValue, &bigint));
338 result = false;
339 JSVMTEST_CALL(OH_JSVM_IsBigInt(env, bigint, &result));
340 ASSERT_TRUE(result);
341 }
342
343 HWTEST_F(JSVMTest, JSVMIsNull001, TestSize.Level1)
344 {
345 JSVM_Value input;
346 bool result = false;
347 JSVMTEST_CALL(OH_JSVM_CreateArray(env, &input));
348 JSVMTEST_CALL(OH_JSVM_IsNull(env, input, &result));
349 ASSERT_FALSE(result);
350
351 JSVM_Value input2;
352 bool result2;
353 JSVMTEST_CALL(OH_JSVM_GetNull(env, &input2));
354 JSVMTEST_CALL(OH_JSVM_IsNull(env, input2, &result2));
355 ASSERT_TRUE(result2);
356 }
357
358 HWTEST_F(JSVMTest, JSVMIsUndefined001, TestSize.Level1)
359 {
360 JSVM_Value input;
361 bool result = false;
362 JSVMTEST_CALL(OH_JSVM_CreateArray(env, &input));
363 JSVMTEST_CALL(OH_JSVM_IsUndefined(env, input, &result));
364 ASSERT_FALSE(result);
365
366 JSVM_Value input2;
367 bool result2;
368 JSVMTEST_CALL(OH_JSVM_GetUndefined(env, &input2));
369 JSVMTEST_CALL(OH_JSVM_IsUndefined(env, input2, &result2));
370 ASSERT_TRUE(result2);
371 }
372
373 HWTEST_F(JSVMTest, OH_JSVM_IsNullOrUndefined001, TestSize.Level1)
374 {
375 JSVM_Value input;
376 bool result = false;
377 JSVMTEST_CALL(OH_JSVM_CreateArray(env, &input));
378 JSVMTEST_CALL(OH_JSVM_IsNullOrUndefined(env, input, &result));
379 ASSERT_FALSE(result);
380
381 JSVM_Value input2;
382 bool result2 = false;
383 JSVMTEST_CALL(OH_JSVM_GetNull(env, &input2));
384 JSVMTEST_CALL(OH_JSVM_IsNullOrUndefined(env, input2, &result2));
385 ASSERT_TRUE(result2);
386
387 result2 = false;
388 JSVMTEST_CALL(OH_JSVM_GetUndefined(env, &input2));
389 JSVMTEST_CALL(OH_JSVM_IsNullOrUndefined(env, input2, &result2));
390 ASSERT_TRUE(result2);
391 }
392
393 HWTEST_F(JSVMTest, JSVMIsLocked001, TestSize.Level1)
394 {
395 bool isLocked = false;
396 JSVMTEST_CALL(OH_JSVM_IsLocked(env, &isLocked));
397 }
398
399 HWTEST_F(JSVMTest, JSVMReleaseLock001, TestSize.Level1)
400 {
401 bool isLocked = false;
402 JSVMTEST_CALL(OH_JSVM_IsLocked(env, &isLocked));
403 JSVMTEST_CALL(OH_JSVM_ReleaseLock(env));
404 }
405
406 HWTEST_F(JSVMTest, JSVMCompileScriptWithOrigin001, TestSize.Level1)
407 {
408 JSVM_Value jsSrc;
409 JSVMTEST_CALL(OH_JSVM_CreateStringUtf8(env, srcProf.c_str(), srcProf.size(), &jsSrc));
410 JSVM_Script script;
411 JSVM_ScriptOrigin origin {
412 .sourceMapUrl = "/data/local/tmp/workload/index.js.map",
413 // 源文件名字
414 .resourceName = "index.js",
415 // scirpt 在源文件中的起始行列号
416 .resourceLineOffset = 0,
417 .resourceColumnOffset = 0,
418 };
419 JSVMTEST_CALL(OH_JSVM_CompileScriptWithOrigin(env, jsSrc, nullptr, 0, true, nullptr, &origin, &script));
420 }
421
422 HWTEST_F(JSVMTest, JSVMCompileScriptWithOrigin002, TestSize.Level1)
423 {
424 JSVM_Value jsSrc = nullptr;
425 bool x = true;
426 JSVMTEST_CALL(OH_JSVM_GetBoolean(env, x, &jsSrc));
427 JSVM_Script script;
428 JSVM_ScriptOrigin origin {
429 .sourceMapUrl = "/data/local/tmp/workload/index.js.map",
430 // 源文件名字
431 .resourceName = "index.js",
432 // scirpt 在源文件中的起始行列号
433 .resourceLineOffset = 0,
434 .resourceColumnOffset = 0,
435 };
436 JSVM_Status status = OH_JSVM_CompileScriptWithOrigin(env, jsSrc, nullptr, 0, true, nullptr, &origin, &script);
437 ASSERT_EQ(status, 3);
438 }
439
440 HWTEST_F(JSVMTest, JSVMCompileScriptWithOrigin003, TestSize.Level1)
441 {
442 JSVM_Value jsSrc = nullptr;
443 bool x = true;
444 JSVMTEST_CALL(OH_JSVM_GetBoolean(env, x, &jsSrc));
445 JSVM_ScriptOrigin origin {
446 .sourceMapUrl = "/data/local/tmp/workload/index.js.map",
447 // 源文件名字
448 .resourceName = "index.js",
449 // scirpt 在源文件中的起始行列号
450 .resourceLineOffset = 0,
451 .resourceColumnOffset = 0,
452 };
453 JSVM_Status status = OH_JSVM_CompileScriptWithOrigin(env, jsSrc, nullptr, 0, true, nullptr, &origin, nullptr);
454 ASSERT_EQ(status, 1);
455 }
456
457 static JSVM_PropertyHandlerConfigurationStruct propertyCfg { nullptr, nullptr, nullptr, nullptr, nullptr,
458 nullptr, nullptr, nullptr, nullptr, nullptr };
459
460 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler001, TestSize.Level1)
461 {
462 JSVM_CallbackStruct param;
__anon8167abb00102(JSVM_Env env, JSVM_CallbackInfo info) 463 param.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
464 JSVM_Value thisVar = nullptr;
465 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr));
466 return thisVar;
467 };
468 param.data = nullptr;
469 JSVM_Value testWrapClass = nullptr;
470 JSVMTEST_CALL(OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", 5, ¶m, 0, nullptr, &propertyCfg, nullptr,
471 &testWrapClass));
472 }
473
474 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler002, TestSize.Level1)
475 {
476 JSVM_CallbackStruct param;
__anon8167abb00202(JSVM_Env env, JSVM_CallbackInfo info) 477 param.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
478 JSVM_Value thisVar = nullptr;
479 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr));
480 return thisVar;
481 };
482 param.data = nullptr;
483 JSVM_Value testWrapClass = nullptr;
484 JSVMTEST_CALL(OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", JSVM_AUTO_LENGTH, ¶m, 0, nullptr,
485 &propertyCfg, nullptr, &testWrapClass));
486 }
487
488 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler003, TestSize.Level1)
489 {
490 JSVM_CallbackStruct param;
__anon8167abb00302(JSVM_Env env, JSVM_CallbackInfo info) 491 param.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
492 JSVM_Value thisVar = nullptr;
493 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr));
494 return thisVar;
495 };
496 param.data = nullptr;
497 JSVM_Value testWrapClass = nullptr;
498 JSVMTEST_CALL(OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", 4, ¶m, 0, nullptr, &propertyCfg, nullptr,
499 &testWrapClass));
500 }
501
502 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler004, TestSize.Level1)
503 {
504 JSVM_CallbackStruct param;
__anon8167abb00402(JSVM_Env env, JSVM_CallbackInfo info) 505 param.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
506 JSVM_Value thisVar = nullptr;
507 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr));
508 return thisVar;
509 };
510 param.data = nullptr;
511 JSVM_Value testWrapClass = nullptr;
512 JSVMTEST_CALL(OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", 6, ¶m, 0, nullptr, &propertyCfg, nullptr,
513 &testWrapClass));
514 }
515
516 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler005, TestSize.Level1)
517 {
518 JSVM_CallbackStruct param;
__anon8167abb00502(JSVM_Env env, JSVM_CallbackInfo info) 519 param.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
520 JSVM_Value thisVar = nullptr;
521 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr));
522 return thisVar;
523 };
524 param.data = nullptr;
525 JSVM_Status status = OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", JSVM_AUTO_LENGTH, ¶m, 0, nullptr,
526 &propertyCfg, nullptr, nullptr);
527 ASSERT_EQ(status, JSVM_INVALID_ARG);
528 }
529
530 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler006, TestSize.Level1)
531 {
532 JSVM_Value testWrapClass = nullptr;
533 JSVM_Status status = OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", JSVM_AUTO_LENGTH, nullptr, 0, nullptr,
534 &propertyCfg, nullptr, &testWrapClass);
535 ASSERT_EQ(status, JSVM_INVALID_ARG);
536 }
537
538 HWTEST_F(JSVMTest, JSVMDefineClassWithPropertyHandler007, TestSize.Level1)
539 {
540 JSVM_CallbackStruct param;
__anon8167abb00602(JSVM_Env env, JSVM_CallbackInfo info) 541 param.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
542 JSVM_Value thisVar = nullptr;
543 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr));
544 return thisVar;
545 };
546 param.data = nullptr;
547 JSVM_Value testWrapClass = nullptr;
548 JSVM_Status status = OH_JSVM_DefineClassWithPropertyHandler(env, "Test2", JSVM_AUTO_LENGTH, ¶m, 0, nullptr,
549 nullptr, nullptr, &testWrapClass);
550 ASSERT_EQ(status, JSVM_INVALID_ARG);
551 }
552
553 HWTEST_F(JSVMTest, JSVMCreateSnapshot001, TestSize.Level1)
554 {
555 const char* blobData = nullptr;
556 size_t blobSize = 0;
557 JSVM_Env envs[1] = { env };
558 JSVM_Status status = OH_JSVM_CreateSnapshot(vm, 1, envs, &blobData, &blobSize);
559 ASSERT_EQ(status, JSVM_GENERIC_FAILURE);
560 }
561
562 HWTEST_F(JSVMTest, JSVMCreateEnvFromSnapshot001, TestSize.Level1)
563 {
564 JSVM_Env env2 = nullptr;
565 JSVM_Status status = OH_JSVM_CreateEnvFromSnapshot(vm, 0, &env2);
566 ASSERT_EQ(status, JSVM_GENERIC_FAILURE);
567 }
568
569 HWTEST_F(JSVMTest, JSVMTraceStart001, TestSize.Level1)
570 {
571 JSVM_Status status = OH_JSVM_TraceStart(0, nullptr, "default", 0);
572 ASSERT_EQ(status, JSVM_OK);
573 }
574
575 HWTEST_F(JSVMTest, JSVMTraceStart002, TestSize.Level1)
576 {
577 std::vector<JSVM_TraceCategory> category = { JSVM_TRACE_WASM };
578 JSVM_Status status = OH_JSVM_TraceStart(category.size(), category.data(), "custom", 100);
579 ASSERT_EQ(status, JSVM_OK);
580 }
581
582 HWTEST_F(JSVMTest, JSVMTraceStart003, TestSize.Level1)
583 {
584 std::vector<JSVM_TraceCategory> category(1);
585 *(int*)&category[0] = 100;
586 JSVM_Status status = OH_JSVM_TraceStart(category.size(), category.data(), "invalid", 0);
587 ASSERT_EQ(status, JSVM_INVALID_ARG);
588 }
589
590 HWTEST_F(JSVMTest, JSVMTraceStart004, TestSize.Level1)
591 {
592 std::vector<JSVM_TraceCategory> category = { JSVM_TRACE_WASM };
593 JSVM_Status status = OH_JSVM_TraceStart(0, category.data(), "invalid", 0);
594 ASSERT_EQ(status, JSVM_INVALID_ARG);
595 }
596
597 HWTEST_F(JSVMTest, JSVMTraceStart005, TestSize.Level1)
598 {
599 JSVM_Status status = OH_JSVM_TraceStart(1, nullptr, "invalid", 0);
600 ASSERT_EQ(status, JSVM_INVALID_ARG);
601 }
602
OutputStream(const char * data,int size,void * streamData)603 bool OutputStream(const char* data, int size, void* streamData)
604 {
605 std::string value(data, size);
606 *(std::string*)streamData = std::string(data, size);
607 return true;
608 }
609
610 HWTEST_F(JSVMTest, JSVMTraceStop001, TestSize.Level1)
611 {
612 JSVM_Status status = OH_JSVM_TraceStart(0, nullptr, "default", 0);
613 ASSERT_EQ(status, JSVM_OK);
614 std::string data;
615 status = OH_JSVM_TraceStop(OutputStream, (void*)&data);
616 ASSERT_EQ(status, JSVM_OK);
617 }
618
619 HWTEST_F(JSVMTest, JSVMTraceStop002, TestSize.Level1)
620 {
621 std::string data;
622 JSVM_Status status = OH_JSVM_TraceStop(OutputStream, (void*)&data);
623 ASSERT_EQ(status, JSVM_INVALID_ARG);
624 }
625
626 HWTEST_F(JSVMTest, JSVMTraceStop003, TestSize.Level1)
627 {
628 JSVM_Status status = OH_JSVM_TraceStart(0, nullptr, "default", 0);
629 ASSERT_EQ(status, JSVM_OK);
630 status = OH_JSVM_TraceStop(OutputStream, nullptr);
631 ASSERT_EQ(status, JSVM_INVALID_ARG);
632 std::string data;
633 status = OH_JSVM_TraceStop(OutputStream, (void*)&data);
634 ASSERT_EQ(status, JSVM_OK);
635 }
636
637 HWTEST_F(JSVMTest, JSVMTraceStop004, TestSize.Level1)
638 {
639 JSVM_Status status = OH_JSVM_TraceStart(0, nullptr, "default", 0);
640 ASSERT_EQ(status, JSVM_OK);
641 std::string data;
642 status = OH_JSVM_TraceStop(nullptr, (void*)&data);
643 ASSERT_EQ(status, JSVM_INVALID_ARG);
644 status = OH_JSVM_TraceStop(OutputStream, (void*)&data);
645 ASSERT_EQ(status, JSVM_OK);
646 }
647
648 HWTEST_F(JSVMTest, JSVMIsNumberObject001, TestSize.Level1)
649 {
650 JSVM_Value result = jsvm::Run("new Number(42)");
651 bool isNumberObject = false;
652 JSVMTEST_CALL(OH_JSVM_IsNumberObject(env, result, &isNumberObject));
653 ASSERT_TRUE(isNumberObject);
654 }
655
656 HWTEST_F(JSVMTest, JSVMIsBooleanObject001, TestSize.Level1)
657 {
658 JSVM_Value result = jsvm::Run("new Boolean(true)");
659 bool isBooleanObject = false;
660 JSVMTEST_CALL(OH_JSVM_IsBooleanObject(env, result, &isBooleanObject));
661 ASSERT_TRUE(isBooleanObject);
662 }
663
664 HWTEST_F(JSVMTest, JSVMIsBigIntObject001, TestSize.Level1)
665 {
666 JSVM_Value result = jsvm::Run("new Object(42n)");
667 bool isBigIntObject = false;
668 JSVMTEST_CALL(OH_JSVM_IsBigIntObject(env, result, &isBigIntObject));
669 ASSERT_TRUE(isBigIntObject);
670 }
671
672 HWTEST_F(JSVMTest, JSVMIsStringObject001, TestSize.Level1)
673 {
674 JSVM_Value result = jsvm::Run("new String(\"test\")");
675 bool isStringObject = false;
676 JSVMTEST_CALL(OH_JSVM_IsStringObject(env, result, &isStringObject));
677 ASSERT_TRUE(isStringObject);
678 }
679
680 HWTEST_F(JSVMTest, JSVMIsSymbolObject001, TestSize.Level1)
681 {
682 JSVM_Value result = jsvm::Run("Object(Symbol('foo'))");
683 bool isSymbolObject = false;
684 JSVMTEST_CALL(OH_JSVM_IsSymbolObject(env, result, &isSymbolObject));
685 ASSERT_TRUE(isSymbolObject);
686 }
687
688 HWTEST_F(JSVMTest, JSVMToStringTag001, TestSize.Level1)
689 {
690 JSVM_Value result;
691 JSVMTEST_CALL(OH_JSVM_GetSymbolToStringTag(env, &result));
692 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.toStringTag")));
693 }
694
695 HWTEST_F(JSVMTest, JSVMToPrimitive001, TestSize.Level1)
696 {
697 JSVM_Value result;
698 JSVMTEST_CALL(OH_JSVM_GetSymbolToPrimitive(env, &result));
699 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.toPrimitive")));
700 }
701
702 HWTEST_F(JSVMTest, JSVMSplit001, TestSize.Level1)
703 {
704 JSVM_Value result;
705 JSVMTEST_CALL(OH_JSVM_GetSymbolSplit(env, &result));
706 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.split")));
707 }
708
709 HWTEST_F(JSVMTest, JSVMSearch001, TestSize.Level1)
710 {
711 JSVM_Value result;
712 JSVMTEST_CALL(OH_JSVM_GetSymbolSearch(env, &result));
713 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.search")));
714 }
715
716 HWTEST_F(JSVMTest, JSVMReplace001, TestSize.Level1)
717 {
718 JSVM_Value result;
719 JSVMTEST_CALL(OH_JSVM_GetSymbolReplace(env, &result));
720 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.replace")));
721 }
722
723 HWTEST_F(JSVMTest, JSVMMatch001, TestSize.Level1)
724 {
725 JSVM_Value result;
726 JSVMTEST_CALL(OH_JSVM_GetSymbolMatch(env, &result));
727 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.match")));
728 }
729
730 HWTEST_F(JSVMTest, JSVMIsConcatSpreadable001, TestSize.Level1)
731 {
732 JSVM_Value result;
733 JSVMTEST_CALL(OH_JSVM_GetSymbolIsConcatSpreadable(env, &result));
734 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.isConcatSpreadable")));
735 }
736
737 HWTEST_F(JSVMTest, CreateProxy, TestSize.Level1)
738 {
739 std::string registerObject = R"JS(
740 target = {
741 message1: "hello",
742 message2: "everyone",
743 };
744
745 handler1 = {};
746 handler2 = {
747 get(target, prop, receiver) {
748 return "world";
749 },
750 };
751 )JS";
752
753 jsvm::Run(registerObject.c_str());
754 auto obj = jsvm::GetProperty(jsvm::Global(), "target");
755 auto handler1 = jsvm::GetProperty(jsvm::Global(), "handler1");
756 auto handler2 = jsvm::GetProperty(jsvm::Global(), "handler2");
757
758 JSVM_Value proxy1 = nullptr;
759 JSVMTEST_CALL(OH_JSVM_CreateProxy(env, obj, handler1, &proxy1));
760
761 JSVM_Value proxy2 = nullptr;
762 JSVMTEST_CALL(OH_JSVM_CreateProxy(env, obj, handler2, &proxy2));
763
764 jsvm::SetProperty(jsvm::Global(), "proxy1", proxy1);
765 jsvm::SetProperty(jsvm::Global(), "proxy2", proxy2);
766
767 std::string checkProxy1 = R"JS(
768 proxy1.message1 == target.message1 && proxy1.message2 == target.message2;
769 )JS";
770
771 auto result = jsvm::Run(checkProxy1.c_str());
772 ASSERT_TRUE(jsvm::IsTrue(result));
773
774 std::string checkProxy2 = R"JS(
775 proxy2.message1 == "world" && proxy2.message2 == "world" &&
776 proxy2.anyProperty == "world";
777 )JS";
778
779 result = jsvm::Run(checkProxy2.c_str());
780 ASSERT_TRUE(jsvm::IsTrue(result));
781 }
782
783 HWTEST_F(JSVMTest, IsProxy, TestSize.Level1)
784 {
785 jsvm::Run(R"JS(
786 target = {
787 message1: "hello",
788 message2: "everyone",
789 };
790
791 handler1 = {};
792 proxy1 = new Proxy(target, handler1);
793 )JS");
794
795 bool isProxy = false;
796
797 auto value = jsvm::GetProperty(jsvm::Global(), "target");
798 JSVMTEST_CALL(OH_JSVM_IsProxy(env, value, &isProxy));
799 ASSERT_TRUE(!isProxy && "target is not JS Proxy");
800
801 value = jsvm::GetProperty(jsvm::Global(), "handler1");
802 JSVMTEST_CALL(OH_JSVM_IsProxy(env, value, &isProxy));
803 ASSERT_TRUE(!isProxy && "handler1 is not JS Proxy");
804
805 value = jsvm::GetProperty(jsvm::Global(), "proxy1");
806 JSVMTEST_CALL(OH_JSVM_IsProxy(env, value, &isProxy));
807 ASSERT_TRUE(isProxy && "proxy1 is JS Proxy");
808 }
809
810 HWTEST_F(JSVMTest, GetProxyTarget, TestSize.Level1)
811 {
812 jsvm::Run(R"JS(
813 target = {
814 message1: "hello",
815 message2: "everyone",
816 };
817
818 handler1 = {};
819 proxy1 = new Proxy(target, handler1);
820 )JS");
821
822 auto target = jsvm::GetProperty(jsvm::Global(), "target");
823 auto proxy1 = jsvm::GetProperty(jsvm::Global(), "proxy1");
824
825 JSVM_Value result = nullptr;
826 JSVMTEST_CALL(OH_JSVM_ProxyGetTarget(env, proxy1, &result));
827
828 ASSERT_TRUE(jsvm::StrictEquals(target, result));
829 }
830
831 static std::string g_scriptEvalMicrotask = R"JS(
832 evaluateMicrotask = false;
833 Promise.resolve().then(()=>{
834 evaluateMicrotask = true;
835 });
836 evaluateMicrotask
837 )JS";
838
839 // Default microtask policy is JSVM_MICROTASK_AUTO
840 HWTEST_F(JSVMTest, MicrotaskPolicyDefault, TestSize.Level1)
841 {
842 auto result = jsvm::Run(g_scriptEvalMicrotask.c_str());
843 ASSERT_TRUE(jsvm::IsFalse(result));
844 result = jsvm::GetProperty(jsvm::Global(), "evaluateMicrotask");
845 ASSERT_TRUE(jsvm::IsTrue(result));
846 }
847
848 // Test Set Microtask Policy to explicit
849 HWTEST_F(JSVMTest, MicrotaskPolicyExplict, TestSize.Level1)
850 {
851 OH_JSVM_SetMicrotaskPolicy(vm, JSVM_MicrotaskPolicy::JSVM_MICROTASK_EXPLICIT);
852 auto result = jsvm::Run(g_scriptEvalMicrotask.c_str());
853 ASSERT_TRUE(jsvm::IsFalse(result));
854 result = jsvm::GetProperty(jsvm::Global(), "evaluateMicrotask");
855 ASSERT_TRUE(jsvm::IsFalse(result));
856 OH_JSVM_PerformMicrotaskCheckpoint(vm);
857 result = jsvm::GetProperty(jsvm::Global(), "evaluateMicrotask");
858 ASSERT_TRUE(jsvm::IsTrue(result));
859 }
860
861 // Test Set Microtask Policy to auto
862 HWTEST_F(JSVMTest, MicrotaskPolicyAuto, TestSize.Level1)
863 {
864 OH_JSVM_SetMicrotaskPolicy(vm, JSVM_MicrotaskPolicy::JSVM_MICROTASK_EXPLICIT);
865 OH_JSVM_SetMicrotaskPolicy(vm, JSVM_MicrotaskPolicy::JSVM_MICROTASK_AUTO);
866 auto result = jsvm::Run(g_scriptEvalMicrotask.c_str());
867 ASSERT_TRUE(jsvm::IsFalse(result));
868 result = jsvm::GetProperty(jsvm::Global(), "evaluateMicrotask");
869 ASSERT_TRUE(jsvm::IsTrue(result));
870 }
871
872 HWTEST_F(JSVMTest, MicrotaskInvalidPolicy, TestSize.Level1)
873 {
874 JSVM_MicrotaskPolicy invalidPolicy = (JSVM_MicrotaskPolicy)2;
875 auto status = OH_JSVM_SetMicrotaskPolicy(vm, invalidPolicy);
876 ASSERT_TRUE(status != JSVM_OK);
877 }
878
879 static std::string g_defineFunction = R"JS(
880 var x1 = 0;
881 var x2 = 0;
882 function f1(x) {
883 x1 = x;
884 return x + 1;
885 }
886 function f2(x) {
887 x2 = x;
888 return x + 1;
889 }
890 )JS";
891
892 static std::string g_init = R"JS(
893 x1 = 0;
894 x2 = 0;
895 )JS";
896
897 HWTEST_F(JSVMTest, PromiseThen, TestSize.Level1)
898 {
899 JSVM_Value promise = nullptr;
900 JSVM_Deferred deffered;
901
902 JSVMTEST_CALL(OH_JSVM_CreatePromise(env, &deffered, &promise));
903 jsvm::Run(g_defineFunction.c_str());
904
905 JSVM_Value f1 = jsvm::GetProperty(jsvm::Global(), "f1");
906
907 JSVMTEST_CALL(OH_JSVM_PromiseRegisterHandler(env, promise, f1, nullptr, nullptr));
908
909 auto x1 = jsvm::GetProperty(jsvm::Global(), "x1");
910 auto x2 = jsvm::GetProperty(jsvm::Global(), "x2");
911 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(0)));
912 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
913
914 OH_JSVM_ResolveDeferred(env, deffered, jsvm::Int32(2));
915 deffered = nullptr;
916
917 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
918 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
919 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(2)));
920 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
921 }
922
923 HWTEST_F(JSVMTest, PromiseThen2, TestSize.Level1)
924 {
925 jsvm::Run(g_defineFunction.c_str());
926
927 JSVM_Value f1 = jsvm::GetProperty(jsvm::Global(), "f1");
928 auto f2 = jsvm::GetProperty(jsvm::Global(), "f2");
929
930 JSVM_Value promise;
931 JSVM_Deferred deffered;
932
933 // Resolve
934 JSVMTEST_CALL(OH_JSVM_CreatePromise(env, &deffered, &promise));
935 JSVMTEST_CALL(OH_JSVM_PromiseRegisterHandler(env, promise, f1, f2, nullptr));
936
937 auto x1 = jsvm::GetProperty(jsvm::Global(), "x1");
938 auto x2 = jsvm::GetProperty(jsvm::Global(), "x2");
939 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(0)));
940 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
941
942 OH_JSVM_ResolveDeferred(env, deffered, jsvm::Int32(2));
943 deffered = nullptr;
944
945 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
946 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
947 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(2)));
948 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
949
950 jsvm::Run(g_init.c_str());
951 // Reject
952 JSVMTEST_CALL(OH_JSVM_CreatePromise(env, &deffered, &promise));
953 JSVMTEST_CALL(OH_JSVM_PromiseRegisterHandler(env, promise, f1, f2, nullptr));
954
955 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
956 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
957 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(0)));
958 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
959
960 OH_JSVM_RejectDeferred(env, deffered, jsvm::Int32(3));
961 deffered = nullptr;
962
963 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
964 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
965 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(0)));
966 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(3)));
967 }
968
969 HWTEST_F(JSVMTest, PromiseThenChain, TestSize.Level1)
970 {
971 jsvm::Run(g_defineFunction.c_str());
972
973 JSVM_Value f1 = jsvm::GetProperty(jsvm::Global(), "f1");
974 auto f2 = jsvm::GetProperty(jsvm::Global(), "f2");
975
976 JSVM_Value promise, promise1, x1, x2;
977 JSVM_Deferred deffered = nullptr;
978
979 // Resolve
980 JSVMTEST_CALL(OH_JSVM_CreatePromise(env, &deffered, &promise));
981 JSVMTEST_CALL(OH_JSVM_PromiseRegisterHandler(env, promise, f1, nullptr, &promise1));
982 JSVMTEST_CALL(OH_JSVM_PromiseRegisterHandler(env, promise1, f2, nullptr, nullptr));
983
984 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
985 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
986 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(0)));
987 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
988
989 OH_JSVM_ResolveDeferred(env, deffered, jsvm::Int32(2));
990 deffered = nullptr;
991
992 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
993 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
994 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(2)));
995 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(3)));
996 }
997
998 HWTEST_F(JSVMTest, PromiseCatch, TestSize.Level1)
999 {
1000 jsvm::Run(g_defineFunction.c_str());
1001
1002 JSVM_Value f1 = jsvm::GetProperty(jsvm::Global(), "f1");
1003
1004 JSVM_Value promise;
1005 JSVM_Value promise1;
1006 JSVM_Deferred deffered = nullptr;
1007
1008 // Resolve
1009 JSVMTEST_CALL(OH_JSVM_CreatePromise(env, &deffered, &promise));
1010 JSVMTEST_CALL(OH_JSVM_PromiseRegisterHandler(env, promise, nullptr, f1, &promise1));
1011
1012 auto x1 = jsvm::GetProperty(jsvm::Global(), "x1");
1013 auto x2 = jsvm::GetProperty(jsvm::Global(), "x2");
1014 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(0)));
1015 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
1016
1017 JSVMTEST_CALL(OH_JSVM_RejectDeferred(env, deffered, jsvm::Int32(2)));
1018 deffered = nullptr;
1019
1020 x1 = jsvm::GetProperty(jsvm::Global(), "x1");
1021 x2 = jsvm::GetProperty(jsvm::Global(), "x2");
1022 ASSERT_TRUE(jsvm::Equals(x1, jsvm::Int32(2)));
1023 ASSERT_TRUE(jsvm::Equals(x2, jsvm::Int32(0)));
1024 }
1025
1026 HWTEST_F(JSVMTest, JSVMHasInstance001, TestSize.Level1)
1027 {
1028 JSVM_Value result;
1029 JSVMTEST_CALL(OH_JSVM_GetSymbolHasInstance(env, &result));
1030 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.hasInstance")));
1031 }
1032
1033 HWTEST_F(JSVMTest, JSVMUnscopables001, TestSize.Level1)
1034 {
1035 JSVM_Value result;
1036 JSVMTEST_CALL(OH_JSVM_GetSymbolUnscopables(env, &result));
1037 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.unscopables")));
1038 }
1039
1040 HWTEST_F(JSVMTest, JSVMAsyncIterator001, TestSize.Level1)
1041 {
1042 JSVM_Value result;
1043 JSVMTEST_CALL(OH_JSVM_GetSymbolAsyncIterator(env, &result));
1044 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.asyncIterator")));
1045 }
1046
1047 HWTEST_F(JSVMTest, JSVMIterator001, TestSize.Level1)
1048 {
1049 JSVM_Value result;
1050 JSVMTEST_CALL(OH_JSVM_GetSymbolIterator(env, &result));
1051 ASSERT_TRUE(jsvm::StrictEquals(result, jsvm::Run("Symbol.iterator")));
1052 }
1053
1054 static jmp_buf g_buf;
1055 static bool g_beforeFlag1 = false;
1056 static bool g_beforeFlag2 = false;
1057 static bool g_beforeFlag3 = false;
1058 static bool g_afterFlag1 = false;
1059 static bool g_afterFlag2 = false;
1060 static int g_nativeValue = 2024;
1061
OnBeforeGC(JSVM_VM vm,JSVM_GCType gcType,JSVM_GCCallbackFlags flags,void * data)1062 void OnBeforeGC(JSVM_VM vm, JSVM_GCType gcType, JSVM_GCCallbackFlags flags, void* data)
1063 {
1064 g_beforeFlag1 = true;
1065 }
1066
OnBeforeGC2(JSVM_VM vm,JSVM_GCType gcType,JSVM_GCCallbackFlags flags,void * data)1067 void OnBeforeGC2(JSVM_VM vm, JSVM_GCType gcType, JSVM_GCCallbackFlags flags, void* data)
1068 {
1069 if (*(int*)data == g_nativeValue) {
1070 g_beforeFlag2 = true;
1071 }
1072 }
1073
OnBeforeGC3(JSVM_VM vm,JSVM_GCType gcType,JSVM_GCCallbackFlags flags,void * data)1074 void OnBeforeGC3(JSVM_VM vm, JSVM_GCType gcType, JSVM_GCCallbackFlags flags, void* data)
1075 {
1076 g_beforeFlag3 = true;
1077 }
1078
OnAfterGC(JSVM_VM vm,JSVM_GCType gcType,JSVM_GCCallbackFlags flags,void * data)1079 void OnAfterGC(JSVM_VM vm, JSVM_GCType gcType, JSVM_GCCallbackFlags flags, void* data)
1080 {
1081 g_afterFlag1 = true;
1082 }
1083
OnAfterGC2(JSVM_VM vm,JSVM_GCType gcType,JSVM_GCCallbackFlags flags,void * data)1084 void OnAfterGC2(JSVM_VM vm, JSVM_GCType gcType, JSVM_GCCallbackFlags flags, void* data)
1085 {
1086 g_afterFlag2 = true;
1087 }
1088
1089 HWTEST_F(JSVMTest, JSVMForwardUsageApplicationScenariosOfGCCB, TestSize.Level1)
1090 {
1091 g_beforeFlag1 = false;
1092 g_beforeFlag2 = false;
1093 g_beforeFlag3 = false;
1094 g_afterFlag1 = false;
1095 g_afterFlag2 = false;
1096 int data = g_nativeValue;
1097 JSVMTEST_CALL(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC, JSVM_GC_TYPE_ALL, NULL));
1098 JSVMTEST_CALL(
1099 OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC2, JSVM_GC_TYPE_ALL, (void*)(&data)));
1100 JSVMTEST_CALL(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC3, JSVM_GC_TYPE_SCAVENGE, NULL));
1101 JSVMTEST_CALL(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_AFTER_GC, OnAfterGC, JSVM_GC_TYPE_ALL, NULL));
1102 JSVMTEST_CALL(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_AFTER_GC, OnAfterGC2, JSVM_GC_TYPE_ALL, NULL));
1103
1104 JSVMTEST_CALL(OH_JSVM_RemoveHandlerForGC(vm, JSVM_CB_TRIGGER_AFTER_GC, OnAfterGC2, NULL));
1105
1106 // can not remove handler that has not been added.
1107 ASSERT_TRUE(OH_JSVM_RemoveHandlerForGC(vm, JSVM_CB_TRIGGER_AFTER_GC, OnAfterGC2, new int(12)) == JSVM_INVALID_ARG);
1108
1109 jsvm::TryTriggerGC();
1110 ASSERT_TRUE(g_beforeFlag1);
1111 ASSERT_TRUE(g_beforeFlag2);
1112 ASSERT_FALSE(g_beforeFlag3);
1113 ASSERT_TRUE(g_afterFlag1);
1114 ASSERT_FALSE(g_afterFlag2);
1115 }
1116
1117 HWTEST_F(JSVMTest, JSVMNegativeApplicationScenariosOfGCCB, TestSize.Level1)
1118 {
1119 JSVMTEST_CALL(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC, JSVM_GC_TYPE_ALL, NULL));
1120 // 1. Repeatedly register the same handler and native-data.
1121 ASSERT_TRUE(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC, JSVM_GC_TYPE_ALL, NULL) ==
1122 JSVM_INVALID_ARG);
1123 // 2. Register an empty handler.
1124 ASSERT_TRUE(OH_JSVM_AddHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, NULL, JSVM_GC_TYPE_ALL, NULL) ==
1125 JSVM_INVALID_ARG);
1126 // 3. Remove unregistered handlers.
1127 ASSERT_TRUE(OH_JSVM_RemoveHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC2, NULL) == JSVM_INVALID_ARG);
1128 // 4. Remove the same handler and native-data repeatedly.
1129 ASSERT_TRUE(OH_JSVM_RemoveHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC, NULL) == JSVM_OK);
1130 ASSERT_TRUE(OH_JSVM_RemoveHandlerForGC(vm, JSVM_CB_TRIGGER_BEFORE_GC, OnBeforeGC, NULL) == JSVM_INVALID_ARG);
1131 }
1132
1133 static bool g_oomHandlerFinished = false;
1134 static bool g_fatalHandlerFinished = false;
1135 static bool g_fatalHandlerFinished2 = false;
1136 static bool g_promiseRejectFinished = false;
1137
OnOOMError(const char * location,const char * detail,bool isHeapOOM)1138 void OnOOMError(const char* location, const char* detail, bool isHeapOOM)
1139 {
1140 g_oomHandlerFinished = true;
1141 longjmp(g_buf, 1);
1142 }
1143
OnFatalError(const char * location,const char * message)1144 void OnFatalError(const char* location, const char* message)
1145 {
1146 g_fatalHandlerFinished = true;
1147 longjmp(g_buf, 1);
1148 }
1149
OnFatalError2(const char * location,const char * message)1150 void OnFatalError2(const char* location, const char* message)
1151 {
1152 g_fatalHandlerFinished2 = true;
1153 longjmp(g_buf, 1);
1154 }
1155
OnPromiseReject(JSVM_Env env,JSVM_PromiseRejectEvent rejectEvent,JSVM_Value rejectInfo)1156 void OnPromiseReject(JSVM_Env env, JSVM_PromiseRejectEvent rejectEvent, JSVM_Value rejectInfo)
1157 {
1158 ASSERT_TRUE(jsvm::IsObject(rejectInfo));
1159 auto promise = jsvm::GetProperty(rejectInfo, "promise");
1160 ASSERT_TRUE(jsvm::IsPromise(promise));
1161 auto value = jsvm::GetProperty(rejectInfo, "value");
1162 ASSERT_TRUE(jsvm::IsNumber(value));
1163 g_promiseRejectFinished = true;
1164 }
1165
1166 HWTEST_F(JSVMTest, JSVMOOM, TestSize.Level1)
1167 {
1168 g_oomHandlerFinished = false;
1169 JSVMTEST_CALL(OH_JSVM_SetHandlerForOOMError(vm, OnOOMError));
1170 static bool oomed = false;
1171 setjmp(g_buf);
1172 if (!oomed) {
1173 oomed = true;
1174 jsvm::TryTriggerOOM();
1175 }
1176 ASSERT_TRUE(g_oomHandlerFinished);
1177 }
1178
1179 HWTEST_F(JSVMTest, JSVMFatalError, TestSize.Level1)
1180 {
1181 g_fatalHandlerFinished = false;
1182 JSVMTEST_CALL(OH_JSVM_SetHandlerForFatalError(vm, OnFatalError));
1183 static bool fataled = false;
1184 setjmp(g_buf);
1185 if (!fataled) {
1186 fataled = true;
1187 jsvm::TryTriggerFatalError(vm);
1188 }
1189 ASSERT_TRUE(jsvm::ToNumber(jsvm::Run("42")) == 42);
1190 ASSERT_TRUE(g_fatalHandlerFinished);
1191 }
1192
1193 HWTEST_F(JSVMTest, JSVMPromiseReject, TestSize.Level1)
1194 {
1195 JSVMTEST_CALL(OH_JSVM_SetHandlerForPromiseReject(vm, OnPromiseReject));
1196 jsvm::Run("new Promise((resolve, reject) => { reject(42); })");
1197 }
1198
1199 HWTEST_F(JSVMTest, JSVMCheckHandler, TestSize.Level1)
1200 {
1201 ASSERT_TRUE(g_oomHandlerFinished);
1202 ASSERT_TRUE(g_fatalHandlerFinished);
1203 ASSERT_TRUE(g_promiseRejectFinished);
1204 }
1205
1206 static bool g_callAsFunctionFlag = false;
1207 static bool g_setNamedPropertyFlag = false;
1208 static bool g_callAsConstructorFlag = false;
1209 static bool g_propertiesFlag = false;
1210
SetNamedPropertyCbInfo2(JSVM_Env env,JSVM_Value name,JSVM_Value property,JSVM_Value thisArg,JSVM_Value data)1211 static JSVM_Value SetNamedPropertyCbInfo2(JSVM_Env env,
1212 JSVM_Value name,
1213 JSVM_Value property,
1214 JSVM_Value thisArg,
1215 JSVM_Value data)
1216 {
1217 g_setNamedPropertyFlag = true;
1218 return property;
1219 }
1220
Add(JSVM_Env env,JSVM_CallbackInfo info)1221 static JSVM_Value Add(JSVM_Env env, JSVM_CallbackInfo info)
1222 {
1223 g_propertiesFlag = true;
1224 size_t argc = 2;
1225 JSVM_Value args[2];
1226 OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
1227 double num1 = 0.0;
1228 double num2 = 0.0;
1229 OH_JSVM_GetValueDouble(env, args[0], &num1);
1230 OH_JSVM_GetValueDouble(env, args[1], &num2);
1231 JSVM_Value sum = nullptr;
1232 OH_JSVM_CreateDouble(env, num1 + num2, &sum);
1233 return sum;
1234 }
1235
GenerateParentClass(JSVM_Env env)1236 JSVM_Value GenerateParentClass(JSVM_Env env)
1237 {
1238 JSVM_Value parentClass = nullptr;
1239 JSVM_CallbackStruct* parentClassConstructor = new JSVM_CallbackStruct;
1240 parentClassConstructor->data = nullptr;
1241 parentClassConstructor->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1242 JSVM_Value thisVar = nullptr;
1243 OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1244 return thisVar;
1245 };
1246 JSVM_Value fooVal = jsvm::Str("bar");
1247 JSVM_PropertyDescriptor des[2];
1248 des[0] = {
1249 .utf8name = "foo",
1250 .value = fooVal,
1251 };
1252 JSVM_CallbackStruct* addMethod = new JSVM_CallbackStruct;
1253 addMethod->data = nullptr;
1254 addMethod->callback = Add;
1255 des[1] = {
1256 .utf8name = "add",
1257 .method = addMethod,
1258 };
1259 JSVM_DefineClassOptions options[1];
1260 options[0].id = JSVM_DEFINE_CLASS_WITH_COUNT;
1261 options[0].content.num = JSVM_OBJECT_INTERFAIELD_COUNT;
1262 JSVMTEST_CALL(OH_JSVM_DefineClassWithOptions(env, "parentClass", JSVM_AUTO_LENGTH, parentClassConstructor,
1263 JSVM_PARENT_CLASS_DES_COUNT, des, nullptr, 1, options, &parentClass));
1264 return parentClass;
1265 }
1266
GenerateSubClass(JSVM_Env env,JSVM_Value parentClass)1267 JSVM_Value GenerateSubClass(JSVM_Env env, JSVM_Value parentClass)
1268 {
1269 JSVM_Value subClass = nullptr;
1270 JSVM_CallbackStruct* subClassConstructor = new JSVM_CallbackStruct;
1271 subClassConstructor->data = nullptr;
1272 subClassConstructor->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1273 JSVM_Value thisVar = nullptr;
1274 g_callAsConstructorFlag = true;
1275 OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1276 return thisVar;
1277 };
1278 JSVM_DefineClassOptions subOptions[2];
1279 JSVM_CallbackStruct* callAsFuncParam = new JSVM_CallbackStruct;
1280 callAsFuncParam->data = nullptr;
1281 callAsFuncParam->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1282 JSVM_Value thisVar = nullptr;
1283 g_callAsFunctionFlag = true;
1284 OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1285 return thisVar;
1286 };
1287 propertyCfg.genericNamedPropertySetterCallback = SetNamedPropertyCbInfo2;
1288 JSVM_PropertyHandler propertyHandler = {
1289 .propertyHandlerCfg = &propertyCfg,
1290 .callAsFunctionCallback = callAsFuncParam,
1291 };
1292 subOptions[0].id = JSVM_DEFINE_CLASS_WITH_COUNT;
1293 subOptions[0].content.num = JSVM_OBJECT_INTERFAIELD_COUNT;
1294 subOptions[1].id = JSVM_DEFINE_CLASS_WITH_PROPERTY_HANDLER;
1295 subOptions[1].content.ptr = &propertyHandler;
1296 JSVMTEST_CALL(OH_JSVM_DefineClassWithOptions(env, "subClass", JSVM_AUTO_LENGTH, subClassConstructor, 0, nullptr,
1297 parentClass, JSVM_DEFINE_CLASS_OPTIONS_COUNT, subOptions, &subClass));
1298 return subClass;
1299 }
1300
1301 /**
1302 * @brief Verify the validity of the following parameters in the OH_JSVM_DefineClassWithOptions interface:
1303 * 'consturctor' | 'properties' | 'parentClass' | 'options'
1304 */
1305 HWTEST_F(JSVMTest, JSVMTestParentClassWithCount, TestSize.Level1)
1306 {
1307 g_callAsFunctionFlag = false;
1308 g_setNamedPropertyFlag = false;
1309 g_callAsConstructorFlag = false;
1310 g_propertiesFlag = false;
1311 // 1. Define parent-class.
1312 JSVM_Value parentClass = GenerateParentClass(env);
1313 // 2. Define sub-class.
1314 JSVM_Value subClass = GenerateSubClass(env, parentClass);
1315 // 3. Verify the validity of 'constructor'.
1316 JSVM_Value subInstance;
1317 ASSERT_FALSE(g_callAsConstructorFlag);
1318 JSVMTEST_CALL(OH_JSVM_NewInstance(env, subClass, 0, nullptr, &subInstance));
1319 ASSERT_TRUE(g_callAsConstructorFlag);
1320
1321 JSVM_Value globalVal;
1322 OH_JSVM_GetGlobal(env, &globalVal);
1323 OH_JSVM_SetNamedProperty(env, globalVal, "obj", subInstance);
1324
1325 // 4. Verify the validity of 'parentClass'.
1326 JSVM_Value subRes = nullptr;
1327 JSVMTEST_CALL(OH_JSVM_GetNamedProperty(env, subInstance, "foo", &subRes));
1328 ASSERT_TRUE(jsvm::ToString(subRes).compare("bar") == 0);
1329 // 5. Verify the validity of 'properties'.
1330 ASSERT_FALSE(g_propertiesFlag);
1331 jsvm::Run("obj.add(3, 4);");
1332 ASSERT_TRUE(g_propertiesFlag);
1333 // 6. Verify the validity of 'options'.
1334 ASSERT_FALSE(g_callAsFunctionFlag);
1335 jsvm::Run("obj()");
1336 ASSERT_TRUE(g_callAsFunctionFlag);
1337 ASSERT_FALSE(g_setNamedPropertyFlag);
1338 jsvm::Run("obj.x = 123;");
1339 ASSERT_TRUE(g_setNamedPropertyFlag);
1340 propertyCfg.genericNamedPropertySetterCallback = nullptr;
1341 }
1342
1343 /**
1344 * @brief If parentClass is not an APIFunction, the status code is JSVM_INVALID_ARG.
1345 */
1346 HWTEST_F(JSVMTest, NonAPIFunction, TestSize.Level1)
1347 {
1348 JSVM_Value script = jsvm::Str("return 2 + 3;");
1349 JSVM_Value nonAPIFunction = nullptr;
1350 JSVMTEST_CALL(OH_JSVM_CreateFunctionWithScript(env, nullptr, 0, 0, nullptr, script, &nonAPIFunction));
1351
1352 JSVM_Value subClass = nullptr;
1353 JSVM_CallbackStruct constructor;
1354 constructor.data = nullptr;
__anon8167abb00a02(JSVM_Env env, JSVM_CallbackInfo info) 1355 constructor.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
1356 JSVM_Value thisVar = nullptr;
1357 OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
1358 return thisVar;
1359 };
1360 JSVM_Status status = OH_JSVM_DefineClassWithOptions(env, "subClass", JSVM_AUTO_LENGTH, &constructor, 0, nullptr,
1361 nonAPIFunction, 0, nullptr, &subClass);
1362 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1363 }
1364
LogFunc(JSVM_Env env,JSVM_CallbackInfo info)1365 static JSVM_Value LogFunc(JSVM_Env env, JSVM_CallbackInfo info)
1366 {
1367 size_t argc = 1;
1368 JSVM_Value argv[1];
1369 JSVMTEST_CALL(OH_JSVM_GetCbInfo(env, info, &argc, argv, NULL, NULL));
1370 return jsvm::Str("log");
1371 }
1372
1373 HWTEST_F(JSVMTest, test_function_private, TestSize.Level1)
1374 {
1375 JSVM_Data key;
1376 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, nullptr, &key));
1377 auto obj = jsvm::Object();
1378 JSVMTEST_CALL(OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("a")));
1379 static JSVM_CallbackStruct cb = { LogFunc, NULL };
1380 JSVM_Value log;
1381 JSVMTEST_CALL(OH_JSVM_CreateFunction(env, "log", JSVM_AUTO_LENGTH, &cb, &log));
1382 JSVMTEST_CALL(OH_JSVM_SetPrivate(env, obj, key, log));
1383 JSVM_Value result;
1384 JSVMTEST_CALL(OH_JSVM_GetPrivate(env, obj, key, &result));
1385 auto ret = jsvm::Call(result);
1386 ASSERT_TRUE(jsvm::Equals(ret, jsvm::Str("log")));
1387 }
1388
1389 HWTEST_F(JSVMTest, test_str_private, TestSize.Level1)
1390 {
1391 JSVM_Data key;
1392 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, nullptr, &key));
1393 auto obj = jsvm::Object();
1394 JSVMTEST_CALL(OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("a")));
1395 JSVMTEST_CALL(OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("log")));
1396 JSVM_Value result;
1397 JSVMTEST_CALL(OH_JSVM_GetPrivate(env, obj, key, &result));
1398 ASSERT_TRUE(jsvm::Equals(result, jsvm::Str("log")));
1399 }
1400
1401 HWTEST_F(JSVMTest, test_different_private_with_same_key, TestSize.Level1)
1402 {
1403 JSVM_Data key;
1404 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key));
1405 JSVM_Data key1;
1406 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key1));
1407 auto obj = jsvm::Object();
1408 JSVMTEST_CALL(OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("a")));
1409 JSVMTEST_CALL(OH_JSVM_SetPrivate(env, obj, key1, jsvm::Str("b")));
1410 JSVM_Value result;
1411 JSVMTEST_CALL(OH_JSVM_GetPrivate(env, obj, key, &result));
1412 JSVM_Value result1;
1413 JSVMTEST_CALL(OH_JSVM_GetPrivate(env, obj, key1, &result1));
1414 ASSERT_TRUE(!jsvm::Equals(result, result1));
1415 }
1416
1417 HWTEST_F(JSVMTest, test_set_private_with_nullptr_key, TestSize.Level1)
1418 {
1419 JSVM_Data key = nullptr;
1420 auto obj = jsvm::Object();
1421 auto status = OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("a"));
1422 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1423 }
1424
1425 HWTEST_F(JSVMTest, test_set_private_with_nullptr_value, TestSize.Level1)
1426 {
1427 JSVM_Data key = nullptr;
1428 auto obj = jsvm::Object();
1429 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key));
1430 auto status = OH_JSVM_SetPrivate(env, obj, key, nullptr);
1431 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1432 }
1433
1434 HWTEST_F(JSVMTest, test_set_private_with_non_object, TestSize.Level1)
1435 {
1436 JSVM_Data key = nullptr;
1437 auto obj = jsvm::True();
1438 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key));
1439 auto status = OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("a"));
1440 ASSERT_TRUE(status == JSVM_OBJECT_EXPECTED);
1441 }
1442
1443 HWTEST_F(JSVMTest, test_set_private_with_non_private, TestSize.Level1)
1444 {
1445 JSVM_Data key = nullptr;
1446 auto obj = jsvm::Object();
1447 JSVMTEST_CALL(OH_JSVM_CreateSymbol(env, jsvm::Str("a"), (JSVM_Value*)&key));
1448 auto status = OH_JSVM_SetPrivate(env, obj, key, jsvm::Str("a"));
1449 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1450 }
1451
1452 HWTEST_F(JSVMTest, test_get_non_exist_private, TestSize.Level1)
1453 {
1454 JSVM_Data key;
1455 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, nullptr, &key));
1456 auto obj = jsvm::Object();
1457 JSVM_Value result;
1458 JSVMTEST_CALL(OH_JSVM_GetPrivate(env, obj, key, &result));
1459 ASSERT_TRUE(jsvm::Equals(result, jsvm::Undefined()));
1460 }
1461
1462 HWTEST_F(JSVMTest, test_get_private_with_nullptr_key, TestSize.Level1)
1463 {
1464 JSVM_Data key = nullptr;
1465 auto obj = jsvm::Object();
1466 JSVM_Value value;
1467 auto status = OH_JSVM_GetPrivate(env, obj, key, &value);
1468 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1469 }
1470
1471 HWTEST_F(JSVMTest, test_get_private_with_nullptr_value, TestSize.Level1)
1472 {
1473 JSVM_Data key = nullptr;
1474 auto obj = jsvm::Object();
1475 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key));
1476 auto status = OH_JSVM_GetPrivate(env, obj, key, nullptr);
1477 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1478 }
1479
1480 HWTEST_F(JSVMTest, test_get_private_with_non_object, TestSize.Level1)
1481 {
1482 JSVM_Data key = nullptr;
1483 auto obj = jsvm::True();
1484 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key));
1485 JSVM_Value value;
1486 auto status = OH_JSVM_GetPrivate(env, obj, key, &value);
1487 ASSERT_TRUE(status == JSVM_OBJECT_EXPECTED);
1488 }
1489
1490 HWTEST_F(JSVMTest, test_get_private_with_non_private, TestSize.Level1)
1491 {
1492 JSVM_Data key = nullptr;
1493 auto obj = jsvm::Object();
1494 JSVMTEST_CALL(OH_JSVM_CreateSymbol(env, jsvm::Str("a"), (JSVM_Value*)&key));
1495 JSVM_Value value;
1496 auto status = OH_JSVM_GetPrivate(env, obj, key, &value);
1497 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1498 }
1499
1500 HWTEST_F(JSVMTest, test_delete_non_exist_private, TestSize.Level1)
1501 {
1502 JSVM_Data key;
1503 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, nullptr, &key));
1504 auto obj = jsvm::Object();
1505 JSVMTEST_CALL(OH_JSVM_DeletePrivate(env, obj, key));
1506 }
1507
1508 HWTEST_F(JSVMTest, test_delete_nullptr_key, TestSize.Level1)
1509 {
1510 JSVM_Data key = nullptr;
1511 auto obj = jsvm::Object();
1512 auto status = OH_JSVM_DeletePrivate(env, obj, key);
1513 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1514 }
1515
1516 HWTEST_F(JSVMTest, test_delete_with_non_object, TestSize.Level1)
1517 {
1518 JSVM_Data key = nullptr;
1519 auto obj = jsvm::True();
1520 JSVMTEST_CALL(OH_JSVM_CreatePrivate(env, jsvm::Str("a"), &key));
1521 auto status = OH_JSVM_DeletePrivate(env, obj, key);
1522 ASSERT_TRUE(status == JSVM_OBJECT_EXPECTED);
1523 }
1524
1525 HWTEST_F(JSVMTest, test_delete_private_with_non_private, TestSize.Level1)
1526 {
1527 JSVM_Data key = nullptr;
1528 auto obj = jsvm::Object();
1529 JSVMTEST_CALL(OH_JSVM_CreateSymbol(env, jsvm::Str("a"), (JSVM_Value*)&key));
1530 auto status = OH_JSVM_DeletePrivate(env, obj, key);
1531 ASSERT_TRUE(status == JSVM_INVALID_ARG);
1532 }
1533
1534 HWTEST_F(JSVMTest, test_set_debug_option1, TestSize.Level1)
1535 {
1536 JSVM_HandleScope handleScope1, handleScope2, handleScope3;
1537 int num = 100;
1538 bool boolValue = false;
1539 JSVM_Value array1[num], array2[num], array3[num];
1540 auto status1 = OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true);
1541 ASSERT_TRUE(status1 == JSVM_OK);
1542 OH_JSVM_OpenHandleScope(env, &handleScope1);
1543 for (int i = 0; i < num; i++) {
1544 OH_JSVM_GetBoolean(env, false, &array1[i]);
1545 OH_JSVM_IsBoolean(env, array1[i], &boolValue);
1546 }
1547 OH_JSVM_OpenHandleScope(env, &handleScope2);
1548 for (int i = 0; i < num; i++) {
1549 OH_JSVM_GetBoolean(env, false, &array2[i]);
1550 OH_JSVM_IsBoolean(env, array2[i], &boolValue);
1551 }
1552 OH_JSVM_OpenHandleScope(env, &handleScope3);
1553 for (int i = 0; i < num; i++) {
1554 OH_JSVM_GetBoolean(env, false, &array3[i]);
1555 OH_JSVM_IsBoolean(env, array3[i], &boolValue);
1556 OH_JSVM_IsBoolean(env, array2[i], &boolValue);
1557 }
1558 OH_JSVM_CloseHandleScope(env, handleScope3);
1559 OH_JSVM_CloseHandleScope(env, handleScope2);
1560 OH_JSVM_CloseHandleScope(env, handleScope1);
1561 auto status2 = OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false);
1562 ASSERT_TRUE(status2 == JSVM_OK);
1563 }
1564
1565 static bool g_fatalErrorFinished = false;
1566
HandleAbort(int sig)1567 static void HandleAbort(int sig)
1568 {
1569 g_fatalErrorFinished = true;
1570 longjmp(g_buf, 1);
1571 }
1572
1573 HWTEST_F(JSVMTest, test_set_debug_option2, TestSize.Level1)
1574 {
1575 JSVM_HandleScope handleScope;
1576 JSVM_Value result;
1577 bool boolValue = false;
1578 auto status1 = OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true);
1579 ASSERT_TRUE(status1 == JSVM_OK);
1580 OH_JSVM_OpenHandleScope(env, &handleScope);
1581 OH_JSVM_GetBoolean(env, true, &result);
1582 OH_JSVM_CloseHandleScope(env, handleScope);
1583 signal(SIGABRT, HandleAbort);
1584 static bool fataled = false;
1585 setjmp(g_buf);
1586 if (!fataled) {
1587 fataled = true;
1588 OH_JSVM_IsBoolean(env, result, &boolValue);
1589 }
1590 auto status2 = OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false);
1591 ASSERT_TRUE(status2 == JSVM_OK);
1592 ASSERT_TRUE(g_fatalErrorFinished);
1593 }
1594
1595 HWTEST_F(JSVMTest, test_set_debug_option3, TestSize.Level1)
1596 {
1597 JSVM_HandleScope handleScope;
1598 JSVM_Value val, escapeVal;
1599 bool boolValue = false;
1600 auto status1 = OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, true);
1601 ASSERT_TRUE(status1 == JSVM_OK);
1602 OH_JSVM_OpenHandleScope(env, &handleScope);
1603 JSVM_EscapableHandleScope scope = nullptr;
1604 OH_JSVM_OpenEscapableHandleScope(env, &scope);
1605 OH_JSVM_GetBoolean(env, true, &val);
1606 OH_JSVM_EscapeHandle(env, scope, val, &escapeVal);
1607 OH_JSVM_CloseEscapableHandleScope(env, scope);
1608 OH_JSVM_IsBoolean(env, escapeVal, &boolValue);
1609 OH_JSVM_CloseHandleScope(env, handleScope);
1610 auto status2 = OH_JSVM_SetDebugOption(env, JSVM_SCOPE_CHECK, false);
1611 ASSERT_TRUE(status2 == JSVM_OK);
1612 }
1613
1614 HWTEST_F(JSVMTest, JSVMCloseHandleScopeUAF, TestSize.Level1)
1615 {
1616 JSVM_HandleScope handle = nullptr;
1617 JSVMTEST_CALL(OH_JSVM_OpenHandleScope(env, &handle));
1618
1619 JSVM_Value jsSrc = nullptr;
1620 JSVMTEST_CALL(OH_JSVM_CreateStringUtf8(env, srcProf.c_str(), srcProf.size(), &jsSrc));
1621
1622 bool cacheRejected = true;
1623 JSVM_Script script = nullptr;
1624 JSVMTEST_CALL(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, &cacheRejected, &script));
1625
1626 JSVMTEST_CALL(OH_JSVM_RetainScript(env, script));
1627 JSVMTEST_CALL(OH_JSVM_ReleaseScript(env, script));
1628
1629 const int length = 32;
1630 char* data = new((char *)script) char[length];
1631 memset(data, 0, length);
1632
1633 JSVMTEST_CALL(OH_JSVM_CloseHandleScope(env, handle));
1634 }