use of org.springframework.asm.Label in project spring-framework by spring-projects.
the class OperatorNot method generateCode.
@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);
}
use of org.springframework.asm.Label in project spring-framework by spring-projects.
the class Ternary method generateCode.
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
// May reach here without it computed if all elements are literals
computeExitTypeDescriptor();
cf.enterCompilationScope();
this.children[0].generateCode(mv, cf);
String lastDesc = cf.lastDescriptor();
Assert.state(lastDesc != null, "No last descriptor");
if (!CodeFlow.isPrimitive(lastDesc)) {
CodeFlow.insertUnboxInsns(mv, 'Z', lastDesc);
}
cf.exitCompilationScope();
Label elseTarget = new Label();
Label endOfIf = new Label();
mv.visitJumpInsn(IFEQ, elseTarget);
cf.enterCompilationScope();
this.children[1].generateCode(mv, cf);
if (!CodeFlow.isPrimitive(this.exitTypeDescriptor)) {
lastDesc = cf.lastDescriptor();
Assert.state(lastDesc != null, "No last descriptor");
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
}
cf.exitCompilationScope();
mv.visitJumpInsn(GOTO, endOfIf);
mv.visitLabel(elseTarget);
cf.enterCompilationScope();
this.children[2].generateCode(mv, cf);
if (!CodeFlow.isPrimitive(this.exitTypeDescriptor)) {
lastDesc = cf.lastDescriptor();
Assert.state(lastDesc != null, "No last descriptor");
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
}
cf.exitCompilationScope();
mv.visitLabel(endOfIf);
cf.pushDescriptor(this.exitTypeDescriptor);
}
use of org.springframework.asm.Label in project spring-framework by spring-projects.
the class Elvis method generateCode.
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
// exit type descriptor can be null if both components are literal expressions
computeExitTypeDescriptor();
cf.enterCompilationScope();
this.children[0].generateCode(mv, cf);
String lastDesc = cf.lastDescriptor();
Assert.state(lastDesc != null, "No last descriptor");
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
cf.exitCompilationScope();
Label elseTarget = new Label();
Label endOfIf = new Label();
mv.visitInsn(DUP);
mv.visitJumpInsn(IFNULL, elseTarget);
// Also check if empty string, as per the code in the interpreted version
mv.visitInsn(DUP);
mv.visitLdcInsn("");
mv.visitInsn(SWAP);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
// if not empty, drop through to elseTarget
mv.visitJumpInsn(IFEQ, endOfIf);
mv.visitLabel(elseTarget);
mv.visitInsn(POP);
cf.enterCompilationScope();
this.children[1].generateCode(mv, cf);
if (!CodeFlow.isPrimitive(this.exitTypeDescriptor)) {
lastDesc = cf.lastDescriptor();
Assert.state(lastDesc != null, "No last descriptor");
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
}
cf.exitCompilationScope();
mv.visitLabel(endOfIf);
cf.pushDescriptor(this.exitTypeDescriptor);
}
use of org.springframework.asm.Label in project spring-framework by spring-projects.
the class MethodReference method generateCode.
@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
CachedMethodExecutor executorToCheck = this.cachedExecutor;
if (executorToCheck == null || !(executorToCheck.get() instanceof ReflectiveMethodExecutor)) {
throw new IllegalStateException("No applicable cached executor found: " + executorToCheck);
}
ReflectiveMethodExecutor methodExecutor = (ReflectiveMethodExecutor) executorToCheck.get();
Method method = methodExecutor.getMethod();
boolean isStaticMethod = Modifier.isStatic(method.getModifiers());
String descriptor = cf.lastDescriptor();
Label skipIfNull = null;
if (descriptor == null && !isStaticMethod) {
// Nothing on the stack but something is needed
cf.loadTarget(mv);
}
if ((descriptor != null || !isStaticMethod) && this.nullSafe) {
mv.visitInsn(DUP);
skipIfNull = new Label();
Label continueLabel = new Label();
mv.visitJumpInsn(IFNONNULL, continueLabel);
CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
mv.visitJumpInsn(GOTO, skipIfNull);
mv.visitLabel(continueLabel);
}
if (descriptor != null && isStaticMethod) {
// Something on the stack when nothing is needed
mv.visitInsn(POP);
}
if (CodeFlow.isPrimitive(descriptor)) {
CodeFlow.insertBoxIfNecessary(mv, descriptor.charAt(0));
}
String classDesc;
if (Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
classDesc = method.getDeclaringClass().getName().replace('.', '/');
} else {
Class<?> publicDeclaringClass = methodExecutor.getPublicDeclaringClass();
Assert.state(publicDeclaringClass != null, "No public declaring class");
classDesc = publicDeclaringClass.getName().replace('.', '/');
}
if (!isStaticMethod && (descriptor == null || !descriptor.substring(1).equals(classDesc))) {
CodeFlow.insertCheckCast(mv, "L" + classDesc);
}
generateCodeForArguments(mv, cf, method, this.children);
mv.visitMethodInsn((isStaticMethod ? INVOKESTATIC : (method.isDefault() ? INVOKEINTERFACE : INVOKEVIRTUAL)), classDesc, method.getName(), CodeFlow.createSignatureDescriptor(method), method.getDeclaringClass().isInterface());
cf.pushDescriptor(this.exitTypeDescriptor);
if (this.originalPrimitiveExitTypeDescriptor != null) {
// The output of the accessor will be a primitive but from the block above it might be null,
// so to have a 'common stack' element at skipIfNull target we need to box the primitive
CodeFlow.insertBoxIfNecessary(mv, this.originalPrimitiveExitTypeDescriptor);
}
if (skipIfNull != null) {
mv.visitLabel(skipIfNull);
}
}
use of org.springframework.asm.Label in project spring-framework by spring-projects.
the class OpNE method generateCode.
@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 operatorClassName = Operator.class.getName().replace('.', '/');
String evaluationContextClassName = EvaluationContext.class.getName().replace('.', '/');
mv.visitMethodInsn(INVOKESTATIC, operatorClassName, "equalityCheck", "(L" + evaluationContextClassName + ";Ljava/lang/Object;Ljava/lang/Object;)Z", false);
// Invert the boolean
Label notZero = new Label();
Label end = new Label();
mv.visitJumpInsn(IFNE, notZero);
mv.visitInsn(ICONST_1);
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(notZero);
mv.visitInsn(ICONST_0);
mv.visitLabel(end);
cf.pushDescriptor("Z");
}
Aggregations