1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef BERBERIS_GUEST_ABI_GUEST_FUNCTION_WRAPPER_SIGNATURE_H_ 18 #define BERBERIS_GUEST_ABI_GUEST_FUNCTION_WRAPPER_SIGNATURE_H_ 19 20 #include <cstdint> 21 #include <type_traits> 22 23 namespace berberis { 24 25 // Signature string: 26 // "<return-type-char><param-type-char><param-type-char>" 27 // 28 // Supported types: 29 // 'v': void (as return type) 30 // 'z': unsigned integer and enum types == 8bit (jboolean equivalent) 31 // 'b': signed integer and enum types == 8bit (jbyte equivalent) 32 // 's': signed integer and enum types == 16bit (jshort equivalent) 33 // 'c': unsigned integer types == 16bit (jchar equivalent) 34 // 'i': integer and enum types == 32bit (jint equivalent) 35 // 'l': integer and enum types == 64bit (jfloat equivalent) 36 // 'p': pointers (to objects and functions but not to members) 37 // 'f': float (floating point 32 bits) 38 // 'd': double (floating point 64 bits) 39 // 40 // Signature char (template constant) for return type or parameter: 41 // kGuestFunctionWrapperSignatureChar<Type> 42 // 43 // Signature (template constant) for function or function pointer: 44 // kGuestFunctionWrapperSignature<int (int)> 45 46 class kGuestFunctionWrapperSignatureCharHelper { 47 public: 48 template <typename Type, std::enable_if_t<std::is_same_v<Type, void>, int> = 0> Value()49 static constexpr char Value() { 50 return 'v'; 51 } 52 53 template <typename Type, 54 std::enable_if_t<(std::is_integral_v<Type> || 55 std::is_enum_v<Type>)&&std::is_unsigned_v<Type> && 56 sizeof(Type) == sizeof(uint8_t), 57 int> = 0> Value()58 static constexpr char Value() { 59 return 'z'; 60 } 61 62 template < 63 typename Type, 64 std::enable_if_t<(std::is_integral_v<Type> || std::is_enum_v<Type>)&&std::is_signed_v<Type> && 65 sizeof(Type) == sizeof(int8_t), 66 int> = 0> Value()67 static constexpr char Value() { 68 return 'b'; 69 } 70 71 template < 72 typename Type, 73 std::enable_if_t<(std::is_integral_v<Type> || std::is_enum_v<Type>)&&std::is_signed_v<Type> && 74 sizeof(Type) == sizeof(int16_t), 75 int> = 0> Value()76 static constexpr char Value() { 77 return 's'; 78 } 79 80 template <typename Type, 81 std::enable_if_t<std::is_integral_v<Type> && std::is_unsigned_v<Type> && 82 sizeof(Type) == sizeof(uint16_t), 83 int> = 0> Value()84 static constexpr char Value() { 85 return 'c'; 86 } 87 88 template <typename Type, 89 std::enable_if_t<(std::is_integral_v<Type> || std::is_enum_v<Type>)&&sizeof(Type) == 90 sizeof(int32_t), 91 int> = 0> Value()92 static constexpr char Value() { 93 return 'i'; 94 } 95 96 template <typename Type, 97 std::enable_if_t<(std::is_integral_v<Type> || std::is_enum_v<Type>)&&sizeof(Type) == 98 sizeof(int64_t), 99 int> = 0> Value()100 static constexpr char Value() { 101 return 'l'; 102 } 103 104 template <typename Type, std::enable_if_t<std::is_pointer_v<Type>, int> = 0> Value()105 static constexpr char Value() { 106 return 'p'; 107 } 108 109 template < 110 typename Type, 111 std::enable_if_t<std::is_same_v<Type, float> && sizeof(Type) == sizeof(int32_t), int> = 0> Value()112 static constexpr char Value() { 113 return 'f'; 114 } 115 116 template < 117 typename Type, 118 std::enable_if_t<std::is_same_v<Type, double> && sizeof(Type) == sizeof(int64_t), int> = 0> Value()119 static constexpr char Value() { 120 return 'd'; 121 } 122 }; 123 124 template <typename Arg> 125 constexpr char kGuestFunctionWrapperSignatureChar = 126 kGuestFunctionWrapperSignatureCharHelper::Value<Arg>(); 127 128 template <typename Func> 129 class kGuestFunctionWrapperSignatureHelper; 130 131 template <typename Result, typename... Args> 132 class kGuestFunctionWrapperSignatureHelper<Result (*)(Args...)> { 133 public: 134 constexpr static const char kValue[] = {kGuestFunctionWrapperSignatureChar<Result>, 135 kGuestFunctionWrapperSignatureChar<Args>..., 136 0}; 137 }; 138 139 template <typename Func> 140 constexpr static const char (&kGuestFunctionWrapperSignature)[sizeof( 141 kGuestFunctionWrapperSignatureHelper<std::decay_t<Func>>::kValue)] = 142 kGuestFunctionWrapperSignatureHelper<std::decay_t<Func>>::kValue; 143 144 } // namespace berberis 145 146 #endif // BERBERIS_GUEST_ABI_GUEST_FUNCTION_WRAPPER_SIGNATURE_H_ 147