1 /* 2 * Copyright (c) 2021 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 ECMASCRIPT_BASE_ALIGNED_STRUCT_H 17 #define ECMASCRIPT_BASE_ALIGNED_STRUCT_H 18 19 #include "ecmascript/base/bit_helper.h" 20 21 namespace panda::ecmascript::base { 22 template<typename...> 23 struct TypeList {}; 24 25 template<typename T> 26 struct TypeList<T> { 27 using Head = T; 28 using Next = TypeList<>; 29 static constexpr size_t Size = 1; 30 }; 31 32 template<typename T, typename... Res> 33 struct TypeList<T, Res...> { 34 using Head = T; 35 using Next = TypeList<Res...>; 36 static constexpr size_t Size = 1 + sizeof...(Res); 37 }; 38 39 template<size_t ElementAlign, typename... Ts> 40 struct AlignedStruct { 41 static constexpr size_t EAS = ElementAlign; 42 43 using ElemTypeList = TypeList<Ts...>; 44 static constexpr size_t NumOfTypes = ElemTypeList::Size; 45 46 template<size_t, typename> 47 struct OffsetAt; 48 49 template<> 50 struct OffsetAt<0, TypeList<>> { 51 static constexpr size_t OFFSET64 = 0; 52 static constexpr size_t OFFSET32 = 0; 53 }; 54 55 template<typename Head, typename... Res> 56 struct OffsetAt<0, TypeList<Head, Res...>> { 57 static constexpr size_t OFFSET64 = 0; 58 static constexpr size_t OFFSET32 = 0; 59 }; 60 61 template<size_t index, typename Head, typename... Res> 62 struct OffsetAt<index, TypeList<Head, Res...>> { 63 static_assert(std::is_class<Head>::value); 64 static constexpr size_t OFFSET64 = 65 RoundUp(Head::SizeArch64, EAS) + OffsetAt<index - 1, TypeList<Res...>>::OFFSET64; 66 67 static constexpr size_t OFFSET32 = 68 RoundUp(Head::SizeArch32, EAS) + OffsetAt<index - 1, TypeList<Res...>>::OFFSET32; 69 }; 70 71 template<size_t index> 72 static size_t GetOffset(bool isArch32) 73 { 74 return isArch32 ? OffsetAt<index, ElemTypeList>::OFFSET32 75 : OffsetAt<index, ElemTypeList>::OFFSET64; 76 }; 77 78 static constexpr size_t SizeArch32 = OffsetAt<NumOfTypes, ElemTypeList>::OFFSET32; 79 static constexpr size_t SizeArch64 = OffsetAt<NumOfTypes, ElemTypeList>::OFFSET64; 80 }; 81 82 struct AlignedPointer { 83 static constexpr size_t SizeArch32 = sizeof(uint32_t); 84 static constexpr size_t SizeArch64 = sizeof(uint64_t); 85 static constexpr size_t Size() 86 { 87 return sizeof(uintptr_t); 88 } 89 }; 90 91 struct AlignedSize { 92 static constexpr size_t SizeArch32 = sizeof(uint32_t); 93 static constexpr size_t SizeArch64 = sizeof(uint64_t); 94 static constexpr size_t Size() 95 { 96 return sizeof(uintptr_t); 97 } 98 }; 99 100 struct AlignedUint64 { 101 static constexpr size_t SizeArch32 = sizeof(uint64_t); 102 static constexpr size_t SizeArch64 = sizeof(uint64_t); 103 static constexpr size_t Size() 104 { 105 return sizeof(uint64_t); 106 } 107 }; 108 109 struct AlignedUint32 { 110 static constexpr size_t SizeArch32 = sizeof(uint32_t); 111 static constexpr size_t SizeArch64 = sizeof(uint32_t); 112 static constexpr size_t Size() 113 { 114 return sizeof(uint32_t); 115 } 116 }; 117 118 struct AlignedUint8 { 119 static constexpr size_t SizeArch32 = sizeof(uint8_t); 120 static constexpr size_t SizeArch64 = sizeof(uint8_t); 121 static constexpr size_t Size() 122 { 123 return sizeof(uint8_t); 124 } 125 }; 126 } 127 #endif // ECMASCRIPT_BASE_ALIGNED_STRUCT_H 128