• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 <gtest/gtest.h>
17 
18 #include "macros.h"
19 #include <libpandafile/include/source_lang_enum.h>
20 
21 #include "libpandabase/utils/logger.h"
22 #include "plugins/ets/runtime/ets_class_linker_extension.h"
23 #include "plugins/ets/runtime/ets_vm.h"
24 #include "runtime/include/class_linker_extension.h"
25 #include "runtime/include/class_root.h"
26 #include "runtime/include/coretypes/class.h"
27 #include "runtime/include/managed_thread.h"
28 #include "runtime/include/panda_vm.h"
29 #include "runtime/include/runtime_options.h"
30 #include "runtime/include/runtime.h"
31 
32 namespace ark::ets::test {
33 
34 class EtsVMTest : public testing::Test {
35 public:
EtsVMTest()36     EtsVMTest()
37     {
38         RuntimeOptions options;
39         options.SetShouldLoadBootPandaFiles(true);
40         options.SetShouldInitializeIntrinsics(false);
41         options.SetCompilerEnableJit(false);
42         options.SetGcType("epsilon");
43         options.SetLoadRuntimes({"ets"});
44 
45         Logger::InitializeStdLogging(Logger::Level::ERROR, 0);
46 
47         auto stdlib = std::getenv("PANDA_STD_LIB");
48         if (stdlib == nullptr) {
49             std::cerr << "PANDA_STD_LIB env variable should be set and point to mock_stdlib.abc" << std::endl;
50             std::abort();
51         }
52         options.SetBootPandaFiles({stdlib});
53 
54         ark::Runtime::Create(options);
55     }
~EtsVMTest()56     ~EtsVMTest() override
57     {
58         Runtime::Destroy();
59     }
60 
61     NO_COPY_SEMANTIC(EtsVMTest);
62     NO_MOVE_SEMANTIC(EtsVMTest);
63 };
64 
AssertCompoundClassRoot(EtsClassLinker * classLinker,EtsClassRoot root)65 static void AssertCompoundClassRoot(EtsClassLinker *classLinker, EtsClassRoot root)
66 {
67     EtsClass *klass = classLinker->GetClassRoot(root);
68     Class *coreClass = klass->GetRuntimeClass();
69 
70     ASSERT_NE(klass, nullptr);
71     ASSERT_TRUE(klass->IsInitialized());
72     ASSERT_TRUE(coreClass->IsInstantiable());
73     ASSERT_FALSE(klass->IsArrayClass());
74     ASSERT_FALSE(klass->IsPrimitive());
75     ASSERT_TRUE(klass->IsClass());
76     ASSERT_FALSE(klass->IsInterface());
77     ASSERT_FALSE(klass->IsAbstract());
78     ASSERT_FALSE(coreClass->IsProxy());
79     ASSERT_EQ(coreClass->GetLoadContext(), classLinker->GetEtsClassLinkerExtension()->GetBootContext());
80 
81     if (root == EtsClassRoot::OBJECT) {
82         ASSERT_TRUE(coreClass->IsObjectClass());
83         ASSERT_EQ(klass->GetBase(), nullptr);
84     } else {
85         ASSERT_FALSE(coreClass->IsObjectClass());
86         ASSERT_NE(klass->GetBase(), nullptr);
87         ASSERT_EQ(klass->GetBase(), classLinker->GetClassRoot(EtsClassRoot::OBJECT));
88     }
89 }
90 
AssertCompoundContainerClassRoot(EtsClassLinker * classLinker,EtsClassRoot root)91 static void AssertCompoundContainerClassRoot(EtsClassLinker *classLinker, EtsClassRoot root)
92 {
93     EtsClass *klass = classLinker->GetClassRoot(root);
94     Class *coreClass = klass->GetRuntimeClass();
95 
96     ASSERT_NE(klass, nullptr);
97     ASSERT_TRUE(klass->IsInitialized());
98     ASSERT_TRUE(coreClass->IsInstantiable());
99     ASSERT_TRUE(klass->IsArrayClass());
100     ASSERT_FALSE(klass->IsPrimitive());
101     ASSERT_TRUE(klass->IsClass());
102     ASSERT_FALSE(klass->IsInterface());
103     ASSERT_TRUE(klass->IsAbstract());
104     ASSERT_FALSE(coreClass->IsProxy());
105     ASSERT_EQ(coreClass->GetLoadContext(), classLinker->GetEtsClassLinkerExtension()->GetBootContext());
106     ASSERT_FALSE(coreClass->IsObjectClass());
107     ASSERT_NE(klass->GetBase(), nullptr);
108     ASSERT_EQ(klass->GetBase(), classLinker->GetClassRoot(EtsClassRoot::OBJECT));
109 }
110 
AssertPrimitiveClassRoot(EtsClassLinker * classLinker,EtsClassRoot root)111 static void AssertPrimitiveClassRoot(EtsClassLinker *classLinker, EtsClassRoot root)
112 {
113     EtsClass *klass = classLinker->GetClassRoot(root);
114     Class *coreClass = klass->GetRuntimeClass();
115 
116     ASSERT_NE(klass, nullptr);
117     ASSERT_TRUE(klass->IsInitialized());
118     ASSERT_FALSE(coreClass->IsInstantiable());
119     ASSERT_FALSE(klass->IsArrayClass());
120     ASSERT_TRUE(klass->IsPrimitive());
121     ASSERT_TRUE(klass->IsPublic());
122     ASSERT_TRUE(klass->IsFinal());
123     ASSERT_FALSE(klass->IsClass());
124     ASSERT_FALSE(klass->IsInterface());
125     ASSERT_TRUE(klass->IsAbstract());
126     ASSERT_FALSE(coreClass->IsProxy());
127     ASSERT_EQ(coreClass->GetLoadContext(), classLinker->GetEtsClassLinkerExtension()->GetBootContext());
128     ASSERT_EQ(klass->GetBase(), nullptr);
129 }
130 
AssertPrimitiveContainerClassRoot(EtsClassLinker * classLinker,EtsClassRoot root)131 static void AssertPrimitiveContainerClassRoot(EtsClassLinker *classLinker, EtsClassRoot root)
132 {
133     EtsClass *klass = classLinker->GetClassRoot(root);
134     Class *coreClass = klass->GetRuntimeClass();
135 
136     ASSERT_NE(klass, nullptr);
137     ASSERT_TRUE(klass->IsInitialized());
138     ASSERT_TRUE(coreClass->IsInstantiable());
139     ASSERT_TRUE(klass->IsArrayClass());
140     ASSERT_FALSE(klass->IsPrimitive());
141     ASSERT_TRUE(klass->IsPublic());
142     ASSERT_TRUE(klass->IsFinal());
143     ASSERT_TRUE(klass->IsClass());
144     ASSERT_FALSE(klass->IsInterface());
145     ASSERT_TRUE(klass->IsAbstract());
146     ASSERT_FALSE(coreClass->IsProxy());
147     ASSERT_EQ(coreClass->GetLoadContext(), classLinker->GetEtsClassLinkerExtension()->GetBootContext());
148     ASSERT_NE(klass->GetBase(), nullptr);
149     ASSERT_EQ(klass->GetBase(), classLinker->GetClassRoot(EtsClassRoot::OBJECT));
150 }
151 
AssertPrimitiveClassRoots(EtsClassLinker * classLinker)152 static void AssertPrimitiveClassRoots(EtsClassLinker *classLinker)
153 {
154     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::BOOLEAN);
155     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::BYTE);
156     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::SHORT);
157     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::CHAR);
158     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::INT);
159     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::LONG);
160     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::FLOAT);
161     AssertPrimitiveClassRoot(classLinker, EtsClassRoot::DOUBLE);
162 }
163 
TEST_F(EtsVMTest,InitTest)164 TEST_F(EtsVMTest, InitTest)
165 {
166     auto runtime = Runtime::GetCurrent();
167     ASSERT_NE(runtime, nullptr);
168 
169     PandaEtsVM *etsVm = PandaEtsVM::GetCurrent();
170     ASSERT_NE(etsVm, nullptr);
171 
172     EtsClassLinker *classLinker = etsVm->GetClassLinker();
173     ASSERT_NE(classLinker, nullptr);
174 
175     EtsClassLinkerExtension *ext = classLinker->GetEtsClassLinkerExtension();
176     ASSERT_NE(ext, nullptr);
177     ASSERT_EQ(ext->GetLanguage(), panda_file::SourceLang::ETS);
178     ASSERT_TRUE(ext->IsInitialized());
179 
180     AssertCompoundClassRoot(classLinker, EtsClassRoot::OBJECT);
181     AssertCompoundClassRoot(classLinker, EtsClassRoot::CLASS);
182     AssertCompoundClassRoot(classLinker, EtsClassRoot::STRING);
183 
184     AssertCompoundContainerClassRoot(classLinker, EtsClassRoot::STRING_ARRAY);
185 
186     AssertPrimitiveClassRoots(classLinker);
187 
188     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::BOOLEAN_ARRAY);
189     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::BYTE_ARRAY);
190     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::SHORT_ARRAY);
191     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::CHAR_ARRAY);
192     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::INT_ARRAY);
193     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::LONG_ARRAY);
194     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::FLOAT_ARRAY);
195     AssertPrimitiveContainerClassRoot(classLinker, EtsClassRoot::DOUBLE_ARRAY);
196 
197     EtsCoroutine *etsCoroutine = EtsCoroutine::GetCurrent();
198     ASSERT_NE(etsCoroutine, nullptr);
199 
200     auto vm = etsCoroutine->GetVM();
201     ASSERT_EQ(vm->GetAssociatedThread(), etsCoroutine);
202 
203     ASSERT_NE(vm, nullptr);
204     ASSERT_EQ(ext->GetLanguage(), vm->GetLanguageContext().GetLanguage());
205 
206     ASSERT_NE(vm->GetHeapManager(), nullptr);
207     ASSERT_NE(vm->GetMemStats(), nullptr);
208 
209     ASSERT_NE(vm->GetGC(), nullptr);
210     ASSERT_NE(vm->GetGCTrigger(), nullptr);
211     ASSERT_NE(vm->GetGCStats(), nullptr);
212     ASSERT_NE(vm->GetReferenceProcessor(), nullptr);
213 
214     ASSERT_NE(vm->GetGlobalObjectStorage(), nullptr);
215     ASSERT_NE(vm->GetStringTable(), nullptr);
216 
217     ASSERT_NE(vm->GetMonitorPool(), nullptr);
218     ASSERT_NE(vm->GetThreadManager(), nullptr);
219     ASSERT_NE(vm->GetRendezvous(), nullptr);
220 
221     ASSERT_NE(vm->GetCompiler(), nullptr);
222     ASSERT_NE(vm->GetCompilerRuntimeInterface(), nullptr);
223 }
224 
225 }  // namespace ark::ets::test
226