package net.bytebuddy.implementation.bytecode.constant;
import net.bytebuddy.description.type.
TypeDefinition;
import net.bytebuddy.implementation.
Implementation;
import net.bytebuddy.implementation.bytecode.
StackManipulation;
import net.bytebuddy.jar.asm.
MethodVisitor;
/**
* Represents a stack assignment that loads the default value of a given type onto the stack.
*/
public enum
DefaultValue implements
StackManipulation {
/**
* The default value of a JVM integer which covers Java's {@code int}, {@code boolean}, {@code byte},
* {@code short} and {@code char} values.
*/
INTEGER(
IntegerConstant.
ZERO),
/**
* The default value of a {@code long}.
*/
LONG(
LongConstant.
ZERO),
/**
* The default value of a {@code float}.
*/
FLOAT(
FloatConstant.
ZERO),
/**
* The default value of a {@code double}.
*/
DOUBLE(
DoubleConstant.
ZERO),
/**
* The default value of a {@code void} which resembles a no-op manipulation.
*/
VOID(
Trivial.
INSTANCE),
/**
* The default value of a reference type which resembles the {@code null} reference.
*/
REFERENCE(
NullConstant.
INSTANCE);
/**
* The stack manipulation that represents the loading of a given default value onto the operand stack.
*/
private final
StackManipulation stackManipulation;
/**
* Creates a new default value load operation.
*
* @param stackManipulation The stack manipulation that represents the loading of a given default value onto the
* operand stack.
*/
DefaultValue(
StackManipulation stackManipulation) {
this.
stackManipulation =
stackManipulation;
}
/**
* Creates a stack assignment that loads the default value for a given type.
*
* @param typeDefinition The type for which a default value should be loaded onto the operand stack.
* @return A stack manipulation loading the default value for the given type.
*/
public static
StackManipulation of(
TypeDefinition typeDefinition) {
if (
typeDefinition.
isPrimitive()) {
if (
typeDefinition.
represents(long.class)) {
return
LONG;
} else if (
typeDefinition.
represents(double.class)) {
return
DOUBLE;
} else if (
typeDefinition.
represents(float.class)) {
return
FLOAT;
} else if (
typeDefinition.
represents(void.class)) {
return
VOID;
} else {
return
INTEGER;
}
} else {
return
REFERENCE;
}
}
@
Override
public boolean
isValid() {
return
stackManipulation.
isValid();
}
@
Override
public
Size apply(
MethodVisitor methodVisitor,
Implementation.
Context implementationContext) {
return
stackManipulation.
apply(
methodVisitor,
implementationContext);
}
}