• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest.h>
17 
18 #include "assembler/assembly-emitter.h"
19 #include "assembler/assembly-parser.h"
20 #include "bytecode_optimizer/optimize_bytecode.h"
21 #include "runtime/include/class_linker.h"
22 #include "runtime/include/runtime.h"
23 #include "mangling.h"
24 
25 namespace panda::bytecodeopt::test {
26 
27 class BytecodeOptPeepholes : public testing::Test {
28 public:
BytecodeOptPeepholes()29     BytecodeOptPeepholes()
30     {
31         RuntimeOptions options;
32         options.SetHeapSizeLimit(128_MB);
33         options.SetShouldLoadBootPandaFiles(false);
34         options.SetShouldInitializeIntrinsics(false);
35         Logger::InitializeDummyLogging();
36 
37         Runtime::Create(options);
38         thread_ = panda::MTManagedThread::GetCurrent();
39         thread_->ManagedCodeBegin();
40     }
41 
~BytecodeOptPeepholes()42     ~BytecodeOptPeepholes()
43     {
44         thread_->ManagedCodeEnd();
45         Runtime::Destroy();
46     }
47 
48 protected:
49     panda::MTManagedThread *thread_;
50 };
51 
TEST_F(BytecodeOptPeepholes,TryBlock)52 TEST_F(BytecodeOptPeepholes, TryBlock)
53 {
54     pandasm::Parser p;
55 
56     auto source = R"(
57     .record E {}
58     .record R {
59         u1 field
60     }
61 
62     .function void R.ctor(R a0) <ctor> {
63         newobj v0, E
64         throw v0
65     }
66 
67     .function u8 try_catch() {
68     try_begin:
69         movi v1, 0x1
70         newobj v0, R
71         movi v1, 0x2
72         call.short R.ctor, v0
73     try_end:
74         ldai 0x0
75         return
76     catch_all:
77         lda v1
78         return
79     .catchall try_begin, try_end, catch_all
80     }
81     )";
82 
83     auto res = p.Parse(source);
84     auto &program = res.Value();
85     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
86     std::string file_name = "bc_peepholes";
87     auto piece = pandasm::AsmEmitter::Emit(file_name, program, nullptr, &maps);
88     ASSERT_NE(piece, false);
89 
90     EXPECT_TRUE(OptimizeBytecode(&program, &maps, file_name, false, true));
91 
92     // Check if there is initobj instruction in the bytecode
93     bool contains_initobj = false;
94     const auto sig_try_catch = pandasm::GetFunctionSignatureFromName("try_catch", {});
95     for (const auto &inst : program.function_table.at(sig_try_catch).ins) {
96         if (inst.opcode == pandasm::Opcode::INITOBJ) {
97             contains_initobj = true;
98         }
99     }
100     EXPECT_FALSE(contains_initobj);
101 
102     auto pf = pandasm::AsmEmitter::Emit(program);
103     ASSERT_NE(pf, nullptr);
104 
105     ClassLinker *class_linker = Runtime::GetCurrent()->GetClassLinker();
106     class_linker->AddPandaFile(std::move(pf));
107     auto *extension = class_linker->GetExtension(panda_file::SourceLang::PANDA_ASSEMBLY);
108     PandaString descriptor;
109 
110     auto *klass = extension->GetClass(ClassHelper::GetDescriptor(utf::CStringAsMutf8("_GLOBAL"), &descriptor));
111     ASSERT_NE(klass, nullptr);
112 
113     Method *method = klass->GetDirectMethod(utf::CStringAsMutf8("try_catch"));
114     ASSERT_NE(method, nullptr);
115 
116     std::vector<Value> args;
117     args.emplace_back(Value(1, interpreter::TypeTag::INT));
118     Value v = method->Invoke(ManagedThread::GetCurrent(), args.data());
119     EXPECT_EQ(v.GetAsLong(), 0x2);
120 }
121 
122 }  // namespace panda::bytecodeopt::test
123