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 #ifndef BYTECODE_OPTIMIZER_RUNTIME_ADAPTER_H 17 #define BYTECODE_OPTIMIZER_RUNTIME_ADAPTER_H 18 19 #include "compiler/optimizer/ir/runtime_interface.h" 20 #include "libpandafile/bytecode_instruction.h" 21 #include "libpandafile/class_data_accessor.h" 22 #include "libpandafile/code_data_accessor.h" 23 #include "libpandafile/field_data_accessor.h" 24 #include "libpandafile/file.h" 25 #include "libpandafile/file-inl.h" 26 #include "libpandafile/file_items.h" 27 #include "libpandafile/method_data_accessor.h" 28 #include "libpandafile/proto_data_accessor.h" 29 #include "libpandafile/proto_data_accessor-inl.h" 30 #include "libpandafile/type_helper.h" 31 32 namespace panda { 33 using compiler::RuntimeInterface; 34 35 class BytecodeOptimizerRuntimeAdapter : public RuntimeInterface { 36 public: BytecodeOptimizerRuntimeAdapter(const panda_file::File &panda_file)37 explicit BytecodeOptimizerRuntimeAdapter(const panda_file::File &panda_file) : panda_file_(panda_file) {} 38 39 ~BytecodeOptimizerRuntimeAdapter() override = default; 40 41 BinaryFilePtr GetBinaryFileForMethod([[maybe_unused]] MethodPtr method) const override 42 { 43 return const_cast<panda_file::File *>(&panda_file_); 44 } 45 46 uint32_t ResolveOffsetByIndex(MethodPtr parent_method, uint16_t index) const override 47 { 48 return panda_file_.ResolveOffsetByIndex(MethodCast(parent_method), index).GetOffset(); 49 } 50 51 MethodId GetMethodId(MethodPtr method) const override 52 { 53 return static_cast<MethodId>(reinterpret_cast<uintptr_t>(method)); 54 } 55 56 size_t GetMethodTotalArgumentsCount(MethodPtr method) const override 57 { 58 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 59 60 ASSERT(!mda.IsExternal()); 61 panda_file::CodeDataAccessor cda(panda_file_, mda.GetCodeId().value()); 62 63 return cda.GetNumArgs(); 64 } 65 66 size_t GetMethodArgumentsCount([[maybe_unused]] MethodPtr caller, MethodId id) const override 67 { 68 panda_file::MethodDataAccessor mda(panda_file_, panda_file::File::EntityId(id)); 69 70 ASSERT(!mda.IsExternal()); 71 panda_file::CodeDataAccessor cda(panda_file_, mda.GetCodeId().value()); 72 73 return cda.GetNumArgs(); 74 } 75 76 size_t GetMethodRegistersCount(MethodPtr method) const override 77 { 78 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 79 80 ASSERT(!mda.IsExternal()); 81 panda_file::CodeDataAccessor cda(panda_file_, mda.GetCodeId().value()); 82 83 return cda.GetNumVregs(); 84 } 85 86 const uint8_t *GetMethodCode(MethodPtr method) const override 87 { 88 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 89 90 ASSERT(!mda.IsExternal()); 91 panda_file::CodeDataAccessor cda(panda_file_, mda.GetCodeId().value()); 92 93 return cda.GetInstructions(); 94 } 95 96 size_t GetMethodCodeSize(MethodPtr method) const override 97 { 98 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 99 100 ASSERT(!mda.IsExternal()); 101 panda_file::CodeDataAccessor cda(panda_file_, mda.GetCodeId().value()); 102 103 return cda.GetCodeSize(); 104 } 105 106 compiler::SourceLanguage GetMethodSourceLanguage(MethodPtr method) const override 107 { 108 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 109 110 ASSERT(!mda.IsExternal()); 111 112 auto source_lang = mda.GetSourceLang(); 113 ASSERT(source_lang.has_value()); 114 115 return static_cast<compiler::SourceLanguage>(source_lang.value()); 116 } 117 118 size_t GetClassIdForMethod(MethodPtr method) const override 119 { 120 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 121 122 return static_cast<size_t>(mda.GetClassId().GetOffset()); 123 } 124 125 std::string GetClassNameFromMethod(MethodPtr method) const override 126 { 127 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 128 129 auto string_data = panda_file_.GetStringData(mda.GetClassId()); 130 131 return std::string(reinterpret_cast<const char *>(string_data.data)); 132 } 133 134 std::string GetMethodName(MethodPtr method) const override 135 { 136 panda_file::MethodDataAccessor mda(panda_file_, MethodCast(method)); 137 138 auto string_data = panda_file_.GetStringData(mda.GetNameId()); 139 140 return std::string(reinterpret_cast<const char *>(string_data.data)); 141 } 142 143 std::string GetMethodFullName(MethodPtr method, bool /* with_signature */) const override 144 { 145 auto class_name = GetClassNameFromMethod(method); 146 auto method_name = GetMethodName(method); 147 148 return class_name + "::" + method_name; 149 } 150 151 private: ToCompilerType(panda_file::Type type)152 static compiler::DataType::Type ToCompilerType(panda_file::Type type) 153 { 154 switch (type.GetId()) { 155 case panda_file::Type::TypeId::VOID: 156 return compiler::DataType::VOID; 157 case panda_file::Type::TypeId::I32: 158 return compiler::DataType::INT32; 159 case panda_file::Type::TypeId::U32: 160 return compiler::DataType::UINT32; 161 case panda_file::Type::TypeId::I64: 162 return compiler::DataType::INT64; 163 case panda_file::Type::TypeId::U64: 164 return compiler::DataType::UINT64; 165 case panda_file::Type::TypeId::F64: 166 return compiler::DataType::FLOAT64; 167 case panda_file::Type::TypeId::REFERENCE: 168 return compiler::DataType::REFERENCE; 169 case panda_file::Type::TypeId::TAGGED: 170 case panda_file::Type::TypeId::INVALID: 171 return compiler::DataType::ANY; 172 default: 173 break; 174 } 175 UNREACHABLE(); 176 } 177 MethodCast(RuntimeInterface::MethodPtr method)178 static panda_file::File::EntityId MethodCast(RuntimeInterface::MethodPtr method) 179 { 180 return panda_file::File::EntityId(reinterpret_cast<uintptr_t>(method)); 181 } 182 183 const panda_file::File &panda_file_; 184 }; 185 } // namespace panda 186 187 #endif // BYTECODE_OPTIMIZER_RUNTIME_ADAPTER_H 188