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 sun.tools.asm.Label; 31 import java.io.PrintStream; 32 import java.util.Hashtable; 33 34 /** 35 * WARNING: The contents of this source file are not part of any 36 * supported API. Code that depends on them does so at its own risk: 37 * they are subject to change or removal without notice. 38 */ 39 public 40 class ReturnStatement extends Statement { 41 Expression expr; 42 43 /** 44 * Constructor 45 */ ReturnStatement(long where, Expression expr)46 public ReturnStatement(long where, Expression expr) { 47 super(RETURN, where); 48 this.expr = expr; 49 } 50 51 /** 52 * Check statement 53 */ check(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp)54 Vset check(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp) { 55 checkLabel(env, ctx); 56 vset = reach(env, vset); 57 if (expr != null) { 58 vset = expr.checkValue(env, ctx, vset, exp); 59 } 60 61 // Make sure the return isn't inside a static initializer 62 if (ctx.field.isInitializer()) { 63 env.error(where, "return.inside.static.initializer"); 64 return DEAD_END; 65 } 66 // Check return type 67 if (ctx.field.getType().getReturnType().isType(TC_VOID)) { 68 if (expr != null) { 69 if (ctx.field.isConstructor()) { 70 env.error(where, "return.with.value.constr", ctx.field); 71 } else { 72 env.error(where, "return.with.value", ctx.field); 73 } 74 expr = null; 75 } 76 } else { 77 if (expr == null) { 78 env.error(where, "return.without.value", ctx.field); 79 } else { 80 expr = convert(env, ctx, ctx.field.getType().getReturnType(), expr); 81 } 82 } 83 CheckContext mctx = ctx.getReturnContext(); 84 if (mctx != null) { 85 mctx.vsBreak = mctx.vsBreak.join(vset); 86 } 87 CheckContext exitctx = ctx.getTryExitContext(); 88 if (exitctx != null) { 89 exitctx.vsTryExit = exitctx.vsTryExit.join(vset); 90 } 91 if (expr != null) { 92 // see if we are returning a value out of a try or synchronized 93 // statement. If so, find the outermost one. . . . 94 Node outerFinallyNode = null; 95 for (Context c = ctx; c != null; c = c.prev) { 96 if (c.node == null) { 97 continue; 98 } 99 if (c.node.op == METHOD) { 100 // Don't search outside current method. Fixes 4084230. 101 break; 102 } 103 if (c.node.op == SYNCHRONIZED) { 104 outerFinallyNode = c.node; 105 break; 106 } else if (c.node.op == FINALLY 107 && ((CheckContext)c).vsContinue != null) { 108 outerFinallyNode = c.node; 109 } 110 } 111 if (outerFinallyNode != null) { 112 if (outerFinallyNode.op == FINALLY) { 113 ((FinallyStatement)outerFinallyNode).needReturnSlot = true; 114 } else { 115 ((SynchronizedStatement)outerFinallyNode).needReturnSlot = true; 116 } 117 } 118 } 119 return DEAD_END; 120 } 121 122 123 /** 124 * Inline 125 */ inline(Environment env, Context ctx)126 public Statement inline(Environment env, Context ctx) { 127 if (expr != null) { 128 expr = expr.inlineValue(env, ctx); 129 } 130 return this; 131 } 132 133 /** 134 * The cost of inlining this statement 135 */ costInline(int thresh, Environment env, Context ctx)136 public int costInline(int thresh, Environment env, Context ctx) { 137 return 1 + ((expr != null) ? expr.costInline(thresh, env, ctx) : 0); 138 } 139 140 /** 141 * Create a copy of the statement for method inlining 142 */ copyInline(Context ctx, boolean valNeeded)143 public Statement copyInline(Context ctx, boolean valNeeded) { 144 Expression e = (expr != null) ? expr.copyInline(ctx) : null; 145 if ((!valNeeded) && (e != null)) { 146 Statement body[] = { 147 new ExpressionStatement(where, e), 148 new InlineReturnStatement(where, null) 149 }; 150 return new CompoundStatement(where, body); 151 } 152 return new InlineReturnStatement(where, e); 153 } 154 155 /** 156 * Code 157 */ code(Environment env, Context ctx, Assembler asm)158 public void code(Environment env, Context ctx, Assembler asm) { 159 if (expr == null) { 160 codeFinally(env, ctx, asm, null, null); 161 asm.add(where, opc_return); 162 } else { 163 expr.codeValue(env, ctx, asm); 164 codeFinally(env, ctx, asm, null, expr.type); 165 asm.add(where, opc_ireturn + expr.type.getTypeCodeOffset()); 166 } 167 } 168 169 /** 170 * Print 171 */ print(PrintStream out, int indent)172 public void print(PrintStream out, int indent) { 173 super.print(out, indent); 174 out.print("return"); 175 if (expr != null) { 176 out.print(" "); 177 expr.print(out); 178 } 179 out.print(";"); 180 } 181 } 182