1
1
/*
2
- * Copyright 2002-2014 the original author or authors.
2
+ * Copyright 2002-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -84,6 +84,7 @@ public String toStringAST() {
84
84
return sb .toString ();
85
85
}
86
86
87
+
87
88
protected boolean isCompilableOperatorUsingNumerics () {
88
89
SpelNodeImpl left = getLeftOperand ();
89
90
SpelNodeImpl right = getRightOperand ();
@@ -94,8 +95,8 @@ protected boolean isCompilableOperatorUsingNumerics() {
94
95
// Supported operand types for equals (at the moment)
95
96
String leftDesc = left .exitTypeDescriptor ;
96
97
String rightDesc = right .exitTypeDescriptor ;
97
- DescriptorComparison dc = DescriptorComparison .checkNumericCompatibility (leftDesc , rightDesc ,
98
- this .leftActualDescriptor , this .rightActualDescriptor );
98
+ DescriptorComparison dc = DescriptorComparison .checkNumericCompatibility (
99
+ leftDesc , rightDesc , this .leftActualDescriptor , this .rightActualDescriptor );
99
100
return (dc .areNumbers && dc .areCompatible );
100
101
}
101
102
@@ -109,9 +110,9 @@ protected void generateComparisonCode(MethodVisitor mv, CodeFlow cf, int compIns
109
110
110
111
boolean unboxLeft = !CodeFlow .isPrimitive (leftDesc );
111
112
boolean unboxRight = !CodeFlow .isPrimitive (rightDesc );
112
- DescriptorComparison dc = DescriptorComparison .checkNumericCompatibility (leftDesc , rightDesc ,
113
- this .leftActualDescriptor , this .rightActualDescriptor );
114
- char targetType = dc .compatibleType ;// CodeFlow.toPrimitiveTargetDesc(leftDesc);
113
+ DescriptorComparison dc = DescriptorComparison .checkNumericCompatibility (
114
+ leftDesc , rightDesc , this .leftActualDescriptor , this .rightActualDescriptor );
115
+ char targetType = dc .compatibleType ; // CodeFlow.toPrimitiveTargetDesc(leftDesc);
115
116
116
117
getLeftOperand ().generateCode (mv , cf );
117
118
if (unboxLeft ) {
@@ -128,23 +129,23 @@ protected void generateComparisonCode(MethodVisitor mv, CodeFlow cf, int compIns
128
129
// assert: SpelCompiler.boxingCompatible(leftDesc, rightDesc)
129
130
Label elseTarget = new Label ();
130
131
Label endOfIf = new Label ();
131
- if (targetType == 'D' ) {
132
+ if (targetType == 'D' ) {
132
133
mv .visitInsn (DCMPG );
133
134
mv .visitJumpInsn (compInstruction1 , elseTarget );
134
135
}
135
- else if (targetType == 'F' ) {
136
+ else if (targetType == 'F' ) {
136
137
mv .visitInsn (FCMPG );
137
138
mv .visitJumpInsn (compInstruction1 , elseTarget );
138
139
}
139
- else if (targetType == 'J' ) {
140
+ else if (targetType == 'J' ) {
140
141
mv .visitInsn (LCMP );
141
142
mv .visitJumpInsn (compInstruction1 , elseTarget );
142
143
}
143
- else if (targetType == 'I' ) {
144
+ else if (targetType == 'I' ) {
144
145
mv .visitJumpInsn (compInstruction2 , elseTarget );
145
146
}
146
147
else {
147
- throw new IllegalStateException ("Unexpected descriptor " + leftDesc );
148
+ throw new IllegalStateException ("Unexpected descriptor " + leftDesc );
148
149
}
149
150
150
151
// Other numbers are not yet supported (isCompilable will not have returned true)
@@ -215,34 +216,35 @@ else if (leftNumber instanceof Byte || rightNumber instanceof Byte) {
215
216
216
217
217
218
/**
218
- * A descriptor comparison encapsulates the result of comparing descriptor for two operands and
219
- * describes at what level they are compatible.
219
+ * A descriptor comparison encapsulates the result of comparing descriptor
220
+ * for two operands and describes at what level they are compatible.
220
221
*/
221
222
protected static class DescriptorComparison {
222
223
223
224
static DescriptorComparison NOT_NUMBERS = new DescriptorComparison (false , false , ' ' );
224
225
225
226
static DescriptorComparison INCOMPATIBLE_NUMBERS = new DescriptorComparison (true , false , ' ' );
226
227
227
- final boolean areNumbers ; // Were the two compared descriptor both for numbers?
228
+ final boolean areNumbers ; // Were the two compared descriptor both for numbers?
228
229
229
- final boolean areCompatible ; // If they were numbers, were they compatible?
230
+ final boolean areCompatible ; // If they were numbers, were they compatible?
231
+
232
+ final char compatibleType ; // When compatible, what is the descriptor of the common type
230
233
231
- final char compatibleType ; // When compatible, what is the descriptor of the common type
232
-
233
234
private DescriptorComparison (boolean areNumbers , boolean areCompatible , char compatibleType ) {
234
235
this .areNumbers = areNumbers ;
235
236
this .areCompatible = areCompatible ;
236
237
this .compatibleType = compatibleType ;
237
238
}
238
239
239
240
/**
240
- * Returns an object that indicates whether the input descriptors are compatible. A declared descriptor
241
- * is what could statically be determined (e.g. from looking at the return value of a property accessor
242
- * method) whilst an actual descriptor is the type of an actual object that was returned, which may differ.
243
- * For generic types with unbound type variables the declared descriptor discovered may be 'Object' but
244
- * from the actual descriptor it is possible to observe that the objects are really numeric values (e.g.
245
- * ints).
241
+ * Return an object that indicates whether the input descriptors are compatible.
242
+ * <p>A declared descriptor is what could statically be determined (e.g. from looking
243
+ * at the return value of a property accessor method) whilst an actual descriptor
244
+ * is the type of an actual object that was returned, which may differ.
245
+ * <p>For generic types with unbound type variables, the declared descriptor
246
+ * discovered may be 'Object' but from the actual descriptor it is possible to
247
+ * observe that the objects are really numeric values (e.g. ints).
246
248
* @param leftDeclaredDescriptor the statically determinable left descriptor
247
249
* @param rightDeclaredDescriptor the statically determinable right descriptor
248
250
* @param leftActualDescriptor the dynamic/runtime left object descriptor
0 commit comments