1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 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 #ifndef rr_Routine_hpp 16 #define rr_Routine_hpp 17 18 // A Clang extension to determine compiler features. 19 // We use it to detect Sanitizer builds (e.g. -fsanitize=memory). 20 #ifndef __has_feature 21 # define __has_feature(x) 0 22 #endif 23 24 #if __has_feature(memory_sanitizer) 25 # include "sanitizer/msan_interface.h" 26 #endif 27 28 #include <memory> 29 30 namespace rr { 31 32 class Routine 33 { 34 public: 35 Routine() = default; 36 virtual ~Routine() = default; 37 38 virtual const void *getEntry(int index = 0) const = 0; 39 }; 40 41 // RoutineT is a type-safe wrapper around a Routine and its function entry, returned by FunctionT 42 template<typename FunctionType> 43 class RoutineT; 44 45 template<typename Return, typename... Arguments> 46 class RoutineT<Return(Arguments...)> 47 { 48 public: 49 using FunctionType = Return (*)(Arguments...); 50 51 RoutineT() = default; 52 RoutineT(const std::shared_ptr<Routine> & routine)53 explicit RoutineT(const std::shared_ptr<Routine> &routine) 54 : routine(routine) 55 { 56 if(routine) 57 { 58 function = reinterpret_cast<FunctionType>(const_cast<void *>(routine->getEntry(0))); 59 } 60 } 61 operator bool() const62 operator bool() const 63 { 64 return function != nullptr; 65 } 66 67 template<typename... Args> operator ()(Args...args) const68 Return operator()(Args... args) const 69 { 70 #if __has_feature(memory_sanitizer) 71 // TODO(b/228253151): Fix support for detecting uninitialized parameters. 72 __msan_unpoison_param(sizeof...(args)); 73 #endif 74 75 return function(args...); 76 } 77 getEntry() const78 const FunctionType getEntry() const 79 { 80 return function; 81 } 82 83 private: 84 std::shared_ptr<Routine> routine; 85 FunctionType function = nullptr; 86 }; 87 88 } // namespace rr 89 90 #endif // rr_Routine_hpp 91