1 /* 2 * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.tree; 27 28 import sun.tools.java.*; 29 import sun.tools.asm.Assembler; 30 import java.io.PrintStream; 31 import java.util.Hashtable; 32 33 /** 34 * WARNING: The contents of this source file are not part of any 35 * supported API. Code that depends on them does so at its own risk: 36 * they are subject to change or removal without notice. 37 */ 38 public 39 class AssignExpression extends BinaryAssignExpression { 40 41 private FieldUpdater updater = null; 42 43 /** 44 * Constructor 45 */ AssignExpression(long where, Expression left, Expression right)46 public AssignExpression(long where, Expression left, Expression right) { 47 super(ASSIGN, where, left, right); 48 } 49 50 /** 51 * Check an assignment expression 52 */ checkValue(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp)53 public Vset checkValue(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp) { 54 if (left instanceof IdentifierExpression) { 55 // we don't want to mark an identifier as having a value 56 // until having evaluated the right-hand side 57 vset = right.checkValue(env, ctx, vset, exp); 58 vset = left.checkLHS(env, ctx, vset, exp); 59 } else { 60 // normally left to right evaluation. 61 vset = left.checkLHS(env, ctx, vset, exp); 62 vset = right.checkValue(env, ctx, vset, exp); 63 } 64 type = left.type; 65 right = convert(env, ctx, type, right); 66 67 // Get field updater (access method) if needed, else null. 68 updater = left.getAssigner(env, ctx); 69 70 return vset; 71 } 72 73 /** 74 * Inline 75 */ inlineValue(Environment env, Context ctx)76 public Expression inlineValue(Environment env, Context ctx) { 77 if (implementation != null) 78 return implementation.inlineValue(env, ctx); 79 // Must be 'inlineLHS' here. But compare with similar case in 80 // 'AssignOpExpression' and 'IncDecExpression', which needs 'inlineValue'. 81 left = left.inlineLHS(env, ctx); 82 right = right.inlineValue(env, ctx); 83 if (updater != null) { 84 updater = updater.inline(env, ctx); 85 } 86 return this; 87 } 88 89 /** 90 * Create a copy of the expression for method inlining 91 */ copyInline(Context ctx)92 public Expression copyInline(Context ctx) { 93 if (implementation != null) 94 return implementation.copyInline(ctx); 95 AssignExpression e = (AssignExpression)clone(); 96 e.left = left.copyInline(ctx); 97 e.right = right.copyInline(ctx); 98 if (updater != null) { 99 e.updater = updater.copyInline(ctx); 100 } 101 return e; 102 } 103 104 /** 105 * The cost of inlining this expression 106 */ costInline(int thresh, Environment env, Context ctx)107 public int costInline(int thresh, Environment env, Context ctx) { 108 /*----------* 109 return 2 + super.costInline(thresh, env, ctx); 110 *----------*/ 111 return (updater != null) 112 // Cost of rhs expression + cost of access method call. 113 // Access method call cost includes lhs cost. 114 ? right.costInline(thresh, env, ctx) + 115 updater.costInline(thresh, env, ctx, false) 116 // Cost of rhs expression + cost of lhs expression + 117 // cost of store instruction. 118 : right.costInline(thresh, env, ctx) + 119 left.costInline(thresh, env, ctx) + 2; 120 } 121 122 /** 123 * Code 124 */ codeValue(Environment env, Context ctx, Assembler asm)125 public void codeValue(Environment env, Context ctx, Assembler asm) { 126 if (updater == null) { 127 // Field is directly accessible. 128 int depth = left.codeLValue(env, ctx, asm); 129 right.codeValue(env, ctx, asm); 130 codeDup(env, ctx, asm, right.type.stackSize(), depth); 131 left.codeStore(env, ctx, asm); 132 } else { 133 // Must use access method. 134 // Left operand is always a 'FieldExpression', or 135 // is rewritten as one via 'implementation'. 136 updater.startAssign(env, ctx, asm); 137 right.codeValue(env, ctx, asm); 138 updater.finishAssign(env, ctx, asm, true); 139 } 140 } 141 code(Environment env, Context ctx, Assembler asm)142 public void code(Environment env, Context ctx, Assembler asm) { 143 if (updater == null) { 144 // Field is directly accessible. 145 left.codeLValue(env, ctx, asm); 146 right.codeValue(env, ctx, asm); 147 left.codeStore(env, ctx, asm); 148 } else { 149 // Must use access method. 150 // Left operand is always a 'FieldExpression', or 151 // is rewritten as one via 'implementation'. 152 updater.startAssign(env, ctx, asm); 153 right.codeValue(env, ctx, asm); 154 updater.finishAssign(env, ctx, asm, false); 155 } 156 } 157 } 158