8308842: Consolidate exceptions thrown from Class-File API

Reviewed-by: briangoetz
This commit is contained in:
Adam Sotona 2023-06-05 18:25:51 +00:00
parent 2b38343e4d
commit 4b8922f576
15 changed files with 147 additions and 64 deletions

View file

@ -26,6 +26,7 @@ package jdk.internal.classfile;
import jdk.internal.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.constantpool.ConstantPool;
import jdk.internal.classfile.constantpool.ConstantPoolException;
import jdk.internal.classfile.constantpool.MethodHandleEntry;
import jdk.internal.classfile.constantpool.ModuleEntry;
import jdk.internal.classfile.constantpool.NameAndTypeEntry;
@ -96,7 +97,7 @@ public sealed interface ClassReader extends ConstantPool
* {@return the constant pool entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero
*/
PoolEntry readEntry(int offset);
@ -106,7 +107,7 @@ public sealed interface ClassReader extends ConstantPool
* offset within the classfile, or null if the index at the specified
* offset is zero}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* @throws ConstantPoolException if the index is out of range of the
* constant pool size
*/
PoolEntry readEntryOrNull(int offset);
@ -115,9 +116,8 @@ public sealed interface ClassReader extends ConstantPool
* {@return the UTF8 entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size, or zero
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a UTF8 entry
*/
Utf8Entry readUtf8Entry(int offset);
@ -127,9 +127,8 @@ public sealed interface ClassReader extends ConstantPool
* offset within the classfile, or null if the index at the specified
* offset is zero}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or the index does not correspond to
* a UTF8 entry
*/
Utf8Entry readUtf8EntryOrNull(int offset);
@ -138,9 +137,8 @@ public sealed interface ClassReader extends ConstantPool
* {@return the module entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size, or zero
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a module entry
*/
ModuleEntry readModuleEntry(int offset);
@ -149,9 +147,8 @@ public sealed interface ClassReader extends ConstantPool
* {@return the package entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size, or zero
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a package entry
*/
PackageEntry readPackageEntry(int offset);
@ -160,9 +157,8 @@ public sealed interface ClassReader extends ConstantPool
* {@return the class entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size, or zero
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a class entry
*/
ClassEntry readClassEntry(int offset);
@ -171,9 +167,8 @@ public sealed interface ClassReader extends ConstantPool
* {@return the name-and-type entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size, or zero
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a name-and-type entry
*/
NameAndTypeEntry readNameAndTypeEntry(int offset);
@ -182,9 +177,8 @@ public sealed interface ClassReader extends ConstantPool
* {@return the method handle entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws IndexOutOfBoundsException if the index is out of range of the
* constant pool size, or zero
* @throws IllegalArgumentException if the index does not correspond to
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a method handle entry
*/
MethodHandleEntry readMethodHandleEntry(int offset);

View file

@ -143,7 +143,7 @@ public class Classfile {
/**
* {@return an option describing whether or not to filter unresolved labels}
* Default is to throw IllegalStateException when any {@link ExceptionCatch},
* Default is to throw IllegalArgumentException when any {@link ExceptionCatch},
* {@link LocalVariableInfo}, {@link LocalVariableTypeInfo}, or {@link CharacterRangeInfo}
* reference to unresolved {@link Label} during bytecode serialization.
* Setting this option to true filters the above elements instead.

View file

@ -234,7 +234,7 @@ public sealed interface CodeBuilder
* @param thenHandler handler that receives a {@linkplain BlockCodeBuilder} to
* generate the body of the {@code if}
* @return this builder
* @throws java.lang.IllegalArgumentException if the operation code is not for a branch instruction that accepts
* @throws IllegalArgumentException if the operation code is not for a branch instruction that accepts
* one or two operands
*/
default CodeBuilder ifThen(Opcode opcode,
@ -284,7 +284,7 @@ public sealed interface CodeBuilder
* @param elseHandler handler that receives a {@linkplain BlockCodeBuilder} to
* generate the body of the {@code else}
* @return this builder
* @throws java.lang.IllegalArgumentException if the operation code is not for a branch instruction that accepts
* @throws IllegalArgumentException if the operation code is not for a branch instruction that accepts
* one or two operands
*/
default CodeBuilder ifThenElse(Opcode opcode,
@ -327,7 +327,7 @@ public sealed interface CodeBuilder
* @param catchHandler handler that receives a {@linkplain CodeBuilder} to
* generate the body of the catch block.
* @return this builder
* @throws java.lang.IllegalArgumentException if an existing catch block catches an exception of the given type.
* @throws IllegalArgumentException if an existing catch block catches an exception of the given type.
* @see #catchingMulti
* @see #catchingAll
*/
@ -344,7 +344,7 @@ public sealed interface CodeBuilder
* @param catchHandler handler that receives a {@linkplain CodeBuilder} to
* generate the body of the catch block.
* @return this builder
* @throws java.lang.IllegalArgumentException if an existing catch block catches one or more exceptions of the given types.
* @throws IllegalArgumentException if an existing catch block catches one or more exceptions of the given types.
* @see #catching
* @see #catchingAll
*/
@ -357,7 +357,7 @@ public sealed interface CodeBuilder
*
* @param catchAllHandler handler that receives a {@linkplain CodeBuilder} to
* generate the body of the catch block
* @throws java.lang.IllegalArgumentException if an existing catch block catches all exceptions.
* @throws IllegalArgumentException if an existing catch block catches all exceptions.
* @see #catching
* @see #catchingMulti
*/
@ -373,6 +373,7 @@ public sealed interface CodeBuilder
* @param catchesHandler a handler that receives a {@linkplain CatchBuilder}
* to generate bodies of catch blocks.
* @return this builder
* @throws IllegalArgumentException if the try block is empty.
* @see CatchBuilder
*/
default CodeBuilder trying(Consumer<BlockCodeBuilder> tryHandler,
@ -386,7 +387,7 @@ public sealed interface CodeBuilder
// Check for empty try block
if (tryBlock.isEmpty()) {
throw new IllegalStateException("The body of the try block is empty");
throw new IllegalArgumentException("The body of the try block is empty");
}
var catchBuilder = new CatchBuilderImpl(this, tryBlock, tryCatchEnd);

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2023, 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 jdk.internal.classfile.constantpool;
/**
* Thrown to indicate that requested entry cannot be obtained from the constant
* pool.
*/
public class ConstantPoolException extends IllegalArgumentException {
@java.io.Serial
private static final long serialVersionUID = 7245472922409094120L;
/**
* Constructs a {@code ConstantPoolException} with no detail message.
*/
public ConstantPoolException() {
super();
}
/**
* Constructs a {@code ConstantPoolException} with the specified detail
* message.
*
* @param message the detail message.
*/
public ConstantPoolException(String message) {
super(message);
}
/**
* Constructs a {@code ConstantPoolException} with the specified cause and
* a detail message of {@code (cause==null ? null : cause.toString())}.
* @param cause the cause (which is saved for later retrieval by the
* {@link Throwable#getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public ConstantPoolException(Throwable cause) {
super(cause);
}
/**
* Constructs a {@code ConstantPoolException} with the specified detail
* message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link Throwable#getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link Throwable#getCause()} method). (A {@code null} value
* is permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public ConstantPoolException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -129,10 +129,14 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
int size = reader.readU2(pos);
var filled = new Object[size];
int p = pos + 2;
int cfLen = reader.classfileLength();
for (int i = 0; i < size; ++i) {
Utf8Entry name = reader.readUtf8Entry(p);
int len = reader.readInt(p + 2);
p += 6;
if (len < 0 || len > cfLen - p) {
throw new IllegalArgumentException("attribute " + name.stringValue() + " too big to handle");
}
var mapper = Attributes.standardAttribute(name);
if (mapper == null) {

View file

@ -35,6 +35,7 @@ import java.util.function.Function;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.BootstrapMethodsAttribute;
import jdk.internal.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.constantpool.ConstantPoolException;
import jdk.internal.classfile.constantpool.LoadableConstantEntry;
import jdk.internal.classfile.constantpool.MethodHandleEntry;
import jdk.internal.classfile.constantpool.ModuleEntry;
@ -91,7 +92,7 @@ public final class ClassReaderImpl
this.options = new Options(options);
this.attributeMapper = this.options.attributeMapper;
if (classfileLength < 4 || readInt(0) != 0xCAFEBABE) {
throw new IllegalStateException("Bad magic number");
throw new IllegalArgumentException("Bad magic number");
}
int constantPoolCount = readU2(8);
int[] cpOffset = new int[constantPoolCount];
@ -118,7 +119,7 @@ public final class ClassReaderImpl
++i;
}
case TAG_UTF8 -> p += 2 + readU2(p);
default -> throw new IllegalStateException(
default -> throw new ConstantPoolException(
"Bad tag (" + tag + ") at index (" + i + ") position (" + p + ")");
}
}
@ -306,7 +307,7 @@ public final class ClassReaderImpl
@Override
public PoolEntry entryByIndex(int index) {
if (index <= 0 || index >= constantPoolCount) {
throw new IndexOutOfBoundsException("Bad CP index: " + index);
throw new ConstantPoolException("Bad CP index: " + index);
}
PoolEntry info = cp[index];
if (info == null) {
@ -336,7 +337,7 @@ public final class ClassReaderImpl
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 IllegalStateException(
default -> throw new ConstantPoolException(
"Bad tag (" + tag + ") at index (" + index + ") position (" + offset + ")");
};
cp[index] = info;
@ -347,14 +348,14 @@ public final class ClassReaderImpl
@Override
public AbstractPoolEntry.Utf8EntryImpl utf8EntryByIndex(int index) {
if (index <= 0 || index >= constantPoolCount) {
throw new IndexOutOfBoundsException("Bad CP UTF8 index: " + index);
throw new ConstantPoolException("Bad CP UTF8 index: " + index);
}
PoolEntry info = cp[index];
if (info == null) {
int offset = cpOffset[index];
int tag = readU1(offset);
final int q = offset + 1;
if (tag != TAG_UTF8) throw new IllegalArgumentException("Not a UTF8 - index: " + index);
if (tag != TAG_UTF8) throw new ConstantPoolException("Not a UTF8 - index: " + index);
AbstractPoolEntry.Utf8EntryImpl uinfo
= new AbstractPoolEntry.Utf8EntryImpl(this, index, buffer, q + 2, readU2(q));
cp[index] = uinfo;
@ -370,7 +371,11 @@ public final class ClassReaderImpl
p += 2;
for (int i = 0; i < cnt; ++i) {
int len = readInt(p + 2);
p += 6 + len;
p += 6;
if (len < 0 || len > classfileLength - p) {
throw new IllegalArgumentException("attribute " + readUtf8Entry(p - 6).stringValue() + " too big to handle");
}
p += len;
}
return p;
}
@ -407,31 +412,31 @@ public final class ClassReaderImpl
@Override
public ModuleEntry readModuleEntry(int pos) {
if (readEntry(pos) instanceof ModuleEntry me) return me;
throw new IllegalArgumentException("Not a module entry at pos: " + pos);
throw new ConstantPoolException("Not a module entry at pos: " + pos);
}
@Override
public PackageEntry readPackageEntry(int pos) {
if (readEntry(pos) instanceof PackageEntry pe) return pe;
throw new IllegalArgumentException("Not a package entry at pos: " + pos);
throw new ConstantPoolException("Not a package entry at pos: " + pos);
}
@Override
public ClassEntry readClassEntry(int pos) {
if (readEntry(pos) instanceof ClassEntry ce) return ce;
throw new IllegalArgumentException("Not a class entry at pos: " + pos);
throw new ConstantPoolException("Not a class entry at pos: " + pos);
}
@Override
public NameAndTypeEntry readNameAndTypeEntry(int pos) {
if (readEntry(pos) instanceof NameAndTypeEntry nate) return nate;
throw new IllegalArgumentException("Not a name and type entry at pos: " + pos);
throw new ConstantPoolException("Not a name and type entry at pos: " + pos);
}
@Override
public MethodHandleEntry readMethodHandleEntry(int pos) {
if (readEntry(pos) instanceof MethodHandleEntry mhe) return mhe;
throw new IllegalArgumentException("Not a method handle entry at pos: " + pos);
throw new ConstantPoolException("Not a method handle entry at pos: " + pos);
}
@Override

View file

@ -199,7 +199,7 @@ public final class DirectCodeBuilder
if (constantPool.options().filterDeadLabels) {
handlersSize--;
} else {
throw new IllegalStateException("Unbound label in exception handler");
throw new IllegalArgumentException("Unbound label in exception handler");
}
} else {
buf.writeU2(startPc);
@ -236,7 +236,7 @@ public final class DirectCodeBuilder
if (constantPool.options().filterDeadLabels) {
crSize--;
} else {
throw new IllegalStateException("Unbound label in character range");
throw new IllegalArgumentException("Unbound label in character range");
}
} else {
b.writeU2(start);
@ -265,7 +265,7 @@ public final class DirectCodeBuilder
if (constantPool.options().filterDeadLabels) {
lvSize--;
} else {
throw new IllegalStateException("Unbound label in local variable type");
throw new IllegalArgumentException("Unbound label in local variable type");
}
}
}
@ -288,7 +288,7 @@ public final class DirectCodeBuilder
if (constantPool.options().filterDeadLabels) {
lvtSize--;
} else {
throw new IllegalStateException("Unbound label in local variable type");
throw new IllegalArgumentException("Unbound label in local variable type");
}
}
}
@ -341,7 +341,7 @@ public final class DirectCodeBuilder
maxStack = gen.maxStack();
maxLocals = gen.maxLocals();
stackMapAttr = gen.stackMapTableAttribute();
} catch (Exception e) {
} catch (IllegalArgumentException e) {
if (buf.getMajorVersion() == Classfile.JAVA_6_VERSION) {
//failover following JVMS-4.10
StackCounter cntr = StackCounter.of(DirectCodeBuilder.this, buf);
@ -697,7 +697,7 @@ public final class DirectCodeBuilder
if (context == this) {
if (lab.getBCI() != -1)
throw new IllegalStateException("Setting label target for already-set label");
throw new IllegalArgumentException("Setting label target for already-set label");
lab.setBCI(bci);
}
else if (context == mruParent) {
@ -752,7 +752,7 @@ public final class DirectCodeBuilder
}
//ToDo: consolidate and open all exceptions
private static final class LabelOverflowException extends IllegalStateException {
private static final class LabelOverflowException extends IllegalArgumentException {
private static final long serialVersionUID = 1L;

View file

@ -78,7 +78,7 @@ public final class SignaturesImpl {
if (t instanceof ThrowableSig ts)
throwsTypes.add(ts);
else
throw new IllegalStateException("not a valid type signature: " + sig);
throw new IllegalArgumentException("not a valid type signature: " + sig);
}
return new MethodSignatureImpl(typeParamTypes, null2Empty(throwsTypes), returnType, null2Empty(paramTypes));
}
@ -157,7 +157,7 @@ public final class SignaturesImpl {
return ty;
case '[': return ArrayTypeSig.of(typeSig());
}
throw new IllegalStateException("not a valid type signature: " + sig);
throw new IllegalArgumentException("not a valid type signature: " + sig);
}
private TypeArg typeArg() {

View file

@ -483,7 +483,7 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
case TAG_FIELDREF -> fieldRefEntry(reference.owner(), reference.nameAndType());
case TAG_METHODREF -> methodRefEntry(reference.owner(), reference.nameAndType());
case TAG_INTERFACEMETHODREF -> interfaceMethodRefEntry(reference.owner(), reference.nameAndType());
default -> throw new IllegalStateException(String.format("Bad tag %d", reference.tag()));
default -> throw new IllegalArgumentException(String.format("Bad tag %d", reference.tag()));
};
}

View file

@ -861,7 +861,7 @@ public final class StackMapGenerator {
err.addSuppressed(suppresed);
throw err;
}
throw new IllegalStateException(sb.toString());
throw new IllegalArgumentException(sb.toString());
}
/**