1 /** 2 * Copyright (c) 2021-2024 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 #ifndef PANDA_RUNTIME_VALUE_H_ 16 #define PANDA_RUNTIME_VALUE_H_ 17 18 #include <cstdarg> 19 #include <cstdint> 20 #include <type_traits> 21 #include <variant> 22 23 #include "libpandafile/file_items.h" 24 #include "runtime/bridge/bridge.h" 25 #include "runtime/include/coretypes/tagged_value.h" 26 27 namespace ark { 28 29 class ObjectHeader; 30 31 class Value { 32 public: Value()33 explicit Value() : value_(0) {} 34 DEFAULT_COPY_SEMANTIC(Value); 35 DEFAULT_MOVE_SEMANTIC(Value); 36 ~Value() = default; 37 38 template <class T> Value(T value)39 explicit Value(T value) 40 { 41 // Disable checks due to clang-tidy bug https://bugs.llvm.org/show_bug.cgi?id=32203 42 // NOLINTNEXTLINE(readability-braces-around-statements, hicpp-braces-around-statements, bugprone-branch-clone) 43 if constexpr (std::is_integral_v<T>) { 44 value_ = static_cast<int64_t>(value); 45 // NOLINTNEXTLINE(readability-braces-around-statements, readability-misleading-indentation) 46 } else if constexpr (std::is_same_v<T, double>) { 47 value_ = bit_cast<int64_t>(value); 48 // NOLINTNEXTLINE(readability-braces-around-statements, readability-misleading-indentation) 49 } else if constexpr (std::is_same_v<T, float>) { 50 value_ = bit_cast<int32_t>(value); 51 } else if constexpr (std::is_pointer_v<T> && std::is_base_of_v<ObjectHeader, std::remove_pointer_t<T>>) { 52 value_ = static_cast<ObjectHeader *>(value); 53 } else { // NOLINTNEXTLINE(readability-misleading-indentation) 54 value_ = value; 55 } 56 } 57 58 template <class T> GetAs() const59 T GetAs() const 60 { 61 static_assert(std::is_integral_v<T>, "T must be integral type"); 62 ASSERT(IsPrimitive()); 63 return static_cast<T>(std::get<0>(value_)); 64 } 65 66 int64_t GetAsLong() const; 67 IsReference() const68 bool IsReference() const 69 { 70 return std::holds_alternative<ObjectHeader *>(value_); 71 } 72 IsPrimitive() const73 bool IsPrimitive() const 74 { 75 return std::holds_alternative<int64_t>(value_); 76 } 77 GetGCRoot()78 ObjectHeader **GetGCRoot() 79 { 80 ASSERT(IsReference()); 81 return &std::get<ObjectHeader *>(value_); 82 } 83 84 template <class VRegisterRef> FromVReg(VRegisterRef vreg)85 static ALWAYS_INLINE Value FromVReg(VRegisterRef vreg) 86 { 87 if (vreg.HasObject()) { 88 return Value(vreg.GetReference()); 89 } 90 return Value(vreg.GetValue()); 91 } 92 93 private: 94 std::variant<int64_t, ObjectHeader *> value_; 95 }; 96 97 } // namespace ark 98 99 #endif // PANDA_RUNTIME_VALUE_H_ 100