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