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_PLUGINS_ETS_RUNTIME_ETS_VTABLE_BUILDER_H 17 #define PANDA_PLUGINS_ETS_RUNTIME_ETS_VTABLE_BUILDER_H 18 19 #include <cstddef> 20 #include <utility> 21 22 #include "runtime/include/vtable_builder-inl.h" 23 24 namespace panda::ets { 25 26 struct EtsVTableSearchBySignature { operatorEtsVTableSearchBySignature27 bool operator()(const MethodInfo &info1, const MethodInfo &info2) const 28 { 29 if (info1.IsEqualByNameAndSignature(info2)) { 30 return true; 31 } 32 // NOTE: the best way is to check subtyping of return types. 33 // If true, check IsEqualByNameAndSignature with replaced return types. 34 // But now no way to check subtyping or casting for methods 35 if (info1.GetName() != info2.GetName()) { 36 return false; 37 } 38 if (((info1.IsAbstract() ^ info2.IsAbstract()) != 0) && (info1.GetReturnType() == info2.GetReturnType()) && 39 (info1.GetSourceLang() == info2.GetSourceLang())) { 40 return true; 41 } 42 return false; 43 } 44 }; 45 46 struct EtsVTableOverridePred { operatorEtsVTableOverridePred47 std::pair<bool, size_t> operator()(const MethodInfo &info1, const MethodInfo &info2) const 48 { 49 // Do not override already overrided default methods 50 if (info2.IsInterfaceMethod() && !info1.IsCopied()) { 51 // Default iface override should take inheritance info consideration. 52 if (info1.IsInterfaceMethod()) { 53 ASSERT(info1.GetMethod() != nullptr); 54 ASSERT(info2.GetMethod() != nullptr); 55 Class *cls1 = info1.GetMethod()->GetClass(); 56 Class *cls2 = info2.GetMethod()->GetClass(); 57 if (cls2->IsAssignableFrom(cls1)) { 58 return std::pair<bool, size_t>(false, MethodInfo::INVALID_METHOD_IDX); 59 } 60 return std::pair<bool, size_t>(true, info1.GetIndex()); 61 } 62 return std::pair<bool, size_t>(false, MethodInfo::INVALID_METHOD_IDX); 63 } 64 65 if (info1.IsPublic() || info1.IsProtected()) { 66 return std::pair<bool, size_t>(true, MethodInfo::INVALID_METHOD_IDX); 67 } 68 69 if (info1.IsPrivate()) { 70 return std::pair<bool, size_t>(false, MethodInfo::INVALID_METHOD_IDX); 71 } 72 73 return std::pair<bool, size_t>(IsInSamePackage(info1, info2), MethodInfo::INVALID_METHOD_IDX); 74 } 75 76 bool IsInSamePackage(const MethodInfo &info1, const MethodInfo &info2) const; 77 }; 78 79 using EtsVTableBuilder = VTableBuilderImpl<EtsVTableSearchBySignature, EtsVTableOverridePred>; 80 81 } // namespace panda::ets 82 83 #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_ITABLE_BUILDER_H 84