Here are the examples of the java api org.springframework.asm.MethodVisitor taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
89 Examples
19
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* For use in mathematical operators, handles converting from a (possibly boxed)
* number on the stack to a primitive numeric type.
* <p>For example, from a Integer to a double, just need to call 'Number.doubleValue()'
* but from an int to a double, need to use the bytecode 'i2d'.
* @param mv the method visitor when instructions should be appended
* @param stackDescriptor a descriptor of the operand on the stack
* @param targetDescriptor a primitive type descriptor
*/
public static void insertNumericUnboxOrPrimitiveTypeCoercion(MethodVisitor mv, @Nullable String stackDescriptor, char targetDescriptor) {
if (!CodeFlow.isPrimitive(stackDescriptor)) {
CodeFlow.insertUnboxNumberInsns(mv, targetDescriptor, stackDescriptor);
} else {
CodeFlow.insertAnyNecessaryTypeConversionBytecodes(mv, targetDescriptor, stackDescriptor);
}
}
19
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Push the byte code to load the target (i.e. what was preplaceded as the first argument
* to CompiledExpression.getValue(target, context))
* @param mv the visitor into which the load instruction should be inserted
*/
public void loadTarget(MethodVisitor mv) {
mv.visitVarInsn(ALOAD, 1);
}
19
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Push the bytecode to load the EvaluationContext (the second parameter preplaceded to
* the compiled expression method).
* @param mv the visitor into which the load instruction should be inserted
* @since 4.3.4
*/
public void loadEvaluationContext(MethodVisitor mv) {
mv.visitVarInsn(ALOAD, 2);
}
19
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Determine the appropriate boxing instruction for a specific type (if it needs
* boxing) and insert the instruction into the supplied visitor.
* @param mv the target visitor for the new instructions
* @param descriptor the descriptor of a type that may or may not need boxing
*/
public static void insertBoxIfNecessary(MethodVisitor mv, @Nullable String descriptor) {
if (descriptor != null && descriptor.length() == 1) {
insertBoxIfNecessary(mv, descriptor.charAt(0));
}
}
19
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* If the codeflow shows the last expression evaluated to java.lang.Boolean then
* insert the necessary instructions to unbox that to a boolean primitive.
* @param mv the visitor into which new instructions should be inserted
*/
public void unboxBooleanIfNecessary(MethodVisitor mv) {
if ("Ljava/lang/Boolean".equals(lastDescriptor())) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
}
}
19
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Determine the appropriate boxing instruction for a specific type (if it needs
* boxing) and insert the instruction into the supplied visitor.
* @param mv the target visitor for the new instructions
* @param ch the descriptor of the type that might need boxing
*/
public static void insertBoxIfNecessary(MethodVisitor mv, char ch) {
switch(ch) {
case 'Z':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
break;
case 'B':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
break;
case 'C':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
break;
case 'D':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
break;
case 'F':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
break;
case 'I':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
break;
case 'J':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
break;
case 'S':
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
break;
case 'L':
case 'V':
case '[':
// no box needed
break;
default:
throw new IllegalArgumentException("Boxing should not be attempted for descriptor '" + ch + "'");
}
}
19
View Source File : SpelNodeImpl.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Generate the bytecode for this node into the supplied visitor. Context info about
* the current expression being compiled is available in the codeflow object, e.g.
* including information about the type of the object currently on the stack.
* @param mv the ASM MethodVisitor into which code should be generated
* @param cf a context object with info about what is on the stack
*/
public void generateCode(MethodVisitor mv, CodeFlow cf) {
throw new IllegalStateException(getClreplaced().getName() + " has no generateCode(..) method");
}
19
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Determine the appropriate boxing instruction for a specific type (if it needs
* boxing) and insert the instruction into the supplied visitor.
* @param mv the target visitor for the new instructions
* @param descriptor the descriptor of a type that may or may not need boxing
*/
public static void insertBoxIfNecessary(MethodVisitor mv, String descriptor) {
if (descriptor.length() == 1) {
insertBoxIfNecessary(mv, descriptor.charAt(0));
}
}
19
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* If the codeflow shows the last expression evaluated to java.lang.Boolean then
* insert the necessary instructions to unbox that to a boolean primitive.
* @param mv the visitor into which new instructions should be inserted
*/
public void unboxBooleanIfNecessary(MethodVisitor mv) {
if (lastDescriptor().equals("Ljava/lang/Boolean")) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
}
}
19
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* For use in mathematical operators, handles converting from a (possibly boxed)
* number on the stack to a primitive numeric type.
* <p>For example, from a Integer to a double, just need to call 'Number.doubleValue()'
* but from an int to a double, need to use the bytecode 'i2d'.
* @param mv the method visitor when instructions should be appended
* @param stackDescriptor a descriptor of the operand on the stack
* @param targetDescriptor a primitive type descriptor
*/
public static void insertNumericUnboxOrPrimitiveTypeCoercion(MethodVisitor mv, String stackDescriptor, char targetDescriptor) {
if (!CodeFlow.isPrimitive(stackDescriptor)) {
CodeFlow.insertUnboxNumberInsns(mv, targetDescriptor, stackDescriptor);
} else {
CodeFlow.insertAnyNecessaryTypeConversionBytecodes(mv, targetDescriptor, stackDescriptor);
}
}
19
View Source File : SpelNodeImpl.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Generate the bytecode for this node into the supplied visitor. Context info about
* the current expression being compiled is available in the codeflow object. For
* example it will include information about the type of the object currently
* on the stack.
* @param mv the ASM MethodVisitor into which code should be generated
* @param cf a context object with info about what is on the stack
*/
public void generateCode(MethodVisitor mv, CodeFlow cf) {
throw new IllegalStateException(getClreplaced().getName() + " has no generateCode(..) method");
}
18
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Insert any necessary cast and value call to convert from a boxed type to a
* primitive value.
* @param mv the method visitor into which instructions should be inserted
* @param ch the primitive type desired as output
* @param stackDescriptor the descriptor of the type on top of the stack
*/
public static void insertUnboxInsns(MethodVisitor mv, char ch, @Nullable String stackDescriptor) {
if (stackDescriptor == null) {
return;
}
switch(ch) {
case 'Z':
if (!stackDescriptor.equals("Ljava/lang/Boolean")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
break;
case 'B':
if (!stackDescriptor.equals("Ljava/lang/Byte")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
break;
case 'C':
if (!stackDescriptor.equals("Ljava/lang/Character")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
break;
case 'D':
if (!stackDescriptor.equals("Ljava/lang/Double")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
break;
case 'F':
if (!stackDescriptor.equals("Ljava/lang/Float")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
break;
case 'I':
if (!stackDescriptor.equals("Ljava/lang/Integer")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
break;
case 'J':
if (!stackDescriptor.equals("Ljava/lang/Long")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
break;
case 'S':
if (!stackDescriptor.equals("Ljava/lang/Short")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
break;
default:
throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + ch + "'");
}
}
18
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Insert the appropriate CHECKCAST instruction for the supplied descriptor.
* @param mv the target visitor into which the instruction should be inserted
* @param descriptor the descriptor of the type to cast to
*/
public static void insertCheckCast(MethodVisitor mv, @Nullable String descriptor) {
if (descriptor != null && descriptor.length() != 1) {
if (descriptor.charAt(0) == '[') {
if (isPrimitiveArray(descriptor)) {
mv.visitTypeInsn(CHECKCAST, descriptor);
} else {
mv.visitTypeInsn(CHECKCAST, descriptor + ";");
}
} else {
if (!descriptor.equals("Ljava/lang/Object")) {
// This is chopping off the 'L' to leave us with "java/lang/String"
mv.visitTypeInsn(CHECKCAST, descriptor.substring(1));
}
}
}
}
18
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Insert any necessary numeric conversion bytecodes based upon what is on the stack and the desired target type.
* @param mv the method visitor into which instructions should be placed
* @param targetDescriptor the (primitive) descriptor of the target type
* @param stackDescriptor the descriptor of the operand on top of the stack
*/
public static void insertAnyNecessaryTypeConversionBytecodes(MethodVisitor mv, char targetDescriptor, String stackDescriptor) {
if (CodeFlow.isPrimitive(stackDescriptor)) {
char stackTop = stackDescriptor.charAt(0);
if (stackTop == 'I' || stackTop == 'B' || stackTop == 'S' || stackTop == 'C') {
if (targetDescriptor == 'D') {
mv.visitInsn(I2D);
} else if (targetDescriptor == 'F') {
mv.visitInsn(I2F);
} else if (targetDescriptor == 'J') {
mv.visitInsn(I2L);
} else if (targetDescriptor == 'I') {
// nop
} else {
throw new IllegalStateException("Cannot get from " + stackTop + " to " + targetDescriptor);
}
} else if (stackTop == 'J') {
if (targetDescriptor == 'D') {
mv.visitInsn(L2D);
} else if (targetDescriptor == 'F') {
mv.visitInsn(L2F);
} else if (targetDescriptor == 'J') {
// nop
} else if (targetDescriptor == 'I') {
mv.visitInsn(L2I);
} else {
throw new IllegalStateException("Cannot get from " + stackTop + " to " + targetDescriptor);
}
} else if (stackTop == 'F') {
if (targetDescriptor == 'D') {
mv.visitInsn(F2D);
} else if (targetDescriptor == 'F') {
// nop
} else if (targetDescriptor == 'J') {
mv.visitInsn(F2L);
} else if (targetDescriptor == 'I') {
mv.visitInsn(F2I);
} else {
throw new IllegalStateException("Cannot get from " + stackTop + " to " + targetDescriptor);
}
} else if (stackTop == 'D') {
if (targetDescriptor == 'D') {
// nop
} else if (targetDescriptor == 'F') {
mv.visitInsn(D2F);
} else if (targetDescriptor == 'J') {
mv.visitInsn(D2L);
} else if (targetDescriptor == 'I') {
mv.visitInsn(D2I);
} else {
throw new IllegalStateException("Cannot get from " + stackDescriptor + " to " + targetDescriptor);
}
}
}
}
18
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* For numbers, use the appropriate method on the number to convert it to the primitive type requested.
* @param mv the method visitor into which instructions should be inserted
* @param targetDescriptor the primitive type desired as output
* @param stackDescriptor the descriptor of the type on top of the stack
*/
public static void insertUnboxNumberInsns(MethodVisitor mv, char targetDescriptor, @Nullable String stackDescriptor) {
if (stackDescriptor == null) {
return;
}
switch(targetDescriptor) {
case 'D':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false);
break;
case 'F':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false);
break;
case 'J':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false);
break;
case 'I':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
break;
// does not handle Z, B, C, S
default:
throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + targetDescriptor + "'");
}
}
18
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Produce appropriate bytecode to store a stack item in an array. The
* instruction to use varies depending on whether the type
* is a primitive or reference type.
* @param mv where to insert the bytecode
* @param arrayElementType the type of the array elements
*/
public static void insertArrayStore(MethodVisitor mv, String arrayElementType) {
if (arrayElementType.length() == 1) {
switch(arrayElementType.charAt(0)) {
case 'I':
mv.visitInsn(IASTORE);
break;
case 'J':
mv.visitInsn(LASTORE);
break;
case 'F':
mv.visitInsn(FASTORE);
break;
case 'D':
mv.visitInsn(DASTORE);
break;
case 'B':
mv.visitInsn(BASTORE);
break;
case 'C':
mv.visitInsn(CASTORE);
break;
case 'S':
mv.visitInsn(SASTORE);
break;
case 'Z':
mv.visitInsn(BASTORE);
break;
default:
throw new IllegalArgumentException("Unexpected arraytype " + arrayElementType.charAt(0));
}
} else {
mv.visitInsn(AASTORE);
}
}
18
View Source File : StringLiteral.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
mv.visitLdcInsn(this.value.getValue());
cf.pushDescriptor(this.exitTypeDescriptor);
}
18
View Source File : OpLT.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
generateComparisonCode(mv, cf, IFGE, IF_ICMPGE);
}
18
View Source File : OpLE.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
generateComparisonCode(mv, cf, IFGT, IF_ICMPGT);
}
18
View Source File : OpGT.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
generateComparisonCode(mv, cf, IFLE, IF_ICMPLE);
}
18
View Source File : OpGE.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
generateComparisonCode(mv, cf, IFLT, IF_ICMPLT);
}
18
View Source File : CompoundExpression.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
for (SpelNodeImpl child : this.children) {
child.generateCode(mv, cf);
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
18
View Source File : BooleanLiteral.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
if (this.value == BooleanTypedValue.TRUE) {
mv.visitLdcInsn(1);
} else {
mv.visitLdcInsn(0);
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
18
View Source File : CompoundExpression.java
License : MIT License
Project Creator : mindcarver
License : MIT License
Project Creator : mindcarver
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
for (int i = 0; i < this.children.length; i++) {
this.children[i].generateCode(mv, cf);
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
18
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Insert the appropriate CHECKCAST instruction for the supplied descriptor.
* @param mv the target visitor into which the instruction should be inserted
* @param descriptor the descriptor of the type to cast to
*/
public static void insertCheckCast(MethodVisitor mv, String descriptor) {
if (descriptor.length() != 1) {
if (descriptor.charAt(0) == '[') {
if (isPrimitiveArray(descriptor)) {
mv.visitTypeInsn(CHECKCAST, descriptor);
} else {
mv.visitTypeInsn(CHECKCAST, descriptor + ";");
}
} else {
if (!descriptor.equals("Ljava/lang/Object")) {
// This is chopping off the 'L' to leave us with "java/lang/String"
mv.visitTypeInsn(CHECKCAST, descriptor.substring(1));
}
}
}
}
18
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Insert any necessary numeric conversion bytecodes based upon what is on the stack and the desired target type.
* @param mv the method visitor into which instructions should be placed
* @param targetDescriptor the (primitive) descriptor of the target type
* @param stackDescriptor the descriptor of the operand on top of the stack
*/
public static void insertAnyNecessaryTypeConversionBytecodes(MethodVisitor mv, char targetDescriptor, String stackDescriptor) {
if (CodeFlow.isPrimitive(stackDescriptor)) {
char stackTop = stackDescriptor.charAt(0);
if (stackTop == 'I' || stackTop == 'B' || stackTop == 'S' || stackTop == 'C') {
if (targetDescriptor == 'D') {
mv.visitInsn(I2D);
} else if (targetDescriptor == 'F') {
mv.visitInsn(I2F);
} else if (targetDescriptor == 'J') {
mv.visitInsn(I2L);
} else if (targetDescriptor == 'I') {
// nop
} else {
throw new IllegalStateException("cannot get from " + stackTop + " to " + targetDescriptor);
}
} else if (stackTop == 'J') {
if (targetDescriptor == 'D') {
mv.visitInsn(L2D);
} else if (targetDescriptor == 'F') {
mv.visitInsn(L2F);
} else if (targetDescriptor == 'J') {
// nop
} else if (targetDescriptor == 'I') {
mv.visitInsn(L2I);
} else {
throw new IllegalStateException("cannot get from " + stackTop + " to " + targetDescriptor);
}
} else if (stackTop == 'F') {
if (targetDescriptor == 'D') {
mv.visitInsn(F2D);
} else if (targetDescriptor == 'F') {
// nop
} else if (targetDescriptor == 'J') {
mv.visitInsn(F2L);
} else if (targetDescriptor == 'I') {
mv.visitInsn(F2I);
} else {
throw new IllegalStateException("cannot get from " + stackTop + " to " + targetDescriptor);
}
} else if (stackTop == 'D') {
if (targetDescriptor == 'D') {
// nop
} else if (targetDescriptor == 'F') {
mv.visitInsn(D2F);
} else if (targetDescriptor == 'J') {
mv.visitInsn(D2L);
} else if (targetDescriptor == 'I') {
mv.visitInsn(D2I);
} else {
throw new IllegalStateException("cannot get from " + stackDescriptor + " to " + targetDescriptor);
}
}
}
}
18
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Insert any necessary cast and value call to convert from a boxed type to a
* primitive value
* @param mv the method visitor into which instructions should be inserted
* @param ch the primitive type desired as output
* @param stackDescriptor the descriptor of the type on top of the stack
*/
public static void insertUnboxInsns(MethodVisitor mv, char ch, String stackDescriptor) {
switch(ch) {
case 'Z':
if (!stackDescriptor.equals("Ljava/lang/Boolean")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
break;
case 'B':
if (!stackDescriptor.equals("Ljava/lang/Byte")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
break;
case 'C':
if (!stackDescriptor.equals("Ljava/lang/Character")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
break;
case 'D':
if (!stackDescriptor.equals("Ljava/lang/Double")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
break;
case 'F':
if (!stackDescriptor.equals("Ljava/lang/Float")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
break;
case 'I':
if (!stackDescriptor.equals("Ljava/lang/Integer")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
break;
case 'J':
if (!stackDescriptor.equals("Ljava/lang/Long")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
break;
case 'S':
if (!stackDescriptor.equals("Ljava/lang/Short")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
break;
default:
throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + ch + "'");
}
}
18
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* For numbers, use the appropriate method on the number to convert it to the primitive type requested.
* @param mv the method visitor into which instructions should be inserted
* @param targetDescriptor the primitive type desired as output
* @param stackDescriptor the descriptor of the type on top of the stack
*/
public static void insertUnboxNumberInsns(MethodVisitor mv, char targetDescriptor, String stackDescriptor) {
switch(targetDescriptor) {
case 'D':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false);
break;
case 'F':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false);
break;
case 'J':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false);
break;
case 'I':
if (stackDescriptor.equals("Ljava/lang/Object")) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
}
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
break;
// does not handle Z, B, C, S
default:
throw new IllegalArgumentException("Unboxing should not be attempted for descriptor '" + targetDescriptor + "'");
}
}
17
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Produce the correct bytecode to build an array. The opcode to use and the
* signature to preplaced along with the opcode can vary depending on the signature
* of the array type.
* @param mv the methodvisitor into which code should be inserted
* @param size the size of the array
* @param arraytype the type of the array
*/
public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) {
insertOptimalLoad(mv, size);
if (arraytype.length() == 1) {
mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype));
} else {
if (arraytype.charAt(0) == '[') {
// Handling the nested array case here.
// If vararg is [[I then we want [I and not [I;
if (CodeFlow.isReferenceTypeArray(arraytype)) {
mv.visitTypeInsn(ANEWARRAY, arraytype + ";");
} else {
mv.visitTypeInsn(ANEWARRAY, arraytype);
}
} else {
mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1));
}
}
}
17
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Create the optimal instruction for loading a number on the stack.
* @param mv where to insert the bytecode
* @param value the value to be loaded
*/
public static void insertOptimalLoad(MethodVisitor mv, int value) {
if (value < 6) {
mv.visitInsn(ICONST_0 + value);
} else if (value < Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, value);
} else if (value < Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, value);
} else {
mv.visitLdcInsn(value);
}
}
17
View Source File : VariableReference.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
if (this.name.equals(ROOT)) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(this.name);
mv.visitMethodInsn(INVOKEINTERFACE, "org/springframework/expression/EvaluationContext", "lookupVariable", "(Ljava/lang/String;)Ljava/lang/Object;", true);
}
CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
cf.pushDescriptor(this.exitTypeDescriptor);
}
17
View Source File : NullLiteral.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
mv.visitInsn(ACONST_NULL);
cf.pushDescriptor(this.exitTypeDescriptor);
}
17
View Source File : IntLiteral.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
Integer intValue = (Integer) this.value.getValue();
replacedert.state(intValue != null, "No int value");
if (intValue == -1) {
// Not sure we can get here because -1 is OpMinus
mv.visitInsn(ICONST_M1);
} else if (intValue >= 0 && intValue < 6) {
mv.visitInsn(ICONST_0 + intValue);
} else {
mv.visitLdcInsn(intValue);
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
17
View Source File : CodeFlow.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Produce the correct bytecode to build an array. The opcode to use and the
* signature to preplaced along with the opcode can vary depending on the signature
* of the array type.
* @param mv the methodvisitor into which code should be inserted
* @param size the size of the array
* @param arraytype the type of the array
*/
public static void insertNewArrayCode(MethodVisitor mv, int size, String arraytype) {
insertOptimalLoad(mv, size);
if (arraytype.length() == 1) {
mv.visitIntInsn(NEWARRAY, CodeFlow.arrayCodeFor(arraytype));
} else {
if (arraytype.charAt(0) == '[') {
// Handling the nested array case here. If vararg
// is [[I then we want [I and not [I;
if (CodeFlow.isReferenceTypeArray(arraytype)) {
mv.visitTypeInsn(ANEWARRAY, arraytype + ";");
} else {
mv.visitTypeInsn(ANEWARRAY, arraytype);
}
} else {
mv.visitTypeInsn(ANEWARRAY, arraytype.substring(1));
}
}
}
17
View Source File : VariableReference.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
if (this.name.equals(ROOT)) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitVarInsn(ALOAD, 2);
mv.visitLdcInsn(name);
mv.visitMethodInsn(INVOKEINTERFACE, "org/springframework/expression/EvaluationContext", "lookupVariable", "(Ljava/lang/String;)Ljava/lang/Object;", true);
}
CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
cf.pushDescriptor(this.exitTypeDescriptor);
}
17
View Source File : PropertyOrFieldReference.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
PropertyAccessor accessorToUse = this.cachedReadAccessor;
if (!(accessorToUse instanceof CompilablePropertyAccessor)) {
throw new IllegalStateException("Property accessor is not compilable: " + accessorToUse);
}
((CompilablePropertyAccessor) accessorToUse).generateCode(this.name, mv, cf);
cf.pushDescriptor(this.exitTypeDescriptor);
}
17
View Source File : IntLiteral.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
int intValue = (Integer) this.value.getValue();
if (intValue == -1) {
// Not sure we can get here because -1 is OpMinus
mv.visitInsn(ICONST_M1);
} else if (intValue >= 0 && intValue < 6) {
mv.visitInsn(ICONST_0 + intValue);
} else {
mv.visitLdcInsn(intValue);
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
17
View Source File : FunctionReference.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
String clreplacedDesc = this.method.getDeclaringClreplaced().getName().replace('.', '/');
generateCodeForArguments(mv, cf, this.method, this.children);
mv.visitMethodInsn(INVOKESTATIC, clreplacedDesc, this.method.getName(), CodeFlow.createSignatureDescriptor(this.method), false);
cf.pushDescriptor(this.exitTypeDescriptor);
}
16
View Source File : TypeReference.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
// TODO Future optimization - if followed by a static method call, skip generating code here
replacedert.state(this.type != null, "No type available");
if (this.type.isPrimitive()) {
if (this.type == Boolean.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Byte.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Character.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Double.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Float.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Integer.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Long.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Short.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Clreplaced;");
}
} else {
mv.visitLdcInsn(Type.getType(this.type));
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
16
View Source File : MapAccessor.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(String propertyName, MethodVisitor mv, CodeFlow cf) {
String descriptor = cf.lastDescriptor();
if (descriptor == null || !descriptor.equals("Ljava/util/Map")) {
if (descriptor == null) {
cf.loadTarget(mv);
}
CodeFlow.insertCheckCast(mv, "Ljava/util/Map");
}
mv.visitLdcInsn(propertyName);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
}
16
View Source File : TypeReference.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
// TODO Future optimization - if followed by a static method call, skip generating code here
if (this.type.isPrimitive()) {
if (this.type == Integer.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Boolean.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Byte.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Short.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Double.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Character.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Float.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Long.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Clreplaced;");
} else if (this.type == Boolean.TYPE) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Clreplaced;");
}
} else {
mv.visitLdcInsn(Type.getType(this.type));
}
cf.pushDescriptor(this.exitTypeDescriptor);
}
16
View Source File : OperatorInstanceof.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
getLeftOperand().generateCode(mv, cf);
mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(this.type));
cf.pushDescriptor(this.exitTypeDescriptor);
}
15
View Source File : CodeFlow.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Called after the main expression evaluation method has been generated, this
* method will callback any registered FieldAdders or ClinitAdders to add any
* extra information to the clreplaced representing the compiled expression.
*/
public void finish() {
if (this.fieldAdders != null) {
for (FieldAdder fieldAdder : this.fieldAdders) {
fieldAdder.generateField(this.clreplacedWriter, this);
}
}
if (this.clinitAdders != null) {
MethodVisitor mv = this.clreplacedWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
// to 0 because there is no 'this' in a clinit
this.nextFreeVariableId = 0;
for (ClinitAdder clinitAdder : this.clinitAdders) {
clinitAdder.generateCode(mv, this);
}
mv.visitInsn(RETURN);
// not supplied due to COMPUTE_MAXS
mv.visitMaxs(0, 0);
mv.visitEnd();
}
}
15
View Source File : SpelNodeImpl.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Generate code that handles building the argument values for the specified method.
* This method will take account of whether the invoked method is a varargs method
* and if it is then the argument values will be appropriately packaged into an array.
* @param mv the method visitor where code should be generated
* @param cf the current codeflow
* @param member the method or constructor for which arguments are being setup
* @param arguments the expression nodes for the expression supplied argument values
*/
protected static void generateCodeForArguments(MethodVisitor mv, CodeFlow cf, Member member, SpelNodeImpl[] arguments) {
String[] paramDescriptors = null;
boolean isVarargs = false;
if (member instanceof Constructor) {
Constructor<?> ctor = (Constructor<?>) member;
paramDescriptors = CodeFlow.toDescriptors(ctor.getParameterTypes());
isVarargs = ctor.isVarArgs();
} else {
// Method
Method method = (Method) member;
paramDescriptors = CodeFlow.toDescriptors(method.getParameterTypes());
isVarargs = method.isVarArgs();
}
if (isVarargs) {
// The final parameter may or may not need packaging into an array, or nothing may
// have been preplaceded to satisfy the varargs and so something needs to be built.
// Current supplied argument being processed
int p = 0;
int childCount = arguments.length;
// Fulfill all the parameter requirements except the last one
for (p = 0; p < paramDescriptors.length - 1; p++) {
generateCodeForArgument(mv, cf, arguments[p], paramDescriptors[p]);
}
SpelNodeImpl lastChild = (childCount == 0 ? null : arguments[childCount - 1]);
String arrayType = paramDescriptors[paramDescriptors.length - 1];
// Determine if the final preplaceded argument is already suitably packaged in array
// form to be preplaceded to the method
if (lastChild != null && arrayType.equals(lastChild.getExitDescriptor())) {
generateCodeForArgument(mv, cf, lastChild, paramDescriptors[p]);
} else {
// trim the leading '[', may leave other '['
arrayType = arrayType.substring(1);
// build array big enough to hold remaining arguments
CodeFlow.insertNewArrayCode(mv, childCount - p, arrayType);
// Package up the remaining arguments into the array
int arrayindex = 0;
while (p < childCount) {
SpelNodeImpl child = arguments[p];
mv.visitInsn(DUP);
CodeFlow.insertOptimalLoad(mv, arrayindex++);
generateCodeForArgument(mv, cf, child, arrayType);
CodeFlow.insertArrayStore(mv, arrayType);
p++;
}
}
} else {
for (int i = 0; i < paramDescriptors.length; i++) {
generateCodeForArgument(mv, cf, arguments[i], paramDescriptors[i]);
}
}
}
15
View Source File : OpPlus.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Walk through a possible tree of nodes that combine strings and append
* them all to the same (on stack) StringBuilder.
*/
private void walk(MethodVisitor mv, CodeFlow cf, @Nullable SpelNodeImpl operand) {
if (operand instanceof OpPlus) {
OpPlus plus = (OpPlus) operand;
walk(mv, cf, plus.getLeftOperand());
walk(mv, cf, plus.getRightOperand());
} else if (operand != null) {
cf.enterCompilationScope();
operand.generateCode(mv, cf);
if (!"Ljava/lang/String".equals(cf.lastDescriptor())) {
mv.visitTypeInsn(CHECKCAST, "java/lang/String");
}
cf.exitCompilationScope();
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
}
}
15
View Source File : OperatorNot.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
this.children[0].generateCode(mv, cf);
cf.unboxBooleanIfNecessary(mv);
Label elseTarget = new Label();
Label endOfIf = new Label();
mv.visitJumpInsn(IFNE, elseTarget);
// TRUE
mv.visitInsn(ICONST_1);
mv.visitJumpInsn(GOTO, endOfIf);
mv.visitLabel(elseTarget);
// FALSE
mv.visitInsn(ICONST_0);
mv.visitLabel(endOfIf);
cf.pushDescriptor(this.exitTypeDescriptor);
}
15
View Source File : SpelNodeImpl.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Generate code that handles building the argument values for the specified method. This method will take account
* of whether the invoked method is a varargs method and if it is then the argument values will be appropriately
* packaged into an array.
* @param mv the method visitor where code should be generated
* @param cf the current codeflow
* @param member the method or constructor for which arguments are being setup
* @param arguments the expression nodes for the expression supplied argument values
*/
protected static void generateCodeForArguments(MethodVisitor mv, CodeFlow cf, Member member, SpelNodeImpl[] arguments) {
String[] paramDescriptors = null;
boolean isVarargs = false;
if (member instanceof Constructor) {
Constructor<?> ctor = (Constructor<?>) member;
paramDescriptors = CodeFlow.toDescriptors(ctor.getParameterTypes());
isVarargs = ctor.isVarArgs();
} else {
// Method
Method method = (Method) member;
paramDescriptors = CodeFlow.toDescriptors(method.getParameterTypes());
isVarargs = method.isVarArgs();
}
if (isVarargs) {
// The final parameter may or may not need packaging into an array, or nothing may
// have been preplaceded to satisfy the varargs and so something needs to be built.
// Current supplied argument being processed
int p = 0;
int childCount = arguments.length;
// Fulfill all the parameter requirements except the last one
for (p = 0; p < paramDescriptors.length - 1; p++) {
generateCodeForArgument(mv, cf, arguments[p], paramDescriptors[p]);
}
SpelNodeImpl lastchild = (childCount == 0 ? null : arguments[childCount - 1]);
String arraytype = paramDescriptors[paramDescriptors.length - 1];
// Determine if the final preplaceded argument is already suitably packaged in array
// form to be preplaceded to the method
if (lastchild != null && lastchild.getExitDescriptor().equals(arraytype)) {
generateCodeForArgument(mv, cf, lastchild, paramDescriptors[p]);
} else {
// trim the leading '[', may leave other '['
arraytype = arraytype.substring(1);
// build array big enough to hold remaining arguments
CodeFlow.insertNewArrayCode(mv, childCount - p, arraytype);
// Package up the remaining arguments into the array
int arrayindex = 0;
while (p < childCount) {
SpelNodeImpl child = arguments[p];
mv.visitInsn(DUP);
CodeFlow.insertOptimalLoad(mv, arrayindex++);
generateCodeForArgument(mv, cf, child, arraytype);
CodeFlow.insertArrayStore(mv, arraytype);
p++;
}
}
} else {
for (int i = 0; i < paramDescriptors.length; i++) {
generateCodeForArgument(mv, cf, arguments[i], paramDescriptors[i]);
}
}
}
15
View Source File : OpPlus.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Walk through a possible tree of nodes that combine strings and append
* them all to the same (on stack) StringBuilder.
*/
private void walk(MethodVisitor mv, CodeFlow cf, SpelNodeImpl operand) {
if (operand instanceof OpPlus) {
OpPlus plus = (OpPlus) operand;
walk(mv, cf, plus.getLeftOperand());
walk(mv, cf, plus.getRightOperand());
} else {
cf.enterCompilationScope();
operand.generateCode(mv, cf);
if (!"Ljava/lang/String".equals(cf.lastDescriptor())) {
mv.visitTypeInsn(CHECKCAST, "java/lang/String");
}
cf.exitCompilationScope();
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
}
}
14
View Source File : OpEQ.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
cf.loadEvaluationContext(mv);
String leftDesc = getLeftOperand().exitTypeDescriptor;
String rightDesc = getRightOperand().exitTypeDescriptor;
boolean leftPrim = CodeFlow.isPrimitive(leftDesc);
boolean rightPrim = CodeFlow.isPrimitive(rightDesc);
cf.enterCompilationScope();
getLeftOperand().generateCode(mv, cf);
cf.exitCompilationScope();
if (leftPrim) {
CodeFlow.insertBoxIfNecessary(mv, leftDesc.charAt(0));
}
cf.enterCompilationScope();
getRightOperand().generateCode(mv, cf);
cf.exitCompilationScope();
if (rightPrim) {
CodeFlow.insertBoxIfNecessary(mv, rightDesc.charAt(0));
}
String operatorClreplacedName = Operator.clreplaced.getName().replace('.', '/');
String evaluationContextClreplacedName = EvaluationContext.clreplaced.getName().replace('.', '/');
mv.visitMethodInsn(INVOKESTATIC, operatorClreplacedName, "equalityCheck", "(L" + evaluationContextClreplacedName + ";Ljava/lang/Object;Ljava/lang/Object;)Z", false);
cf.pushDescriptor("Z");
}
14
View Source File : InlineList.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
@Override
public void generateCode(MethodVisitor mv, CodeFlow codeflow) {
final String constantFieldName = "inlineList$" + codeflow.nextFieldId();
final String clreplacedName = codeflow.getClreplacedName();
codeflow.registerNewField((cw, cflow) -> cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, constantFieldName, "Ljava/util/List;", null, null));
codeflow.registerNewClinit((mVisitor, cflow) -> generateClinitCode(clreplacedName, constantFieldName, mVisitor, cflow, false));
mv.visitFieldInsn(GETSTATIC, clreplacedName, constantFieldName, "Ljava/util/List;");
codeflow.pushDescriptor("Ljava/util/List");
}
See More Examples