1 /**
2 * Copyright (c) 2021-2022 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 "macros.h"
17 #if defined(PANDA_TARGET_MOBILE)
18 #elif defined(USE_STD_FILESYSTEM)
19 #include <filesystem>
20 #else
21 #include <experimental/filesystem>
22 #endif
23 #include "optimizer/ir_builder/ir_builder.h"
24 #include "optimizer/optimizations/cleanup.h"
25 #include "optimizer/code_generator/encode.h"
26 #include "include/class_linker.h"
27 #include "assembly-parser.h"
28 #include "include/runtime.h"
29 #include "compiler.h"
30 #include "utils/expected.h"
31 #include "compiler_options.h"
32 #include "unit_test.h"
33
34 #include "utils/utf.h"
35
36 namespace panda::compiler {
Initialize(int argc,char ** argv)37 void PandaRuntimeTest::Initialize([[maybe_unused]] int argc, char **argv)
38 {
39 ASSERT(argc > 0);
40 exec_path_ = argv[0];
41 }
42
PandaRuntimeTest()43 PandaRuntimeTest::PandaRuntimeTest()
44 {
45 ASSERT(exec_path_ != nullptr);
46 #if !defined(PANDA_TARGET_MOBILE)
47 #if defined(USE_STD_FILESYSTEM)
48 std::filesystem::path exec_name(exec_path_);
49 #else
50 std::experimental::filesystem::path exec_name(exec_path_);
51 #endif // defined(USE_STD_FILESYSTEM)
52 std::string pandastdlib_path = exec_name.parent_path() / "../pandastdlib/arkstdlib.abc";
53 #else
54 std::string exec_name = "compiler_unit_tests";
55 std::string pandastdlib_path = "../pandastdlib/arkstdlib.abc";
56 #endif
57 panda::RuntimeOptions runtime_options(exec_name);
58 runtime_options.SetBootPandaFiles({pandastdlib_path});
59 runtime_options.SetLoadRuntimes({"core"});
60 runtime_options.SetHeapSizeLimit(50_MB);
61 runtime_options.SetEnableAn(true);
62 runtime_options.SetGcType("epsilon");
63 Logger::InitializeDummyLogging();
64 EXPECT_TRUE(panda::Runtime::Create(runtime_options));
65
66 allocator_ = new ArenaAllocator(panda::SpaceType::SPACE_TYPE_INTERNAL);
67 local_allocator_ = new ArenaAllocator(panda::SpaceType::SPACE_TYPE_INTERNAL);
68 builder_ = new IrConstructor();
69
70 graph_ = CreateGraph();
71 }
72
~PandaRuntimeTest()73 PandaRuntimeTest::~PandaRuntimeTest()
74 {
75 delete builder_;
76 delete allocator_;
77 delete local_allocator_;
78 panda::Runtime::Destroy();
79 }
80
GetDefaultRuntime()81 RuntimeInterface *PandaRuntimeTest::GetDefaultRuntime()
82 {
83 return Graph::GetDefaultRuntime();
84 }
85
ParseToFile(const char * source,const char * file_name)86 std::unique_ptr<const panda_file::File> AsmTest::ParseToFile(const char *source, const char *file_name)
87 {
88 panda::pandasm::Parser parser;
89 auto res = parser.Parse(source, file_name);
90 if (parser.ShowError().err != pandasm::Error::ErrorType::ERR_NONE) {
91 std::cerr << "Parse failed: " << parser.ShowError().message << std::endl
92 << parser.ShowError().whole_line << std::endl;
93 ADD_FAILURE();
94 return nullptr;
95 }
96 return pandasm::AsmEmitter::Emit(res.Value());
97 }
98
Parse(const char * source,const char * file_name)99 bool AsmTest::Parse(const char *source, const char *file_name)
100 {
101 auto pfile = ParseToFile(source, file_name);
102 if (pfile == nullptr) {
103 ADD_FAILURE();
104 return false;
105 }
106 GetClassLinker()->AddPandaFile(std::move(pfile));
107 return true;
108 }
109
BuildGraph(const char * method_name,Graph * graph)110 Graph *AsmTest::BuildGraph(const char *method_name, Graph *graph)
111 {
112 auto loader = GetClassLinker();
113 PandaString storage;
114 auto extension = loader->GetExtension(panda_file::SourceLang::PANDA_ASSEMBLY);
115 auto *thread = MTManagedThread::GetCurrent();
116 thread->ManagedCodeBegin();
117 auto klass = extension->GetClass(ClassHelper::GetDescriptor(utf::CStringAsMutf8("_GLOBAL"), &storage));
118 thread->ManagedCodeEnd();
119
120 auto method = klass->GetDirectMethod(utf::CStringAsMutf8(method_name));
121 if (method == nullptr) {
122 ADD_FAILURE();
123 return nullptr;
124 }
125 if (graph == nullptr) {
126 graph = CreateGraph();
127 }
128 graph->SetMethod(method);
129 if (!graph->RunPass<IrBuilder>()) {
130 ADD_FAILURE();
131 return nullptr;
132 }
133 return graph;
134 }
135
CleanUp(Graph * graph)136 void AsmTest::CleanUp(Graph *graph)
137 {
138 graph->RunPass<Cleanup>();
139 }
140
~CommonTest()141 CommonTest::~CommonTest()
142 {
143 // Look at examples in encoder_constructors tests.
144 // Used for destroy MasmHolder.
145 Encoder *encoder = Encoder::Create(allocator_, arch_, false);
146 if (encoder != nullptr) {
147 encoder->~Encoder();
148 }
149 delete builder_;
150 delete allocator_;
151 delete object_allocator_;
152 delete local_allocator_;
153 PoolManager::Finalize();
154
155 panda::mem::MemConfig::Finalize();
156 }
157 } // namespace panda::compiler
158
main(int argc,char ** argv)159 int main(int argc, char **argv)
160 {
161 ::testing::InitGoogleTest(&argc, argv);
162
163 panda::compiler::PandaRuntimeTest::Initialize(argc, argv);
164 panda::compiler::options.SetCompilerUseSafepoint(false);
165 return RUN_ALL_TESTS();
166 }
167