private void doConvertAndCast(ClassNode targetType, boolean coerce) {
    int size = stack.size();
    throwExceptionForNoStackElement(size, targetType, coerce);

    ClassNode top = stack.get(size - 1);
    targetType = targetType.redirect();
    if (targetType == top) return;

    if (coerce) {
      controller.getInvocationWriter().coerce(top, targetType);
      return;
    }

    boolean primTarget = ClassHelper.isPrimitiveType(targetType);
    boolean primTop = ClassHelper.isPrimitiveType(top);

    if (primTop && primTarget) {
      // here we box and unbox to get the goal type
      if (convertPrimitive(top, targetType)) {
        replace(targetType);
        return;
      }
      box();
    } else if (primTop) {
      // top is primitive, target is not
      // so box and do groovy cast
      controller.getInvocationWriter().castToNonPrimitiveIfNecessary(top, targetType);
    } else if (primTarget) {
      // top is not primitive so unbox
      // leave that BH#doCast later
    } else {
      controller.getInvocationWriter().castToNonPrimitiveIfNecessary(top, targetType);
    }

    MethodVisitor mv = controller.getMethodVisitor();
    if (primTarget
        && !ClassHelper.boolean_TYPE.equals(targetType)
        && !primTop
        && ClassHelper.getWrapper(targetType).equals(top)) {
      BytecodeHelper.doCastToPrimitive(mv, top, targetType);
    } else {
      top = stack.get(size - 1);
      if (!WideningCategories.implementsInterfaceOrSubclassOf(top, targetType)) {
        BytecodeHelper.doCast(mv, targetType);
      }
    }
    replace(targetType);
  }
 /**
  * ensure last marked parameter on the stack is a primitive boolean if mark==stack size, we assume
  * an empty expression or statement. was used and we will use the value given in emptyDefault as
  * boolean if mark==stack.size()-1 the top element will be cast to boolean using Groovy truth. In
  * other cases we throw a GroovyBugError
  */
 public void castToBool(int mark, boolean emptyDefault) {
   int size = stack.size();
   MethodVisitor mv = controller.getMethodVisitor();
   if (mark == size) {
     // no element, so use emptyDefault
     if (emptyDefault) {
       mv.visitIntInsn(BIPUSH, 1);
     } else {
       mv.visitIntInsn(BIPUSH, 0);
     }
     stack.add(null);
   } else if (mark == stack.size() - 1) {
     ClassNode last = stack.get(size - 1);
     // nothing to do in that case
     if (last == ClassHelper.boolean_TYPE) return;
     // not a primitive type, so call booleanUnbox
     if (!ClassHelper.isPrimitiveType(last)) {
       controller.getInvocationWriter().castNonPrimitiveToBool(last);
     } else {
       primitive2b(mv, last);
     }
   } else {
     throw new GroovyBugError(
         "operand stack contains " + stack.size() + " elements, but we expected only " + mark);
   }
   stack.set(mark, ClassHelper.boolean_TYPE);
 }
  protected void evaluateBinaryExpression(String message, BinaryExpression binExp) {
    CompileStack compileStack = controller.getCompileStack();

    Expression receiver = binExp.getLeftExpression();
    Expression arguments = binExp.getRightExpression();

    // ensure VariableArguments are read, not stored
    compileStack.pushLHS(false);
    controller.getInvocationWriter().makeSingleArgumentCall(receiver, message, arguments);
    compileStack.popLHS();
  }
 protected void assignToArray(
     Expression parent, Expression receiver, Expression index, Expression rhsValueLoader) {
   // let's replace this assignment to a subscript operator with a
   // method call
   // e.g. x[5] = 10
   // -> (x, [], 5), =, 10
   // -> methodCall(x, "putAt", [5, 10])
   ArgumentListExpression ae = new ArgumentListExpression(index, rhsValueLoader);
   controller
       .getInvocationWriter()
       .makeCall(
           parent,
           receiver,
           new ConstantExpression("putAt"),
           ae,
           InvocationWriter.invokeMethod,
           false,
           false,
           false);
   controller.getOperandStack().pop();
   // return value of assignment
   rhsValueLoader.visit(controller.getAcg());
 }