001: /*
002: * Copyright 1994-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.tree;
027:
028: import sun.tools.java.*;
029: import sun.tools.asm.Assembler;
030: import sun.tools.asm.Label;
031: import java.io.PrintStream;
032: import java.util.Hashtable;
033:
034: /**
035: * WARNING: The contents of this source file are not part of any
036: * supported API. Code that depends on them does so at its own risk:
037: * they are subject to change or removal without notice.
038: */
039: public class WhileStatement extends Statement {
040: Expression cond;
041: Statement body;
042:
043: /**
044: * Constructor
045: */
046: public WhileStatement(long where, Expression cond, Statement body) {
047: super (WHILE, where);
048: this .cond = cond;
049: this .body = body;
050: }
051:
052: /**
053: * Check a while statement
054: */
055: Vset check(Environment env, Context ctx, Vset vset, Hashtable exp) {
056: checkLabel(env, ctx);
057: CheckContext newctx = new CheckContext(ctx, this );
058: // remember what was unassigned on entry
059: Vset vsEntry = vset.copy();
060: // check the condition. Determine which variables have values if
061: // it returns true or false.
062: ConditionVars cvars = cond.checkCondition(env, newctx, reach(
063: env, vset), exp);
064: cond = convert(env, newctx, Type.tBoolean, cond);
065: // check the body, given that the condition returned true.
066: vset = body.check(env, newctx, cvars.vsTrue, exp);
067: vset = vset.join(newctx.vsContinue);
068: // make sure the back-branch fits the entry of the loop
069: ctx.checkBackBranch(env, this , vsEntry, vset);
070: // Exit the while loop by testing false or getting a break statement
071: vset = newctx.vsBreak.join(cvars.vsFalse);
072: return ctx.removeAdditionalVars(vset);
073: }
074:
075: /**
076: * Inline
077: */
078: public Statement inline(Environment env, Context ctx) {
079: ctx = new Context(ctx, this );
080: cond = cond.inlineValue(env, ctx);
081: if (body != null) {
082: body = body.inline(env, ctx);
083: }
084: return this ;
085: }
086:
087: /**
088: * The cost of inlining this statement
089: */
090: public int costInline(int thresh, Environment env, Context ctx) {
091: return 1
092: + cond.costInline(thresh, env, ctx)
093: + ((body != null) ? body.costInline(thresh, env, ctx)
094: : 0);
095: }
096:
097: /**
098: * Create a copy of the statement for method inlining
099: */
100: public Statement copyInline(Context ctx, boolean valNeeded) {
101: WhileStatement s = (WhileStatement) clone();
102: s.cond = cond.copyInline(ctx);
103: if (body != null) {
104: s.body = body.copyInline(ctx, valNeeded);
105: }
106: return s;
107: }
108:
109: /**
110: * Code
111: */
112: public void code(Environment env, Context ctx, Assembler asm) {
113: CodeContext newctx = new CodeContext(ctx, this );
114:
115: asm.add(where, opc_goto, newctx.contLabel);
116:
117: Label l1 = new Label();
118: asm.add(l1);
119:
120: if (body != null) {
121: body.code(env, newctx, asm);
122: }
123:
124: asm.add(newctx.contLabel);
125: cond.codeBranch(env, newctx, asm, l1, true);
126: asm.add(newctx.breakLabel);
127: }
128:
129: /**
130: * Print
131: */
132: public void print(PrintStream out, int indent) {
133: super .print(out, indent);
134: out.print("while ");
135: cond.print(out);
136: if (body != null) {
137: out.print(" ");
138: body.print(out, indent);
139: } else {
140: out.print(";");
141: }
142: }
143: }
|