📄 fields.c
字号:
/*0001*//*
/*0002./ * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
/*0003./ *
/*0004./ * This software is the confidential and proprietary information of Sun
/*0005./ * Microsystems, Inc. ("Confidential Information"). You shall not
/*0006./ * disclose such Confidential Information and shall use it only in
/*0007./ * accordance with the terms of the license agreement you entered into
/*0008./ * with Sun.
/*0009./ *
/*0010./ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
/*0011./ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/*0012./ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/*0013./ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
/*0014./ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
/*0015./ * THIS SOFTWARE OR ITS DERIVATIVES.
/*0016./ *
/*0017./ */
/*0018*/
/*0019*//*=========================================================================
/*0020./ * SYSTEM: KVM
/*0021./ * SUBSYSTEM: Internal runtime structures
/*0022./ * FILE: fields.c
/*0023./ * OVERVIEW: Internal runtime structures for storing different kinds
/*0024./ * of fields (constants, variables, methods, interfaces).
/*0025./ * Tables of these fields are created every time a new class
/*0026./ * is loaded into the virtual machine.
/*0027./ * AUTHOR: Antero Taivalsaari, Sun Labs
/*0028./ * Edited by Doug Simon 11/1998
/*0029./ * Sheng Liang, Frank Yellin
/*0030./ *=======================================================================*/
/*0031*/
/*0032*//*=========================================================================
/*0033./ * Include files
/*0034./ *=======================================================================*/
/*0035*/
/*0036*/#include <global.h>
/*0037*/
/*0038*//*=========================================================================
/*0039./ * Static variables and definitions (specific to this file)
/*0040./ *=======================================================================*/
/*0041*/
/*0042*/static void change_Key_to_MethodSignatureInternal(unsigned char**, char**);
/*0043*/static void change_MethodSignature_to_KeyInternal(CONST_CHAR_HANDLE,
/*0044*/ int *offsetP,
/*0045*/ unsigned char **to);
/*0046*/
/*0047*//*=========================================================================
/*0048./ * Operations on field and method tables
/*0049./ *=======================================================================*/
/*0050*/
/*0051*//*=========================================================================
/*0052./ * FUNCTION: lookupField()
/*0053./ * TYPE: public instance-level operation
/*0054./ * OVERVIEW: Find a field table entry with the given field name.
/*0055./ * INTERFACE:
/*0056./ * parameters: class pointer, field name pointer
/*0057./ * returns: pointer to the field or NIL
/*0058./ *=======================================================================*/
/*0059*/
/*0060*/FIELD lookupField(INSTANCE_CLASS thisClass, NameTypeKey key) {
/*0061*/ do {
/*0062*/ FIELDTABLE fieldTable = thisClass->fieldTable;
/*0063*/ /* Get the length of the field table */
/*0064*/ FOR_EACH_FIELD(thisField, fieldTable)
/*0065*/ if (thisField->nameTypeKey.i == key.i) {
/*0066*/ return thisField;
/*0067*/ }
/*0068*/ END_FOR_EACH_FIELD
/*0069*/ thisClass = thisClass->superClass;
/*0070*/ } while (thisClass != NULL);
/*0071*/ return NULL;
/*0072*/}
/*0073*/
/*0074*//*=========================================================================
/*0075./ * FUNCTION: lookupMethod()
/*0076./ * TYPE: public instance-level operation
/*0077./ * OVERVIEW: Find a method table entry with the given name and type
/*0078./ * using a simple linear lookup strategy.
/*0079./ * INTERFACE:
/*0080./ * parameters: class pointer, method name and signature pointers
/*0081./ * returns: pointer to the method or NIL
/*0082./ *
/*0083./ * NOTES: This is a naive implementation with linear search.
/*0084./ * In most cases this does not matter, however, since
/*0085./ * inline caching (turning ENABLEFASTBYTECODES on)
/*0086./ * allows us to avoid the method lookup overhead.
/*0087./ *=======================================================================*/
/*0088*/
/*0089*/METHOD lookupMethod(CLASS thisClass, NameTypeKey key,
/*0090*/ INSTANCE_CLASS currentClass)
/*0091*/{
/*0092*/ INSTANCE_CLASS thisInstanceClass =
/*0093*/ IS_ARRAY_CLASS(thisClass) ? JavaLangObject : (INSTANCE_CLASS)thisClass;
/*0094*/ do {
/*0095*/ METHODTABLE methodTable = thisInstanceClass->methodTable;
/*0096*/ FOR_EACH_METHOD(thisMethod, methodTable)
/*0097*/ if (thisMethod->nameTypeKey.i == key.i) {
/*0098*/ if ( currentClass == NULL
/*0099*/ || currentClass == thisInstanceClass
/*0100*/ || ((ACC_PUBLIC|ACC_PROTECTED) & thisMethod->accessFlags)
/*0101*/ || ( ((thisMethod->accessFlags & ACC_PRIVATE) == 0)
/*0102*/ && thisInstanceClass->clazz.packageName ==
/*0103*/ currentClass->clazz.packageName)
/*0104*/ ) {
/*0105*/ return thisMethod;
/*0106*/ }
/*0107*/ }
/*0108*/ END_FOR_EACH_METHOD
/*0109*/ /* If the class has a superclass, look its methods as well */
/*0110*/ thisInstanceClass = thisInstanceClass->superClass;
/*0111*/ } while (thisInstanceClass != NULL);
/*0112*/
/*0113*/ /* Before we give up on an interface class, check any interfaces that
/*0114./ * it implements */
/*0115*/ if ((thisClass->accessFlags & ACC_INTERFACE)
/*0116*/ && (((INSTANCE_CLASS)thisClass)->ifaceTable != NULL)) {
/*0117*/ CONSTANTPOOL constantPool = ((INSTANCE_CLASS)thisClass)->constPool;
/*0118*/ unsigned short *ifaceTable = ((INSTANCE_CLASS)thisClass)->ifaceTable;
/*0119*/ int tableLength = ifaceTable[0];
/*0120*/ int i;
/*0121*/ for (i = 1; i <= tableLength; i++) {
/*0122*/ int cpIndex = ifaceTable[i];
/*0123*/ CLASS intf = constantPool->entries[cpIndex].clazz;
/*0124*/ METHOD temp = lookupMethod(intf, key, currentClass);
/*0125*/ if (temp != NULL) {
/*0126*/ return temp;
/*0127*/ }
/*0128*/ }
/*0129*/ }
/*0130*/ return NULL;
/*0131*/}
/*0132*/
/*0133*//*=========================================================================
/*0134./ * FUNCTION: getSpecialMethod()
/*0135./ * TYPE: public instance-level operation
/*0136./ * OVERVIEW: Find a specific special method (<clinit>, main)
/*0137./ * using a simple linear lookup strategy.
/*0138./ * INTERFACE:
/*0139./ * parameters: class pointer, method name and signature pointers
/*0140./ * returns: pointer to the method or NIL
/*0141./ *=======================================================================*/
/*0142*/
/*0143*/METHOD getSpecialMethod(INSTANCE_CLASS thisClass, NameTypeKey key)
/*0144*/{
/*0145*/ METHODTABLE methodTable = thisClass->methodTable;
/*0146*/ FOR_EACH_METHOD(thisMethod, methodTable)
/*0147*/ if ( (thisMethod->accessFlags & ACC_STATIC)
/*0148*/ && (thisMethod->nameTypeKey.i == key.i))
/*0149*/ return thisMethod;
/*0150*/ END_FOR_EACH_METHOD
/*0151*/ return NIL;
/*0152*/}
/*0153*/
/*0359*//*=========================================================================
/*0360./ * Internal operations on signatures
/*0361./ *=======================================================================*/
/*0362*/
/*0363*//*=========================================================================
/*0364./ * FUNCTION: change_Key_to_FieldSignature()
/*0365./ * change_Key_to_FieldSignature_inBuffer()
/*0366./ *
/*0367./ * TYPE: public instance-level operation on runtime classes
/*0368./ * OVERVIEW: Converts a FieldType key to its actual signature
/*0369./ *
/*0370./ * INTERFACE:
/*0371./ * parameters: key: An existing FieldType key
/*0372./ * resultBuffer: Where to put the result
/*0373./ *
/*0374./ * returns: getClassName() returns a pointer to the result
/*0375./ * getClassName_inBuffer() returns a pointer to the NULL
/*0376./ * at the end of the result. The result is in the
/*0377./ * passed buffer.
/*0378./ *
/*0379./ * DANGER: change_Key_to_FieldSignature_inBuffer() doesn't return what you
/*0380./ * expect.
/*0381./ *
/*0382./ *=======================================================================*/
/*0383*/
/*0384*/char *
/*0385*/change_Key_to_FieldSignature(FieldTypeKey key) {
/*0386*/ char *endBuffer = change_Key_to_FieldSignature_inBuffer(key, str_buffer);
/*0387*/ int length = endBuffer - str_buffer;
/*0388*/ char *result = mallocBytes(length + 1);
/*0389*/ memcpy(result, str_buffer, length);
/*0390*/ result[length] = 0;
/*0391*/ return result;
/*0392*/}
/*0393*/
/*0394*/char* /* returns end of buffer */
/*0395*/change_Key_to_FieldSignature_inBuffer(FieldTypeKey key, char *resultBuffer) {
/*0396*/ char *p = resultBuffer;
/*0397*/ int depth = key >> FIELD_KEY_ARRAY_SHIFT;
/*0398*/ FieldTypeKey baseClassKey = key & 0x1FFF;
/*0399*/ if (depth == MAX_FIELD_KEY_ARRAY_DEPTH) {
/*0400*/ /* just use whatever the real classname is */
/*0401*/ return getClassName_inBuffer(change_Key_to_CLASS(key), resultBuffer);
/*0402*/ }
/*0403*/ if (depth > 0) {
/*0404*/ memset(p, '[', depth);
/*0405*/ p += depth;
/*0406*/ }
/*0407*/ if (baseClassKey <= 255) {
/*0408*/ *p++ = (char)baseClassKey;
/*0409*/ } else {
/*0410*/ *p++ = 'L';
/*0411*/ p = getClassName_inBuffer(change_Key_to_CLASS(baseClassKey), p);
/*0412*/ *p++ = ';';
/*0413*/ }
/*0414*/ *p = '\0';
/*0415*/ return p;
/*0416*/}
/*0417*/
/*0418*//*=========================================================================
/*0419./ * FUNCTION: change_Key_to_MethodSignature()
/*0420./ * change_Key_to_MethodSignature_inBuffer()
/*0421./ *
/*0422./ * TYPE: public instance-level operation on runtime classes
/*0423./ * OVERVIEW: Converts a MethodType key to its actual signature
/*0424./ *
/*0425./ * INTERFACE:
/*0426./ * parameters: key: An existing MethodType key
/*0427./ * resultBuffer: Where to put the result
/*0428./ *
/*0429./ * returns: getClassName() returns a pointer to the result
/*0430./ * getClassName_inBuffer() returns a pointer to the NULL
/*0431./ * at the end of the result. The result is in the
/*0432./ * passed buffer.
/*0433./ *
/*0434./ * DANGER: change_Key_to_MethodSignature_inBuffer() doesn't return what you
/*0435./ * expect.
/*0436./ *
/*0437./ * DANGER: change_Key_to_MethodSignature() allocates a byte array, and marks
/*0438./ * this array as a temporary root. This function should only be
/*0439./ * called inside START_TEMPORARY_ROOTS ... END_TEMPORARY_ROOTS
/*0440./ *
/*0441./ * NOTE: The algorithm for converting a method signature to a key is
/*0442./ * explained in the documentation below for change_MethodSignature_to_Key()
/*0443./ *=======================================================================*/
/*0444*/
/*0445*/char *
/*0446*/change_Key_to_MethodSignature(MethodTypeKey key)
/*0447*/{
/*0448*/ char *endBuffer = change_Key_to_MethodSignature_inBuffer(key, str_buffer);
/*0449*/ int length = endBuffer - str_buffer;
/*0450*/ char *result = mallocBytes(length + 1);
/*0451*/ memcpy(result, str_buffer, length);
/*0452*/ result[length] = 0;
/*0453*/ return result;
/*0454*/}
/*0455*/
/*0456*/char* /* returns end of string */
/*0457*/change_Key_to_MethodSignature_inBuffer(MethodTypeKey key, char *resultBuffer) {
/*0458*/ int codedSignatureLength;
/*0459*/ unsigned char *codedSignature =
/*0460*/ (unsigned char *)change_Key_to_Name(key, &codedSignatureLength);
/*0461*/
/*0462*/ unsigned char *from = codedSignature; /* for parsing the codedSignature */
/*0463*/ char *to = resultBuffer; /* for writing to the result */
/*0464*/
/*0465*/ int argCount = *from++; /* the first byte is the arg count */
/*0466*/
/*0467*/ *to++ = '('; /* message signatures start with '(' */
/*0468*/
/*0469*/ /* Parse the coded signature one argument at a time, and put the
/*0470./ * resulting signature into the result. "from" and "to" are updated.
/*0471./ */
/*0472*/ while (--argCount >= 0) {
/*0473*/ change_Key_to_MethodSignatureInternal(&from, &to);
/*0474*/ }
/*0475*/
/*0476*/ /* Now output the closing ')' */
/*0477*/ *to++ = ')';
/*0478*/
/*0479*/ /* And the return type */
/*0480*/ change_Key_to_MethodSignatureInternal(&from, &to);
/*0481*/
/*0482*/ /* And the closing NULL */
/*0483*/ *to = '\0';
/*0484*/
/*0485*/ /* Return the end of the string */
/*0486*/ return to;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -