• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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-parser.h"
19 #include "compiler/optimizer/ir/basicblock.h"
20 #include "graph_test.h"
21 #include "mem/pool_manager.h"
22 #include "optimize_bytecode.h"
23 
24 using namespace testing::ext;
25 
26 namespace panda::bytecodeopt {
27 using namespace compiler;
28 using namespace panda::pandasm;
29 
30 class OptimizeBytecodeTest : public testing::Test {
31 public:
SetUpTestCase(void)32     static void SetUpTestCase(void) {}
TearDownTestCase(void)33     static void TearDownTestCase(void) {}
SetUp()34     void SetUp() {}
TearDown()35     void TearDown() {}
36 
EmitAndOptimize(const std::string & abc_file_name,panda::pandasm::Program & program) const37     void EmitAndOptimize(const std::string &abc_file_name, panda::pandasm::Program &program) const
38     {
39         panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps panda_file_to_asm_maps {};
40         EXPECT_TRUE(panda::pandasm::AsmEmitter::Emit(abc_file_name, program, nullptr, &panda_file_to_asm_maps, false));
41         EXPECT_TRUE(panda::bytecodeopt::OptimizeBytecode(&program, &panda_file_to_asm_maps, abc_file_name, true));
42     }
43 };
44 
45 /**
46  * @tc.name: optimize_bytecode_test_001
47  * @tc.desc: Verify the OptimizeBytecode function.
48  * @tc.type: FUNC
49  * @tc.require: issueNumber
50  */
51 HWTEST_F(OptimizeBytecodeTest, optimize_bytecode_test_001, TestSize.Level1) {
52     const auto source = R"(
53         .language ECMAScript
54         .array array_unsigned_byte u8 3 { 1 2 3 }
55         .record Asm4 { i32 asm1 }
56         .function any func_main_0(any a0, any a1, any a2) <static> {
57             ldundefined
58             stglobalvar 0x0, "j"
59             ldundefined
60             stglobalvar 0x1, "n"
61             lda.str "a b c"
62             stglobalvar 0x2, "n"
63             ldglobalvar 0x3, "n"
64             getpropiterator
65             sta v0
66         jump_label_1:
67             getnextpropname v0
68             sta v1
69             ldundefined
70             eq 0x4, v1
71             jnez jump_label_0
72             lda v1
73             stglobalvar 0x5, "j"
74             tryldglobalbyname 0x6, "console"
75             sta v1
76             ldobjbyname 0x7, "log"
77             sta v2
78             ldglobalvar 0x9, "n"
79             sta v3
80             ldglobalvar 0xa, "j"
81             ldobjbyvalue 0xb, v3
82             sta v3
83             lda v2
84             callthis1 0xd, v1, v3
85             jmp jump_label_1
86         jump_label_0:
87             ldundefined
88             returnundefined
89         }
90     )";
91 
92     panda::pandasm::Parser parser;
93     auto res = parser.Parse(source);
94     auto &program = res.Value();
95     const std::string fun_name = "func_main_0:(any,any,any)";
96     auto it = program.function_table.find(fun_name);
97     EXPECT_NE(it, program.function_table.end());
98     EmitAndOptimize("codegenTryCatch.abc", program);
99 }
100 
101 /**
102  * @tc.name: optimize_bytecode_test_002
103  * @tc.desc: Verify the OptimizeBytecode function.
104  * @tc.type: FUNC
105  * @tc.require: issueNumber
106  */
107 HWTEST_F(OptimizeBytecodeTest, optimize_bytecode_test_002, TestSize.Level1) {
108     const auto source = R"(
109         .language ECMAScript
110         .array array_unsigned_byte u8 3 { 1 2 3 }
111         .record Asm4 { i32 asm1 }
112         .function any func_main_0(any a0, any a1, any a2) <static> {
113             ldundefined
114             stglobalvar 0x0, "j"
115             ldundefined
116             stglobalvar 0x1, "n"
117             lda.str "a b c"
118             stglobalvar 0x2, "n"
119             ldglobalvar 0x3, "n"
120             getpropiterator
121             sta v0
122         jump_label_1:
123             getnextpropname v0
124             sta v1
125             ldundefined
126             eq 0x4, v1
127             jnez jump_label_0
128             lda v1
129             stglobalvar 0x5, "j"
130             tryldglobalbyname 0x6, "console"
131             sta v1
132             ldobjbyname 0x7, "log"
133             sta v2
134             ldglobalvar 0x9, "n"
135             sta v3
136             ldglobalvar 0xa, "j"
137             ldobjbyvalue 0xb, v3
138             sta v3
139             lda v2
140             callthis1 0xd, v1, v3
141             jmp jump_label_1
142         jump_label_0:
143             ldundefined
144             returnundefined
145         }
146     )";
147     panda::pandasm::Parser parser;
148     auto res = parser.Parse(source);
149     auto &program = res.Value();
150     const std::string fun_name = "func_main_0:(any,any,any)";
151     auto it = program.function_table.find(fun_name);
152 
153     EXPECT_NE(it, program.function_table.end());
154     const std::string abc_file_name = "codegenTryCatch.abc";
155 
156     panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps panda_file_to_asm_maps {};
157     EXPECT_TRUE(panda::pandasm::AsmEmitter::Emit(abc_file_name, program, nullptr, &panda_file_to_asm_maps, false));
158 }
159 
160 /**
161  * @tc.name: optimize_bytecode_test_003
162  * @tc.desc: Verify the OptimizeBytecode function.
163  * @tc.type: FUNC
164  * @tc.require: issueNumber
165  */
166 HWTEST_F(OptimizeBytecodeTest, optimize_bytecode_test_003, TestSize.Level1) {
167     const auto source = R"(
168         .language ECMAScript
169         .array array_unsigned_byte u8 3 { 1 2 3 }
170         .record Asm4 { i32 asm1 }
171         .function any func_main_0(any a0, any a1, any a2) <static> {
172             ldundefined
173             stglobalvar 0x0, "j"
174             ldundefined
175             stglobalvar 0x1, "n"
176             lda.str "a b c"
177             stglobalvar 0x2, "n"
178             ldglobalvar 0x3, "n"
179             getpropiterator
180             sta v0
181         jump_label_1:
182             getnextpropname v0
183             sta v1
184             ldundefined
185             eq 0x4, v1
186             jnez jump_label_0
187             lda v1
188             stglobalvar 0x5, "j"
189             tryldglobalbyname 0x6, "console"
190             sta v1
191             ldobjbyname 0x7, "log"
192             sta v2
193             ldglobalvar 0x9, "n"
194             sta v3
195             ldglobalvar 0xa, "j"
196             ldobjbyvalue 0xb, v3
197             sta v3
198             lda v2
199             callthis1 0xd, v1, v3
200             jmp jump_label_1
201         jump_label_0:
202             ldundefined
203             returnundefined
204         }
205     )";
206 
207     panda::pandasm::Parser parser;
208     auto res = parser.Parse(source);
209     auto &program = res.Value();
210     const std::string fun_name = "func_main_0:(any,any,any)";
211     auto it = program.function_table.find(fun_name);
212 
213     Function::CatchBlock cat;
214     cat.try_end_label = "random";  // random: It's a random string
215     it->second.catch_blocks.push_back(cat);
216     EXPECT_NE(it, program.function_table.end());
217 
218     const std::string abc_file_name = "codegenTryCatch.abc";
219 
220     panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps panda_file_to_asm_maps {};
221     EXPECT_TRUE(panda::pandasm::AsmEmitter::Emit(abc_file_name, program, nullptr, &panda_file_to_asm_maps, false));
222     // do not optimize function having catch blocks"
223     EXPECT_FALSE(panda::bytecodeopt::OptimizeBytecode(&program, &panda_file_to_asm_maps, abc_file_name, true));
224 }
225 }  // namespace panda::bytecodeopt