xref: /aosp_15_r20/art/runtime/dex/dex_file_annotations.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_DEX_DEX_FILE_ANNOTATIONS_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_DEX_DEX_FILE_ANNOTATIONS_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h"
21*795d594fSAndroid Build Coastguard Worker #include "handle.h"
22*795d594fSAndroid Build Coastguard Worker #include "mirror/dex_cache.h"
23*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array.h"
24*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker namespace mirror {
29*795d594fSAndroid Build Coastguard Worker class ClassLoader;
30*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
31*795d594fSAndroid Build Coastguard Worker class ArtField;
32*795d594fSAndroid Build Coastguard Worker class ArtMethod;
33*795d594fSAndroid Build Coastguard Worker class ClassLinker;
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker namespace annotations {
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker // Field annotations.
38*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForField(ArtField* field,
39*795d594fSAndroid Build Coastguard Worker                                              Handle<mirror::Class> annotation_class)
40*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
41*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForField(ArtField* field)
42*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
43*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForField(ArtField* field)
44*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
45*795d594fSAndroid Build Coastguard Worker bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class)
46*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
47*795d594fSAndroid Build Coastguard Worker 
48*795d594fSAndroid Build Coastguard Worker // Method annotations.
49*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationDefaultValue(ArtMethod* method)
50*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
51*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForMethod(ArtMethod* method,
52*795d594fSAndroid Build Coastguard Worker                                               Handle<mirror::Class> annotation_class)
53*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
54*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForMethod(ArtMethod* method)
55*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
56*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetExceptionTypesForMethod(ArtMethod* method)
57*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
58*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetParameterAnnotations(ArtMethod* method)
59*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
60*795d594fSAndroid Build Coastguard Worker uint32_t GetNumberOfAnnotatedMethodParameters(ArtMethod* method)
61*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
62*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForMethodParameter(ArtMethod* method,
63*795d594fSAndroid Build Coastguard Worker                                                        uint32_t parameter_idx,
64*795d594fSAndroid Build Coastguard Worker                                                        Handle<mirror::Class> annotation_class)
65*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
66*795d594fSAndroid Build Coastguard Worker bool GetParametersMetadataForMethod(
67*795d594fSAndroid Build Coastguard Worker     ArtMethod* method,
68*795d594fSAndroid Build Coastguard Worker     /*out*/ MutableHandle<mirror::ObjectArray<mirror::String>>* names,
69*795d594fSAndroid Build Coastguard Worker     /*out*/ MutableHandle<mirror::IntArray>* access_flags) REQUIRES_SHARED(Locks::mutator_lock_);
70*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForMethod(
71*795d594fSAndroid Build Coastguard Worker     ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
72*795d594fSAndroid Build Coastguard Worker // Check whether `method` is annotated with `annotation_class`.
73*795d594fSAndroid Build Coastguard Worker // If `lookup_in_resolved_boot_classes` is true, look up any of the
74*795d594fSAndroid Build Coastguard Worker // method's annotations' classes in the bootstrap class loader's
75*795d594fSAndroid Build Coastguard Worker // resolved types; if it is false (default value), resolve them as a
76*795d594fSAndroid Build Coastguard Worker // side effect.
77*795d594fSAndroid Build Coastguard Worker bool IsMethodAnnotationPresent(ArtMethod* method,
78*795d594fSAndroid Build Coastguard Worker                                Handle<mirror::Class> annotation_class,
79*795d594fSAndroid Build Coastguard Worker                                uint32_t visibility = DexFile::kDexVisibilityRuntime)
80*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker // Check whether a method from the `dex_file` with the given `method_index`
83*795d594fSAndroid Build Coastguard Worker // is annotated with @dalvik.annotation.optimization.FastNative or
84*795d594fSAndroid Build Coastguard Worker // @dalvik.annotation.optimization.CriticalNative with build visibility.
85*795d594fSAndroid Build Coastguard Worker // If yes, return the associated access flags, i.e. kAccFastNative or kAccCriticalNative.
86*795d594fSAndroid Build Coastguard Worker EXPORT uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file,
87*795d594fSAndroid Build Coastguard Worker                                                      const dex::ClassDef& class_def,
88*795d594fSAndroid Build Coastguard Worker                                                      uint32_t method_index);
89*795d594fSAndroid Build Coastguard Worker // An overload of `GetNativeMethodAnnotationAccessFlags()` that takes a `MethodAnnotationsItem`.
90*795d594fSAndroid Build Coastguard Worker uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file,
91*795d594fSAndroid Build Coastguard Worker                                               const dex::MethodAnnotationsItem& method_annotations);
92*795d594fSAndroid Build Coastguard Worker // Is the method from the `dex_file` with the given `field_index`
93*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.NeverCompile?
94*795d594fSAndroid Build Coastguard Worker EXPORT bool MethodIsNeverCompile(const DexFile& dex_file,
95*795d594fSAndroid Build Coastguard Worker                                  const dex::ClassDef& class_def,
96*795d594fSAndroid Build Coastguard Worker                                  uint32_t method_index);
97*795d594fSAndroid Build Coastguard Worker // An overload of `MethodIsNeverCompile()` that takes a `MethodAnnotationsItem`.
98*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverCompile(const DexFile& dex_file,
99*795d594fSAndroid Build Coastguard Worker                           const dex::MethodAnnotationsItem& method_annotations);
100*795d594fSAndroid Build Coastguard Worker // Is the method from the `dex_file` with the given `field_index`
101*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.NeverInline?
102*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverInline(const DexFile& dex_file,
103*795d594fSAndroid Build Coastguard Worker                          const dex::ClassDef& class_def,
104*795d594fSAndroid Build Coastguard Worker                          uint32_t method_index);
105*795d594fSAndroid Build Coastguard Worker // Is the field from the `dex_file` with the given `field_index`
106*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.ReachabilitySensitive?
107*795d594fSAndroid Build Coastguard Worker bool FieldIsReachabilitySensitive(const DexFile& dex_file,
108*795d594fSAndroid Build Coastguard Worker                                   const dex::ClassDef& class_def,
109*795d594fSAndroid Build Coastguard Worker                                   uint32_t field_index);
110*795d594fSAndroid Build Coastguard Worker // Is the method from the `dex_file` with the given `method_index`
111*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.ReachabilitySensitive?
112*795d594fSAndroid Build Coastguard Worker bool MethodIsReachabilitySensitive(const DexFile& dex_file,
113*795d594fSAndroid Build Coastguard Worker                                    const dex::ClassDef& class_def,
114*795d594fSAndroid Build Coastguard Worker                                    uint32_t method_index);
115*795d594fSAndroid Build Coastguard Worker // Does the method from the `dex_file` with the given `method_index` contain an access to a field
116*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.ReachabilitySensitive, or a call to a method
117*795d594fSAndroid Build Coastguard Worker // with that annotation?
118*795d594fSAndroid Build Coastguard Worker // Class_def is the class defining the method. We consider only accessses to classes or methods
119*795d594fSAndroid Build Coastguard Worker // declared in the static type of the corresponding object. We may overlook accesses to annotated
120*795d594fSAndroid Build Coastguard Worker // fields or methods that are in neither class_def nor a containing (outer) class.
121*795d594fSAndroid Build Coastguard Worker bool MethodContainsRSensitiveAccess(const DexFile& dex_file,
122*795d594fSAndroid Build Coastguard Worker                                     const dex::ClassDef& class_def,
123*795d594fSAndroid Build Coastguard Worker                                     uint32_t method_index);
124*795d594fSAndroid Build Coastguard Worker // Is the given class annotated with @dalvik.annotation.optimization.DeadReferenceSafe?
125*795d594fSAndroid Build Coastguard Worker bool HasDeadReferenceSafeAnnotation(const DexFile& dex_file,
126*795d594fSAndroid Build Coastguard Worker                                     const dex::ClassDef& class_def);
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker // Class annotations.
129*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForClass(Handle<mirror::Class> klass,
130*795d594fSAndroid Build Coastguard Worker                                       Handle<mirror::Class> annotation_class)
131*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
132*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForClass(Handle<mirror::Class> klass)
133*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
134*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetDeclaredClasses(Handle<mirror::Class> klass)
135*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
136*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetDeclaringClass(Handle<mirror::Class> klass)
137*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
138*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetEnclosingClass(Handle<mirror::Class> klass)
139*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
140*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetEnclosingMethod(Handle<mirror::Class> klass)
141*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
142*795d594fSAndroid Build Coastguard Worker bool GetInnerClass(Handle<mirror::Class> klass, /*out*/ ObjPtr<mirror::String>* name)
143*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
144*795d594fSAndroid Build Coastguard Worker bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags)
145*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
146*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForClass(
147*795d594fSAndroid Build Coastguard Worker     Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
148*795d594fSAndroid Build Coastguard Worker EXPORT const char* GetSourceDebugExtension(Handle<mirror::Class> klass)
149*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
150*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetNestHost(Handle<mirror::Class> klass)
151*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
152*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetNestMembers(Handle<mirror::Class> klass)
153*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
154*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> getRecordAnnotationElement(Handle<mirror::Class> klass,
155*795d594fSAndroid Build Coastguard Worker                                                   Handle<mirror::Class> array_class,
156*795d594fSAndroid Build Coastguard Worker                                                   const char* element_name)
157*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
158*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetPermittedSubclasses(Handle<mirror::Class> klass)
159*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
160*795d594fSAndroid Build Coastguard Worker bool IsClassAnnotationPresent(Handle<mirror::Class> klass,
161*795d594fSAndroid Build Coastguard Worker                               Handle<mirror::Class> annotation_class)
162*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker // Map back from a PC to the line number in a method.
165*795d594fSAndroid Build Coastguard Worker int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t rel_pc)
166*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker // Annotations iterator.
169*795d594fSAndroid Build Coastguard Worker class RuntimeEncodedStaticFieldValueIterator : public EncodedStaticFieldValueIterator {
170*795d594fSAndroid Build Coastguard Worker  public:
171*795d594fSAndroid Build Coastguard Worker   // A constructor meant to be called from runtime code.
RuntimeEncodedStaticFieldValueIterator(Handle<mirror::DexCache> dex_cache,Handle<mirror::ClassLoader> class_loader,ClassLinker * linker,const dex::ClassDef & class_def)172*795d594fSAndroid Build Coastguard Worker   RuntimeEncodedStaticFieldValueIterator(Handle<mirror::DexCache> dex_cache,
173*795d594fSAndroid Build Coastguard Worker                                          Handle<mirror::ClassLoader> class_loader,
174*795d594fSAndroid Build Coastguard Worker                                          ClassLinker* linker,
175*795d594fSAndroid Build Coastguard Worker                                          const dex::ClassDef& class_def)
176*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_)
177*795d594fSAndroid Build Coastguard Worker       : EncodedStaticFieldValueIterator(*dex_cache->GetDexFile(), class_def),
178*795d594fSAndroid Build Coastguard Worker         dex_cache_(dex_cache),
179*795d594fSAndroid Build Coastguard Worker         class_loader_(class_loader),
180*795d594fSAndroid Build Coastguard Worker         linker_(linker) {
181*795d594fSAndroid Build Coastguard Worker   }
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   template<bool kTransactionActive>
184*795d594fSAndroid Build Coastguard Worker   void ReadValueToField(ArtField* field) const REQUIRES_SHARED(Locks::mutator_lock_);
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker  private:
187*795d594fSAndroid Build Coastguard Worker   const Handle<mirror::DexCache> dex_cache_;  // Dex cache to resolve literal objects.
188*795d594fSAndroid Build Coastguard Worker   const Handle<mirror::ClassLoader> class_loader_;  // ClassLoader to resolve types.
189*795d594fSAndroid Build Coastguard Worker   ClassLinker* const linker_;  // Linker to resolve literal objects.
190*795d594fSAndroid Build Coastguard Worker   DISALLOW_IMPLICIT_CONSTRUCTORS(RuntimeEncodedStaticFieldValueIterator);
191*795d594fSAndroid Build Coastguard Worker };
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker enum class VisitorStatus : uint8_t { kVisitBreak, kVisitNext, kVisitInner };
194*795d594fSAndroid Build Coastguard Worker 
195*795d594fSAndroid Build Coastguard Worker class AnnotationVisitor {
196*795d594fSAndroid Build Coastguard Worker  public:
~AnnotationVisitor()197*795d594fSAndroid Build Coastguard Worker   virtual ~AnnotationVisitor() {}
198*795d594fSAndroid Build Coastguard Worker   virtual VisitorStatus VisitAnnotation(const char* annotation_descriptor, uint8_t visibility) = 0;
199*795d594fSAndroid Build Coastguard Worker   virtual VisitorStatus VisitAnnotationElement(const char* element_name,
200*795d594fSAndroid Build Coastguard Worker                                                uint8_t type,
201*795d594fSAndroid Build Coastguard Worker                                                const JValue& value) = 0;
202*795d594fSAndroid Build Coastguard Worker   virtual VisitorStatus VisitArrayElement(uint8_t depth,
203*795d594fSAndroid Build Coastguard Worker                                           uint32_t index,
204*795d594fSAndroid Build Coastguard Worker                                           uint8_t type,
205*795d594fSAndroid Build Coastguard Worker                                           const JValue& value) = 0;
206*795d594fSAndroid Build Coastguard Worker 
HasError()207*795d594fSAndroid Build Coastguard Worker   bool HasError() const { return has_error_; }
SetErrorMsg(const std::string & msg)208*795d594fSAndroid Build Coastguard Worker   void SetErrorMsg(const std::string& msg) {
209*795d594fSAndroid Build Coastguard Worker     DCHECK(!has_error_) << "Already had an error set. New error: " << msg
210*795d594fSAndroid Build Coastguard Worker                         << ", old error: " << error_msg_;
211*795d594fSAndroid Build Coastguard Worker     has_error_ = true;
212*795d594fSAndroid Build Coastguard Worker     error_msg_ = msg;
213*795d594fSAndroid Build Coastguard Worker   }
GetErrorMsg()214*795d594fSAndroid Build Coastguard Worker   const std::string& GetErrorMsg() const { return error_msg_; }
215*795d594fSAndroid Build Coastguard Worker 
216*795d594fSAndroid Build Coastguard Worker  protected:
217*795d594fSAndroid Build Coastguard Worker   // Whether we found an error while visiting the annotations. If true, `error_msg_` will contain
218*795d594fSAndroid Build Coastguard Worker   // the information about the error.
219*795d594fSAndroid Build Coastguard Worker   bool has_error_ = false;
220*795d594fSAndroid Build Coastguard Worker   std::string error_msg_;
221*795d594fSAndroid Build Coastguard Worker };
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker // Visit all annotation elements and array elements without creating
224*795d594fSAndroid Build Coastguard Worker // Arrays or Objects in the managed heap.
225*795d594fSAndroid Build Coastguard Worker void VisitClassAnnotations(Handle<mirror::Class> klass, AnnotationVisitor* visitor)
226*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
227*795d594fSAndroid Build Coastguard Worker 
228*795d594fSAndroid Build Coastguard Worker }  // namespace annotations
229*795d594fSAndroid Build Coastguard Worker 
230*795d594fSAndroid Build Coastguard Worker }  // namespace art
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_DEX_DEX_FILE_ANNOTATIONS_H_
233