• 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 #ifndef ECMASCRIPT_TESTS_TEST_HELPER_H
17 #define ECMASCRIPT_TESTS_TEST_HELPER_H
18 
19 #include "ecmascript/interpreter/interpreter.h"
20 #include "ecmascript/ecma_runtime_call_info.h"
21 #include "ecmascript/ecma_vm.h"
22 #include "ecmascript/js_function.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/mem/mem_common.h"
25 #include "ecmascript/napi/include/jsnapi.h"
26 #include "ecmascript/object_factory.h"
27 #include "gtest/gtest.h"
28 
29 namespace panda::test {
30 using panda::ecmascript::EcmaHandleScope;
31 using panda::ecmascript::EcmaRuntimeCallInfo;
32 using panda::ecmascript::EcmaVM;
33 using panda::ecmascript::InterpretedFrame;
34 using panda::ecmascript::InterpretedBuiltinFrame;
35 using panda::ecmascript::InterpretedEntryFrame;
36 using panda::ecmascript::JSTaggedType;
37 using panda::ecmascript::JSTaggedValue;
38 using panda::ecmascript::JSThread;
39 using panda::ecmascript::NUM_MANDATORY_JSFUNC_ARGS;
40 using ecmascript::JSRuntimeOptions;
41 
42 #define HWTEST_F_L0(testsuit, testcase) HWTEST_F(testsuit, testcase, testing::ext::TestSize.Level0)
43 #define HWTEST_P_L0(testsuit, testcase) HWTEST_P(testsuit, testcase, testing::ext::TestSize.Level0)
44 #define EXPECT_EXCEPTION()                           \
45     EXPECT_TRUE(thread->HasPendingException());      \
46     EXPECT_TRUE(thread->GetException().IsJSError()); \
47     thread->ClearException()
48 
49 class TestHelper {
50 public:
CreateEcmaRuntimeCallInfo(JSThread * thread,JSTaggedValue newTgt,uint32_t argvLength)51     static EcmaRuntimeCallInfo* CreateEcmaRuntimeCallInfo(JSThread *thread, JSTaggedValue newTgt, uint32_t argvLength)
52     {
53         const uint8_t testDecodedSize = 2;
54         // argvLength includes number of int64_t to store value and tag of function, 'this' and call args
55         // It doesn't include new.target argument
56         int32_t numActualArgs = argvLength / testDecodedSize + 1;
57         JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
58 
59         size_t frameSize = 0;
60         if (thread->IsAsmInterpreter()) {
61             frameSize = InterpretedEntryFrame::NumOfMembers() + numActualArgs;
62         } else {
63             frameSize = InterpretedFrame::NumOfMembers() + numActualArgs;
64         }
65         JSTaggedType *newSp = sp - frameSize;  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
66         for (int i = numActualArgs; i > 0; i--) {
67             newSp[i - 1] = JSTaggedValue::Undefined().GetRawData();
68         }
69         EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp - 2);
70         *(--newSp) = numActualArgs;
71         *(--newSp) = panda::ecmascript::ToUintPtr(thread);
72         ecmaRuntimeCallInfo->SetNewTarget(newTgt);
73         return ecmaRuntimeCallInfo;
74     }
75 
SetupFrame(JSThread * thread,EcmaRuntimeCallInfo * info)76     static JSTaggedType *SetupFrame(JSThread *thread, EcmaRuntimeCallInfo *info)
77     {
78         JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
79         size_t frameSize = 0;
80         if (thread->IsAsmInterpreter()) {
81             // 2 means thread and numArgs
82             frameSize = InterpretedEntryFrame::NumOfMembers() + info->GetArgsNumber() + NUM_MANDATORY_JSFUNC_ARGS + 2;
83         } else {
84             // 2 means thread and numArgs
85             frameSize = InterpretedFrame::NumOfMembers() + info->GetArgsNumber() + NUM_MANDATORY_JSFUNC_ARGS + 2;
86         }
87         JSTaggedType *newSp = sp - frameSize;  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
88 
89         InterpretedEntryFrame *state = reinterpret_cast<InterpretedEntryFrame *>(newSp) - 1;
90         state->base.type = ecmascript::FrameType::INTERPRETER_ENTRY_FRAME;
91         state->base.prev = sp;
92         state->pc = nullptr;
93         thread->SetCurrentSPFrame(newSp);
94         return sp;
95     }
96 
TearDownFrame(JSThread * thread,JSTaggedType * prev)97     static void TearDownFrame(JSThread *thread, JSTaggedType *prev)
98     {
99         thread->SetCurrentSPFrame(prev);
100     }
101 
102     // If you want to call once create, you can refer to BuiltinsMathTest for detail.
103     static void CreateEcmaVMWithScope(EcmaVM *&instance, JSThread *&thread, EcmaHandleScope *&scope,
104         bool tryLoadStubFile = false, bool useCInterpreter = false)
105     {
106         JSRuntimeOptions options;
107         options.SetEnableForceGC(true);
108         if (tryLoadStubFile) {
109             options.SetEnableAsmInterpreter(true);
110         }
111         if (useCInterpreter) {
112             options.SetEnableAsmInterpreter(false);
113         }
114         instance = JSNApi::CreateEcmaVM(options);
115         instance->SetEnableForceGC(true);
116         ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
117         thread = instance->GetJSThread();
118         scope = new EcmaHandleScope(thread);
119         auto globalEnv = instance->GetGlobalEnv();
120         methodFunction_ = instance->GetFactory()->NewJSFunction(globalEnv);
121     }
122 
DestroyEcmaVMWithScope(EcmaVM * instance,EcmaHandleScope * scope)123     static inline void DestroyEcmaVMWithScope(EcmaVM *instance, EcmaHandleScope *scope)
124     {
125         delete scope;
126         scope = nullptr;
127         instance->SetEnableForceGC(false);
128         auto thread = instance->GetJSThread();
129         thread->ClearException();
130         JSNApi::DestroyJSVM(instance);
131     }
132 
133 private:
134     inline static ecmascript::JSHandle<ecmascript::JSFunction> methodFunction_;
135 };
136 }  // namespace panda::test
137 #endif  // ECMASCRIPT_TESTS_TEST_HELPER_H
138