📄 loader.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: Class loader
/*0022./ * FILE: loader.c
/*0023./ * OVERVIEW: Structures and operations needed for loading
/*0024./ * Java classfiles (class loader).
/*0025./ * AUTHOR: Antero Taivalsaari, Sun Labs
/*0026./ * Edited by Doug Simon 11/1998
/*0027./ * Extensive changes for spec-compliance by Sheng Liang
/*0028./ * Frank Yellin (lots of additional checks for JLS (Java
/*0029./ * Language Spec) compliance)
/*0030./ *=======================================================================*/
/*0031*/
/*0032*//*=========================================================================
/*0033./ * Include files
/*0034./ *=======================================================================*/
/*0035*/
/*0036*/#include <global.h>
/*0037*/
/*0038*//*=========================================================================
/*0039./ * Macros and constants
/*0040./ *=======================================================================*/
/*0041*/
/*0042*/#define STRING_POOL(i) (*((char **)(&StringPool->data[i])))
/*0043*/
/*0044*/#define RECOGNIZED_CLASS_FLAGS (ACC_PUBLIC | \
/*0045*/ ACC_FINAL | \
/*0046*/ ACC_SUPER | \
/*0047*/ ACC_INTERFACE | \
/*0048*/ ACC_ABSTRACT)
/*0049*/
/*0050*/#define RECOGNIZED_FIELD_FLAGS (ACC_PUBLIC | \
/*0051*/ ACC_PRIVATE | \
/*0052*/ ACC_PROTECTED | \
/*0053*/ ACC_STATIC | \
/*0054*/ ACC_FINAL | \
/*0055*/ ACC_VOLATILE | \
/*0056*/ ACC_TRANSIENT)
/*0057*/
/*0058*/#define RECOGNIZED_METHOD_FLAGS (ACC_PUBLIC | \
/*0059*/ ACC_PRIVATE | \
/*0060*/ ACC_PROTECTED | \
/*0061*/ ACC_STATIC | \
/*0062*/ ACC_FINAL | \
/*0063*/ ACC_SYNCHRONIZED | \
/*0064*/ ACC_NATIVE | \
/*0065*/ ACC_ABSTRACT )
/*0066*/
/*0067*//*=========================================================================
/*0068./ * Static functions (used only in this file)
/*0069./ *=======================================================================*/
/*0070*/
/*0071*/#if USESTATIC
/*0072*/static void moveClassFieldsToStatic(INSTANCE_CLASS CurrentClass);
/*0073*/#else
/*0074*/# define moveClassFieldsToStatic(CurrentClass)
/*0075*/#endif
/*0076*/
/*0077*/static void ignoreAttributes(FILEPOINTER_HANDLE ClassFile,
/*0078*/ POINTERLIST_HANDLE StringPool);
/*0079*/
/*0080*/static void NoClassDefFoundError(INSTANCE_CLASS thisClass);
/*0081*/
/*0082*//*=========================================================================
/*0083./ * Class file verification operations (performed during class loading)
/*0084./ *=======================================================================*/
/*0085*/
/*0086*//*=========================================================================
/*0087./ * FUNCTION: skipOverFieldName()
/*0088./ * TYPE: private class file load operation
/*0089./ * OVERVIEW: skip over a legal field name in a get a given string
/*0090./ * INTERFACE:
/*0091./ * parameters: string: a string in which the field name is skipped
/*0092./ * slash_okay: is '/' OK.
/*0093./ * length: length of the string
/*0094./ * returns: what's remaining after skipping the field name
/*0095./ *=======================================================================*/
/*0096*/
/*0097*/static const char *
/*0098*/skipOverFieldName(const char *string, bool_t slash_okay, unsigned short length)
/*0099*/{
/*0100*/ const char *p;
/*0101*/ unsigned short ch;
/*0102*/ unsigned short last_ch = 0;
/*0103*/ /* last_ch == 0 implies we are looking at the first char. */
/*0104*/ for (p = string; p != string + length; last_ch = ch) {
/*0105*/ const char *old_p = p;
/*0106*/ ch = *p;
/*0107*/ if (ch < 128) {
/*0108*/ p++;
/*0109*/ /* quick check for ascii */
/*0110*/ if ((ch >= 'a' && ch <= 'z') ||
/*0111*/ (ch >= 'A' && ch <= 'Z') ||
/*0112*/ (last_ch && ch >= '0' && ch <= '9')) {
/*0113*/ continue;
/*0114*/ }
/*0115*/ } else {
/*0116*/ /* KVM simplification: we give up checking for those Unicode
/*0117./ chars larger than 127. Otherwise we'll have to include a
/*0118./ couple of large Unicode tables, bloating the footprint by
/*0119./ 8~10K. */
/*0120*/ const char *tmp_p = p;
/*0121*/ ch = utf2unicode((const char**)&tmp_p);
/*0122*/ p = tmp_p;
/*0123*/ continue;
/*0124*/ }
/*0125*/
/*0126*/ if (slash_okay && ch == '/' && last_ch) {
/*0127*/ if (last_ch == '/') {
/*0128*/ return NULL; /* Don't permit consecutive slashes */
/*0129*/ }
/*0130*/ } else if (ch == '_' || ch == '$') {
/*0131*/ /* continue */
/*0132*/ } else {
/*0133*/ return last_ch ? old_p : NULL;
/*0134*/ }
/*0135*/ }
/*0136*/ return last_ch ? p : NULL;
/*0137*/}
/*0138*/
/*0139*//*=========================================================================
/*0140./ * FUNCTION: skipOverFieldType()
/*0141./ * TYPE: private class file load operation
/*0142./ * OVERVIEW: skip over a legal field signature in a get a given string
/*0143./ * INTERFACE:
/*0144./ * parameters: string: a string in which the field signature is skipped
/*0145./ * slash_okay: is '/' OK.
/*0146./ * length: length of the string
/*0147./ * returns: what's remaining after skipping the field signature
/*0148./ *=======================================================================*/
/*0149*/
/*0150*/static const char *
/*0151*/skipOverFieldType(const char *string, bool_t void_okay, unsigned short length)
/*0152*/{
/*0153*/ unsigned int depth = 0;
/*0154*/ for (;length > 0;) {
/*0155*/ switch (string[0]) {
/*0156*/ case 'V':
/*0157*/ if (!void_okay) return NULL;
/*0158*/ /* FALL THROUGH */
/*0159*/ case 'Z':
/*0160*/ case 'B':
/*0161*/ case 'C':
/*0162*/ case 'S':
/*0163*/ case 'I':
/*0164*/ case 'J':
/*0165*/#if IMPLEMENTS_FLOAT
/*0166*/ case 'F':
/*0167*/ case 'D':
/*0168*/#endif
/*0169*/ return string + 1;
/*0170*/
/*0171*/ case 'L': {
/*0172*/ /* Skip over the class name, if one is there. */
/*0173*/ const char *p = skipOverFieldName((const char *) (string + 1),
/*0174*/ TRUE, (unsigned short) (length - 1));
/*0175*/ /* The next character better be a semicolon. */
/*0176*/ if (p != NULL && p < string + length && p[0] == ';') {
/*0177*/ return p + 1;
/*0178*/ }
/*0179*/ return NULL;
/*0180*/ }
/*0181*/
/*0182*/ case '[':
/*0183*/ /* The rest of what's there better be a legal signature. */
/*0184*/ string++;
/*0185*/ length--;
/*0186*/ if (++depth == 256) {
/*0187*/ return NULL;
/*0188*/ }
/*0189*/ void_okay = FALSE;
/*0190*/ break;
/*0191*/
/*0192*/ default:
/*0193*/ return NULL;
/*0194*/ }
/*0195*/ }
/*0196*/ return NULL;
/*0197*/}
/*0198*/
/*0199*//*=========================================================================
/*0200./ * FUNCTION: getUTF8String()
/*0201./ * TYPE: private class file load operation
/*0202./ * OVERVIEW: get a UTF8 string from string pool, check index validity
/*0203./ * INTERFACE:
/*0204./ * parameters: String pool, index
/*0205./ * returns: Pointer to UTF8 string
/*0206./ *=======================================================================*/
/*0207*/
/*0208*/static char *
/*0209*/getUTF8String(POINTERLIST_HANDLE StringPoolH, unsigned short index)
/*0210*/{
/*0211*/ POINTERLIST StringPool = unhand(StringPoolH);
/*0212*/ if (index >= StringPool->length ||
/*0213*/ STRING_POOL(index) == NULL) {
/*0214*/ fatalError(KVM_MSG_BAD_UTF8_INDEX);
/*0215*/ }
/*0216*/ return STRING_POOL(index);
/*0217*/}
/*0218*/
/*0219*//*=========================================================================
/*0220./ * FUNCTION: verifyUTF8String()
/*0221./ * TYPE: private class file load operation
/*0222./ * OVERVIEW: validate a UTF8 string
/*0223./ * INTERFACE:
/*0224./ * parameters: pointer to UTF8 string
/*0225./ * returns: nothing
/*0226./ *=======================================================================*/
/*0227*/
/*0228*/static void
/*0229*/verifyUTF8String(char* bytes, unsigned short length)
/*0230*/{
/*0231*/ int i;
/*0232*/ for (i=0; i<length; i++) {
/*0233*/ unsigned int c = ((unsigned char *)bytes)[i];
/*0234*/ if (c == 0) /* no embedded zeros */
/*0235*/ goto failed;
/*0236*/ if (c < 128)
/*0237*/ continue;
/*0238*/ switch (c >> 4) {
/*0239*/ default:
/*0240*/ break;
/*0241*/
/*0242*/ case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
/*0243*/ goto failed;
/*0244*/
/*0245*/ case 0xC: case 0xD:
/*0246*/ /* 110xxxxx 10xxxxxx */
/*0247*/ i++;
/*0248*/ if (i >= length)
/*0249*/ goto failed;
/*0250*/ if ((bytes[i] & 0xC0) == 0x80)
/*0251*/ break;
/*0252*/ goto failed;
/*0253*/
/*0254*/ case 0xE:
/*0255*/ /* 1110xxxx 10xxxxxx 10xxxxxx */
/*0256*/ i += 2;
/*0257*/ if (i >= length)
/*0258*/ goto failed;
/*0259*/ if (((bytes[i-1] & 0xC0) == 0x80) &&
/*0260*/ ((bytes[i] & 0xC0) == 0x80))
/*0261*/ break;
/*0262*/ goto failed;
/*0263*/ } /* end of switch */
/*0264*/ }
/*0265*/ return;
/*0266*/
/*0267*/ failed:
/*0268*/ fatalError(KVM_MSG_BAD_UTF8_STRING);
/*0269*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -