History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/tree/TryStatement.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/tree/TryStatement.java+317−0
@@ -0,0 +1,317 @@
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 sun.tools.asm.TryData;
32+import sun.tools.asm.CatchData;
33+import java.io.PrintStream;
34+import java.util.Enumeration;
35+import java.util.Hashtable;
36+
37+/**
38+ * WARNING: The contents of this source file are not part of any
39+ * supported API. Code that depends on them does so at its own risk:
40+ * they are subject to change or removal without notice.
41+ */
42+public
43+class TryStatement extends Statement {
44+ Statement body;
45+ Statement args[];
46+ long arrayCloneWhere; // private note posted from MethodExpression
47+
48+ /**
49+ * Constructor
50+ */
51+ public TryStatement(long where, Statement body, Statement args[]) {
52+ super(TRY, where);
53+ this.body = body;
54+ this.args = args;
55+ }
56+
57+ /**
58+ * Check statement
59+ */
60+ Vset check(Environment env, Context ctx, Vset vset, Hashtable exp) {
61+ checkLabel(env, ctx);
62+ try {
63+ vset = reach(env, vset);
64+ Hashtable newexp = new Hashtable();
65+ CheckContext newctx = new CheckContext(ctx, this);
66+
67+ // Check 'try' block. A variable is DA (DU) before the try
68+ // block if it is DA (DU) before the try statement.
69+ Vset vs = body.check(env, newctx, vset.copy(), newexp);
70+
71+ // A variable is DA before a catch block if it is DA before the
72+ // try statement. A variable is DU before a catch block if it
73+ // is DU after the try block and before any 'break', 'continue',
74+ // 'throw', or 'return' contained therein. That is, the variable
75+ // is DU upon entry to the try-statement and is not assigned to
76+ // anywhere within the try block.
77+ Vset cvs = Vset.firstDAandSecondDU(vset, vs.copy().join(newctx.vsTryExit));
78+
79+ for (int i = 0 ; i < args.length ; i++) {
80+ // A variable is DA (DU) after a try statement if
81+ // it is DA (DU) after every catch block.
82+ vs = vs.join(args[i].check(env, newctx, cvs.copy(), exp));
83+ }
84+
85+ // Check that catch statements are actually reached
86+ for (int i = 1 ; i < args.length ; i++) {
87+ CatchStatement cs = (CatchStatement)args[i];
88+ if (cs.field == null) {
89+ continue;
90+ }
91+ Type type = cs.field.getType();
92+ ClassDefinition def = env.getClassDefinition(type);
93+
94+ for (int j = 0 ; j < i ; j++) {
95+ CatchStatement cs2 = (CatchStatement)args[j];
96+ if (cs2.field == null) {
97+ continue;
98+ }
99+ Type t = cs2.field.getType();
100+ ClassDeclaration c = env.getClassDeclaration(t);
101+ if (def.subClassOf(env, c)) {
102+ env.error(args[i].where, "catch.not.reached");
103+ break;
104+ }
105+ }
106+ }
107+
108+ ClassDeclaration ignore1 = env.getClassDeclaration(idJavaLangError);
109+ ClassDeclaration ignore2 = env.getClassDeclaration(idJavaLangRuntimeException);
110+
111+ // Make sure the exception is actually throw in that part of the code
112+ for (int i = 0 ; i < args.length ; i++) {
113+ CatchStatement cs = (CatchStatement)args[i];
114+ if (cs.field == null) {
115+ continue;
116+ }
117+ Type type = cs.field.getType();
118+ if (!type.isType(TC_CLASS)) {
119+ // CatchStatement.checkValue() will have already printed
120+ // an error message
121+ continue;
122+ }
123+
124+ ClassDefinition def = env.getClassDefinition(type);
125+
126+ // Anyone can throw these!
127+ if (def.subClassOf(env, ignore1) || def.superClassOf(env, ignore1) ||
128+ def.subClassOf(env, ignore2) || def.superClassOf(env, ignore2)) {
129+ continue;
130+ }
131+
132+ // Make sure the exception is actually throw in that part of the code
133+ boolean ok = false;
134+ for (Enumeration e = newexp.keys() ; e.hasMoreElements() ; ) {
135+ ClassDeclaration c = (ClassDeclaration)e.nextElement();
136+ if (def.superClassOf(env, c) || def.subClassOf(env, c)) {
137+ ok = true;
138+ break;
139+ }
140+ }
141+ if (!ok && arrayCloneWhere != 0
142+ && def.getName().toString().equals("java.lang.CloneNotSupportedException")) {
143+ env.error(arrayCloneWhere, "warn.array.clone.supported", def.getName());
144+ }
145+
146+ if (!ok) {
147+ env.error(cs.where, "catch.not.thrown", def.getName());
148+ }
149+ }
150+
151+ // Only carry over exceptions that are not caught
152+ for (Enumeration e = newexp.keys() ; e.hasMoreElements() ; ) {
153+ ClassDeclaration c = (ClassDeclaration)e.nextElement();
154+ ClassDefinition def = c.getClassDefinition(env);
155+ boolean add = true;
156+ for (int i = 0 ; i < args.length ; i++) {
157+ CatchStatement cs = (CatchStatement)args[i];
158+ if (cs.field == null) {
159+ continue;
160+ }
161+ Type type = cs.field.getType();
162+ if (type.isType(TC_ERROR))
163+ continue;
164+ if (def.subClassOf(env, env.getClassDeclaration(type))) {
165+ add = false;
166+ break;
167+ }
168+ }
169+ if (add) {
170+ exp.put(c, newexp.get(c));
171+ }
172+ }
173+ // A variable is DA (DU) after a try statement if it is DA (DU)
174+ // after the try block and after every catch block. These variables
175+ // are represented by 'vs'. If the try statement is labelled, we
176+ // may also exit from it (including from within a catch block) via
177+ // a break statement.
178+ // If there is a finally block, the Vset returned here is further
179+ // adjusted. Note that this 'TryStatement' node will be a child of
180+ // a 'FinallyStatement' node in that case.
181+ return ctx.removeAdditionalVars(vs.join(newctx.vsBreak));
182+ } catch (ClassNotFound e) {
183+ env.error(where, "class.not.found", e.name, opNames[op]);
184+ return vset;
185+ }
186+ }
187+
188+ /**
189+ * Inline
190+ */
191+ public Statement inline(Environment env, Context ctx) {
192+ if (body != null) {
193+ body = body.inline(env, new Context(ctx, this));
194+ }
195+ if (body == null) {
196+ return null;
197+ }
198+ for (int i = 0 ; i < args.length ; i++) {
199+ if (args[i] != null) {
200+ args[i] = args[i].inline(env, new Context(ctx, this));
201+ }
202+ }
203+ return (args.length == 0) ? eliminate(env, body) : this;
204+ }
205+
206+ /**
207+ * Create a copy of the statement for method inlining
208+ */
209+ public Statement copyInline(Context ctx, boolean valNeeded) {
210+ TryStatement s = (TryStatement)clone();
211+ if (body != null) {
212+ s.body = body.copyInline(ctx, valNeeded);
213+ }
214+ s.args = new Statement[args.length];
215+ for (int i = 0 ; i < args.length ; i++) {
216+ if (args[i] != null) {
217+ s.args[i] = args[i].copyInline(ctx, valNeeded);
218+ }
219+ }
220+ return s;
221+ }
222+
223+ /**
224+ * Compute cost of inlining this statement
225+ */
226+ public int costInline(int thresh, Environment env, Context ctx){
227+
228+ // Don't inline methods containing try statements.
229+ // If the try statement is being inlined in order to
230+ // inline a method that returns a value which is
231+ // a subexpression of an expression involving the
232+ // operand stack, then the early operands may get lost.
233+ // This shows up as a verifier error. For example,
234+ // in the following:
235+ //
236+ // public static int test() {
237+ // try { return 2; } catch (Exception e) { return 0; }
238+ // }
239+ //
240+ // System.out.println(test());
241+ //
242+ // an inlined call to test() might look like this:
243+ //
244+ // 0 getstatic <Field java.io.PrintStream out>
245+ // 3 iconst_2
246+ // 4 goto 9
247+ // 7 pop
248+ // 8 iconst_0
249+ // 9 invokevirtual <Method void println(int)>
250+ // 12 return
251+ // Exception table:
252+ // from to target type
253+ // 3 7 7 <Class java.lang.Exception>
254+ //
255+ // This fails to verify because the operand stored
256+ // for System.out gets axed at an exception, leading to
257+ // an inconsistent stack depth at pc=7.
258+ //
259+ // Note that although all code must be able to be inlined
260+ // to implement initializers, this problem doesn't come up,
261+ // as try statements themselves can never be expressions.
262+ // It suffices here to make sure they are never inlined as part
263+ // of optimization.
264+
265+ return thresh;
266+ }
267+
268+ /**
269+ * Code
270+ */
271+ public void code(Environment env, Context ctx, Assembler asm) {
272+ CodeContext newctx = new CodeContext(ctx, this);
273+
274+ TryData td = new TryData();
275+ for (int i = 0 ; i < args.length ; i++) {
276+ Type t = ((CatchStatement)args[i]).field.getType();
277+ if (t.isType(TC_CLASS)) {
278+ td.add(env.getClassDeclaration(t));
279+ } else {
280+ td.add(t);
281+ }
282+ }
283+ asm.add(where, opc_try, td);
284+ if (body != null) {
285+ body.code(env, newctx, asm);
286+ }
287+
288+ asm.add(td.getEndLabel());
289+ asm.add(where, opc_goto, newctx.breakLabel);
290+
291+ for (int i = 0 ; i < args.length ; i++) {
292+ CatchData cd = td.getCatch(i);
293+ asm.add(cd.getLabel());
294+ args[i].code(env, newctx, asm);
295+ asm.add(where, opc_goto, newctx.breakLabel);
296+ }
297+
298+ asm.add(newctx.breakLabel);
299+ }
300+
301+ /**
302+ * Print
303+ */
304+ public void print(PrintStream out, int indent) {
305+ super.print(out, indent);
306+ out.print("try ");
307+ if (body != null) {
308+ body.print(out, indent);
309+ } else {
310+ out.print("<empty>");
311+ }
312+ for (int i = 0 ; i < args.length ; i++) {
313+ out.print(" ");
314+ args[i].print(out, indent);
315+ }
316+ }
317+}