|
Java example source code file (ConstantPool.java)
The ConstantPool.java Java example source code
/*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 in the LICENSE file that
* accompanied this code).
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.classfile;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
/**
* See JVMS, section 4.5.
*
* <p>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class ConstantPool {
public static class InvalidIndex extends ConstantPoolException {
private static final long serialVersionUID = -4350294289300939730L;
InvalidIndex(int index) {
super(index);
}
@Override
public String getMessage() {
// i18n
return "invalid index #" + index;
}
}
public static class UnexpectedEntry extends ConstantPoolException {
private static final long serialVersionUID = 6986335935377933211L;
UnexpectedEntry(int index, int expected_tag, int found_tag) {
super(index);
this.expected_tag = expected_tag;
this.found_tag = found_tag;
}
@Override
public String getMessage() {
// i18n?
return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
}
public final int expected_tag;
public final int found_tag;
}
public static class InvalidEntry extends ConstantPoolException {
private static final long serialVersionUID = 1000087545585204447L;
InvalidEntry(int index, int tag) {
super(index);
this.tag = tag;
}
@Override
public String getMessage() {
// i18n?
return "unexpected tag at #" + index + ": " + tag;
}
public final int tag;
}
public static class EntryNotFound extends ConstantPoolException {
private static final long serialVersionUID = 2885537606468581850L;
EntryNotFound(Object value) {
super(-1);
this.value = value;
}
@Override
public String getMessage() {
// i18n?
return "value not found: " + value;
}
public final Object value;
}
public static final int CONSTANT_Utf8 = 1;
public static final int CONSTANT_Integer = 3;
public static final int CONSTANT_Float = 4;
public static final int CONSTANT_Long = 5;
public static final int CONSTANT_Double = 6;
public static final int CONSTANT_Class = 7;
public static final int CONSTANT_String = 8;
public static final int CONSTANT_Fieldref = 9;
public static final int CONSTANT_Methodref = 10;
public static final int CONSTANT_InterfaceMethodref = 11;
public static final int CONSTANT_NameAndType = 12;
public static final int CONSTANT_MethodHandle = 15;
public static final int CONSTANT_MethodType = 16;
public static final int CONSTANT_InvokeDynamic = 18;
public static enum RefKind {
REF_getField(1, "getfield"),
REF_getStatic(2, "getstatic"),
REF_putField(3, "putfield"),
REF_putStatic(4, "putstatic"),
REF_invokeVirtual(5, "invokevirtual"),
REF_invokeStatic(6, "invokestatic"),
REF_invokeSpecial(7, "invokespecial"),
REF_newInvokeSpecial(8, "newinvokespecial"),
REF_invokeInterface(9, "invokeinterface");
public final int tag;
public final String name;
RefKind(int tag, String name) {
this.tag = tag;
this.name = name;
}
static RefKind getRefkind(int tag) {
switch(tag) {
case 1:
return REF_getField;
case 2:
return REF_getStatic;
case 3:
return REF_putField;
case 4:
return REF_putStatic;
case 5:
return REF_invokeVirtual;
case 6:
return REF_invokeStatic;
case 7:
return REF_invokeSpecial;
case 8:
return REF_newInvokeSpecial;
case 9:
return REF_invokeInterface;
default:
return null;
}
}
}
ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
int count = cr.readUnsignedShort();
pool = new CPInfo[count];
for (int i = 1; i < count; i++) {
int tag = cr.readUnsignedByte();
switch (tag) {
case CONSTANT_Class:
pool[i] = new CONSTANT_Class_info(this, cr);
break;
case CONSTANT_Double:
pool[i] = new CONSTANT_Double_info(cr);
i++;
break;
case CONSTANT_Fieldref:
pool[i] = new CONSTANT_Fieldref_info(this, cr);
break;
case CONSTANT_Float:
pool[i] = new CONSTANT_Float_info(cr);
break;
case CONSTANT_Integer:
pool[i] = new CONSTANT_Integer_info(cr);
break;
case CONSTANT_InterfaceMethodref:
pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
break;
case CONSTANT_InvokeDynamic:
pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);
break;
case CONSTANT_Long:
pool[i] = new CONSTANT_Long_info(cr);
i++;
break;
case CONSTANT_MethodHandle:
pool[i] = new CONSTANT_MethodHandle_info(this, cr);
break;
case CONSTANT_MethodType:
pool[i] = new CONSTANT_MethodType_info(this, cr);
break;
case CONSTANT_Methodref:
pool[i] = new CONSTANT_Methodref_info(this, cr);
break;
case CONSTANT_NameAndType:
pool[i] = new CONSTANT_NameAndType_info(this, cr);
break;
case CONSTANT_String:
pool[i] = new CONSTANT_String_info(this, cr);
break;
case CONSTANT_Utf8:
pool[i] = new CONSTANT_Utf8_info(cr);
break;
default:
throw new InvalidEntry(i, tag);
}
}
}
public ConstantPool(CPInfo[] pool) {
this.pool = pool;
}
public int size() {
return pool.length;
}
public int byteLength() {
int length = 2;
for (int i = 1; i < size(); ) {
CPInfo cpInfo = pool[i];
length += cpInfo.byteLength();
i += cpInfo.size();
}
return length;
}
public CPInfo get(int index) throws InvalidIndex {
if (index <= 0 || index >= pool.length)
throw new InvalidIndex(index);
CPInfo info = pool[index];
if (info == null) {
// this occurs for indices referencing the "second half" of an
// 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
throw new InvalidIndex(index);
}
return pool[index];
}
private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
CPInfo info = get(index);
if (info.getTag() != expected_type)
throw new UnexpectedEntry(index, expected_type, info.getTag());
return info;
}
public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
}
public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
}
public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
}
public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
return getUTF8Info(index).value;
}
public int getUTF8Index(String value) throws EntryNotFound {
for (int i = 1; i < pool.length; i++) {
CPInfo info = pool[i];
if (info instanceof CONSTANT_Utf8_info &&
((CONSTANT_Utf8_info) info).value.equals(value))
return i;
}
throw new EntryNotFound(value);
}
public Iterable<CPInfo> entries() {
return new Iterable<CPInfo>() {
public Iterator<CPInfo> iterator() {
return new Iterator<CPInfo>() {
public boolean hasNext() {
return next < pool.length;
}
public CPInfo next() {
current = pool[next];
switch (current.getTag()) {
case CONSTANT_Double:
case CONSTANT_Long:
next += 2;
break;
default:
next += 1;
}
return current;
}
public void remove() {
throw new UnsupportedOperationException();
}
private CPInfo current;
private int next = 1;
};
}
};
}
private CPInfo[] pool;
public interface Visitor<R,P> {
R visitClass(CONSTANT_Class_info info, P p);
R visitDouble(CONSTANT_Double_info info, P p);
R visitFieldref(CONSTANT_Fieldref_info info, P p);
R visitFloat(CONSTANT_Float_info info, P p);
R visitInteger(CONSTANT_Integer_info info, P p);
R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);
R visitLong(CONSTANT_Long_info info, P p);
R visitNameAndType(CONSTANT_NameAndType_info info, P p);
R visitMethodref(CONSTANT_Methodref_info info, P p);
R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);
R visitMethodType(CONSTANT_MethodType_info info, P p);
R visitString(CONSTANT_String_info info, P p);
R visitUtf8(CONSTANT_Utf8_info info, P p);
}
public static abstract class CPInfo {
CPInfo() {
this.cp = null;
}
CPInfo(ConstantPool cp) {
this.cp = cp;
}
public abstract int getTag();
/** The number of slots in the constant pool used by this entry.
* 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */
public int size() {
return 1;
}
public abstract int byteLength();
public abstract <R,D> R accept(Visitor
Other Java examples (source code examples)Here is a short list of links related to this Java ConstantPool.java source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.