Beispiel #1
0
  /**
   * Transform a call to a pruned instance method (or static impl) into a call to the null method,
   * which will be used to replace <code>x</code>.
   */
  public static JMethodCall transformToNullMethodCall(JMethodCall x, JProgram program) {
    JExpression instance = x.getInstance();
    List<JExpression> args = x.getArgs();
    if (program.isStaticImpl(x.getTarget())) {
      instance = args.get(0);
      args = args.subList(1, args.size());
    } else {
      /*
       * We assert that method must be non-static, otherwise it would have been
       * rescued.
       */
      // assert !x.getTarget().isStatic();
      /*
       * HACK HACK HACK: ControlFlowAnalyzer has special hacks for dealing with
       * ClassLiterals, which causes the body of ClassLiteralHolder's clinit to
       * never be rescured. This in turn causes invalid references to static
       * methods, which violates otherwise good assumptions about compiler
       * operation.
       *
       * TODO: Remove this when ControlFlowAnalyzer doesn't special-case
       * CLH.clinit().
       */
      if (x.getTarget().isStatic() && instance == null) {
        instance = program.getLiteralNull();
      }
    }
    assert (instance != null);
    if (!instance.hasSideEffects()) {
      instance = program.getLiteralNull();
    }

    JMethodCall newCall =
        new JMethodCall(
            x.getSourceInfo(),
            instance,
            program.getNullMethod(),
            primitiveTypeOrNullTypeOrArray(program, x.getType()));
    // Retain the original arguments, they will be evaluated for side effects.
    for (JExpression arg : args) {
      if (arg.hasSideEffects()) {
        newCall.addArg(arg);
      }
    }
    return newCall;
  }
Beispiel #2
0
  /**
   * Transform a reference to a pruned instance field into a reference to the null field, which will
   * be used to replace <code>x</code>.
   */
  public static JFieldRef transformToNullFieldRef(JFieldRef x, JProgram program) {
    JExpression instance = x.getInstance();

    /*
     * We assert that field must be non-static if it's an rvalue, otherwise it
     * would have been rescued.
     */
    // assert !x.getField().isStatic();
    /*
     * HACK HACK HACK: ControlFlowAnalyzer has special hacks for dealing with
     * ClassLiterals, which causes the body of ClassLiteralHolder's clinit to
     * never be rescured. This in turn causes invalid references to static
     * methods, which violates otherwise good assumptions about compiler
     * operation.
     *
     * TODO: Remove this when ControlFlowAnalyzer doesn't special-case
     * CLH.clinit().
     */
    if (x.getField().isStatic() && instance == null) {
      instance = program.getLiteralNull();
    }

    assert instance != null;
    if (!instance.hasSideEffects()) {
      instance = program.getLiteralNull();
    }

    JFieldRef fieldRef =
        new JFieldRef(
            x.getSourceInfo(),
            instance,
            program.getNullField(),
            x.getEnclosingType(),
            primitiveTypeOrNullTypeOrArray(program, x.getType()));
    return fieldRef;
  }
Beispiel #3
0
  /** Returns an ast node representing the expression {@code expression != null}. */
  public static JExpression createOptimizedNotNullComparison(
      JProgram program, SourceInfo info, JExpression expression) {
    JReferenceType type = (JReferenceType) expression.getType();
    if (type.isNullType()) {
      return program.getLiteralBoolean(false);
    }

    if (!type.canBeNull()) {
      return createOptimizedMultiExpression(expression, program.getLiteralBoolean(true));
    }

    return new JBinaryOperation(
        info,
        program.getTypePrimitiveBoolean(),
        JBinaryOperator.NEQ,
        expression,
        program.getLiteralNull());
  }