langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
changeset 42827 36468b5fa7f4
parent 42499 49b675740462
child 42828 cce89649f958
equal deleted inserted replaced
42826:563b42fc70ba 42827:36468b5fa7f4
  2252             return builder.build(lval);
  2252             return builder.build(lval);
  2253         case SELECT: {
  2253         case SELECT: {
  2254             final JCFieldAccess s = (JCFieldAccess)lval;
  2254             final JCFieldAccess s = (JCFieldAccess)lval;
  2255             Symbol lid = TreeInfo.symbol(s.selected);
  2255             Symbol lid = TreeInfo.symbol(s.selected);
  2256             if (lid != null && lid.kind == TYP) return builder.build(lval);
  2256             if (lid != null && lid.kind == TYP) return builder.build(lval);
  2257             return abstractRval(s.selected, new TreeBuilder() {
  2257             return abstractRval(s.selected, selected -> builder.build(make.Select(selected, s.sym)));
  2258                     public JCExpression build(final JCExpression selected) {
       
  2259                         return builder.build(make.Select(selected, s.sym));
       
  2260                     }
       
  2261                 });
       
  2262         }
  2258         }
  2263         case INDEXED: {
  2259         case INDEXED: {
  2264             final JCArrayAccess i = (JCArrayAccess)lval;
  2260             final JCArrayAccess i = (JCArrayAccess)lval;
  2265             return abstractRval(i.indexed, new TreeBuilder() {
  2261             return abstractRval(i.indexed, indexed -> abstractRval(i.index, syms.intType, index -> {
  2266                     public JCExpression build(final JCExpression indexed) {
  2262                 JCExpression newLval = make.Indexed(indexed, index);
  2267                         return abstractRval(i.index, syms.intType, new TreeBuilder() {
  2263                 newLval.setType(i.type);
  2268                                 public JCExpression build(final JCExpression index) {
  2264                 return builder.build(newLval);
  2269                                     JCExpression newLval = make.Indexed(indexed, index);
  2265             }));
  2270                                     newLval.setType(i.type);
       
  2271                                     return builder.build(newLval);
       
  2272                                 }
       
  2273                             });
       
  2274                     }
       
  2275                 });
       
  2276         }
  2266         }
  2277         case TYPECAST: {
  2267         case TYPECAST: {
  2278             return abstractLval(((JCTypeCast)lval).expr, builder);
  2268             return abstractLval(((JCTypeCast)lval).expr, builder);
  2279         }
  2269         }
  2280         }
  2270         }
  2281         throw new AssertionError(lval);
  2271         throw new AssertionError(lval);
  2282     }
  2272     }
  2283 
  2273 
  2284     // evaluate and discard the first expression, then evaluate the second.
  2274     // evaluate and discard the first expression, then evaluate the second.
  2285     JCExpression makeComma(final JCExpression expr1, final JCExpression expr2) {
  2275     JCExpression makeComma(final JCExpression expr1, final JCExpression expr2) {
  2286         return abstractRval(expr1, new TreeBuilder() {
  2276         return abstractRval(expr1, discarded -> expr2);
  2287                 public JCExpression build(final JCExpression discarded) {
       
  2288                     return expr2;
       
  2289                 }
       
  2290             });
       
  2291     }
  2277     }
  2292 
  2278 
  2293 /**************************************************************************
  2279 /**************************************************************************
  2294  * Translation methods
  2280  * Translation methods
  2295  *************************************************************************/
  2281  *************************************************************************/
  3193 
  3179 
  3194         if (boxingReq || depScanner.dependencyFound) {
  3180         if (boxingReq || depScanner.dependencyFound) {
  3195             // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
  3181             // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
  3196             // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
  3182             // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
  3197             // (but without recomputing x)
  3183             // (but without recomputing x)
  3198             JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
  3184             JCTree newTree = abstractLval(tree.lhs, lhs -> {
  3199                     public JCExpression build(final JCExpression lhs) {
  3185                 Tag newTag = tree.getTag().noAssignOp();
  3200                         JCTree.Tag newTag = tree.getTag().noAssignOp();
  3186                 // Erasure (TransTypes) can change the type of
  3201                         // Erasure (TransTypes) can change the type of
  3187                 // tree.lhs.  However, we can still get the
  3202                         // tree.lhs.  However, we can still get the
  3188                 // unerased type of tree.lhs as it is stored
  3203                         // unerased type of tree.lhs as it is stored
  3189                 // in tree.type in Attr.
  3204                         // in tree.type in Attr.
  3190                 OperatorSymbol newOperator = operators.resolveBinary(tree,
  3205                         OperatorSymbol newOperator = operators.resolveBinary(tree,
  3191                                                               newTag,
  3206                                                                       newTag,
  3192                                                               tree.type,
  3207                                                                       tree.type,
  3193                                                               tree.rhs.type);
  3208                                                                       tree.rhs.type);
  3194                 //Need to use the "lhs" at two places, once on the future left hand side
  3209                         //Need to use the "lhs" at two places, once on the future left hand side
  3195                 //and once in the future binary operator. But further processing may change
  3210                         //and once in the future binary operator. But further processing may change
  3196                 //the components of the tree in place (see visitSelect for e.g. <Class>.super.<ident>),
  3211                         //the components of the tree in place (see visitSelect for e.g. <Class>.super.<ident>),
  3197                 //so cloning the tree to avoid interference between the uses:
  3212                         //so cloning the tree to avoid interference between the uses:
  3198                 JCExpression expr = (JCExpression) lhs.clone();
  3213                         JCExpression expr = (JCExpression) lhs.clone();
  3199                 if (expr.type != tree.type)
  3214                         if (expr.type != tree.type)
  3200                     expr = make.TypeCast(tree.type, expr);
  3215                             expr = make.TypeCast(tree.type, expr);
  3201                 JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
  3216                         JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
  3202                 opResult.operator = newOperator;
  3217                         opResult.operator = newOperator;
  3203                 opResult.type = newOperator.type.getReturnType();
  3218                         opResult.type = newOperator.type.getReturnType();
  3204                 JCExpression newRhs = boxingReq ?
  3219                         JCExpression newRhs = boxingReq ?
  3205                     make.TypeCast(types.unboxedType(tree.type), opResult) :
  3220                             make.TypeCast(types.unboxedType(tree.type), opResult) :
  3206                     opResult;
  3221                             opResult;
  3207                 return make.Assign(lhs, newRhs).setType(tree.type);
  3222                         return make.Assign(lhs, newRhs).setType(tree.type);
  3208             });
  3223                     }
       
  3224                 });
       
  3225             result = translate(newTree);
  3209             result = translate(newTree);
  3226             return;
  3210             return;
  3227         }
  3211         }
  3228         tree.lhs = translate(tree.lhs, tree);
  3212         tree.lhs = translate(tree.lhs, tree);
  3229         tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
  3213         tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
  3285         // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2
  3269         // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2
  3286         // or
  3270         // or
  3287         // translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2
  3271         // translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2
  3288         // where OP is += or -=
  3272         // where OP is += or -=
  3289         final boolean cast = TreeInfo.skipParens(tree.arg).hasTag(TYPECAST);
  3273         final boolean cast = TreeInfo.skipParens(tree.arg).hasTag(TYPECAST);
  3290         return abstractLval(tree.arg, new TreeBuilder() {
  3274         return abstractLval(tree.arg, tmp1 -> abstractRval(tmp1, tree.arg.type, tmp2 -> {
  3291                 public JCExpression build(final JCExpression tmp1) {
  3275             Tag opcode = (tree.hasTag(POSTINC))
  3292                     return abstractRval(tmp1, tree.arg.type, new TreeBuilder() {
  3276                 ? PLUS_ASG : MINUS_ASG;
  3293                             public JCExpression build(final JCExpression tmp2) {
  3277             //"tmp1" and "tmp2" may refer to the same instance
  3294                                 JCTree.Tag opcode = (tree.hasTag(POSTINC))
  3278             //(for e.g. <Class>.super.<ident>). But further processing may
  3295                                     ? PLUS_ASG : MINUS_ASG;
  3279             //change the components of the tree in place (see visitSelect),
  3296                                 //"tmp1" and "tmp2" may refer to the same instance
  3280             //so cloning the tree to avoid interference between the two uses:
  3297                                 //(for e.g. <Class>.super.<ident>). But further processing may
  3281             JCExpression lhs = (JCExpression)tmp1.clone();
  3298                                 //change the components of the tree in place (see visitSelect),
  3282             lhs = cast
  3299                                 //so cloning the tree to avoid interference between the two uses:
  3283                 ? make.TypeCast(tree.arg.type, lhs)
  3300                                 JCExpression lhs = (JCExpression)tmp1.clone();
  3284                 : lhs;
  3301                                 lhs = cast
  3285             JCExpression update = makeAssignop(opcode,
  3302                                     ? make.TypeCast(tree.arg.type, lhs)
  3286                                          lhs,
  3303                                     : lhs;
  3287                                          make.Literal(1));
  3304                                 JCExpression update = makeAssignop(opcode,
  3288             return makeComma(update, tmp2);
  3305                                                              lhs,
  3289         }));
  3306                                                              make.Literal(1));
       
  3307                                 return makeComma(update, tmp2);
       
  3308                             }
       
  3309                         });
       
  3310                 }
       
  3311             });
       
  3312     }
  3290     }
  3313 
  3291 
  3314     public void visitUnary(JCUnary tree) {
  3292     public void visitUnary(JCUnary tree) {
  3315         boolean isUpdateOperator = tree.getTag().isIncOrDecUnaryOp();
  3293         boolean isUpdateOperator = tree.getTag().isIncOrDecUnaryOp();
  3316         if (isUpdateOperator && !tree.arg.type.isPrimitive()) {
  3294         if (isUpdateOperator && !tree.arg.type.isPrimitive()) {