1 /*
2  * Copyright 2014 - 2020 Rafael Winterhalter
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.bytebuddy.implementation.bytecode.constant;
17
18 import net.bytebuddy.description.type.TypeDefinition;
19 import net.bytebuddy.implementation.Implementation;
20 import net.bytebuddy.implementation.bytecode.StackManipulation;
21 import net.bytebuddy.jar.asm.MethodVisitor;
22
23 /**
24  * Represents a stack assignment that loads the default value of a given type onto the stack.
25  */

26 public enum DefaultValue implements StackManipulation {
27
28     /**
29      * The default value of a JVM integer which covers Java's {@code int}, {@code boolean}, {@code byte},
30      * {@code short} and {@code char} values.
31      */

32     INTEGER(IntegerConstant.ZERO),
33
34     /**
35      * The default value of a {@code long}.
36      */

37     LONG(LongConstant.ZERO),
38
39     /**
40      * The default value of a {@code float}.
41      */

42     FLOAT(FloatConstant.ZERO),
43
44     /**
45      * The default value of a {@code double}.
46      */

47     DOUBLE(DoubleConstant.ZERO),
48
49     /**
50      * The default value of a {@code void} which resembles a no-op manipulation.
51      */

52     VOID(Trivial.INSTANCE),
53
54     /**
55      * The default value of a reference type which resembles the {@code null} reference.
56      */

57     REFERENCE(NullConstant.INSTANCE);
58
59     /**
60      * The stack manipulation that represents the loading of a given default value onto the operand stack.
61      */

62     private final StackManipulation stackManipulation;
63
64     /**
65      * Creates a new default value load operation.
66      *
67      * @param stackManipulation The stack manipulation that represents the loading of a given default value onto the
68      *                          operand stack.
69      */

70     DefaultValue(StackManipulation stackManipulation) {
71         this.stackManipulation = stackManipulation;
72     }
73
74     /**
75      * Creates a stack assignment that loads the default value for a given type.
76      *
77      * @param typeDefinition The type for which a default value should be loaded onto the operand stack.
78      * @return A stack manipulation loading the default value for the given type.
79      */

80     public static StackManipulation of(TypeDefinition typeDefinition) {
81         if (typeDefinition.isPrimitive()) {
82             if (typeDefinition.represents(long.class)) {
83                 return LONG;
84             } else if (typeDefinition.represents(double.class)) {
85                 return DOUBLE;
86             } else if (typeDefinition.represents(float.class)) {
87                 return FLOAT;
88             } else if (typeDefinition.represents(void.class)) {
89                 return VOID;
90             } else {
91                 return INTEGER;
92             }
93         } else {
94             return REFERENCE;
95         }
96     }
97
98     /**
99      * {@inheritDoc}
100      */

101     public boolean isValid() {
102         return stackManipulation.isValid();
103     }
104
105     /**
106      * {@inheritDoc}
107      */

108     public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
109         return stackManipulation.apply(methodVisitor, implementationContext);
110     }
111 }
112