handle MODULE and PACKAGE constant on the pool (module-info.class)

This commit is contained in:
Volker Berlin 2019-10-14 21:51:54 +02:00
parent e0659a7033
commit 833cd8c80a

View File

@ -1,124 +1,135 @@
/* /*
Copyright 2011 - 2017 Volker Berlin (i-net software) Copyright 2011 - 2019 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package de.inetsoftware.classparser; package de.inetsoftware.classparser;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
/** /**
* @author Volker Berlin * @author Volker Berlin
*/ */
public class ConstantPool { public class ConstantPool {
private final Object[] constantPool; private final Object[] constantPool;
/** /**
* http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4 * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4
* http://docs.oracle.com/javase/specs/jvms/se5.0/html/ClassFile.doc.html#20080 * http://docs.oracle.com/javase/specs/jvms/se5.0/html/ClassFile.doc.html#20080
* *
* @param input * @param input
* the stream of the class * the stream of the class
* @throws IOException * @throws IOException
* if any IO error occur * if any IO error occur
*/ */
ConstantPool( DataInputStream input ) throws IOException { ConstantPool( DataInputStream input ) throws IOException {
int count = input.readUnsignedShort(); int count = input.readUnsignedShort();
Object[] pool = constantPool = new Object[count]; Object[] pool = constantPool = new Object[count];
for( int i = 1; i < count; i++ ) { for( int i = 1; i < count; i++ ) {
byte type = input.readByte(); byte type = input.readByte();
switch( type ) { switch( type ) {
case 1: //CONSTANT_Utf8 case 1: //CONSTANT_Utf8
pool[i] = input.readUTF(); pool[i] = input.readUTF();
break; break;
case 3: //CONSTANT_Integer case 3: //CONSTANT_Integer
pool[i] = new Integer( input.readInt() ); pool[i] = new Integer( input.readInt() );
break; break;
case 4: //CONSTANT_Float case 4: //CONSTANT_Float
pool[i] = new Float( input.readFloat() ); pool[i] = new Float( input.readFloat() );
break; break;
case 5: //CONSTANT_Long case 5: //CONSTANT_Long
pool[i] = new Long( input.readLong() ); pool[i] = new Long( input.readLong() );
i++; i++;
break; break;
case 6: //CONSTANT_Double case 6: //CONSTANT_Double
pool[i] = new Double( input.readDouble() ); pool[i] = new Double( input.readDouble() );
i++; i++;
break; break;
case 7: //CONSTANT_Class case 7: //CONSTANT_Class
case 8: //CONSTANT_String case 8: //CONSTANT_String
pool[i] = new int[] { type, input.readUnsignedShort() }; case 19: // CONSTANT_Module
break; case 20: // CONSTANT_Package
case 9: //CONSTANT_Fieldref pool[i] = new int[] { type, input.readUnsignedShort() };
case 10: //CONSTANT_Methodref break;
case 11: //CONSTANT_InterfaceMethodref case 9: //CONSTANT_Fieldref
case 12: //CONSTANT_NameAndType case 10: //CONSTANT_Methodref
pool[i] = new int[] { type, input.readUnsignedShort(), input.readUnsignedShort() }; case 11: //CONSTANT_InterfaceMethodref
break; case 12: //CONSTANT_NameAndType
default: pool[i] = new int[] { type, input.readUnsignedShort(), input.readUnsignedShort() };
throw new IOException( "Unknown constant pool type: " + type ); break;
} default:
} throw new IOException( "Unknown constant pool type: " + type );
}
boolean repeat; }
do {
repeat = false; boolean repeat;
for( int i = 0; i < count; i++ ) { do {
if( pool[i] instanceof int[] ) { repeat = false;
int[] data = (int[])pool[i]; for( int i = 0; i < count; i++ ) {
switch( data[0] ) { if( pool[i] instanceof int[] ) {
case 7: //CONSTANT_Class int[] data = (int[])pool[i];
pool[i] = new ConstantClass( (String)pool[data[1]] ); switch( data[0] ) {
break; case 7: //CONSTANT_Class
case 8: //CONSTANT_String pool[i] = new ConstantClass( (String)pool[data[1]] );
pool[i] = pool[data[1]]; break;
break; case 8: //CONSTANT_String
case 9: //CONSTANT_Fieldref case 19: // CONSTANT_Module
if( pool[data[1]] instanceof int[] || pool[data[2]] instanceof int[] ) { case 20: // CONSTANT_Package
repeat = true; pool[i] = pool[data[1]];
} else { break;
pool[i] = new ConstantFieldRef( (ConstantClass)pool[data[1]], (ConstantNameAndType)pool[data[2]] ); case 9: //CONSTANT_Fieldref
} if( pool[data[1]] instanceof int[] || pool[data[2]] instanceof int[] ) {
break; repeat = true;
case 10: //CONSTANT_Methodref } else {
if( pool[data[1]] instanceof int[] || pool[data[2]] instanceof int[] ) { pool[i] = new ConstantFieldRef( (ConstantClass)pool[data[1]], (ConstantNameAndType)pool[data[2]] );
repeat = true; }
} else { break;
pool[i] = new ConstantMethodRef( (ConstantClass)pool[data[1]], (ConstantNameAndType)pool[data[2]] ); case 10: //CONSTANT_Methodref
} if( pool[data[1]] instanceof int[] || pool[data[2]] instanceof int[] ) {
break; repeat = true;
case 11: //CONSTANT_InterfaceMethodref } else {
if( pool[data[1]] instanceof int[] || pool[data[2]] instanceof int[] ) { pool[i] = new ConstantMethodRef( (ConstantClass)pool[data[1]], (ConstantNameAndType)pool[data[2]] );
repeat = true; }
} else { break;
pool[i] = new ConstantInterfaceRef( (ConstantClass)pool[data[1]], (ConstantNameAndType)pool[data[2]] ); case 11: //CONSTANT_InterfaceMethodref
} if( pool[data[1]] instanceof int[] || pool[data[2]] instanceof int[] ) {
break; repeat = true;
case 12: //CONSTANT_NameAndType } else {
pool[i] = new ConstantNameAndType( (String)pool[data[1]], (String)pool[data[2]] ); pool[i] = new ConstantInterfaceRef( (ConstantClass)pool[data[1]], (ConstantNameAndType)pool[data[2]] );
break; }
default: break;
throw new IOException( "Unknown constant pool type: " + data[0] ); case 12: //CONSTANT_NameAndType
} pool[i] = new ConstantNameAndType( (String)pool[data[1]], (String)pool[data[2]] );
} break;
} default:
} while( repeat ); throw new IOException( "Unknown constant pool type: " + data[0] );
} }
}
public Object get( int index ) { }
return constantPool[index]; } while( repeat );
} }
}
/**
* Get a object from the pool at the given index.
*
* @param index
* the index
* @return the object
*/
public Object get( int index ) {
return constantPool[index];
}
}