package org.simantics.scl.compiler.elaboration.java; import org.cojen.classfile.TypeDesc; import org.objectweb.asm.Label; import org.simantics.scl.compiler.constants.ComparisonFunction; import org.simantics.scl.compiler.constants.FunctionValue; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.utils.Constants; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; public class EqualsFunction extends FunctionValue implements ComparisonFunction { private static final TVar A = Types.var(Kinds.STAR); public static final EqualsFunction INSTANCE = new EqualsFunction(); private EqualsFunction() { super(new TVar[] {A}, Types.NO_EFFECTS, Types.BOOLEAN, A, A); } @Override public Type applyExact(MethodBuilder mb, Val[] parameters) { parameters[0].push(mb); parameters[1].push(mb); TypeDesc parameterType = mb.getJavaTypeTranslator().getTypeDesc(parameters[0]); if(parameterType.isPrimitive()) { if(parameterType.equals(TypeDesc.VOID)) { mb.loadConstant(true); } else { Label end = mb.createLabel(); Label isEqual = mb.createLabel(); mb.ifComparisonBranch(isEqual, "==", parameterType); mb.loadConstant(false); mb.branch(end); mb.setLocation(isEqual); mb.loadConstant(true); mb.setLocation(end); } } else mb.invokeStatic("java/util/Objects", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[2]); return Types.BOOLEAN; } @Override public String toString() { return "=="; } @Override public void generateCondition(MethodBuilder mb, Val[] parameters, Cont then_, Cont else_) { parameters[0].push(mb); parameters[1].push(mb); TypeDesc parameterType = mb.getJavaTypeTranslator().getTypeDesc(parameters[0]); if(parameterType.isPrimitive()) { if(parameterType.equals(TypeDesc.VOID)) { mb.jump(then_); } else { mb.ifComparisonBranch(mb.getLabel(then_), "==", parameterType); mb.jump(else_); mb.ensureExists(then_); } } else { mb.invokeStatic("java/util/Objects", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[2]); mb.ifZeroComparisonBranch(mb.getLabel(else_), "=="); mb.jump(then_); mb.ensureExists(else_); } } }