• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "ecmascript/ecma_vm.h"
17 #include "ecmascript/js_runtime_options.h"
18 #include "ecmascript/tests/test_helper.h"
19 
20 #include <csetjmp>
21 #include <csignal>
22 using namespace panda::ecmascript;
23 using namespace common;
24 
25 namespace panda::test {
26 class EcmaVMTest : public BaseTestWithOutScope {
27 };
28 
29 static thread_local sigjmp_buf g_env;
30 static thread_local bool g_abortFlag = false;
31 static std::mutex g_signalMutex;
32 
ProcessHandleAllocAbort(int sig)33 static void ProcessHandleAllocAbort(int sig)
34 {
35     ForceResetAssertData();
36     g_abortFlag = true;
37     siglongjmp(g_env, sig);
38 }
39 
RegisterSignal(struct sigaction * oldAct=nullptr)40 static int RegisterSignal(struct sigaction* oldAct = nullptr)
41 {
42     std::lock_guard<std::mutex> lock(g_signalMutex);
43 
44     struct sigaction act;
45     act.sa_handler = ProcessHandleAllocAbort;
46     sigemptyset(&act.sa_mask);
47     sigaddset(&act.sa_mask, SIGABRT);
48     act.sa_flags = 0;
49 
50     return sigaction(SIGABRT, &act, oldAct);
51 }
52 
RestoreSignal(const struct sigaction * oldAct)53 static void RestoreSignal(const struct sigaction* oldAct)
54 {
55     std::lock_guard<std::mutex> lock(g_signalMutex);
56     sigaction(SIGABRT, oldAct, nullptr);
57 }
58 
ResetAbortFlag()59 static void ResetAbortFlag()
60 {
61     g_abortFlag = false;
62 }
63 
64 class EcmaVmIterator : public ecmascript::RootVisitor {
65 public:
66     EcmaVmIterator() = default;
67     ~EcmaVmIterator() = default;
68 
VisitRoot(Root type,ObjectSlot slot)69     void VisitRoot([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot slot) override {}
70 
VisitRangeRoot(Root type,ObjectSlot start,ObjectSlot end)71     void VisitRangeRoot([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot start,
72         [[maybe_unused]] ObjectSlot end) override
73     {
74         CHECK_NO_HANDLE_ALLOC;
75     }
76 
VisitBaseAndDerivedRoot(Root type,ObjectSlot base,ObjectSlot derived,uintptr_t baseOldObject)77     void VisitBaseAndDerivedRoot([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base,
78         [[maybe_unused]] ObjectSlot derived, [[maybe_unused]] uintptr_t baseOldObject) override {}
79 };
80 
81 /*
82  * @tc.name: CreateEcmaVMInTwoWays
83  * @tc.desc: Create EcmaVM in 2 ways, check the Options state
84  * @tc.type: FUNC
85  * @tc.require:
86  */
HWTEST_F_L0(EcmaVMTest,CreateEcmaVMInTwoWays)87 HWTEST_F_L0(EcmaVMTest, CreateEcmaVMInTwoWays)
88 {
89     RuntimeOption options;
90     options.SetLogLevel(common::LOG_LEVEL::ERROR);
91     EcmaVM::SetMultiThreadCheck(true);
92     EcmaVM *ecmaVm1 = JSNApi::CreateJSVM(options);
93     EXPECT_TRUE(ecmaVm1->GetMultiThreadCheck());
94     auto jsthread1 = ecmaVm1->GetJSThread();
95     EXPECT_TRUE(jsthread1 != nullptr);
96 
97     std::thread t1([&]() {
98         JSRuntimeOptions options2;
99         options2.SetEnableArkTools(false);
100         options2.SetEnableForceGC(false);
101         options2.SetForceFullGC(false);
102         options2.SetArkProperties(ArkProperties::GC_STATS_PRINT);
103         options2.SetMemConfigProperty("jsHeap500");
104         // A non-production gc strategy. Prohibit stw-gc 10 times.
105         EcmaVM::SetMultiThreadCheck(false);
106         EcmaVM *ecmaVm2 = JSNApi::CreateEcmaVM(options2);
107         auto jsthread2 = ecmaVm2->GetJSThread();
108         EXPECT_FALSE(ecmaVm2->GetMultiThreadCheck());
109         EXPECT_TRUE(jsthread2 != nullptr);
110         EXPECT_TRUE(ecmaVm1 != ecmaVm2);
111 
112         JSRuntimeOptions options1Out = ecmaVm1->GetJSOptions();
113         JSRuntimeOptions options2Out = ecmaVm2->GetJSOptions();
114 
115         EXPECT_TRUE(&options1Out != &options2Out);
116 
117         EXPECT_TRUE(options1Out.EnableArkTools() != options2Out.EnableArkTools());
118         EXPECT_TRUE(options1Out.EnableForceGC() != options2Out.EnableForceGC());
119         EXPECT_TRUE(options1Out.ForceFullGC() != options2Out.ForceFullGC());
120         EXPECT_TRUE(options1Out.GetArkProperties() != options2Out.GetArkProperties());
121         EXPECT_TRUE(options2Out.GetHeapSize() == 500_MB);
122 
123         options2.SetAsmOpcodeDisableRange("1,10");
124         options2.ParseAsmInterOption();
125         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleStart == 1); // 1 targer start
126         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleEnd == 10); // 10 targer end
127 
128         options2.SetAsmOpcodeDisableRange("0x1,0xa");
129         options2.ParseAsmInterOption();
130         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleStart == 1); // 1 targer start
131         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleEnd == 10); // 10 targer end
132 
133         options2.SetAsmOpcodeDisableRange(",");
134         options2.ParseAsmInterOption();
135         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleStart == 0);
136         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleEnd == kungfu::BYTECODE_STUB_END_ID);
137 
138         options2.SetAsmOpcodeDisableRange("@,@");
139         options2.ParseAsmInterOption();
140         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleStart == 0);
141         EXPECT_TRUE(options2.GetAsmInterParsedOption().handleEnd == kungfu::BYTECODE_STUB_END_ID);
142 
143         JSNApi::DestroyJSVM(ecmaVm2);
144     });
145     t1.join();
146     JSNApi::DestroyJSVM(ecmaVm1);
147 }
148 
HWTEST_F_L0(EcmaVMTest,DumpExceptionObject)149 HWTEST_F_L0(EcmaVMTest, DumpExceptionObject)
150 {
151     RuntimeOption option;
152     option.SetLogLevel(common::LOG_LEVEL::ERROR);
153     EcmaVM *ecmaVm = JSNApi::CreateJSVM(option);
154     auto thread = ecmaVm->GetJSThread();
155     int arkProperties = thread->GetEcmaVM()->GetJSOptions().GetArkProperties();
156     ecmaVm->GetJSOptions().SetArkProperties(arkProperties | ArkProperties::EXCEPTION_BACKTRACE);
157     EXPECT_TRUE(ecmaVm->GetJSOptions().EnableExceptionBacktrace());
158     JSNApi::DestroyJSVM(ecmaVm);
159 }
160 
HWTEST_F_L0(EcmaVMTest,LargeHeap)161 HWTEST_F_L0(EcmaVMTest, LargeHeap)
162 {
163     RuntimeOption option;
164     option.SetLargeHeap(true);
165     EcmaVM *ecmaVm = JSNApi::CreateJSVM(option);
166     EXPECT_TRUE(ecmaVm->GetJSOptions().GetLargeHeap());
167     JSNApi::DestroyJSVM(ecmaVm);
168 }
169 
HWTEST_F_L0(EcmaVMTest,TestHandleAlocate)170 HWTEST_F_L0(EcmaVMTest, TestHandleAlocate)
171 {
172     RuntimeOption option;
173     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
174     EcmaVM *ecmaVm = JSNApi::CreateJSVM(option);
175     [[maybe_unused]]HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(ecmaVm);
176 
177     ObjectFactory *factory = ecmaVm->GetFactory();
178     // JS_ARRAY_BUFFER
179     factory->NewJSArrayBuffer(10);
180     // JS_SHARED_ARRAY_BUFFER
181     factory->NewJSSharedArrayBuffer(10);
182     // PROMISE_REACTIONS
183     factory->NewPromiseReaction();
184     // PROMISE_CAPABILITY
185     factory->NewPromiseCapability();
186     // PROMISE_RECORD
187     factory->NewPromiseRecord();
188     // RESOLVING_FUNCTIONS_RECORD
189     factory->NewResolvingFunctionsRecord();
190 
191     struct sigaction oldAct;
192     ASSERT_TRUE(RegisterSignal(&oldAct) != -1);
193 
194     {
195         EcmaVmIterator ecmaVmIterator;
196         auto ret = sigsetjmp(g_env, 1);
197         if (ret != SIGABRT) {
198             ecmaVm->Iterate(ecmaVmIterator);
199         } else {
200             EXPECT_TRUE(g_abortFlag);
201         }
202     }
203 
204     RestoreSignal(&oldAct);
205     ResetAbortFlag();
206 
207     ASSERT_TRUE(RegisterSignal(&oldAct) != -1);
208     {
209         EcmaVmIterator ecmaVmIterator;
210         auto ret = sigsetjmp(g_env, 1);
211         if (ret != SIGABRT) {
212             ecmaVm->IterateHandle(ecmaVmIterator);
213         } else {
214             EXPECT_TRUE(g_abortFlag);
215         }
216     }
217 
218     RestoreSignal(&oldAct);
219     ResetAbortFlag();
220     JSNApi::DestroyJSVM(ecmaVm);
221 }
222 }  // namespace panda::ecmascript
223