text: /*
   * Copyright (C) 2008 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  /*
   * Basic reflection calls and utility functions.
   */
  #ifndef _DALVIK_REFLECT_REFLECT
  #define _DALVIK_REFLECT_REFLECT
  
  bool dvmReflectStartup(void);
  bool dvmReflectProxyStartup(void);
  bool dvmReflectAnnotationStartup(void);
  void dvmReflectShutdown(void);
  
  /*
   * During startup, validate the "box" classes, e.g. java/lang/Integer.
   */
  bool dvmValidateBoxClasses();
  
  /*
   * Get all fields declared by a class.
   *
   * Includes both class and instance fields.
   */
  ArrayObject* dvmGetDeclaredFields(ClassObject* clazz, bool publicOnly);
  
  /*
   * Get all constructors declared by a class.
   */
  ArrayObject* dvmGetDeclaredConstructors(ClassObject* clazz, bool publicOnly);
  
  /*
   * Get all methods declared by a class.
   *
   * This includes both static and virtual methods, and can include private
   * members if "publicOnly" is false.  It does not include Miranda methods,
   * since those weren't declared in the class, or constructors.
   */
  ArrayObject* dvmGetDeclaredMethods(ClassObject* clazz, bool publicOnly);
  
  /*
   * Get all interfaces a class implements. If this is unable to allocate
   * the result array, this raises an OutOfMemoryError and returns NULL.
   */
  ArrayObject* dvmGetInterfaces(ClassObject* clazz);
  
  /*
   * Convert slot numbers back to objects.
   */
  Field* dvmSlotToField(ClassObject* clazz, int slot);
  Method* dvmSlotToMethod(ClassObject* clazz, int slot);
  
  /*
   * Convert a primitive value, performing a widening conversion if necessary.
   */
  int dvmConvertPrimitiveValue(PrimitiveType srcType,
      PrimitiveType dstType, const s4* srcPtr, s4* dstPtr);
  
  /*
   * Convert the argument to the specified type.
   *
   * Returns the width of the argument (1 for most types, 2 for J/D, -1 on
   * error).
   */
  int dvmConvertArgument(DataObject* arg, ClassObject* type, s4* ins);
  
  /*
   * Create a wrapper object for a primitive data type.  If "returnType" is
   * not primitive, this just returns "value" cast to an object.
   */
  DataObject* dvmWrapPrimitive(JValue value, ClassObject* returnType);
  
  /*
   * Unwrap a boxed primitive.  If "returnType" is not primitive, this just
   * returns "value" cast into a JValue.
   */
  bool dvmUnwrapPrimitive(Object* value, ClassObject* returnType,
      JValue* pResult);
  
  /*
   * Return the class object that matches the method's signature.  For
   * primitive types, returns the box class.
   */
  ClassObject* dvmGetBoxedReturnType(const Method* meth);
  
  /*
   * JNI reflection support.
   */
  Field* dvmGetFieldFromReflectObj(Object* obj);
  Method* dvmGetMethodFromReflectObj(Object* obj);
  Object* dvmCreateReflectObjForField(const ClassObject* clazz, Field* field);
  Object* dvmCreateReflectObjForMethod(const ClassObject* clazz, Method* method);
  
  /*
   * Quick test to determine if the method in question is a reflection call.
   * Used for some stack parsing.  Currently defined as "the method's declaring
   * class is java.lang.reflect.Method".
   */
  INLINE bool dvmIsReflectionMethod(const Method* method)
  {
      return (method->clazz == gDvm.classJavaLangReflectMethod);
  }
  
  /*
   * Proxy class generation.
   */
  ClassObject* dvmGenerateProxyClass(StringObject* str, ArrayObject* interfaces,
      Object* loader);
  
  /*
   * Create a new java.lang.reflect.Method object based on "meth".
   */
  Object* dvmCreateReflectMethodObject(const Method* meth);
  
  /*
   * Return an array of Annotation objects for the specified piece.  For method
   * parameters this is an array of arrays of Annotation objects.
   *
   * Method also applies to Constructor.
   */
  ArrayObject* dvmGetClassAnnotations(const ClassObject* clazz);
  ArrayObject* dvmGetMethodAnnotations(const Method* method);
  ArrayObject* dvmGetFieldAnnotations(const Field* field);
  ArrayObject* dvmGetParameterAnnotations(const Method* method);
  
  /*
   * Find the default value for an annotation member.
   */
  Object* dvmGetAnnotationDefaultValue(const Method* method);
  
  /*
   * Get the list of thrown exceptions for a method.  Returns NULL if there
   * are no exceptions listed.
   */
  ArrayObject* dvmGetMethodThrows(const Method* method);
  
  /*
   * Get the Signature annotation.
   */
  ArrayObject* dvmGetClassSignatureAnnotation(const ClassObject* clazz);
  ArrayObject* dvmGetMethodSignatureAnnotation(const Method* method);
  ArrayObject* dvmGetFieldSignatureAnnotation(const Field* field);
  
  /*
   * Get the EnclosingMethod attribute from an annotation.  Returns a Method
   * object, or NULL.
   */
  Object* dvmGetEnclosingMethod(const ClassObject* clazz);
  
  /*
   * Return clazz's declaring class, or NULL if there isn't one.
   */
  ClassObject* dvmGetDeclaringClass(const ClassObject* clazz);
  
  /*
   * Return clazz's enclosing class, or NULL if there isn't one.
   */
  ClassObject* dvmGetEnclosingClass(const ClassObject* clazz);
  
  /*
   * Get the EnclosingClass attribute from an annotation.  If found, returns
   * "true".  A String with the original name of the class and the original
   * access flags are returned through the arguments.  (The name will be NULL
   * for an anonymous inner class.)
   */
  bool dvmGetInnerClass(const ClassObject* clazz, StringObject** pName,
      int* pAccessFlags);
  
  /*
   * Get an array of class objects from the MemberClasses annotation.  Returns
   * NULL if none found.
   */
  ArrayObject* dvmGetDeclaredClasses(const ClassObject* clazz);
  
  /*
   * Used to pass values out of annotation (and encoded array) processing
   * functions.
   */
  typedef struct AnnotationValue {
      JValue  value;
      u1      type;
  } AnnotationValue;
  
  
  /**
   * Iterator structure for iterating over DexEncodedArray instances. The
   * structure should be treated as opaque.
   */
  typedef struct {
      const u1* cursor;                    /* current cursor */
      u4 elementsLeft;                     /* number of elements left to read */
      const DexEncodedArray* encodedArray; /* instance being iterated over */
      u4 size;                             /* number of elements in instance */
      const ClassObject* clazz;            /* class to resolve with respect to */
  } EncodedArrayIterator;
  
  /**
   * Initializes an encoded array iterator.
   * 
   * @param iterator iterator to initialize
   * @param encodedArray encoded array to iterate over
   * @param clazz class to use when resolving strings and types
   */
  void dvmEncodedArrayIteratorInitialize(EncodedArrayIterator* iterator,
          const DexEncodedArray* encodedArray, const ClassObject* clazz);
  
  /**
   * Returns whether there are more elements to be read.
   */
  bool dvmEncodedArrayIteratorHasNext(const EncodedArrayIterator* iterator);
  
  /**
   * Returns the next decoded value from the iterator, advancing its
   * cursor. This returns primitive values in their corresponding union
   * slots, and returns everything else (including nulls) as object
   * references in the "l" union slot.
   * 
   * The caller must call dvmReleaseTrackedAlloc() on any returned reference.
   * 
   * @param value pointer to store decoded value into
   * @returns true if a value was decoded and the cursor advanced; false if
   * the last value had already been decoded or if there was a problem decoding
   */
  bool dvmEncodedArrayIteratorGetNext(EncodedArrayIterator* iterator,
          AnnotationValue* value);
  
  #endif /*_DALVIK_REFLECT_REFLECT*/
  