⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reflect.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * @(#)reflect.c	1.72 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * *//* * This entire file is conditionally compiled */#ifdef CVM_REFLECT#include "javavm/include/preloader.h"#include "javavm/include/reflect.h"#include "javavm/include/indirectmem.h"#include "javavm/include/localroots.h"#include "javavm/include/common_exceptions.h"#ifdef CVM_CLASSLOADING#include "javavm/include/constantpool.h"#endif#include "generated/offsets/java_lang_Class.h"#include "generated/offsets/java_lang_reflect_AccessibleObject.h"#include "generated/offsets/java_lang_reflect_Constructor.h"#include "generated/offsets/java_lang_reflect_Field.h"#include "generated/offsets/java_lang_reflect_Method.h"#include "generated/jni/java_lang_reflect_Modifier.h"/********************************************************************************* * * NOTE: * NOTE: documentation for all of these functions is in reflect.h. * NOTE: * **********************************************************************************//* * NOTE: These macros always walk from subclass towards superclass *//* * Field traversal macros */#define	WALK_DECLARED_FIELDS(cb, fb, body)				\{									\    int _i_, _list_count_ = CVMcbFieldCount(cb);			\    /* Walk in declared order */					\    for (_i_ = 0; _i_ < _list_count_; _i_++) {				\	CVMFieldBlock* fb = CVMcbFieldSlot(cb, _i_);			\	body;								\    }									\}#define	COUNT_DECLARED_FIELDS(cb, count)				\{									\    int _i_, _list_count_ = CVMcbFieldCount(cb);			\    /* Walk in reverse declared order */				\    for (_i_ = _list_count_ - 1; _i_ >= 0; _i_--) {			\        (count)++;							\    }									\}#define	WALK_INSTANCE_FIELDS(cb, fb, body)				\{									\    CVMClassBlock* _cb_;   				                \    for (_cb_ = cb; _cb_; _cb_ = CVMcbSuperclass(_cb_)) {		\	WALK_DECLARED_FIELDS(_cb_, fb, body);				\    }									\}/* Note that this does in fact traverse all static fields associated   with an interface's classblock because interfaces show up in their   own interface array. See classes.h for more details. */#define	WALK_INTERFACE_FIELDS(cb, fb, body)				\{									\    int _j_, _icnt_ = CVMcbInterfaceCount(cb);				\    int _declaredCnt_ = CVMcbImplementsCount(cb);			\    CVMClassBlock* _cb_;						\    /* Walk self interface first if this is an interface: */		\    if (CVMcbIs(cb, INTERFACE)) {					\        _cb_ = CVMcbInterfacecb(cb, _declaredCnt_);			\        WALK_DECLARED_FIELDS(_cb_, fb, body);				\    }									\    /* Walk from subinterface towards superinterface */			\    for (_j_ = 0; _j_ < _icnt_; _j_++) {				\        if (CVMcbIs(cb, INTERFACE) && (_j_ == _declaredCnt_)) {		\            continue; /* Skip the self interface. */          		\        }								\        _cb_ = CVMcbInterfacecb(cb,_j_);				\        WALK_DECLARED_FIELDS(_cb_, fb, body);				\    }									\}#define	COUNT_INTERFACE_FIELDS(cb, count)				\{									\    int _j_, _icnt_ = CVMcbInterfaceCount(cb);				\    /* Walk from subinterface towards superinterface */			\    for (_j_ = 0; _j_ < _icnt_; _j_++) {				\        CVMClassBlock* _cb_ = CVMcbInterfacecb(cb,_j_);			\        COUNT_DECLARED_FIELDS(_cb_, count);				\    }									\}/* * Method traversal macros */#define	WALK_DECLARED_METHODS(cb, mb, body)				\{									\    int _i_, _list_count_ = CVMcbMethodCount(cb);			\    /* Walk in declared order */					\    for (_i_ = 0; _i_ < _list_count_; _i_++) {				\	CVMMethodBlock *mb = CVMcbMethodSlot(cb, _i_);			\	body;								\    }									\}#define	WALK_INSTANCE_METHODS(cb, mb, body)				    \{									    \    int _tcnt_ = CVMcbMethodTableCount(cb), _i_;			    \    /* We don't have the strange invariant from JDK 1.2 that */		    \    /* slot 0 of the methodtable is empty */				    \    /* Walk from subtype towards supertype */				    \    for (_i_ = _tcnt_ - 1; _i_ >= 0; _i_--) {				    \	CVMMethodBlock* mb = CVMcbMethodTableSlot(cb,_i_);		    \	/* See CVMclassPrepareInterfaces() in for miranda method details */ \	if (CVMmbIsMiranda(mb)) {					    \	    if (!CVMmbMirandaIsNonPublic(mb)) {				    \		/* get the interface cb for miranda methods generated	    \		 * for unimplemented interfaces.	       		    \		 */							    \		mb = CVMmbMirandaInterfaceMb(mb);			    \	    } else {							    \		/* Skip miranda methods generated for non-public methods */ \		continue;						    \	    }								    \	}								    \	body;								    \    }									    \}#define	WALK_SUPER_METHODS(cb, mb, body)				\{									\    CVMClassBlock* _cb_;    						\    for (_cb_ = (cb);  _cb_ != NULL; _cb_ = CVMcbSuperclass(_cb_)) {    \	WALK_DECLARED_METHODS(_cb_, mb, body);				\    }									\}/* NOTE that upon first examination this macro might appear not to   work, but instead to miss the methods declared in this interface.   However, it does in fact work as expected, for two reasons. First,   each interface contains a reference to itself in its implemented   interfaces table. Second, the implemented interfaces table always   contains a flattened version of the interface hierarchy (for both   classes and interfaces), so recursion is never necessary in this   traversal. See classes.h (the interfaces member of CVMClassBlock)   for more details. */#define	WALK_INTERFACE_METHODS(cb, mb, body)				\{									\    int _icnt_ = CVMcbInterfaceCount(cb), _j_;				\    int _declaredCnt_ = CVMcbImplementsCount(cb);			\    CVMClassBlock* _cb_;						\    CVMassert(CVMcbIs(cb, INTERFACE));                                  \    /* Walk self interface first: */					\    {									\        _cb_ = CVMcbInterfacecb(cb,_declaredCnt_);			\        WALK_DECLARED_METHODS(_cb_, mb, {				\	    /* The interface method <clinit> need not be public */	\    	    if (CVMmbIs(mb, PUBLIC)) {					\		body;							\	    }								\	});								\    }									\    /* Walk from subinterface towards superinterface */			\    for (_j_ = 0; _j_ < _icnt_; _j_++) {				\        if (_j_ == _declaredCnt_) {					\            continue; /* Skip the self interface. */          		\        }								\        _cb_ = CVMcbInterfacecb(cb,_j_);				\        WALK_DECLARED_METHODS(_cb_, mb, {				\	    /* The interface method <clinit> need not be public */	\    	    if (CVMmbIs(mb, PUBLIC)) {					\		body;							\	    }								\	});								\    }									\}CVMBool CVMreflectEnsureInitialized(CVMExecEnv* ee, CVMClassBlock* cb) {    CVMBool result;    CVMD_gcSafeExec(ee, {	JNIEnv* env = CVMexecEnv2JniEnv(ee);	/* 	 * CVMclassInit requires a JNI local frame so it can make method	 * calls using JNI.	 */	if (CVMjniPushLocalFrame(env, 4) == JNI_OK) {	    /* %comment c018 */	    result = CVMclassInit(ee, cb);	    CVMjniPopLocalFrame(env, NULL);	} else 	    result = CVM_FALSE;    });    return result;}voidCVMreflectFields(CVMExecEnv* ee,		 CVMClassBlock* cb,		 int which,		 CVMArrayOfRefICell* result){    CVMBool mustAbort = CVM_FALSE;    const CVMClassBlock* classJavaLangReflectField =	CVMsystemClass(java_lang_reflect_Field);    CVMInt32 j;    CVMInt32 count = 0;    if (CVMcbIs(cb, PRIMITIVE) ||	CVMisArrayClass(cb)) {	/* Allocate zero-length array of java.lang.reflect.Field objects */	/* Casting away const is safe here (see classes.h, runtime flags) */	CVMreflectNewArray(ee, (CVMClassBlock*) classJavaLangReflectField,			   0, (CVMArrayOfAnyTypeICell*) result);	return;    }    CVMreflectEnsureLinked(ee, cb);        switch (which) {    case REFLECT_MEMBER_PUBLIC: {	/* NOTE: this discrepancy between the treatment of interfaces	   and regular classes comes about because interfaces re-use	   their interface array as a flattened hierarchy of their	   superinterfaces and also contain themselves in that table.	   The reason for this self-reference is to make construction	   of a real class's interface array easier; it is then simply	   the concatenation of the interface arrays of all its	   implemented interfaces. See classes.h for more details. */		CVMBool isInterface = CVMcbIs(cb, INTERFACE);	if (!isInterface) {	    /* Don't double-count interface fields since interfaces	       are in their own interface arrays. */	    WALK_INSTANCE_FIELDS(cb, fb, {		/* count public class fields */		if (CVMfbIs(fb, PUBLIC))		    count++;	    });	}		/* all interface fields are public and accessible */	COUNT_INTERFACE_FIELDS(cb, count);		/* Allocate array of java.lang.reflect.Field objects */	/* Casting away const is safe here (see classes.h, runtime flags) */	CVMreflectNewArray(ee, (CVMClassBlock*) classJavaLangReflectField,			   count, (CVMArrayOfAnyTypeICell*) result);	if (CVMID_icellIsNull(result)) /* exception occurred */	    return;		j = count;		CVMID_localrootBegin(ee); {	    CVMID_localrootDeclare(CVMObjectICell, fieldICell);	    if (!isInterface) {		WALK_INSTANCE_FIELDS(cb, fb, {		    if (CVMfbIs(fb, PUBLIC)) {			CVMreflectNewJavaLangReflectField(ee, fb, fieldICell);			if (CVMID_icellIsNull(fieldICell)) { /* exception already								thrown */			    /* Must execute CVMID_localrootEnd() */			    mustAbort = CVM_TRUE;			    goto abort1;			}			j--;			CVMID_arrayWriteRef(ee, result, j, fieldICell);		    }		});	    }	    CVMwithAssertsOnly(count = j);	    j = 0;	    WALK_INTERFACE_FIELDS(cb, fb, {		CVMreflectNewJavaLangReflectField(ee, fb, fieldICell);		if (CVMID_icellIsNull(fieldICell)) { /* exception already							thrown */		    /* Must execute CVMID_localrootEnd() */		    mustAbort = CVM_TRUE;		    goto abort1;		}		CVMID_arrayWriteRef(ee, result, j, fieldICell);		j++;	    });	    CVMassert(j == count);	}     abort1:	CVMID_localrootEnd();	if (mustAbort)	    return;	break;	    } /* case REFLECT_MEMBER_PUBLIC */        case REFLECT_MEMBER_DECLARED: {	COUNT_DECLARED_FIELDS(cb, count);		/* Allocate array of java.lang.reflect.Field objects */	/* Casting away const is safe here (see classes.h, runtime flags) */	CVMreflectNewArray(ee, (CVMClassBlock*) classJavaLangReflectField,			   count, (CVMArrayOfAnyTypeICell*) result);	if (CVMID_icellIsNull(result)) /* exception occurred */	    return;		j = count;		CVMID_localrootBegin(ee); {	    CVMID_localrootDeclare(CVMObjectICell, fieldICell);	    WALK_DECLARED_FIELDS(cb, fb, {		CVMreflectNewJavaLangReflectField(ee, fb, fieldICell);		if (CVMID_icellIsNull(fieldICell)) { /* exception already							thrown */		    /* Must execute CVMID_localrootEnd() */		    mustAbort = CVM_TRUE;		    goto abort2;		}		j--;		CVMID_arrayWriteRef(ee, result, j, fieldICell);	    });	}     abort2:	CVMID_localrootEnd();	if (mustAbort)	    return;		CVMassert(j == 0);	break;	    } /* case REFLECT_MEMBER_DECLARED */        default:	CVMassert(CVM_FALSE);    }}voidCVMreflectField(CVMExecEnv* ee,		CVMClassBlock* cb,		const char* name,		int which,		CVMObjectICell* result){    CVMFieldTypeID nameCookie;    if (CVMcbIs(cb, PRIMITIVE) || CVMisArrayClass(cb)) {	CVMthrowNoSuchFieldException(ee, "attempt to find field of "				     "primitive or array class");	return;    }    CVMreflectEnsureLinked(ee, cb);    /*     * We need to use the "new" function, because the "lookup" function     * is only valid when we know that the type already exists.     */    nameCookie = CVMtypeidNewMembername(ee, name);    if (nameCookie == CVM_TYPEID_ERROR) {	/* Clear the exception. A new one will be thrown when the field	 * is not found. */	CVMclearLocalException(ee);    }        switch (which) {    case REFLECT_MEMBER_PUBLIC: {	CVMBool isInterface = CVMcbIs(cb, INTERFACE);	if (!isInterface) {	    WALK_INSTANCE_FIELDS(cb, fb, {		if (CVMfbIs(fb, PUBLIC) &&		    CVMtypeidIsSameName(nameCookie, CVMfbNameAndTypeID(fb))) {		    CVMreflectNewJavaLangReflectField(ee, fb, result);		    /* We don't need to check for throwing OutOfMemoryError		       since CVMreflectNewJavaLangReflectField does it 		       already */		    goto finish;		}	    });	}	WALK_INTERFACE_FIELDS(cb, fb, {	    if (CVMtypeidIsSameName(nameCookie, CVMfbNameAndTypeID(fb))) {		CVMreflectNewJavaLangReflectField(ee, fb, result);		/* We don't need to check for throwing OutOfMemoryError		   since CVMreflectNewJavaLangReflectField does it already */		goto finish;	    }	});	break;    }    case REFLECT_MEMBER_DECLARED: {	WALK_DECLARED_FIELDS(cb, fb, {	    if (CVMtypeidIsSameName(nameCookie, CVMfbNameAndTypeID(fb))) {		CVMreflectNewJavaLangReflectField(ee, fb, result);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -