classdecoder.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 531 行 · 第 1/2 页
JAVA
531 行
/**
* $Id: ClassDecoder.java,v 1.9 2004/02/24 08:04:15 epr Exp $
*/
package org.jnode.vm.classmgr;
import org.jnode.system.BootLog;
public final class ClassDecoder {
// ------------------------------------------
// VM ClassLoader Code
// ------------------------------------------
private static char[] ConstantValueAttrName;
private static char[] CodeAttrName;
private static char[] ExceptionsAttrName;
private static char[] LineNrTableAttrName;
//private static final Logger log = Logger.getLogger(ClassDecoder.class);
private static final void cl_init() {
if (ConstantValueAttrName == null) {
ConstantValueAttrName = "ConstantValue".toCharArray();
}
if (CodeAttrName == null) {
CodeAttrName = "Code".toCharArray();
}
if (ExceptionsAttrName == null) {
ExceptionsAttrName = "Exceptions".toCharArray();
}
if (LineNrTableAttrName == null) {
LineNrTableAttrName = "LineNumberTable".toCharArray();
}
}
/**
* Convert a class-file image into a Class object. Steps taken in this
* phase: 1. Decode the class-file image (CLS_LS_DECODED) 2. Load the
* super-class of the loaded class (CLS_LS_DEFINED) 3. Link the class so
* that the VMT is set and the offset of the non-static fields are set
* correctly.
*
* @param className
* @param data
* @param offset
* @param class_image_length
* @param rejectNatives
* @param clc
* @return The defined class
*/
public static final VmType defineClass(String className, byte[] data,
int offset, int class_image_length, boolean rejectNatives,
VmClassLoader clc) {
cl_init();
VmType cls = decodeClass(data, offset, class_image_length,
rejectNatives, clc);
return cls;
}
/**
* Decode a given class.
*
* @param data
* @param offset
* @param class_image_length
* @param rejectNatives
* @param clc
* @return The decoded class
* @throws ClassFormatError
*/
private static final VmType decodeClass(byte[] data, int offset,
int class_image_length, boolean rejectNatives, VmClassLoader clc)
throws ClassFormatError {
if (data == null) { throw new ClassFormatError(
"ClassDecoder.decodeClass: data==null"); }
final ClassReader reader = new ClassReader(data, offset,
class_image_length);
final VmStatics statics = clc.getStatics();
final int slotSize = clc.getArchitecture().getReferenceSize();
final int magic = reader.readu4();
if (magic != 0xCAFEBABE) { throw new ClassFormatError("invalid magic"); }
final int min_version = reader.readu2();
final int maj_version = reader.readu2();
if (false) {
BootLog.debug("Class file version " + maj_version + ";"
+ min_version);
}
final int cpcount = reader.readu2();
// allocate enough space for the CP
final byte[] tags = new byte[ cpcount];
final VmCP cp = new VmCP(cpcount);
for (int i = 1; i < cpcount; i++) {
final int tag = reader.readu1();
tags[ i] = (byte) tag;
switch (tag) {
case 1:
// Utf8
cp.setUTF8(i, new String(reader.readUTF()));
break;
case 3:
// int
cp.setInt(i, reader.readu4());
break;
case 4:
// float
cp.setInt(i, reader.readu4());
break;
case 5:
// long
cp.setLong(i, reader.readu8());
i++;
break;
case 6:
// double
cp.setLong(i, reader.readu8());
i++;
break;
case 7:
// class
cp.setConstClass(i, new VmConstClass(cp, reader.readu2()));
break;
case 8:
// String
cp.setInt(i, reader.readu2());
break;
case 9:
// Fieldref
{
final int clsIdx = reader.readu2();
final int ntIdx = reader.readu2();
cp.setConstFieldRef(i, new VmConstFieldRef(cp, clsIdx,
ntIdx));
}
break;
case 10:
// Methodref
{
final int clsIdx = reader.readu2();
final int ntIdx = reader.readu2();
cp.setConstMethodRef(i, new VmConstMethodRef(cp, clsIdx,
ntIdx));
}
break;
case 11:
// IMethodref
{
final int clsIdx = reader.readu2();
final int ntIdx = reader.readu2();
cp.setConstIMethodRef(i, new VmConstIMethodRef(cp, clsIdx,
ntIdx));
}
break;
case 12:
// Name and Type
{
final int nIdx = reader.readu2();
final int dIdx = reader.readu2();
cp.setConstNameAndType(i, new VmConstNameAndType(cp, nIdx,
dIdx));
}
break;
default:
throw new ClassFormatError("Invalid constantpool tag: "
+ tags[ i]);
}
}
// Now patch the required entries
for (int i = 1; i < cpcount; i++) {
switch (tags[ i]) {
case 8:
// String
final int idx = cp.getInt(i);
final int staticsIdx = statics.allocConstantStringField(cp
.getUTF8(idx));
cp.setString(i, new VmConstString(staticsIdx));
break;
}
}
final int classModifiers = reader.readu2();
final VmConstClass this_class = cp.getConstClass(reader.readu2());
final String clsName = this_class.getClassName();
final VmConstClass super_class = cp.getConstClass(reader.readu2());
final String superClassName;
if (super_class != null) {
superClassName = super_class.getClassName();
} else {
superClassName = null;
}
// Allocate the class object
final VmType cls;
if (Modifier.isInterface(classModifiers)) {
cls = new VmInterfaceClass(clsName, superClassName, clc,
classModifiers);
} else {
cls = new VmNormalClass(clsName, superClassName, clc,
classModifiers);
}
cls.setCp(cp);
// Interface table
readInterfaces(reader, cls, cp);
// Field table
readFields(reader, cls, cp, statics, slotSize);
// Method Table
readMethods(reader, rejectNatives, cls, cp, statics);
return cls;
}
/**
* Read the interfaces table
*
* @param reader
* @param cls
* @param cp
*/
private static void readInterfaces(ClassReader reader, VmType cls, VmCP cp) {
final int icount = reader.readu2();
if (icount > 0) {
final VmImplementedInterface[] itable = new VmImplementedInterface[ icount];
for (int i = 0; i < icount; i++) {
final VmConstClass icls = cp.getConstClass(reader.readu2());
itable[ i] = new VmImplementedInterface(icls.getClassName());
}
cls.setInterfaceTable(itable);
}
}
/**
* Read the fields table
*
* @param reader
* @param cls
* @param cp
* @param slotSize
*/
private static void readFields(ClassReader reader, VmType cls, VmCP cp,
VmStatics statics, int slotSize) {
final int fcount = reader.readu2();
if (fcount > 0) {
final VmField[] ftable = new VmField[ fcount];
int objectSize = 0;
for (int i = 0; i < fcount; i++) {
final boolean wide;
int modifiers = reader.readu2();
final String name = cp.getUTF8(reader.readu2());
final String signature = cp.getUTF8(reader.readu2());
switch (signature.charAt(0)) {
case 'J':
case 'D':
modifiers = modifiers | Modifier.ACC_WIDE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?