1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#include "macros.h"
17b1994897Sopenharmony_ci#if defined(PANDA_TARGET_MOBILE)
18b1994897Sopenharmony_ci#elif defined(USE_STD_FILESYSTEM)
19b1994897Sopenharmony_ci#include <filesystem>
20b1994897Sopenharmony_ci#else
21b1994897Sopenharmony_ci#include <experimental/filesystem>
22b1994897Sopenharmony_ci#endif
23b1994897Sopenharmony_ci#include "optimizer/ir_builder/ir_builder.h"
24b1994897Sopenharmony_ci#include "optimizer/optimizations/cleanup.h"
25b1994897Sopenharmony_ci#include "optimizer/code_generator/encode.h"
26b1994897Sopenharmony_ci#include "include/class_linker.h"
27b1994897Sopenharmony_ci#include "assembly-parser.h"
28b1994897Sopenharmony_ci#include "include/runtime.h"
29b1994897Sopenharmony_ci#include "compiler.h"
30b1994897Sopenharmony_ci#include "utils/expected.h"
31b1994897Sopenharmony_ci#include "compiler_options.h"
32b1994897Sopenharmony_ci#include "unit_test.h"
33b1994897Sopenharmony_ci
34b1994897Sopenharmony_ci#include "utils/utf.h"
35b1994897Sopenharmony_ci
36b1994897Sopenharmony_cinamespace panda::compiler {
37b1994897Sopenharmony_civoid PandaRuntimeTest::Initialize([[maybe_unused]] int argc, char **argv)
38b1994897Sopenharmony_ci{
39b1994897Sopenharmony_ci    ASSERT(argc > 0);
40b1994897Sopenharmony_ci    exec_path_ = argv[0];
41b1994897Sopenharmony_ci}
42b1994897Sopenharmony_ci
43b1994897Sopenharmony_ciPandaRuntimeTest::PandaRuntimeTest()
44b1994897Sopenharmony_ci{
45b1994897Sopenharmony_ci    ASSERT(exec_path_ != nullptr);
46b1994897Sopenharmony_ci#if !defined(PANDA_TARGET_MOBILE)
47b1994897Sopenharmony_ci#if defined(USE_STD_FILESYSTEM)
48b1994897Sopenharmony_ci    std::filesystem::path exec_name(exec_path_);
49b1994897Sopenharmony_ci#else
50b1994897Sopenharmony_ci    std::experimental::filesystem::path exec_name(exec_path_);
51b1994897Sopenharmony_ci#endif  // defined(USE_STD_FILESYSTEM)
52b1994897Sopenharmony_ci    std::string pandastdlib_path = exec_name.parent_path() / "../pandastdlib/arkstdlib.abc";
53b1994897Sopenharmony_ci#else
54b1994897Sopenharmony_ci    std::string exec_name = "compiler_unit_tests";
55b1994897Sopenharmony_ci    std::string pandastdlib_path = "../pandastdlib/arkstdlib.abc";
56b1994897Sopenharmony_ci#endif
57b1994897Sopenharmony_ci    panda::RuntimeOptions runtime_options(exec_name);
58b1994897Sopenharmony_ci    runtime_options.SetBootPandaFiles({pandastdlib_path});
59b1994897Sopenharmony_ci    runtime_options.SetLoadRuntimes({"core"});
60b1994897Sopenharmony_ci    runtime_options.SetHeapSizeLimit(50_MB);
61b1994897Sopenharmony_ci    runtime_options.SetEnableAn(true);
62b1994897Sopenharmony_ci    runtime_options.SetGcType("epsilon");
63b1994897Sopenharmony_ci    Logger::InitializeDummyLogging();
64b1994897Sopenharmony_ci    EXPECT_TRUE(panda::Runtime::Create(runtime_options));
65b1994897Sopenharmony_ci
66b1994897Sopenharmony_ci    allocator_ = new ArenaAllocator(panda::SpaceType::SPACE_TYPE_INTERNAL);
67b1994897Sopenharmony_ci    local_allocator_ = new ArenaAllocator(panda::SpaceType::SPACE_TYPE_INTERNAL);
68b1994897Sopenharmony_ci    builder_ = new IrConstructor();
69b1994897Sopenharmony_ci
70b1994897Sopenharmony_ci    graph_ = CreateGraph();
71b1994897Sopenharmony_ci}
72b1994897Sopenharmony_ci
73b1994897Sopenharmony_ciPandaRuntimeTest::~PandaRuntimeTest()
74b1994897Sopenharmony_ci{
75b1994897Sopenharmony_ci    delete builder_;
76b1994897Sopenharmony_ci    delete allocator_;
77b1994897Sopenharmony_ci    delete local_allocator_;
78b1994897Sopenharmony_ci    panda::Runtime::Destroy();
79b1994897Sopenharmony_ci}
80b1994897Sopenharmony_ci
81b1994897Sopenharmony_ciRuntimeInterface *PandaRuntimeTest::GetDefaultRuntime()
82b1994897Sopenharmony_ci{
83b1994897Sopenharmony_ci    return Graph::GetDefaultRuntime();
84b1994897Sopenharmony_ci}
85b1994897Sopenharmony_ci
86b1994897Sopenharmony_cistd::unique_ptr<const panda_file::File> AsmTest::ParseToFile(const char *source, const char *file_name)
87b1994897Sopenharmony_ci{
88b1994897Sopenharmony_ci    panda::pandasm::Parser parser;
89b1994897Sopenharmony_ci    auto res = parser.Parse(source, file_name);
90b1994897Sopenharmony_ci    if (parser.ShowError().err != pandasm::Error::ErrorType::ERR_NONE) {
91b1994897Sopenharmony_ci        std::cerr << "Parse failed: " << parser.ShowError().message << std::endl
92b1994897Sopenharmony_ci                  << parser.ShowError().whole_line << std::endl;
93b1994897Sopenharmony_ci        ADD_FAILURE();
94b1994897Sopenharmony_ci        return nullptr;
95b1994897Sopenharmony_ci    }
96b1994897Sopenharmony_ci    return pandasm::AsmEmitter::Emit(res.Value());
97b1994897Sopenharmony_ci}
98b1994897Sopenharmony_ci
99b1994897Sopenharmony_cibool AsmTest::Parse(const char *source, const char *file_name)
100b1994897Sopenharmony_ci{
101b1994897Sopenharmony_ci    auto pfile = ParseToFile(source, file_name);
102b1994897Sopenharmony_ci    if (pfile == nullptr) {
103b1994897Sopenharmony_ci        ADD_FAILURE();
104b1994897Sopenharmony_ci        return false;
105b1994897Sopenharmony_ci    }
106b1994897Sopenharmony_ci    GetClassLinker()->AddPandaFile(std::move(pfile));
107b1994897Sopenharmony_ci    return true;
108b1994897Sopenharmony_ci}
109b1994897Sopenharmony_ci
110b1994897Sopenharmony_ciGraph *AsmTest::BuildGraph(const char *method_name, Graph *graph)
111b1994897Sopenharmony_ci{
112b1994897Sopenharmony_ci    auto loader = GetClassLinker();
113b1994897Sopenharmony_ci    PandaString storage;
114b1994897Sopenharmony_ci    auto extension = loader->GetExtension(panda_file::SourceLang::PANDA_ASSEMBLY);
115b1994897Sopenharmony_ci    auto *thread = MTManagedThread::GetCurrent();
116b1994897Sopenharmony_ci    thread->ManagedCodeBegin();
117b1994897Sopenharmony_ci    auto klass = extension->GetClass(ClassHelper::GetDescriptor(utf::CStringAsMutf8("_GLOBAL"), &storage));
118b1994897Sopenharmony_ci    thread->ManagedCodeEnd();
119b1994897Sopenharmony_ci
120b1994897Sopenharmony_ci    auto method = klass->GetDirectMethod(utf::CStringAsMutf8(method_name));
121b1994897Sopenharmony_ci    if (method == nullptr) {
122b1994897Sopenharmony_ci        ADD_FAILURE();
123b1994897Sopenharmony_ci        return nullptr;
124b1994897Sopenharmony_ci    }
125b1994897Sopenharmony_ci    if (graph == nullptr) {
126b1994897Sopenharmony_ci        graph = CreateGraph();
127b1994897Sopenharmony_ci    }
128b1994897Sopenharmony_ci    graph->SetMethod(method);
129b1994897Sopenharmony_ci    if (!graph->RunPass<IrBuilder>()) {
130b1994897Sopenharmony_ci        ADD_FAILURE();
131b1994897Sopenharmony_ci        return nullptr;
132b1994897Sopenharmony_ci    }
133b1994897Sopenharmony_ci    return graph;
134b1994897Sopenharmony_ci}
135b1994897Sopenharmony_ci
136b1994897Sopenharmony_civoid AsmTest::CleanUp(Graph *graph)
137b1994897Sopenharmony_ci{
138b1994897Sopenharmony_ci    graph->RunPass<Cleanup>();
139b1994897Sopenharmony_ci}
140b1994897Sopenharmony_ci
141b1994897Sopenharmony_ciCommonTest::~CommonTest()
142b1994897Sopenharmony_ci{
143b1994897Sopenharmony_ci    // Look at examples in encoder_constructors tests.
144b1994897Sopenharmony_ci    // Used for destroy MasmHolder.
145b1994897Sopenharmony_ci    Encoder *encoder = Encoder::Create(allocator_, arch_, false);
146b1994897Sopenharmony_ci    if (encoder != nullptr) {
147b1994897Sopenharmony_ci        encoder->~Encoder();
148b1994897Sopenharmony_ci    }
149b1994897Sopenharmony_ci    delete builder_;
150b1994897Sopenharmony_ci    delete allocator_;
151b1994897Sopenharmony_ci    delete object_allocator_;
152b1994897Sopenharmony_ci    delete local_allocator_;
153b1994897Sopenharmony_ci    PoolManager::Finalize();
154b1994897Sopenharmony_ci
155b1994897Sopenharmony_ci    panda::mem::MemConfig::Finalize();
156b1994897Sopenharmony_ci}
157b1994897Sopenharmony_ci}  // namespace panda::compiler
158b1994897Sopenharmony_ci
159b1994897Sopenharmony_ciint main(int argc, char **argv)
160b1994897Sopenharmony_ci{
161b1994897Sopenharmony_ci    ::testing::InitGoogleTest(&argc, argv);
162b1994897Sopenharmony_ci
163b1994897Sopenharmony_ci    panda::compiler::PandaRuntimeTest::Initialize(argc, argv);
164b1994897Sopenharmony_ci    panda::compiler::options.SetCompilerUseSafepoint(false);
165b1994897Sopenharmony_ci    return RUN_ALL_TESTS();
166b1994897Sopenharmony_ci}
167