Merge branch '6.2.x'
# Conflicts: # spring-core/src/main/java/org/springframework/cglib/core/CodeEmitter.java
This commit is contained in:
commit
37319fc367
|
@ -27,34 +27,38 @@ import org.springframework.asm.Type;
|
|||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public class CodeEmitter extends LocalVariablesSorter {
|
||||
private static final Signature BOOLEAN_VALUE =
|
||||
TypeUtils.parseSignature("boolean booleanValue()");
|
||||
|
||||
// SPRING PATCH BEGIN
|
||||
private static final Signature BOOLEAN_VALUE_OF =
|
||||
TypeUtils.parseSignature("Boolean valueOf(boolean)");
|
||||
private static final Signature INTEGER_VALUE_OF =
|
||||
TypeUtils.parseSignature("Integer valueOf(int)");
|
||||
private static final Signature BYTE_VALUE_OF =
|
||||
TypeUtils.parseSignature("Byte valueOf(byte)");
|
||||
private static final Signature SHORT_VALUE_OF =
|
||||
TypeUtils.parseSignature("Short valueOf(short)");
|
||||
private static final Signature LONG_VALUE_OF =
|
||||
TypeUtils.parseSignature("Long valueOf(long)");
|
||||
private static final Signature FLOAT_VALUE_OF =
|
||||
TypeUtils.parseSignature("Float valueOf(float)");
|
||||
private static final Signature DOUBLE_VALUE_OF =
|
||||
TypeUtils.parseSignature("Double valueOf(double)");
|
||||
private static final Signature CHARACTER_VALUE_OF =
|
||||
TypeUtils.parseSignature("Character valueOf(char)");
|
||||
private static final Signature DOUBLE_VALUE_OF =
|
||||
TypeUtils.parseSignature("Double valueOf(double)");
|
||||
private static final Signature FLOAT_VALUE_OF =
|
||||
TypeUtils.parseSignature("Float valueOf(float)");
|
||||
private static final Signature INTEGER_VALUE_OF =
|
||||
TypeUtils.parseSignature("Integer valueOf(int)");
|
||||
private static final Signature LONG_VALUE_OF =
|
||||
TypeUtils.parseSignature("Long valueOf(long)");
|
||||
private static final Signature SHORT_VALUE_OF =
|
||||
TypeUtils.parseSignature("Short valueOf(short)");
|
||||
// SPRING PATCH END
|
||||
|
||||
private static final Signature BOOLEAN_VALUE =
|
||||
TypeUtils.parseSignature("boolean booleanValue()");
|
||||
private static final Signature CHAR_VALUE =
|
||||
TypeUtils.parseSignature("char charValue()");
|
||||
private static final Signature LONG_VALUE =
|
||||
TypeUtils.parseSignature("long longValue()");
|
||||
private static final Signature DOUBLE_VALUE =
|
||||
TypeUtils.parseSignature("double doubleValue()");
|
||||
private static final Signature FLOAT_VALUE =
|
||||
TypeUtils.parseSignature("float floatValue()");
|
||||
private static final Signature INT_VALUE =
|
||||
TypeUtils.parseSignature("int intValue()");
|
||||
private static final Signature LONG_VALUE =
|
||||
TypeUtils.parseSignature("long longValue()");
|
||||
private static final Signature CSTRUCT_NULL =
|
||||
TypeUtils.parseConstructor("");
|
||||
private static final Signature CSTRUCT_STRING =
|
||||
|
@ -70,7 +74,6 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public static final int REM = Constants.IREM;
|
||||
public static final int AND = Constants.IAND;
|
||||
public static final int OR = Constants.IOR;
|
||||
|
||||
public static final int GT = Constants.IFGT;
|
||||
public static final int LT = Constants.IFLT;
|
||||
public static final int GE = Constants.IFGE;
|
||||
|
@ -79,48 +82,9 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public static final int EQ = Constants.IFEQ;
|
||||
|
||||
private ClassEmitter ce;
|
||||
|
||||
private State state;
|
||||
|
||||
private static class State
|
||||
extends MethodInfo
|
||||
{
|
||||
ClassInfo classInfo;
|
||||
int access;
|
||||
Signature sig;
|
||||
Type[] argumentTypes;
|
||||
int localOffset;
|
||||
Type[] exceptionTypes;
|
||||
|
||||
State(ClassInfo classInfo, int access, Signature sig, Type[] exceptionTypes) {
|
||||
this.classInfo = classInfo;
|
||||
this.access = access;
|
||||
this.sig = sig;
|
||||
this.exceptionTypes = exceptionTypes;
|
||||
localOffset = TypeUtils.isStatic(access) ? 0 : 1;
|
||||
argumentTypes = sig.getArgumentTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassInfo getClassInfo() {
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return access;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signature getSignature() {
|
||||
return sig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getExceptionTypes() {
|
||||
return exceptionTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CodeEmitter(ClassEmitter ce, MethodVisitor mv, int access, Signature sig, Type[] exceptionTypes) {
|
||||
super(access, sig.getDescriptor(), mv);
|
||||
|
@ -134,6 +98,7 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
this.state = wrap.state;
|
||||
}
|
||||
|
||||
|
||||
public boolean isStaticHook() {
|
||||
return false;
|
||||
}
|
||||
|
@ -172,9 +137,17 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
exception.getInternalName());
|
||||
}
|
||||
|
||||
public void goTo(Label label) { mv.visitJumpInsn(Constants.GOTO, label); }
|
||||
public void ifnull(Label label) { mv.visitJumpInsn(Constants.IFNULL, label); }
|
||||
public void ifnonnull(Label label) { mv.visitJumpInsn(Constants.IFNONNULL, label); }
|
||||
public void goTo(Label label) {
|
||||
mv.visitJumpInsn(Constants.GOTO, label);
|
||||
}
|
||||
|
||||
public void ifnull(Label label) {
|
||||
mv.visitJumpInsn(Constants.IFNULL, label);
|
||||
}
|
||||
|
||||
public void ifnonnull(Label label) {
|
||||
mv.visitJumpInsn(Constants.IFNONNULL, label);
|
||||
}
|
||||
|
||||
public void if_jump(int mode, Label label) {
|
||||
mv.visitJumpInsn(mode, label);
|
||||
|
@ -188,8 +161,12 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
int intOp = -1;
|
||||
int jumpmode = mode;
|
||||
switch (mode) {
|
||||
case GE: jumpmode = LT; break;
|
||||
case LE: jumpmode = GT; break;
|
||||
case GE:
|
||||
jumpmode = LT;
|
||||
break;
|
||||
case LE:
|
||||
jumpmode = GT;
|
||||
break;
|
||||
}
|
||||
switch (type.getSort()) {
|
||||
case Type.LONG:
|
||||
|
@ -214,12 +191,22 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
throw new IllegalArgumentException("Bad comparison for type " + type);
|
||||
default:
|
||||
switch (mode) {
|
||||
case EQ: intOp = Constants.IF_ICMPEQ; break;
|
||||
case NE: intOp = Constants.IF_ICMPNE; break;
|
||||
case GE: swap(); /* fall through */
|
||||
case LT: intOp = Constants.IF_ICMPLT; break;
|
||||
case LE: swap(); /* fall through */
|
||||
case GT: intOp = Constants.IF_ICMPGT; break;
|
||||
case EQ:
|
||||
intOp = Constants.IF_ICMPEQ;
|
||||
break;
|
||||
case NE:
|
||||
intOp = Constants.IF_ICMPNE;
|
||||
break;
|
||||
case GE:
|
||||
swap(); /* fall through */
|
||||
case LT:
|
||||
intOp = Constants.IF_ICMPLT;
|
||||
break;
|
||||
case LE:
|
||||
swap(); /* fall through */
|
||||
case GT:
|
||||
intOp = Constants.IF_ICMPGT;
|
||||
break;
|
||||
}
|
||||
mv.visitJumpInsn(intOp, label);
|
||||
return;
|
||||
|
@ -227,43 +214,87 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
if_jump(jumpmode, label);
|
||||
}
|
||||
|
||||
public void pop() { mv.visitInsn(Constants.POP); }
|
||||
public void pop2() { mv.visitInsn(Constants.POP2); }
|
||||
public void dup() { mv.visitInsn(Constants.DUP); }
|
||||
public void dup2() { mv.visitInsn(Constants.DUP2); }
|
||||
public void dup_x1() { mv.visitInsn(Constants.DUP_X1); }
|
||||
public void dup_x2() { mv.visitInsn(Constants.DUP_X2); }
|
||||
public void dup2_x1() { mv.visitInsn(Constants.DUP2_X1); }
|
||||
public void dup2_x2() { mv.visitInsn(Constants.DUP2_X2); }
|
||||
public void swap() { mv.visitInsn(Constants.SWAP); }
|
||||
public void aconst_null() { mv.visitInsn(Constants.ACONST_NULL); }
|
||||
public void pop() {
|
||||
mv.visitInsn(Constants.POP);
|
||||
}
|
||||
|
||||
public void pop2() {
|
||||
mv.visitInsn(Constants.POP2);
|
||||
}
|
||||
|
||||
public void dup() {
|
||||
mv.visitInsn(Constants.DUP);
|
||||
}
|
||||
|
||||
public void dup2() {
|
||||
mv.visitInsn(Constants.DUP2);
|
||||
}
|
||||
|
||||
public void dup_x1() {
|
||||
mv.visitInsn(Constants.DUP_X1);
|
||||
}
|
||||
|
||||
public void dup_x2() {
|
||||
mv.visitInsn(Constants.DUP_X2);
|
||||
}
|
||||
|
||||
public void dup2_x1() {
|
||||
mv.visitInsn(Constants.DUP2_X1);
|
||||
}
|
||||
|
||||
public void dup2_x2() {
|
||||
mv.visitInsn(Constants.DUP2_X2);
|
||||
}
|
||||
|
||||
public void swap() {
|
||||
mv.visitInsn(Constants.SWAP);
|
||||
}
|
||||
|
||||
public void aconst_null() {
|
||||
mv.visitInsn(Constants.ACONST_NULL);
|
||||
}
|
||||
|
||||
public void swap(Type prev, Type type) {
|
||||
if (type.getSize() == 1) {
|
||||
if (prev.getSize() == 1) {
|
||||
swap(); // same as dup_x1(), pop();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
dup_x2();
|
||||
pop();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (prev.getSize() == 1) {
|
||||
dup2_x1();
|
||||
pop2();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
dup2_x2();
|
||||
pop2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void monitorenter() { mv.visitInsn(Constants.MONITORENTER); }
|
||||
public void monitorexit() { mv.visitInsn(Constants.MONITOREXIT); }
|
||||
public void monitorenter() {
|
||||
mv.visitInsn(Constants.MONITORENTER);
|
||||
}
|
||||
|
||||
public void math(int op, Type type) { mv.visitInsn(type.getOpcode(op)); }
|
||||
public void monitorexit() {
|
||||
mv.visitInsn(Constants.MONITOREXIT);
|
||||
}
|
||||
|
||||
public void array_load(Type type) { mv.visitInsn(type.getOpcode(Constants.IALOAD)); }
|
||||
public void array_store(Type type) { mv.visitInsn(type.getOpcode(Constants.IASTORE)); }
|
||||
public void math(int op, Type type) {
|
||||
mv.visitInsn(type.getOpcode(op));
|
||||
}
|
||||
|
||||
public void array_load(Type type) {
|
||||
mv.visitInsn(type.getOpcode(Constants.IALOAD));
|
||||
}
|
||||
|
||||
public void array_store(Type type) {
|
||||
mv.visitInsn(type.getOpcode(Constants.IASTORE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts from one primitive numeric type to another
|
||||
|
@ -273,42 +304,56 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
if (from == Type.DOUBLE_TYPE) {
|
||||
if (to == Type.FLOAT_TYPE) {
|
||||
mv.visitInsn(Constants.D2F);
|
||||
} else if (to == Type.LONG_TYPE) {
|
||||
}
|
||||
else if (to == Type.LONG_TYPE) {
|
||||
mv.visitInsn(Constants.D2L);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitInsn(Constants.D2I);
|
||||
cast_numeric(Type.INT_TYPE, to);
|
||||
}
|
||||
} else if (from == Type.FLOAT_TYPE) {
|
||||
}
|
||||
else if (from == Type.FLOAT_TYPE) {
|
||||
if (to == Type.DOUBLE_TYPE) {
|
||||
mv.visitInsn(Constants.F2D);
|
||||
} else if (to == Type.LONG_TYPE) {
|
||||
}
|
||||
else if (to == Type.LONG_TYPE) {
|
||||
mv.visitInsn(Constants.F2L);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitInsn(Constants.F2I);
|
||||
cast_numeric(Type.INT_TYPE, to);
|
||||
}
|
||||
} else if (from == Type.LONG_TYPE) {
|
||||
}
|
||||
else if (from == Type.LONG_TYPE) {
|
||||
if (to == Type.DOUBLE_TYPE) {
|
||||
mv.visitInsn(Constants.L2D);
|
||||
} else if (to == Type.FLOAT_TYPE) {
|
||||
}
|
||||
else if (to == Type.FLOAT_TYPE) {
|
||||
mv.visitInsn(Constants.L2F);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitInsn(Constants.L2I);
|
||||
cast_numeric(Type.INT_TYPE, to);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (to == Type.BYTE_TYPE) {
|
||||
mv.visitInsn(Constants.I2B);
|
||||
} else if (to == Type.CHAR_TYPE) {
|
||||
}
|
||||
else if (to == Type.CHAR_TYPE) {
|
||||
mv.visitInsn(Constants.I2C);
|
||||
} else if (to == Type.DOUBLE_TYPE) {
|
||||
}
|
||||
else if (to == Type.DOUBLE_TYPE) {
|
||||
mv.visitInsn(Constants.I2D);
|
||||
} else if (to == Type.FLOAT_TYPE) {
|
||||
}
|
||||
else if (to == Type.FLOAT_TYPE) {
|
||||
mv.visitInsn(Constants.I2F);
|
||||
} else if (to == Type.LONG_TYPE) {
|
||||
}
|
||||
else if (to == Type.LONG_TYPE) {
|
||||
mv.visitInsn(Constants.I2L);
|
||||
} else if (to == Type.SHORT_TYPE) {
|
||||
}
|
||||
else if (to == Type.SHORT_TYPE) {
|
||||
mv.visitInsn(Constants.I2S);
|
||||
}
|
||||
}
|
||||
|
@ -318,13 +363,17 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public void push(int i) {
|
||||
if (i < -1) {
|
||||
mv.visitLdcInsn(i);
|
||||
} else if (i <= 5) {
|
||||
}
|
||||
else if (i <= 5) {
|
||||
mv.visitInsn(TypeUtils.ICONST(i));
|
||||
} else if (i <= Byte.MAX_VALUE) {
|
||||
}
|
||||
else if (i <= Byte.MAX_VALUE) {
|
||||
mv.visitIntInsn(Constants.BIPUSH, i);
|
||||
} else if (i <= Short.MAX_VALUE) {
|
||||
}
|
||||
else if (i <= Short.MAX_VALUE) {
|
||||
mv.visitIntInsn(Constants.SIPUSH, i);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitLdcInsn(i);
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +381,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public void push(long value) {
|
||||
if (value == 0L || value == 1L) {
|
||||
mv.visitInsn(TypeUtils.LCONST(value));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
@ -340,14 +390,17 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public void push(float value) {
|
||||
if (value == 0f || value == 1f || value == 2f) {
|
||||
mv.visitInsn(TypeUtils.FCONST(value));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void push(double value) {
|
||||
if (value == 0d || value == 1d) {
|
||||
mv.visitInsn(TypeUtils.DCONST(value));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
@ -363,7 +416,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public void newarray(Type type) {
|
||||
if (TypeUtils.isPrimitive(type)) {
|
||||
mv.visitIntInsn(Constants.NEWARRAY, TypeUtils.NEWARRAY(type));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
emit_type(Constants.ANEWARRAY, type);
|
||||
}
|
||||
}
|
||||
|
@ -388,6 +442,7 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
|
||||
/**
|
||||
* Pushes the specified argument of the current method onto the stack.
|
||||
*
|
||||
* @param index the zero-based index into the argument list
|
||||
*/
|
||||
public void load_arg(int index) {
|
||||
|
@ -573,7 +628,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
String desc;
|
||||
if (TypeUtils.isArray(type)) {
|
||||
desc = type.getDescriptor();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
desc = type.getInternalName();
|
||||
}
|
||||
mv.visitTypeInsn(opcode, desc);
|
||||
|
@ -584,9 +640,17 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
aaload();
|
||||
}
|
||||
|
||||
public void aaload() { mv.visitInsn(Constants.AALOAD); }
|
||||
public void aastore() { mv.visitInsn(Constants.AASTORE); }
|
||||
public void athrow() { mv.visitInsn(Constants.ATHROW); }
|
||||
public void aaload() {
|
||||
mv.visitInsn(Constants.AALOAD);
|
||||
}
|
||||
|
||||
public void aastore() {
|
||||
mv.visitInsn(Constants.AASTORE);
|
||||
}
|
||||
|
||||
public void athrow() {
|
||||
mv.visitInsn(Constants.ATHROW);
|
||||
}
|
||||
|
||||
public Label make_label() {
|
||||
return new Label();
|
||||
|
@ -622,7 +686,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
float density;
|
||||
if (keys.length == 0) {
|
||||
density = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
density = (float) keys.length / (keys[keys.length - 1] - keys[0] + 1);
|
||||
}
|
||||
process_switch(keys, callback, density >= 0.5f);
|
||||
|
@ -656,7 +721,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
callback.processCase(i + min, end);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Label[] labels = new Label[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
labels[i] = make_label();
|
||||
|
@ -673,9 +739,11 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
callback.processDefault();
|
||||
mark(end);
|
||||
|
||||
} catch (RuntimeException | Error e) {
|
||||
}
|
||||
catch (RuntimeException | Error e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
}
|
||||
|
@ -724,6 +792,7 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
* on the top of the stack with the wrapped (Object) equivalent using valueOf() methods.
|
||||
* For example, char -> Character.
|
||||
* If the class is Void, a null is pushed onto the stack instead.
|
||||
*
|
||||
* @param type the class indicating the current type of the top stack value
|
||||
*/
|
||||
public void box(Type type) {
|
||||
|
@ -732,31 +801,32 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
case Type.VOID:
|
||||
aconst_null();
|
||||
break;
|
||||
// SPRING PATCH BEGIN
|
||||
case Type.CHAR:
|
||||
invoke_static(Constants.TYPE_CHARACTER, CHARACTER_VALUE_OF);
|
||||
break;
|
||||
case Type.BOOLEAN:
|
||||
invoke_static(Constants.TYPE_BOOLEAN, BOOLEAN_VALUE_OF);
|
||||
break;
|
||||
case Type.INT:
|
||||
invoke_static(Constants.TYPE_INTEGER, INTEGER_VALUE_OF);
|
||||
break;
|
||||
case Type.BYTE:
|
||||
invoke_static(Constants.TYPE_BYTE, BYTE_VALUE_OF);
|
||||
break;
|
||||
case Type.SHORT:
|
||||
invoke_static(Constants.TYPE_SHORT, SHORT_VALUE_OF);
|
||||
break;
|
||||
case Type.LONG:
|
||||
invoke_static(Constants.TYPE_LONG, LONG_VALUE_OF);
|
||||
break;
|
||||
case Type.FLOAT:
|
||||
invoke_static(Constants.TYPE_FLOAT, FLOAT_VALUE_OF);
|
||||
break;
|
||||
case Type.DOUBLE:
|
||||
invoke_static(Constants.TYPE_DOUBLE, DOUBLE_VALUE_OF);
|
||||
break;
|
||||
case Type.CHAR:
|
||||
invoke_static(Constants.TYPE_CHARACTER, CHARACTER_VALUE_OF);
|
||||
case Type.FLOAT:
|
||||
invoke_static(Constants.TYPE_FLOAT, FLOAT_VALUE_OF);
|
||||
break;
|
||||
|
||||
case Type.LONG:
|
||||
invoke_static(Constants.TYPE_LONG, LONG_VALUE_OF);
|
||||
break;
|
||||
case Type.INT:
|
||||
invoke_static(Constants.TYPE_INTEGER, INTEGER_VALUE_OF);
|
||||
break;
|
||||
case Type.SHORT:
|
||||
invoke_static(Constants.TYPE_SHORT, SHORT_VALUE_OF);
|
||||
break;
|
||||
case Type.BYTE:
|
||||
invoke_static(Constants.TYPE_BYTE, BYTE_VALUE_OF);
|
||||
break;
|
||||
// SPRING PATCH END
|
||||
default:
|
||||
Type boxed = TypeUtils.getBoxedType(type);
|
||||
new_instance(boxed);
|
||||
|
@ -765,7 +835,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
dup_x2();
|
||||
dup_x2();
|
||||
pop();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// p -> po -> opo -> oop -> o
|
||||
dup_x1();
|
||||
swap();
|
||||
|
@ -779,6 +850,7 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
* If the argument is a primitive class, replaces the object
|
||||
* on the top of the stack with the unwrapped (primitive)
|
||||
* equivalent. For example, Character -> char.
|
||||
*
|
||||
* @param type the class indicating the desired type of the top stack value
|
||||
*/
|
||||
public void unbox(Type type) {
|
||||
|
@ -812,7 +884,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
|
||||
if (sig == null) {
|
||||
checkcast(type);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
checkcast(t);
|
||||
invoke_virtual(t, sig);
|
||||
}
|
||||
|
@ -860,7 +933,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
default:
|
||||
push(0);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
aconst_null();
|
||||
}
|
||||
}
|
||||
|
@ -883,7 +957,8 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
unbox(type);
|
||||
mark(end);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
checkcast(type);
|
||||
}
|
||||
}
|
||||
|
@ -901,11 +976,14 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
Signature sig = method.getSignature();
|
||||
if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) {
|
||||
invoke_constructor(type, sig);
|
||||
} else if (TypeUtils.isStatic(method.getModifiers())) {
|
||||
}
|
||||
else if (TypeUtils.isStatic(method.getModifiers())) {
|
||||
invoke_static(type, sig, TypeUtils.isInterface(classInfo.getModifiers()));
|
||||
} else if (TypeUtils.isInterface(classInfo.getModifiers())) {
|
||||
}
|
||||
else if (TypeUtils.isInterface(classInfo.getModifiers())) {
|
||||
invoke_interface(type, sig);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
invoke_virtual(virtualType, sig);
|
||||
}
|
||||
}
|
||||
|
@ -913,4 +991,50 @@ public class CodeEmitter extends LocalVariablesSorter {
|
|||
public void invoke(MethodInfo method) {
|
||||
invoke(method, method.getClassInfo().getType());
|
||||
}
|
||||
|
||||
|
||||
private static class State extends MethodInfo {
|
||||
|
||||
ClassInfo classInfo;
|
||||
|
||||
int access;
|
||||
|
||||
Signature sig;
|
||||
|
||||
Type[] argumentTypes;
|
||||
|
||||
int localOffset;
|
||||
|
||||
Type[] exceptionTypes;
|
||||
|
||||
State(ClassInfo classInfo, int access, Signature sig, Type[] exceptionTypes) {
|
||||
this.classInfo = classInfo;
|
||||
this.access = access;
|
||||
this.sig = sig;
|
||||
this.exceptionTypes = exceptionTypes;
|
||||
localOffset = TypeUtils.isStatic(access) ? 0 : 1;
|
||||
argumentTypes = sig.getArgumentTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassInfo getClassInfo() {
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return access;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signature getSignature() {
|
||||
return sig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getExceptionTypes() {
|
||||
return exceptionTypes;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -392,7 +392,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
|||
}
|
||||
else {
|
||||
// a single resource with the given name
|
||||
return new Resource[] {getResourceLoader().getResource(locationPattern)};
|
||||
return new Resource[] {getResource(locationPattern)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue