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 PANDA_VERIFIER_JOB_QUEUE_JOB_H 17 #define PANDA_VERIFIER_JOB_QUEUE_JOB_H 18 19 #include "source_lang_enum.h" 20 #include "verification/cflow/cflow_info.h" 21 #include "verification/verification_options.h" 22 #include "verification/plugins.h" 23 #include "verification/public_internal.h" 24 25 #include "runtime/include/class_linker.h" 26 #include "runtime/include/method.h" 27 28 #include <cstdint> 29 #include <functional> 30 #include <optional> 31 32 namespace panda::verifier { 33 class Job { 34 public: Job(Service * service,Method const * method,const MethodOptions & options)35 Job(Service *service, Method const *method, const MethodOptions &options) 36 : service_ {service}, 37 classLinker_ {service->classLinker}, 38 method_ {method}, 39 lang_ {method->GetClass()->GetSourceLang()}, 40 langContext_ {plugins::GetLanguageContextBase(method_->GetClass()->GetSourceLang())}, 41 classLinkerCtx_ {classLinker_->GetExtension(langContext_)->GetBootContext()}, 42 options_ {options}, 43 plugin_ {plugin::GetLanguagePlugin(lang_)} 44 { 45 } 46 47 ~Job() = default; 48 NO_MOVE_SEMANTIC(Job); 49 NO_COPY_SEMANTIC(Job); 50 IsFieldPresentForOffset(uint32_t offset)51 bool IsFieldPresentForOffset(uint32_t offset) const 52 { 53 return fields_.count(offset) != 0; 54 } 55 IsMethodPresentForOffset(uint32_t offset)56 bool IsMethodPresentForOffset(uint32_t offset) const 57 { 58 return methods_.count(offset) != 0; 59 } 60 IsTypePresentForOffset(uint32_t offset)61 bool IsTypePresentForOffset(uint32_t offset) const 62 { 63 return types_.count(offset) != 0; 64 } 65 GetCachedField(uint32_t offset)66 Field const *GetCachedField(uint32_t offset) const 67 { 68 return fields_.at(offset); 69 } 70 GetCachedMethod(uint32_t offset)71 Method const *GetCachedMethod(uint32_t offset) const 72 { 73 return methods_.at(offset); 74 } 75 GetCachedType(uint32_t offset)76 Type GetCachedType(uint32_t offset) const 77 { 78 return types_.at(offset); 79 } 80 GetService()81 Service *GetService() const 82 { 83 return service_; 84 } 85 JobMethod()86 Method const *JobMethod() const 87 { 88 return method_; 89 } 90 JobMethodCflow()91 const CflowMethodInfo &JobMethodCflow() const 92 { 93 return *cflowInfo_; 94 } 95 JobPlugin()96 const plugin::Plugin *JobPlugin() const 97 { 98 return plugin_; 99 } 100 101 template <typename Handler> ForAllCachedTypes(Handler && handler)102 void ForAllCachedTypes(Handler &&handler) const 103 { 104 for (const auto &item : types_) { 105 handler(item.second); 106 } 107 } 108 109 template <typename Handler> ForAllCachedMethods(Handler && handler)110 void ForAllCachedMethods(Handler &&handler) const 111 { 112 for (const auto &item : methods_) { 113 handler(item.second); 114 } 115 } 116 117 template <typename Handler> ForAllCachedFields(Handler && handler)118 void ForAllCachedFields(Handler &&handler) const 119 { 120 for (const auto &item : fields_) { 121 handler(item.second); 122 } 123 } 124 Options()125 const auto &Options() const 126 { 127 return options_; 128 } 129 130 bool DoChecks(TypeSystem *types); 131 132 class ErrorHandler : public ClassLinkerErrorHandler { 133 void OnError(ClassLinker::Error error, PandaString const &message) override; 134 }; 135 136 private: 137 Service *service_; 138 ClassLinker *classLinker_; 139 Method const *method_; 140 panda_file::SourceLang lang_; 141 LanguageContext langContext_; 142 ClassLinkerContext *classLinkerCtx_; 143 const MethodOptions &options_; 144 PandaUniquePtr<CflowMethodInfo> cflowInfo_; 145 146 plugin::Plugin const *const plugin_; 147 148 // NOTE(vdyadov): store file_id for double check during verification 149 // offset -> cache item 150 PandaUnorderedMap<uint32_t, Field const *> fields_; 151 PandaUnorderedMap<uint32_t, Method const *> methods_; 152 PandaUnorderedMap<uint32_t, Type> types_; 153 154 bool ResolveIdentifiers(); 155 156 bool UpdateTypes(TypeSystem *types) const; 157 158 bool Verify(TypeSystem *types) const; 159 AddField(uint32_t offset,Field const * field)160 void AddField(uint32_t offset, Field const *field) 161 { 162 fields_.emplace(offset, field); 163 } 164 AddMethod(uint32_t offset,Method const * method)165 void AddMethod(uint32_t offset, Method const *method) 166 { 167 methods_.emplace(offset, method); 168 } 169 AddType(uint32_t offset,Type const * type)170 void AddType(uint32_t offset, Type const *type) 171 { 172 types_.emplace(offset, *type); 173 } 174 }; 175 } // namespace panda::verifier 176 177 #endif // PANDA_VERIFIER_JOB_QUEUE_JOB_H 178