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_FIELD_H_
16 #define PANDA_RUNTIME_FIELD_H_
17 
18 #include <cstdint>
19 #include <atomic>
20 
21 #include "intrinsics_enum.h"
22 #include "libpandafile/file.h"
23 #include "libpandafile/file_items.h"
24 #include "libpandafile/modifiers.h"
25 #include "runtime/include/compiler_interface.h"
26 #include "runtime/include/class_helper.h"
27 #include "runtime/include/value-inl.h"
28 #include "libpandabase/macros.h"
29 
30 namespace ark {
31 
32 class Class;
33 
34 class ClassLinkerErrorHandler;
35 
36 class Field {
37 public:
38     using UniqId = uint64_t;
39 
Field(Class *klass, panda_file::File::EntityId fileId, uint32_t accessFlags, panda_file::Type type)40     Field(Class *klass, panda_file::File::EntityId fileId, uint32_t accessFlags, panda_file::Type type)
41         : classWord_(static_cast<ClassHelper::ClassWordSize>(ToObjPtrType(klass))), fileId_(fileId)
42     {
43         accessFlags_ = accessFlags | (static_cast<uint32_t>(type.GetEncoding()) << ACC_TYPE_SHIFT);
44     }
45 
GetClass() const46     Class *GetClass() const
47     {
48         return reinterpret_cast<Class *>(classWord_);
49     }
50 
SetClass(Class *cls)51     void SetClass(Class *cls)
52     {
53         classWord_ = static_cast<ClassHelper::ClassWordSize>(ToObjPtrType(cls));
54     }
55 
GetClassOffset()56     static constexpr uint32_t GetClassOffset()
57     {
58         return MEMBER_OFFSET(Field, classWord_);
59     }
60 
61     PANDA_PUBLIC_API const panda_file::File *GetPandaFile() const;
62 
GetFileId() const63     panda_file::File::EntityId GetFileId() const
64     {
65         return fileId_;
66     }
67 
GetAccessFlags() const68     uint32_t GetAccessFlags() const
69     {
70         return accessFlags_;
71     }
72 
GetOffset() const73     uint32_t GetOffset() const
74     {
75         return offset_;
76     }
77 
SetOffset(uint32_t offset)78     void SetOffset(uint32_t offset)
79     {
80         offset_ = offset;
81     }
82 
GetOffsetOffset()83     static constexpr uint32_t GetOffsetOffset()
84     {
85         return MEMBER_OFFSET(Field, offset_);
86     }
87 
88     PANDA_PUBLIC_API Class *ResolveTypeClass(ClassLinkerErrorHandler *errorHandler = nullptr) const;
89 
GetType() const90     panda_file::Type GetType() const
91     {
92         return panda_file::Type(GetTypeId());
93     }
94 
GetTypeId() const95     panda_file::Type::TypeId GetTypeId() const
96     {
97         return static_cast<panda_file::Type::TypeId>((accessFlags_ & ACC_TYPE) >> ACC_TYPE_SHIFT);
98     }
99 
GetAccessFlagsOffset()100     static constexpr uint32_t GetAccessFlagsOffset()
101     {
102         return MEMBER_OFFSET(Field, accessFlags_);
103     }
104 
105     PANDA_PUBLIC_API panda_file::File::StringData GetName() const;
106 
IsPublic() const107     bool IsPublic() const
108     {
109         return (accessFlags_ & ACC_PUBLIC) != 0;
110     }
111 
IsPrivate() const112     bool IsPrivate() const
113     {
114         return (accessFlags_ & ACC_PRIVATE) != 0;
115     }
116 
IsProtected() const117     bool IsProtected() const
118     {
119         return (accessFlags_ & ACC_PROTECTED) != 0;
120     }
121 
IsStatic() const122     bool IsStatic() const
123     {
124         return (accessFlags_ & ACC_STATIC) != 0;
125     }
126 
IsVolatile() const127     bool IsVolatile() const
128     {
129         return (accessFlags_ & ACC_VOLATILE) != 0;
130     }
131 
IsFinal() const132     bool IsFinal() const
133     {
134         return (accessFlags_ & ACC_FINAL) != 0;
135     }
136 
IsReadonly() const137     bool IsReadonly() const
138     {
139         return (accessFlags_ & ACC_READONLY) != 0;
140     }
141 
CalcUniqId(const panda_file::File *file, panda_file::File::EntityId fileId)142     static inline UniqId CalcUniqId(const panda_file::File *file, panda_file::File::EntityId fileId)
143     {
144         constexpr uint64_t HALF = 32ULL;
145         uint64_t uid = file->GetFilenameHash();
146         uid <<= HALF;
147         uid |= fileId.GetOffset();
148         return uid;
149     }
150 
GetUniqId() const151     UniqId GetUniqId() const
152     {
153         return CalcUniqId(GetPandaFile(), fileId_);
154     }
155 
156     ~Field() = default;
157 
158     NO_COPY_SEMANTIC(Field);
159     NO_MOVE_SEMANTIC(Field);
160 
161 private:
162     ClassHelper::ClassWordSize classWord_;
163     panda_file::File::EntityId fileId_;
164     uint32_t accessFlags_;
165     uint32_t offset_ {0};
166 };
167 
168 }  // namespace ark
169 
170 #endif  // PANDA_RUNTIME_FIELD_H_
171