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 #ifndef BERBERIS_RUNTIME_PRIMITIVES_HOST_CODE_H_
17 #define BERBERIS_RUNTIME_PRIMITIVES_HOST_CODE_H_
18
19 #include <cstdint>
20
21 namespace berberis {
22
23 // Pointer to host executable machine code.
24 using HostCode = const void*;
25
26 template <typename T>
AsHostCode(T ptr)27 inline HostCode AsHostCode(T ptr) {
28 return reinterpret_cast<HostCode>(ptr);
29 }
30
31 template <typename T>
AsFuncPtr(HostCode ptr)32 inline T AsFuncPtr(HostCode ptr) {
33 return reinterpret_cast<T>(const_cast<void*>(ptr));
34 }
35
36 // Note: ideally we would like the class to be a local class in the AsFuncPtr function below, but
37 // C++ doesn't allow that: local classes are not supposed to have template members.
38 class AsFuncPtrAdaptor;
39 AsFuncPtrAdaptor AsFuncPtr(HostCode ptr);
40 class [[nodiscard]] AsFuncPtrAdaptor {
41 // Note: we need this helper to describe the operator on the next line. Otherwise the C++ syntax
42 // parser becomes very confused. It has to come before the operator to help the parser, though.
43 template <typename Result, typename... Args>
44 using MakeFunctionType = Result (*)(Args...);
45
46 public:
47 template <typename Result, typename... Args>
48 operator MakeFunctionType<Result, Args...>() {
49 return reinterpret_cast<MakeFunctionType<Result, Args...>>(ptr_);
50 }
51
52 private:
53 AsFuncPtrAdaptor() = delete;
54 AsFuncPtrAdaptor(const AsFuncPtrAdaptor&) = delete;
55 AsFuncPtrAdaptor(AsFuncPtrAdaptor&&) = delete;
56 AsFuncPtrAdaptor& operator=(const AsFuncPtrAdaptor&) = delete;
57 AsFuncPtrAdaptor& operator=(AsFuncPtrAdaptor&&) = delete;
AsFuncPtrAdaptor(HostCode ptr)58 constexpr explicit AsFuncPtrAdaptor(HostCode ptr) noexcept : ptr_(const_cast<void*>(ptr)) {}
59 friend AsFuncPtrAdaptor AsFuncPtr(HostCode);
60 void* ptr_;
61 };
62
63 // The result of this function is assumed to be assigned to a non-auto variable type, which will
64 // involve the conversion operator of AsFuncPtrAdaptor.
AsFuncPtr(HostCode ptr)65 inline AsFuncPtrAdaptor AsFuncPtr(HostCode ptr) {
66 return AsFuncPtrAdaptor{ptr};
67 }
68
69 struct HostCodePiece {
70 HostCode code;
71 uint32_t size;
72 };
73
74 } // namespace berberis
75
76 #endif // BERBERIS_RUNTIME_PRIMITIVES_HOST_CODE_H_
77