8341277: Validate slot argument for instruction factories

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2024-10-02 03:30:02 +00:00
parent 0f381137cb
commit 39c17b3926
15 changed files with 366 additions and 80 deletions

View file

@ -429,6 +429,8 @@ public sealed interface CodeBuilder
* @param tk the load type
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code tk} is {@link TypeKind#VOID void}
* or {@code slot} is out of range
* @since 23
*/
default CodeBuilder loadLocal(TypeKind tk, int slot) {
@ -440,6 +442,8 @@ public sealed interface CodeBuilder
* @param tk the store type
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code tk} is {@link TypeKind#VOID void}
* or {@code slot} is out of range
* @since 23
*/
default CodeBuilder storeLocal(TypeKind tk, int slot) {
@ -793,6 +797,7 @@ public sealed interface CodeBuilder
* @param startScope the start scope of the variable
* @param endScope the end scope of the variable
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder localVariable(int slot, Utf8Entry nameEntry, Utf8Entry descriptorEntry, Label startScope, Label endScope) {
return with(LocalVariable.of(slot, nameEntry, descriptorEntry, startScope, endScope));
@ -806,6 +811,7 @@ public sealed interface CodeBuilder
* @param startScope the start scope of the variable
* @param endScope the end scope of the variable
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder localVariable(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) {
return localVariable(slot,
@ -822,6 +828,7 @@ public sealed interface CodeBuilder
* @param startScope the start scope of the variable
* @param endScope the end scope of the variable
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder localVariableType(int slot, Utf8Entry nameEntry, Utf8Entry signatureEntry, Label startScope, Label endScope) {
return with(LocalVariableType.of(slot, nameEntry, signatureEntry, startScope, endScope));
@ -835,6 +842,7 @@ public sealed interface CodeBuilder
* @param startScope the start scope of the variable
* @param endScope the end scope of the variable
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder localVariableType(int slot, String name, Signature signature, Label startScope, Label endScope) {
return localVariableType(slot,
@ -877,6 +885,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder aload(int slot) {
return loadLocal(TypeKind.REFERENCE, slot);
@ -925,6 +934,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder astore(int slot) {
return storeLocal(TypeKind.REFERENCE, slot);
@ -958,6 +968,7 @@ public sealed interface CodeBuilder
* Generate an instruction pushing an int in the range of byte onto the operand stack.
* @param b the int in the range of byte
* @return this builder
* @throws IllegalArgumentException if {@code b} is out of range of byte
*/
default CodeBuilder bipush(int b) {
return with(ConstantInstruction.ofArgument(Opcode.BIPUSH, b));
@ -1094,6 +1105,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder dload(int slot) {
return loadLocal(TypeKind.DOUBLE, slot);
@ -1139,6 +1151,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder dstore(int slot) {
return storeLocal(TypeKind.DOUBLE, slot);
@ -1306,6 +1319,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder fload(int slot) {
return loadLocal(TypeKind.FLOAT, slot);
@ -1351,6 +1365,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder fstore(int slot) {
return storeLocal(TypeKind.FLOAT, slot);
@ -1726,6 +1741,7 @@ public sealed interface CodeBuilder
* @param slot the local variable slot
* @param val the increment value
* @return this builder
* @throws IllegalArgumentException if {@code slot} or {@code val} is out of range
*/
default CodeBuilder iinc(int slot, int val) {
return with(IncrementInstruction.of(slot, val));
@ -1739,6 +1755,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder iload(int slot) {
return loadLocal(TypeKind.INT, slot);
@ -1997,6 +2014,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder istore(int slot) {
return storeLocal(TypeKind.INT, slot);
@ -2159,6 +2177,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder lload(int slot) {
return loadLocal(TypeKind.LONG, slot);
@ -2228,6 +2247,7 @@ public sealed interface CodeBuilder
*
* @param slot the local variable slot
* @return this builder
* @throws IllegalArgumentException if {@code slot} is out of range
*/
default CodeBuilder lstore(int slot) {
return storeLocal(TypeKind.LONG, slot);
@ -2278,6 +2298,7 @@ public sealed interface CodeBuilder
* @param array the array type
* @param dims the number of dimensions
* @return this builder
* @throws IllegalArgumentException if {@code dims} is out of range
*/
default CodeBuilder multianewarray(ClassEntry array, int dims) {
return with(NewMultiArrayInstruction.of(array, dims));
@ -2289,6 +2310,7 @@ public sealed interface CodeBuilder
* @param dims the number of dimensions
* @return this builder
* @throws IllegalArgumentException if {@code array} represents a primitive type
* or if {@code dims} is out of range
*/
default CodeBuilder multianewarray(ClassDesc array, int dims) {
return multianewarray(constantPool().classEntry(array), dims);
@ -2327,6 +2349,8 @@ public sealed interface CodeBuilder
* Generate an instruction to create a new array of a primitive type
* @param typeKind the primitive array type
* @return this builder
* @throws IllegalArgumentException when the {@code typeKind} is not a legal
* primitive array component type
*/
default CodeBuilder newarray(TypeKind typeKind) {
return with(NewPrimitiveArrayInstruction.of(typeKind));
@ -2423,6 +2447,7 @@ public sealed interface CodeBuilder
* Generate an instruction pushing an int in the range of short onto the operand stack.
* @param s the int in the range of short
* @return this builder
* @throws IllegalArgumentException if {@code s} is out of range of short
*/
default CodeBuilder sipush(int s) {
return with(ConstantInstruction.ofArgument(Opcode.SIPUSH, s));

View file

@ -30,6 +30,7 @@ import java.lang.classfile.Instruction;
import java.lang.classfile.Label;
import java.lang.classfile.Opcode;
import jdk.internal.classfile.impl.AbstractInstruction;
import jdk.internal.classfile.impl.BytecodeHelpers;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
@ -112,10 +113,10 @@ public sealed interface DiscontinuedInstruction extends Instruction {
* which must be of kind {@link Opcode.Kind#DISCONTINUED_RET}
* @param slot the local variable slot to load return address from
* @throws IllegalArgumentException if the opcode kind is not
* {@link Opcode.Kind#DISCONTINUED_RET}.
* {@link Opcode.Kind#DISCONTINUED_RET} or if {@code slot} is out of range
*/
static RetInstruction of(Opcode op, int slot) {
Util.checkKind(op, Opcode.Kind.DISCONTINUED_RET);
BytecodeHelpers.validateRet(op, slot);
return new AbstractInstruction.UnboundRetInstruction(op, slot);
}
@ -123,6 +124,7 @@ public sealed interface DiscontinuedInstruction extends Instruction {
* {@return a RET instruction}
*
* @param slot the local variable slot to load return address from
* @throws IllegalArgumentException if {@code slot} is out of range
*/
static RetInstruction of(int slot) {
return of(slot < 256 ? Opcode.RET : Opcode.RET_W, slot);

View file

@ -58,6 +58,7 @@ public sealed interface IncrementInstruction extends Instruction
*
* @param slot the local variable slot to increment
* @param constant the value to increment by
* @throws IllegalArgumentException if {@code slot} or {@code constant} is out of range
*/
static IncrementInstruction of(int slot, int constant) {
return new AbstractInstruction.UnboundIncrementInstruction(slot, constant);

View file

@ -62,9 +62,12 @@ public sealed interface LoadInstruction extends Instruction
*
* @param kind the type of the value to be loaded
* @param slot the local variable slot to load from
* @throws IllegalArgumentException if {@code kind} is
* {@link TypeKind#VOID void} or {@code slot} is out of range
*/
static LoadInstruction of(TypeKind kind, int slot) {
return of(BytecodeHelpers.loadOpcode(kind, slot), slot);
var opcode = BytecodeHelpers.loadOpcode(kind, slot); // validates slot, trusted
return new AbstractInstruction.UnboundLoadInstruction(opcode, slot);
}
/**
@ -74,10 +77,11 @@ public sealed interface LoadInstruction extends Instruction
* which must be of kind {@link Opcode.Kind#LOAD}
* @param slot the local variable slot to load from
* @throws IllegalArgumentException if the opcode kind is not
* {@link Opcode.Kind#LOAD}.
* {@link Opcode.Kind#LOAD} or {@code slot} is out of range
*/
static LoadInstruction of(Opcode op, int slot) {
Util.checkKind(op, Opcode.Kind.LOAD);
BytecodeHelpers.validateSlot(op, slot, true);
return new AbstractInstruction.UnboundLoadInstruction(op, slot);
}
}

View file

@ -92,6 +92,7 @@ public sealed interface LocalVariable extends PseudoInstruction
* @param descriptorEntry the local variable descriptor
* @param startScope the start range of the local variable scope
* @param endScope the end range of the local variable scope
* @throws IllegalArgumentException if {@code slot} is out of range
*/
static LocalVariable of(int slot, Utf8Entry nameEntry, Utf8Entry descriptorEntry, Label startScope, Label endScope) {
return new AbstractPseudoInstruction.UnboundLocalVariable(slot, nameEntry, descriptorEntry,
@ -106,6 +107,7 @@ public sealed interface LocalVariable extends PseudoInstruction
* @param descriptor the local variable descriptor
* @param startScope the start range of the local variable scope
* @param endScope the end range of the local variable scope
* @throws IllegalArgumentException if {@code slot} is out of range
*/
static LocalVariable of(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) {
return of(slot,

View file

@ -89,6 +89,7 @@ public sealed interface LocalVariableType extends PseudoInstruction
* @param signatureEntry the local variable signature
* @param startScope the start range of the local variable scope
* @param endScope the end range of the local variable scope
* @throws IllegalArgumentException if {@code slot} is out of range
*/
static LocalVariableType of(int slot, Utf8Entry nameEntry, Utf8Entry signatureEntry, Label startScope, Label endScope) {
return new AbstractPseudoInstruction.UnboundLocalVariableType(slot, nameEntry, signatureEntry,
@ -103,6 +104,7 @@ public sealed interface LocalVariableType extends PseudoInstruction
* @param signature the local variable signature
* @param startScope the start range of the local variable scope
* @param endScope the end range of the local variable scope
* @throws IllegalArgumentException if {@code slot} is out of range
*/
static LocalVariableType of(int slot, String name, Signature signature, Label startScope, Label endScope) {
return of(slot,

View file

@ -29,6 +29,7 @@ import java.lang.classfile.CodeModel;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.Instruction;
import jdk.internal.classfile.impl.AbstractInstruction;
import jdk.internal.classfile.impl.BytecodeHelpers;
import jdk.internal.javac.PreviewFeature;
/**
@ -58,9 +59,11 @@ public sealed interface NewMultiArrayInstruction extends Instruction
*
* @param arrayTypeEntry the type of the array
* @param dimensions the number of dimensions of the array
* @throws IllegalArgumentException if {@code dimensions} is out of range
*/
static NewMultiArrayInstruction of(ClassEntry arrayTypeEntry,
int dimensions) {
BytecodeHelpers.validateMultiArrayDimensions(dimensions);
return new AbstractInstruction.UnboundNewMultidimensionalArrayInstruction(arrayTypeEntry, dimensions);
}
}

View file

@ -61,9 +61,12 @@ public sealed interface StoreInstruction extends Instruction
*
* @param kind the type of the value to be stored
* @param slot the local variable slot to store to
* @throws IllegalArgumentException if {@code kind} is {@link
* TypeKind#VOID void} or {@code slot} is out of range
*/
static StoreInstruction of(TypeKind kind, int slot) {
return of(BytecodeHelpers.storeOpcode(kind, slot), slot);
var opcode = BytecodeHelpers.storeOpcode(kind, slot); // validates slot
return new AbstractInstruction.UnboundStoreInstruction(opcode, slot);
}
/**
@ -73,10 +76,11 @@ public sealed interface StoreInstruction extends Instruction
* which must be of kind {@link Opcode.Kind#STORE}
* @param slot the local variable slot to store to
* @throws IllegalArgumentException if the opcode kind is not
* {@link Opcode.Kind#STORE}.
* {@link Opcode.Kind#STORE} or {@code slot} is out of range
*/
static StoreInstruction of(Opcode op, int slot) {
Util.checkKind(op, Opcode.Kind.STORE);
BytecodeHelpers.validateSlot(op, slot, false);
return new AbstractInstruction.UnboundStoreInstruction(op, slot);
}
}