• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 ES2PANDA_COMPILER_CHECKER_ETS_TYPE_CONVERTER_H
17 #define ES2PANDA_COMPILER_CHECKER_ETS_TYPE_CONVERTER_H
18 
19 #include "checker/types/typeFlag.h"
20 #include "checker/types/ets/types.h"
21 
22 namespace ark::es2panda::checker {
23 class ETSChecker;
24 
25 class TypeConverter {
26 public:
27     TypeConverter(ETSChecker *checker, TypeRelation *relation, Type *target, Type *source);
28     Type *Result() const;
29     void SetResult(Type *result);
30     Type *Source() const;
31     Type *Target() const;
32     TypeRelation *Relation() const;
33     ETSChecker *Checker() const;
34 
35     //  Function should be used ONLY if all the required checks were passed and
36     //  correct conversion is possible without accuracy loss!
37     template <typename SourceType, typename TargetType>
ConvertConstant(SourceType * source,ArenaAllocator * allocator)38     static TargetType *ConvertConstant(SourceType *source, ArenaAllocator *allocator)
39     {
40         if constexpr (std::is_same_v<std::decay_t<SourceType>, std::decay_t<TargetType>>) {
41             return source;
42         } else {
43             auto target = allocator->New<TargetType>(static_cast<typename TargetType::UType>(source->GetValue()));
44 
45             if constexpr (!std::is_same_v<std::decay_t<TargetType>, DoubleType> &&
46                           !std::is_same_v<std::decay_t<TargetType>, FloatType>) {
47                 ES2PANDA_ASSERT(source->GetValue() == static_cast<typename SourceType::UType>(target->GetValue()));
48             } else if constexpr (std::is_same_v<std::decay_t<SourceType>, DoubleType>) {
49                 ES2PANDA_ASSERT((std::is_same_v<std::decay_t<TargetType>, FloatType>));
50                 ES2PANDA_ASSERT(
51                     std::isnan(source->GetValue()) || std::isinf(source->GetValue()) ||
52                     (std::abs(source->GetValue()) <= static_cast<double>(std::numeric_limits<float>::max()) &&
53                      std::abs(source->GetValue()) >= static_cast<double>(std::numeric_limits<float>::min())));
54             }
55 
56             return target;
57         }
58     }
59 
60     //  Function should be used ONLY if all the required checks were passed and
61     //  correct conversion is possible without accuracy loss!
62     template <typename TargetType>
ConvertConstantType(Type * source,ArenaAllocator * allocator)63     static Type *ConvertConstantType(Type *source, ArenaAllocator *allocator)
64     {
65         switch (static_cast<TypeFlag>(source->TypeFlags() & (TypeFlag::ETS_NUMERIC | TypeFlag::CHAR))) {
66             case TypeFlag::INT:
67                 return ConvertConstant<IntType, TargetType>(source->AsIntType(), allocator);
68 
69             case TypeFlag::LONG:
70                 return ConvertConstant<LongType, TargetType>(source->AsLongType(), allocator);
71 
72             case TypeFlag::DOUBLE:
73                 return ConvertConstant<DoubleType, TargetType>(source->AsDoubleType(), allocator);
74 
75             case TypeFlag::SHORT:
76                 return ConvertConstant<ShortType, TargetType>(source->AsShortType(), allocator);
77 
78             case TypeFlag::FLOAT:
79                 return ConvertConstant<FloatType, TargetType>(source->AsFloatType(), allocator);
80 
81             case TypeFlag::BYTE:
82                 return ConvertConstant<ByteType, TargetType>(source->AsByteType(), allocator);
83 
84             case TypeFlag::CHAR:
85                 return ConvertConstant<CharType, TargetType>(source->AsCharType(), allocator);
86 
87             default:
88                 ES2PANDA_UNREACHABLE();
89         }
90     }
91 
92     //  Function should be used ONLY if all the required checks were passed and
93     //  correct conversion is possible without accuracy loss!
ConvertConstantTypes(Type * source,Type * target,ArenaAllocator * allocator)94     static Type *ConvertConstantTypes(Type *source, Type *target, ArenaAllocator *allocator)
95     {
96         ES2PANDA_ASSERT(source->IsETSPrimitiveType() && target->IsETSPrimitiveType() && source->IsConstantType());
97 
98         switch (static_cast<TypeFlag>(target->TypeFlags() & (TypeFlag::ETS_NUMERIC | TypeFlag::CHAR))) {
99             case TypeFlag::INT:
100                 return ConvertConstantType<IntType>(source, allocator);
101 
102             case TypeFlag::LONG:
103                 return ConvertConstantType<LongType>(source, allocator);
104 
105             case TypeFlag::DOUBLE:
106                 return ConvertConstantType<DoubleType>(source, allocator);
107 
108             case TypeFlag::SHORT:
109                 return ConvertConstantType<ShortType>(source, allocator);
110 
111             case TypeFlag::FLOAT:
112                 return ConvertConstantType<FloatType>(source, allocator);
113 
114             case TypeFlag::BYTE:
115                 return ConvertConstantType<ByteType>(source, allocator);
116 
117             case TypeFlag::CHAR:
118                 return ConvertConstantType<CharType>(source, allocator);
119 
120             default:
121                 ES2PANDA_UNREACHABLE();
122         }
123     }
124 
125 private:
126     ETSChecker *checker_;
127     TypeRelation *relation_;
128     Type *target_;
129     Type *source_;
130     Type *result_ {};
131 };
132 }  // namespace ark::es2panda::checker
133 
134 #endif
135