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 36namespace panda::compiler { 37void PandaRuntimeTest::Initialize([[maybe_unused]] int argc, char **argv) 38{ 39 ASSERT(argc > 0); 40 exec_path_ = argv[0]; 41} 42 43PandaRuntimeTest::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 73PandaRuntimeTest::~PandaRuntimeTest() 74{ 75 delete builder_; 76 delete allocator_; 77 delete local_allocator_; 78 panda::Runtime::Destroy(); 79} 80 81RuntimeInterface *PandaRuntimeTest::GetDefaultRuntime() 82{ 83 return Graph::GetDefaultRuntime(); 84} 85 86std::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 99bool 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 110Graph *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 136void AsmTest::CleanUp(Graph *graph) 137{ 138 graph->RunPass<Cleanup>(); 139} 140 141CommonTest::~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 159int 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