From e706346bc30a55f613096fc6c08f1f8cbb8dd700 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Fri, 26 Apr 2024 09:11:29 +0200 Subject: [PATCH] implemented proposed simpler solution with lower and upper bound tags --- .../classfile/impl/ClassReaderImpl.java | 112 ++++++------------ 1 file changed, 38 insertions(+), 74 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java index 1a0c01d6a3548..ca73f860072a6 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java @@ -339,6 +339,10 @@ void writeConstantPoolEntries(BufWriter buf) { // Constantpool @Override public PoolEntry entryByIndex(int index) { + return entryByIndex(index, 0, 0xff); + } + + private PoolEntry entryByIndex(int index, int lowerBoundTag, int upperBoundTag) { if (index <= 0 || index >= constantPoolCount) { throw new ConstantPoolException("Bad CP index: " + index); } @@ -349,6 +353,10 @@ public PoolEntry entryByIndex(int index) { throw new ConstantPoolException("Unusable CP index: " + index); } int tag = readU1(offset); + if (tag < lowerBoundTag || tag > upperBoundTag) { + throw new ConstantPoolException( + "Bad tag (" + tag + ") at index (" + index + ") position (" + offset + ")"); + } final int q = offset + 1; info = switch (tag) { case TAG_UTF8 -> new AbstractPoolEntry.Utf8EntryImpl(this, index, buffer, q + 2, readU2(q)); @@ -356,18 +364,23 @@ public PoolEntry entryByIndex(int index) { case TAG_FLOAT -> new AbstractPoolEntry.FloatEntryImpl(this, index, readFloat(q)); case TAG_LONG -> new AbstractPoolEntry.LongEntryImpl(this, index, readLong(q)); case TAG_DOUBLE -> new AbstractPoolEntry.DoubleEntryImpl(this, index, readDouble(q)); - case TAG_CLASS -> new AbstractPoolEntry.ClassEntryImpl(this, index, readUtf8Entry(q)); - case TAG_STRING -> new AbstractPoolEntry.StringEntryImpl(this, index, readUtf8Entry(q)); - case TAG_FIELDREF -> new AbstractPoolEntry.FieldRefEntryImpl(this, index, readClassEntry(q), readNameAndTypeEntry(q + 2)); - case TAG_METHODREF -> new AbstractPoolEntry.MethodRefEntryImpl(this, index, readClassEntry(q), readNameAndTypeEntry(q + 2)); - case TAG_INTERFACEMETHODREF -> new AbstractPoolEntry.InterfaceMethodRefEntryImpl(this, index, readClassEntry(q), readNameAndTypeEntry(q + 2)); - case TAG_NAMEANDTYPE -> new AbstractPoolEntry.NameAndTypeEntryImpl(this, index, readUtf8Entry(q), readUtf8Entry(q + 2)); - case TAG_METHODHANDLE -> new AbstractPoolEntry.MethodHandleEntryImpl(this, index, readU1(q), readAbstractMemberRefEntry(q + 1)); - case TAG_METHODTYPE -> new AbstractPoolEntry.MethodTypeEntryImpl(this, index, readUtf8Entry(q)); - case TAG_CONSTANTDYNAMIC -> new AbstractPoolEntry.ConstantDynamicEntryImpl(this, index, readU2(q), readNameAndTypeEntry(q + 2)); - case TAG_INVOKEDYNAMIC -> new AbstractPoolEntry.InvokeDynamicEntryImpl(this, index, readU2(q), readNameAndTypeEntry(q + 2)); - case TAG_MODULE -> new AbstractPoolEntry.ModuleEntryImpl(this, index, readUtf8Entry(q)); - case TAG_PACKAGE -> new AbstractPoolEntry.PackageEntryImpl(this, index, readUtf8Entry(q)); + case TAG_CLASS -> new AbstractPoolEntry.ClassEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q)); + case TAG_STRING -> new AbstractPoolEntry.StringEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q)); + case TAG_FIELDREF -> new AbstractPoolEntry.FieldRefEntryImpl(this, index, (AbstractPoolEntry.ClassEntryImpl) readClassEntry(q), + (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2)); + case TAG_METHODREF -> new AbstractPoolEntry.MethodRefEntryImpl(this, index, (AbstractPoolEntry.ClassEntryImpl) readClassEntry(q), + (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2)); + case TAG_INTERFACEMETHODREF -> new AbstractPoolEntry.InterfaceMethodRefEntryImpl(this, index, (AbstractPoolEntry.ClassEntryImpl) readClassEntry(q), + (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2)); + case TAG_NAMEANDTYPE -> new AbstractPoolEntry.NameAndTypeEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q), + (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q + 2)); + case TAG_METHODHANDLE -> new AbstractPoolEntry.MethodHandleEntryImpl(this, index, readU1(q), + readEntry(q + 1, AbstractPoolEntry.AbstractMemberRefEntry.class, TAG_FIELDREF, TAG_INTERFACEMETHODREF)); + case TAG_METHODTYPE -> new AbstractPoolEntry.MethodTypeEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q)); + case TAG_CONSTANTDYNAMIC -> new AbstractPoolEntry.ConstantDynamicEntryImpl(this, index, readU2(q), (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2)); + case TAG_INVOKEDYNAMIC -> new AbstractPoolEntry.InvokeDynamicEntryImpl(this, index, readU2(q), (AbstractPoolEntry.NameAndTypeEntryImpl) readNameAndTypeEntry(q + 2)); + case TAG_MODULE -> new AbstractPoolEntry.ModuleEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q)); + case TAG_PACKAGE -> new AbstractPoolEntry.PackageEntryImpl(this, index, (AbstractPoolEntry.Utf8EntryImpl) readUtf8Entry(q)); default -> throw new ConstantPoolException( "Bad tag (" + tag + ") at index (" + index + ") position (" + offset + ")"); }; @@ -418,7 +431,11 @@ public PoolEntry readEntry(int pos) { @Override public T readEntry(int pos, Class cls) { - var e = readEntry(pos); + return readEntry(pos, cls, 0, 0xff); + } + + private T readEntry(int pos, Class cls, int lowerBoundTag, int upperBoundTag) { + var e = entryByIndex(readU2(pos), lowerBoundTag, upperBoundTag); if (cls.isInstance(e)) return cls.cast(e); throw new ConstantPoolException("Not a " + cls.getSimpleName() + " at index: " + readU2(pos)); } @@ -433,7 +450,7 @@ public PoolEntry readEntryOrNull(int pos) { } @Override - public AbstractPoolEntry.Utf8EntryImpl readUtf8Entry(int pos) { + public Utf8Entry readUtf8Entry(int pos) { int index = readU2(pos); return utf8EntryByIndex(index); } @@ -449,80 +466,27 @@ public Utf8Entry readUtf8EntryOrNull(int pos) { @Override public ModuleEntry readModuleEntry(int pos) { - return readEntry(pos, ModuleEntry.class); + return readEntry(pos, ModuleEntry.class, TAG_MODULE, TAG_MODULE); } @Override public PackageEntry readPackageEntry(int pos) { - return readEntry(pos, PackageEntry.class); - } - - private int readIndex(int pos) { - int index = readU2(pos); - if (index <= 0 || index >= constantPoolCount) { - throw new ConstantPoolException("Bad CP index: " + index); - } - return index; - } - - private int getOffset(int index) { - int offset = cpOffset[index]; - if (offset == 0) { - throw new ConstantPoolException("Unusable CP index: " + index); - } - return offset; + return readEntry(pos, PackageEntry.class, TAG_PACKAGE, TAG_PACKAGE); } @Override - public AbstractPoolEntry.ClassEntryImpl readClassEntry(int pos) { - int index = readIndex(pos); - PoolEntry info = cp[index]; - if (info == null) { - int offset = getOffset(index); - if (readU1(offset) == TAG_CLASS) { - info = new AbstractPoolEntry.ClassEntryImpl(this, index, readUtf8Entry(offset + 1)); - cp[index] = info; - } - } - if (info instanceof AbstractPoolEntry.ClassEntryImpl ce) return ce; - throw new ConstantPoolException("Not a ClassEntry at index: " + index); + public ClassEntry readClassEntry(int pos) { + return readEntry(pos, ClassEntry.class, TAG_CLASS, TAG_CLASS); } @Override - public AbstractPoolEntry.NameAndTypeEntryImpl readNameAndTypeEntry(int pos) { - int index = readIndex(pos); - PoolEntry info = cp[index]; - if (info == null) { - int offset = getOffset(index); - if (readU1(offset) == TAG_NAMEANDTYPE) { - info = new AbstractPoolEntry.NameAndTypeEntryImpl(this, index, readUtf8Entry(offset + 1), readUtf8Entry(offset + 3)); - cp[index] = info; - } - } - if (info instanceof AbstractPoolEntry.NameAndTypeEntryImpl nte) return nte; - throw new ConstantPoolException("Not a NameAndTypeEntry at index: " + index); - } - - private AbstractPoolEntry.AbstractMemberRefEntry readAbstractMemberRefEntry(int pos) { - int index = readIndex(pos); - PoolEntry info = cp[index]; - if (info == null) { - int offset = getOffset(index); - info = switch (readU1(offset)) { - case TAG_FIELDREF -> new AbstractPoolEntry.FieldRefEntryImpl(this, index, readClassEntry(offset + 1), readNameAndTypeEntry(offset + 3)); - case TAG_METHODREF -> new AbstractPoolEntry.MethodRefEntryImpl(this, index, readClassEntry(offset + 1), readNameAndTypeEntry(offset + 3)); - case TAG_INTERFACEMETHODREF -> new AbstractPoolEntry.InterfaceMethodRefEntryImpl(this, index, readClassEntry(offset + 1), readNameAndTypeEntry(offset + 3)); - default -> null; - }; - cp[index] = info; - } - if (info instanceof AbstractPoolEntry.AbstractMemberRefEntry amre) return amre; - throw new ConstantPoolException("Not a MemberRefEntry at index: " + index); + public NameAndTypeEntry readNameAndTypeEntry(int pos) { + return readEntry(pos, NameAndTypeEntry.class, TAG_NAMEANDTYPE, TAG_NAMEANDTYPE); } @Override public MethodHandleEntry readMethodHandleEntry(int pos) { - return readEntry(pos, MethodHandleEntry.class); + return readEntry(pos, MethodHandleEntry.class, TAG_METHODHANDLE, TAG_METHODHANDLE); } @Override