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
16 #ifndef PANDA_VERIFIER_ABSTRACT_TYPED_VALUE_HPP
17 #define PANDA_VERIFIER_ABSTRACT_TYPED_VALUE_HPP
18
19 #include "verification/type/type_type.h"
20 #include "verification/value/abstract_value.h"
21
22 #include "verification/value/origin.h"
23
24 #include "libpandafile/bytecode_instruction.h"
25
26 #include "macros.h"
27
28 namespace ark::verifier {
29 class AbstractTypedValue {
30 using ValueOrigin = Origin<ark::BytecodeInstructionSafe>;
31
32 public:
IsNone()33 bool IsNone() const
34 {
35 return type_.IsNone();
36 }
37 AbstractTypedValue() = default;
38 AbstractTypedValue(const AbstractTypedValue &) = default;
39 AbstractTypedValue(AbstractTypedValue &&) = default;
40 AbstractTypedValue &operator=(const AbstractTypedValue &) = default;
41 AbstractTypedValue &operator=(AbstractTypedValue &&) = default;
42 ~AbstractTypedValue() = default;
AbstractTypedValue(Type type,AbstractValue value)43 AbstractTypedValue(Type type, AbstractValue value) : value_ {std::move(value)}, type_ {type} {}
AbstractTypedValue(const AbstractTypedValue & atv,const ark::BytecodeInstructionSafe & inst)44 AbstractTypedValue(const AbstractTypedValue &atv, const ark::BytecodeInstructionSafe &inst)
45 : value_ {atv.value_}, type_ {atv.type_}, origin_ {inst}
46 {
47 }
AbstractTypedValue(Type type,AbstractValue value,const ark::BytecodeInstructionSafe & inst)48 AbstractTypedValue(Type type, AbstractValue value, const ark::BytecodeInstructionSafe &inst)
49 : value_ {std::move(value)}, type_ {type}, origin_ {inst}
50 {
51 }
AbstractTypedValue(Type type,AbstractValue value,ValueOrigin origin)52 AbstractTypedValue(Type type, AbstractValue value, ValueOrigin origin)
53 : value_ {std::move(value)}, type_ {type}, origin_ {std::move(origin)}
54 {
55 }
56 struct Start {};
AbstractTypedValue(Type type,AbstractValue value,Start start,size_t n)57 AbstractTypedValue(Type type, AbstractValue value, [[maybe_unused]] Start start, size_t n)
58 : value_ {std::move(value)}, type_ {type}, origin_ {OriginType::START, n}
59 {
60 }
SetAbstractType(Type type)61 AbstractTypedValue &SetAbstractType(Type type)
62 {
63 type_ = type;
64 return *this;
65 }
SetAbstractValue(const AbstractValue & value)66 AbstractTypedValue &SetAbstractValue(const AbstractValue &value)
67 {
68 value_ = value;
69 return *this;
70 }
GetAbstractType()71 Type GetAbstractType() const
72 {
73 return type_;
74 }
GetAbstractValue()75 const AbstractValue &GetAbstractValue() const
76 {
77 return value_;
78 }
IsConsistent()79 bool IsConsistent() const
80 {
81 return type_.IsConsistent();
82 }
GetOrigin()83 ValueOrigin &GetOrigin()
84 {
85 return origin_;
86 }
GetOrigin()87 const ValueOrigin &GetOrigin() const
88 {
89 return origin_;
90 }
ToString(TypeSystem const * tsys)91 PandaString ToString(TypeSystem const *tsys) const
92 {
93 // currently only types and origin printed
94 PandaString result {GetAbstractType().ToString(tsys)};
95 if (origin_.IsValid()) {
96 if (origin_.AtStart()) {
97 result += "@start";
98 } else {
99 result += "@" + OffsetToHexStr(origin_.GetOffset());
100 }
101 }
102 return result;
103 }
104
105 private:
106 AbstractValue value_;
107 Type type_;
108 ValueOrigin origin_;
109
110 friend AbstractTypedValue AtvJoin(AbstractTypedValue const * /* lhs */, AbstractTypedValue const * /* rhs */,
111 TypeSystem * /* tsys */);
112 };
113
AtvJoin(AbstractTypedValue const * lhs,AbstractTypedValue const * rhs,TypeSystem * tsys)114 inline AbstractTypedValue AtvJoin(AbstractTypedValue const *lhs, AbstractTypedValue const *rhs, TypeSystem *tsys)
115 {
116 if (lhs->origin_.IsValid() && rhs->origin_.IsValid() && lhs->origin_ == rhs->origin_) {
117 return {TpUnion(lhs->type_, rhs->GetAbstractType(), tsys), lhs->value_ & rhs->GetAbstractValue(), lhs->origin_};
118 }
119 return {TpUnion(lhs->type_, rhs->GetAbstractType(), tsys), lhs->value_ & rhs->GetAbstractValue()};
120 }
121
122 } // namespace ark::verifier
123
124 #endif // !PANDA_VERIFIER_ABSTRACT_TYPED_VALUE_HPP
125