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