KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jbet > Node


1 /*
2  * JBET - Java Binary Enhancement Tool
3  * Copyright (c) 2003 Networks Associates Technology, Inc.
4  *
5  * This software was developed under DARPA/SPAWAR contract
6  * N66001-00-C-8602 "SPMA" as part of the
7  * DARPA OASIS research program.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */

30
31 package jbet;
32 import java.util.*;
33
34 /** Value-DAG stores input, output, and operations as nodes. Nodes are capable
35  * of generating their own code. This means that any rearrangement of common
36  * subexpressions etc. should take place within the DAG representation.
37
38  * Different DAG node types use subclasses of Node:
39
40  * Two argument arithmetic uses Node.N2
41  * One argument arithmetic uses Node.N1
42
43  * Block inputs are Node.var
44  * Temporary outputs are Node.assign
45  * Constants are Node.c*
46  * JVM new instruction is Node.New
47  * Method calls are Node.invoke?
48  * instanceof and checkcast Node.Cast
49
50  * @author Andrew Reisse
51  */

52
53 public class Node implements Cloneable JavaDoc {
54     
55     Node safeclone() {
56     try {
57         return (Node) clone();
58     } catch (CloneNotSupportedException JavaDoc e) {
59         throw new IllegalStateException JavaDoc(e.getMessage());
60     }
61     }
62
63     public BasicBlock sb; // originating block.
64
public int op; // operation this node performs, if any.
65
public int count; // number of times same calculation is used.
66
public HashSet destinations; // inputs of blocks which use this calculated value
67

68     public boolean esneed; // if destinations is non-null and non-empty, whether
69
// this value is needed by the block's exit record.
70
public int clocal = -1; // local to store result of non-idempotent operation in.
71
public boolean done; // temporary used by Codegen1.. not used any more?
72
public boolean required; // not used any more??
73

74     public boolean external;
75     public Object JavaDoc otype;
76
77     public String JavaDoc comment;
78
79     // requires chains nodes together in a BasicBlock.
80
// the first "numParams()" entries point to the input Nodes for this Node
81
// .. additional entries in requires are other precedence relations
82
// Larry says: a requires entry may point to an extra node
83
// .. that isn't really in the DAG, result of duplicate elimination
84
public Vector requires = new Vector();
85     int number = -1;
86     boolean noreplace; // never set
87

88     //Node direct_user;
89
boolean hasDirectUsers;
90     HashSet users;
91     boolean hasIndirectUsers;
92
93     public int serial;
94
95     public boolean isFake() { return false;};
96
97     public static Node.var[] NONE = new Node.var[0];
98     
99     public static Node EXIT = new Node() {
100         public boolean equals(Object JavaDoc o) { return o == this; }
101         public boolean isFake() { return true; }
102         protected String JavaDoc toString1 (int flags) { return "EXIT"; }
103     };
104     
105     
106     // op values for non-operation node types
107
public static final int OP_VAR = 0;
108     public static final int OP_CINT = 1;
109     public static final int OP_CSTRING = 2;
110
111     // one argument operations
112
public static final int OP_INEG = 101;
113     public static final int OP_ARRAYLENGTH = 102;
114     public static final int OP_L2I = 103;
115     public static final int OP_I2L = 104;
116
117     public static final int OP_FNEG = 105;
118     public static final int OP_L2F = 106;
119     public static final int OP_I2F = 107;
120     public static final int OP_F2I = 108;
121     public static final int OP_F2L = 109;
122     public static final int OP_DNEG = 110;
123     public static final int OP_L2D = 111;
124     public static final int OP_I2D = 112;
125     public static final int OP_F2D = 113;
126     public static final int OP_D2I = 114;
127     public static final int OP_D2L = 115;
128     public static final int OP_D2F = 116;
129     public static final int OP_I2B = 117;
130     public static final int OP_I2C = 118;
131     public static final int OP_I2S = 119;
132     public static final int OP_LNEG = 120;
133     
134     // two argument operations
135
public static final int OP_IADD = 201;
136     public static final int OP_ISUB = 202;
137     public static final int OP_IMUL = 203;
138     public static final int OP_IDIV = 204;
139     public static final int OP_IAND = 205;
140     public static final int OP_IOR = 206;
141     public static final int OP_IXOR = 207;
142
143     public static final int OP_LADD = 208;
144     public static final int OP_LSUB = 209;
145     public static final int OP_LMUL = 210;
146     public static final int OP_LDIV = 211;
147     public static final int OP_LAND = 212;
148     public static final int OP_LOR = 213;
149     public static final int OP_LXOR = 214;
150     public static final int OP_LCMP = 215;
151
152     public static final int OP_FADD = 216;
153     public static final int OP_FSUB = 217;
154     public static final int OP_FMUL = 218;
155     public static final int OP_FDIV = 219;
156
157     public static final int OP_FCMPL = 220;
158     public static final int OP_FCMPG = 221;
159
160     public static final int OP_DADD = 222;
161     public static final int OP_DSUB = 223;
162     public static final int OP_DMUL = 224;
163     public static final int OP_DDIV = 225;
164
165     public static final int OP_DCMPL = 226;
166     public static final int OP_DCMPG = 227;
167
168     public static final int OP_IREM = 228;
169     public static final int OP_ISHR = 229;
170     public static final int OP_ISHL = 230;
171
172     public static final int OP_LSHR = 231;
173     public static final int OP_LSHL = 232;
174     public static final int OP_LREM = 233;
175
176     public static final int OP_IUSHR = 234;
177     public static final int OP_LUSHR = 235;
178     
179     public static final int OP_FREM = 236;
180     public static final int OP_DREM = 237;
181  
182     // method calls and fields
183
public static final int OP_INVOKESTATIC = 901;
184     public static final int OP_INVOKEVIRTUAL = 902;
185     public static final int OP_INVOKEINTERFACE = 903;
186     public static final int OP_GETFIELD = 904;
187     public static final int OP_GETSTATIC = 905;
188     public static final int OP_PUTFIELD = 906;
189     public static final int OP_PUTSTATIC = 907;
190
191     // for toString
192
public static final int TOSTR_DFL = 1;
193     public static final int TOSTR_EXTRA = 2;
194     public static final int TOSTR_SRC = 4;
195     public static final int TOSTR_FLAGS1 = 7;
196     public static final int TOSTR_COMMENT = 8;
197
198     static final String JavaDoc op1char = "-#IL-FFIL-DDDILFBCS-";
199     static final String JavaDoc op2char = "+-*/&|^+-*/&|^?+-*/??+-*/??%><><%->>%%";
200
201     // translation to JVM opcodes
202
public static final int op1jvm[] = {Instruction.OP_INEG,
203                  Instruction.OP_ARRAYLENGTH,
204                  Instruction.OP_L2I,
205                  Instruction.OP_I2L,
206                  Instruction.OP_FNEG,
207                  Instruction.OP_L2F,
208                  Instruction.OP_I2F,
209                  Instruction.OP_F2I,
210                  Instruction.OP_F2L,
211                  Instruction.OP_DNEG,
212                  Instruction.OP_L2D,
213                  Instruction.OP_I2D,
214                  Instruction.OP_F2D,
215                  Instruction.OP_D2I,
216                  Instruction.OP_D2L,
217                  Instruction.OP_D2F,
218                                  Instruction.OP_I2B,
219                  Instruction.OP_I2C,
220                                  Instruction.OP_I2S,
221                  Instruction.OP_LNEG,
222                  };
223
224     public static final int op2jvm[] = {Instruction.OP_IADD, Instruction.OP_ISUB,
225                                  Instruction.OP_IMUL, Instruction.OP_IDIV,
226                                  Instruction.OP_IAND, Instruction.OP_IOR,
227                  Instruction.OP_IXOR,
228
229                                  Instruction.OP_LADD, Instruction.OP_LSUB,
230                                  Instruction.OP_LMUL, Instruction.OP_LDIV,
231                                  Instruction.OP_LAND, Instruction.OP_LOR,
232                                  Instruction.OP_LXOR, Instruction.OP_LCMP,
233
234                  Instruction.OP_FADD, Instruction.OP_FSUB,
235                                  Instruction.OP_FMUL, Instruction.OP_FDIV,
236                  Instruction.OP_FCMPL,Instruction.OP_FCMPG,
237                  Instruction.OP_DADD, Instruction.OP_DSUB,
238                                  Instruction.OP_DMUL, Instruction.OP_DDIV,
239                  Instruction.OP_DCMPL,Instruction.OP_DCMPG,
240                                  Instruction.OP_IREM, Instruction.OP_ISHR,
241                  Instruction.OP_ISHL,
242
243                  Instruction.OP_LSHR, Instruction.OP_LSHL,
244                  Instruction.OP_LREM,
245                  Instruction.OP_IUSHR, Instruction.OP_LUSHR,
246                  Instruction.OP_FREM, Instruction.OP_DREM
247                                 };
248
249     static final Type op2ptype[] = { Type.INT, Type.INT,
250                      Type.INT, Type.INT,
251                      Type.INT, Type.INT,
252                      Type.INT, Type.INT,
253                      Type.INT, Type.INT,
254                      Type.INT, Type.INT,
255                      Type.INT, Type.INT,
256                      Type.LONG,Type.LONG,
257                      Type.LONG,Type.LONG,
258                      Type.LONG,Type.LONG,
259                      Type.LONG,Type.LONG,
260                      Type.LONG,Type.LONG,
261                      Type.LONG,Type.LONG,
262                      Type.LONG,Type.LONG,
263                      Type.LONG,Type.LONG,
264                      Type.FLOAT,Type.FLOAT,
265                      Type.FLOAT,Type.FLOAT,
266                      Type.FLOAT,Type.FLOAT,
267                      Type.FLOAT,Type.FLOAT,
268                      Type.FLOAT,Type.FLOAT,
269                      Type.FLOAT,Type.FLOAT,
270                      Type.DOUBLE,Type.DOUBLE,
271                      Type.DOUBLE,Type.DOUBLE,
272                      Type.DOUBLE,Type.DOUBLE,
273                      Type.DOUBLE,Type.DOUBLE,
274                      Type.DOUBLE,Type.DOUBLE,
275                      Type.DOUBLE,Type.DOUBLE,
276                      Type.INT,Type.INT,
277                      Type.INT,Type.INT,
278                      Type.INT,Type.INT,
279                      Type.LONG,Type.INT,
280                      Type.LONG,Type.INT,
281                      Type.LONG, Type.LONG,
282                      Type.INT, Type.INT,
283                      Type.LONG, Type.INT,
284                      Type.FLOAT,Type.FLOAT,
285                      Type.DOUBLE,Type.DOUBLE };
286
287     // type used by operation (N1 or N2) nodes
288
static final Type op1ptype[] = { Type.INT,
289                       Type.ARRAY,
290                       Type.LONG,
291                       Type.INT,
292                       Type.FLOAT,
293                       Type.LONG,
294                       Type.INT,
295                       Type.FLOAT,
296                       Type.FLOAT,
297                       Type.DOUBLE,
298                       Type.LONG,
299                       Type.INT,
300                       Type.FLOAT,
301                       Type.DOUBLE,
302                       Type.DOUBLE,
303                       Type.DOUBLE,
304                       Type.INT,
305                       Type.INT,
306                       Type.INT,
307                       Type.LONG,
308                                     } ;
309
310     // type produced by operation (N1 or N2) nodes
311
static final Type op1type[] = { Type.INT,
312                      Type.INT,
313                      Type.INT,
314                      Type.LONG,
315                      Type.FLOAT,
316                      Type.FLOAT,
317                      Type.FLOAT,
318                      Type.INT,
319                      Type.LONG,
320                      Type.DOUBLE,
321                      Type.DOUBLE,
322                      Type.DOUBLE,
323                      Type.DOUBLE,
324                      Type.INT,
325                      Type.LONG,
326                      Type.FLOAT,
327                      Type.BYTE,
328                      Type.CHAR,
329                      Type.SHORT,
330                      Type.INT,
331                      Type.LONG,
332     } ;
333
334     static final Type op2type[] = { Type.INT,
335                     Type.INT,
336                     Type.INT,
337                     Type.INT,
338                     Type.INT,
339                     Type.INT,
340                     Type.INT,
341                     Type.LONG,
342                     Type.LONG,
343                     Type.LONG,
344                     Type.LONG,
345                     Type.LONG,
346                     Type.LONG,
347                     Type.LONG,
348                     Type.INT,
349                     Type.FLOAT,
350                     Type.FLOAT,
351                     Type.FLOAT,
352                     Type.FLOAT,
353                     Type.BOOLEAN,
354                     Type.BOOLEAN,
355                     Type.DOUBLE,
356                     Type.DOUBLE,
357                     Type.DOUBLE,
358                     Type.DOUBLE,
359                     Type.BOOLEAN,
360                     Type.BOOLEAN,
361                     Type.INT,
362                     Type.INT,
363                     Type.INT,
364                     Type.LONG,
365                     Type.LONG,
366                     Type.LONG, Type.INT, Type.LONG,
367                                     Type.FLOAT,Type.DOUBLE };
368
369     // translation from JVM opcodes
370
public static final int jvm2node[] = new int [256];
371
372     static {
373     jvm2node[Instruction.OP_IADD] = Node.OP_IADD;
374     jvm2node[Instruction.OP_ISUB] = Node.OP_ISUB;
375     jvm2node[Instruction.OP_IMUL] = Node.OP_IMUL;
376     jvm2node[Instruction.OP_IDIV] = Node.OP_IDIV;
377         jvm2node[Instruction.OP_IREM] = Node.OP_IREM;
378     jvm2node[Instruction.OP_IAND] = Node.OP_IAND;
379     jvm2node[Instruction.OP_IOR ] = Node.OP_IOR;
380     jvm2node[Instruction.OP_IXOR] = Node.OP_IXOR;
381     jvm2node[Instruction.OP_INEG] = Node.OP_INEG;
382     jvm2node[Instruction.OP_DNEG] = Node.OP_DNEG;
383     jvm2node[Instruction.OP_FNEG] = Node.OP_FNEG;
384     jvm2node[Instruction.OP_LNEG] = Node.OP_LNEG;
385     jvm2node[Instruction.OP_ARRAYLENGTH] = Node.OP_ARRAYLENGTH;
386     jvm2node[Instruction.OP_LADD] = Node.OP_LADD;
387     jvm2node[Instruction.OP_LSUB] = Node.OP_LSUB;
388     jvm2node[Instruction.OP_LMUL] = Node.OP_LMUL;
389     jvm2node[Instruction.OP_LDIV] = Node.OP_LDIV;
390     jvm2node[Instruction.OP_LAND] = Node.OP_LAND;
391     jvm2node[Instruction.OP_LOR ] = Node.OP_LOR;
392     jvm2node[Instruction.OP_LXOR] = Node.OP_LXOR;
393     jvm2node[Instruction.OP_LCMP] = Node.OP_LCMP;
394     jvm2node[Instruction.OP_L2I ] = Node.OP_L2I;
395     jvm2node[Instruction.OP_I2L ] = Node.OP_I2L;
396     jvm2node[Instruction.OP_FADD] = Node.OP_FADD;
397     jvm2node[Instruction.OP_FSUB] = Node.OP_FSUB;
398     jvm2node[Instruction.OP_FMUL] = Node.OP_FMUL;
399     jvm2node[Instruction.OP_FDIV] = Node.OP_FDIV;
400     jvm2node[Instruction.OP_FCMPL] = Node.OP_FCMPL;
401     jvm2node[Instruction.OP_FCMPG] = Node.OP_FCMPG;
402     jvm2node[Instruction.OP_L2F ] = Node.OP_L2F;
403     jvm2node[Instruction.OP_I2F ] = Node.OP_I2F;
404     jvm2node[Instruction.OP_F2I ] = Node.OP_F2I;
405     jvm2node[Instruction.OP_F2L ] = Node.OP_F2L;
406     jvm2node[Instruction.OP_DADD] = Node.OP_DADD;
407     jvm2node[Instruction.OP_DSUB] = Node.OP_DSUB;
408     jvm2node[Instruction.OP_DMUL] = Node.OP_DMUL;
409     jvm2node[Instruction.OP_DDIV] = Node.OP_DDIV;
410     jvm2node[Instruction.OP_DCMPL] = Node.OP_DCMPL;
411     jvm2node[Instruction.OP_DCMPG] = Node.OP_DCMPG;
412     jvm2node[Instruction.OP_L2D ] = Node.OP_L2D;
413     jvm2node[Instruction.OP_I2D ] = Node.OP_I2D;
414     jvm2node[Instruction.OP_F2D ] = Node.OP_F2D;
415     jvm2node[Instruction.OP_D2I ] = Node.OP_D2I;
416     jvm2node[Instruction.OP_D2L ] = Node.OP_D2L;
417     jvm2node[Instruction.OP_D2F ] = Node.OP_D2F;
418         jvm2node[Instruction.OP_I2C ] = Node.OP_I2C;
419         jvm2node[Instruction.OP_I2B ] = Node.OP_I2B;
420         jvm2node[Instruction.OP_I2S ] = Node.OP_I2S;
421         jvm2node[Instruction.OP_LSHR ] = Node.OP_LSHR;
422         jvm2node[Instruction.OP_LSHL ] = Node.OP_LSHL;
423         jvm2node[Instruction.OP_ISHR ] = Node.OP_ISHR;
424         jvm2node[Instruction.OP_ISHL ] = Node.OP_ISHL;
425         jvm2node[Instruction.OP_LREM ] = Node.OP_LREM;
426         jvm2node[Instruction.OP_IUSHR ] = Node.OP_IUSHR;
427         jvm2node[Instruction.OP_LUSHR ] = Node.OP_LUSHR;
428         jvm2node[Instruction.OP_FREM ] = Node.OP_FREM;
429         jvm2node[Instruction.OP_DREM ] = Node.OP_DREM;
430     }
431
432     public boolean isinit() { return false; }
433
434     public Node usesAt(int i) {
435     return (Node) requires.elementAt(i);
436     }
437
438     /* Return the type of a parameter */
439
440     public Type paramType (int i) {
441     throw new IllegalStateException JavaDoc (getClass().getName() + ": invalid param number " + i);
442     }
443
444     /** Return the count of input parameters for this
445      * subtype of Node. The first numParams() items in "requires"
446      * are parameter Nodes.
447      * @return count of parameters
448      */

449     public int numParams() {
450     return 0;
451     }
452
453     final int objectHashCode() { return super.hashCode(); }
454
455     public final String JavaDoc toString() {
456     if (comment != null)
457         return toString1 (TOSTR_EXTRA) + " /* " + comment + " */ ";
458     else
459         if (serial >= 0)
460         return toString1 (TOSTR_EXTRA);
461         else
462         return "(" + toString1 (TOSTR_EXTRA) + ")*" + serial;
463     }
464
465     public final String JavaDoc toString (int flags) {
466     if ((flags & TOSTR_COMMENT) != 0 && comment != null)
467         return toString1 (flags & TOSTR_FLAGS1) + " /* " + comment + " */ ";
468     else if ((flags & TOSTR_SRC) != 0 && clocal != -1 && !idempotent())
469         return "t" + clocal;
470     else
471         if (serial >= 0)
472         return toString1 (flags & TOSTR_FLAGS1);
473         else
474         return "(" + toString1 (flags & TOSTR_FLAGS1) + ")*" + serial;
475
476     }
477
478     protected String JavaDoc toString1 (int flags) { return "invalid node " + getClass().getName(); }
479
480     /* convert JVM instruction to node operation types */
481     public final int jvm2node (int jvm_op) { return jvm2node[jvm_op]; }
482
483     /* @return list of destinations as string */
484     public final String JavaDoc destinationString() {
485     StringBuffer JavaDoc out = new StringBuffer JavaDoc();
486     
487     if (destinations != null)
488         for (Iterator i = destinations.iterator(); i.hasNext();) {
489         out.append (i.next());
490         if (i.hasNext() || esneed)
491             out.append (", ");
492         }
493     if (esneed) {
494         out.append ("es");
495     } else if (destinations == null) {
496         out.append ("none");
497     }
498     if (required) {
499       out.append (",require");
500     }
501
502     return out.toString();
503     }
504
505     public void addDestination(Node n) {
506     if (destinations == null)
507         destinations = new HashSet();
508     destinations.add(n);
509     }
510
511     /* Also add this to n.producers */
512
513     public void addDestination2 (Node.var n) {
514     if (destinations == null)
515         destinations = new HashSet();
516     destinations.add (n);
517     n.producers.add (this);
518     }
519
520
521     /* mark which inputs are needed by this tree */
522     public void findinputs (int[] mk) { }
523
524     /* set refcounts of all nodes */
525     public final void addrefcounts () {
526       Vector s = new Vector();
527       allnodes (s);
528       for (Iterator i = s.iterator(); i.hasNext(); ) {
529     ((Node)i.next()).count++;
530       }
531     }
532
533     /* find all nodes in this tree */
534     public final HashSet allnodes() { HashSet v = new HashSet(); allnodes (v); return v; }
535
536     /* Add all nodes in this tree to v */
537     public final void allnodes (Collection v) { allnodes (v, true); }
538     public void allnodes (Collection v, boolean doRequires) {
539     v.add (this);
540
541     if (doRequires)
542         for (Iterator i = requires.iterator(); i.hasNext(); )
543         ((Node)i.next()).allnodes (v, doRequires);
544     else
545         for (int i = 0; i < numParams(); i++)
546         usesAt (i).allnodes (v, doRequires);
547     }
548
549     /* Can this node be traversed a number of times other than one
550        (with the same results)? */

551     public boolean idempotent() { return true; }
552
553     public boolean hasSideEffect() { return false; }
554
555     public final int countDests (int extra, boolean leaveonstack) {
556     int nvars = 0;
557     if (extra != -1) nvars++;
558     if (leaveonstack) nvars++;
559     if (destinations != null)
560         for (Iterator i = destinations.iterator(); i.hasNext();)
561         if (i.next() instanceof Node.var)
562             nvars++;
563     return nvars;
564     }
565     
566
567     /** Generate code for storing to the destinations (which should have been
568      * pushed by the code generated by this.codegen().
569      */

570     public final void storeDests (Snippit out, LocalAccess locals, int extra, boolean leaveonstack) {
571     if ( this.type().equals( Type.VOID ) ) return;
572     if (this instanceof ret) return; // BLETCH
573

574     int nvars = countDests(extra, leaveonstack);
575     
576     out.setDupX (type(), nvars-1 );
577     
578     if (destinations != null)
579     for (Iterator i = destinations.iterator(); i.hasNext();) {
580         Object JavaDoc o = i.next();
581         if (o instanceof Node.var) {
582         Node.var dest = (var) o;
583         //locals.store (out, dest.outlvt, dest.t);
584
locals.store (out, dest.outlvt, type());
585         }
586     }
587
588     if (extra != -1)
589         locals.store (out, extra, type());
590     }
591     
592     
593       
594     /* @return the type produced by this node */
595
596     public Type type() { throw new IllegalStateException JavaDoc ("invalid node " + getClass().getName()); }
597
598     /** @return the set of nodes rquired by this node, not counting the inputs */
599     public final InternSet requires() {
600     InternSet out = new InternSet();
601     for (int i = numParams(); i < requires.size(); i++)
602         out.add (requires.elementAt (i));
603     return out;
604     }
605
606     /** indicate that this node requires another as input */
607     public void require (Node n)
608     {
609     if (n == this)
610         throw new IllegalStateException JavaDoc ("node cannot require itself");
611     if (n instanceof Node.Cast)
612         require (((Node.Cast) n).val);
613
614     if (n.idempotent ())
615         return;//throw new IllegalStateException ("node cannot require nodes without side effects");
616
if (idempotent())
617         return;//throw new IllegalStateException ("nodes without side effects cannot require anything");
618

619     requires.addElement (n);
620     }
621
622     public final void require (Collection c)
623     {
624     for (Iterator i = c.iterator(); i.hasNext(); ) {
625         Object JavaDoc o = i.next();
626         require ((Node)o);
627     }
628     }
629
630     public void require2 (Node n)
631     {
632     require (n);
633     for (int i = 0; i < numParams(); i++)
634         usesAt (i).require2 (n);
635     //throw new IllegalStateException ("require2 used");
636
}
637
638     public final void require2 (Collection c)
639     {
640     require (c);
641     for (int i = 0; i < numParams(); i++)
642         usesAt (i).require2 (c);
643     //throw new IllegalStateException ("require2 used");
644
}
645
646     /* make all in c require this */
647     public final void urequire (Collection c)
648     {
649     for (Iterator i = c.iterator(); i.hasNext(); ) {
650         Node o = (Node) i.next();
651         o.require (this);
652     }
653     }
654
655     /* Substitutions */
656
657     /*
658        when replace returns one node, that one node replaces one parameter
659        of another node. Suppose a dag is (x * f(z)),
660        and you want to replace x with y. The nodes are:
661        
662        $A N2(*,$C,$B)
663        $B invokestatic(f,$D)
664        $C x
665        $D z
666        
667        The expression is $A. When you replace x with y, $C becomes y. So the
668        graph is now:
669        $A N2(*,$C,$B)
670        $B invokestatic(f,$D)
671        $C x
672        $D z
673        
674     */

675
676     public static class SubMethod
677     {
678     public Node f (Node in) throws Throwable JavaDoc { return in; }
679     }
680
681     public final Node replace (Hashtable subs, SubMethod sm) throws Throwable JavaDoc {
682     return replace (subs, sm, true);
683     }
684
685     public final Node replace (Hashtable subs, SubMethod sm, boolean recursive) throws Throwable JavaDoc {
686
687     if (noreplace)
688         return this;
689
690     if (recursive)
691         replace1 (subs, sm);
692
693     Node mn = sm.f (this);
694     Node hn = (Node) subs.get (this);
695     Node nn;
696
697     if (mn != null && hn != null && mn != hn)
698         throw new IllegalStateException JavaDoc ("subs and sm conflict for " + this + ": " + hn + " / " + mn);
699     else if (hn != null)
700         nn = hn;
701     else
702         nn = mn;
703
704     if (destinations != null && this != nn) {
705         loop: while (true) {
706         for (Iterator i = destinations.iterator(); i.hasNext(); ) {
707             Object JavaDoc o = i.next();
708             Object JavaDoc so = subs.get (o);
709
710             /*
711             if (so != null && !(so instanceof Node.var)) {
712             nn.destinations.remove (o);
713             continue loop;
714             } else if (so != null && so != o) {
715             nn.destinations.remove (o);
716             nn.destinations.add (so);
717             continue loop;
718             }
719             */

720
721             Node.var vn = (Node.var) o;
722             if (this != nn) {
723             vn.producers.remove (this);
724             vn.producers.add (nn);
725             }
726             nn.addDestination (vn);
727         }
728         break loop;
729         }
730
731         if (destinations.size() == 0)
732         destinations = null;
733     }
734
735     return nn;
736     }
737
738     protected final void replace1 (Hashtable subs, SubMethod sm) throws Throwable JavaDoc {
739
740     for (int i = 0; i < requires.size(); i++)
741         requires.setElementAt (usesAt (i).replace (subs, sm, false), i);
742     }
743
744     /* Generate code for this node. The parameters must be on the operand stack in the
745        proper order prior to this code executing. */

746
747     public void codegen1 (Snippit out) {
748
749     throw new IllegalStateException JavaDoc
750         ("use of abstract codegen1 by class " + getClass().getName());
751     }
752
753     // ================================================================
754
// Subclasses of Node
755
// ================================================================
756

757     /* An assignment statment (temporary use only) */
758
759     public static class assign extends Node {
760     public boolean idempotent () { return false; }
761     public boolean hasSideEffect () { return true; }
762
763     public Node val; static { jbet.cmd.property.makeProperty("val"); }
764     public Node get__val() { return (Node) usesAt(0); }
765     public void set__val(Node n) { requires.setElementAt(n, 0); }
766
767     public int numParams() { return 1; }
768
769     public Type paramType (int i) {
770         return val.type();
771     }
772
773     int lvt;
774
775     public assign (int lo, Node v, BasicBlock b) {
776         requires.setSize(1); lvt = lo; val = v; sb=b; }
777
778     protected String JavaDoc toString1 (int flags) { return "&" + lvt + " = " + val; }
779     public boolean equals (Object JavaDoc io) { return io == this; }
780     public Type type() { /*return val.type();*/ return Type.VOID; }
781     }
782
783     /* a method parameter */
784     public static class param extends Node {
785     int v;
786     Type t;
787     public param (int n, Type tt) {
788         v = n; t = tt;
789         esneed = false;
790     }
791         
792     protected String JavaDoc toString1 (int flags) {
793         if (flags == TOSTR_SRC)
794         return "p" + v;
795         else
796         return "&" + v;
797     }
798     /*
799     public void codegen (Snippit out, CodeGenerator cg) {
800         out.push( new Instruction().setLoad(t, v) );
801     }
802     */

803     public Type type() {
804         return t;
805     }
806     public boolean equals (Object JavaDoc io) {
807         return io instanceof param &&
808         ((param)io).v == v && ((param)io).t.equals(t) &&
809         sb==((Node)io).sb;
810     }
811     public int hashCode() { return v * 33; }
812     }
813
814     static class LoadMarker extends Node {
815     Node n;
816     LoadMarker(Node nn) { n = nn; }
817     public String JavaDoc toString1 (int flags) { return "LOADMARKER " + n; };
818     public boolean isFake() { return true; }
819     }
820
821     static class DupMarker extends Node {
822     DupMarker() {}
823     public String JavaDoc toString1 (int flags) { return "DUPMARKER"; }
824     public boolean isFake() { return true; }
825     }
826
827     /* something arbitrary */
828     static class other extends Node {
829     Object JavaDoc o;
830     Type t;
831
832     other (Object JavaDoc io, Type it) {
833         o = io; t = it;
834     }
835
836     public Type type() {
837         if (t == null)
838         throw new IllegalStateException JavaDoc ("no type specified for " + o.toString());
839         return t;
840     }
841
842     protected String JavaDoc toString1 (int flags) { return o.toString(); }
843
844     public boolean equals (Object JavaDoc io) {
845         if (io instanceof other) {
846         other oo = (other) io;
847         return
848             (t == null && oo.t == null && o.equals (oo.o)) ||
849             (t != null && oo.t != null && o.equals (oo.o) && t.equals (oo.t));
850         }
851         return false;
852     }
853     }
854
855     public static class marker extends Node
856     {
857     String JavaDoc message;
858
859     public marker (String JavaDoc msg) { message = msg; }
860
861     public boolean hasSideEffect () { return true; }
862     public boolean idempotent () { return false; }
863
864     protected String JavaDoc toString1 (int flags) { return message; }
865     public void codegen1 (Snippit out) { }
866     public Type type () { return Type.VOID; }
867     public boolean equals (Object JavaDoc io) { return (io == this); }
868     public boolean isFake() { return true;}
869     }
870
871     /* A load (from a block input) */
872     public static class var extends Node
873     {
874     
875     var split(BasicBlock b) {
876         var ret = new var(v, t);
877         ret.name = name;
878         ret.producers = new HashSet(producers);
879         if (destinations != null)
880         ret.destinations = new HashSet(destinations);
881         ret.outlvt = outlvt;
882         if (exobject) throw new IllegalStateException JavaDoc
883         ("exobjects can not safely be split");
884         for (Iterator i = producers.iterator(); i.hasNext();) {
885         Node p = (Node) i.next();
886         p.destinations.add(ret);
887         }
888         ret.sb = b;
889         return ret;
890     }
891     
892     public String JavaDoc name;
893     // name is the the variables name in the orignanal
894
// program, if applicable
895
public int v;
896     public Type t;
897     public HashSet producers; // set of Nodes in other blocks that lead to us
898

899     public int outlvt;
900     public boolean leftover;
901         public boolean exobject;
902
903     public var (int _v, Type _t) {
904         v = _v; t = _t; producers = new HashSet();
905         outlvt = -1; leftover = exobject = false;
906     }
907
908     protected String JavaDoc toString1 (int flags) {
909
910         if (flags == TOSTR_DFL || flags == TOSTR_EXTRA) {
911         String JavaDoc out = sb != null ? ("&" + sb.swval + ":" + v) : ("&?:" + v);
912         if (producers.size() == 1 &&
913             producers.iterator().next() instanceof Node.New)
914             out += "/N" + ((Node.New)producers.iterator().next()).serial;
915
916         if (flags == TOSTR_EXTRA) {
917             if (exobject)
918             out += "/E";
919             if (outlvt >= 0)
920             out += "!" + outlvt;
921             if (name != null)
922             out += "{" + name + "}";
923             /*
924             if (obfuscator != null)
925               out += "%" + obfuscator.toString();
926             */

927             if (producers.size() == 0 && !exobject)
928             out += "_BUG";
929         }
930         return out;
931         } else {
932         if (name == null) {
933             if (v >= 0)
934             name = "b" + sb.swval + "v" + v;
935             else
936             name = "b" + sb.swval + "s" + (-v);
937         }
938         return name;
939         }
940     }
941
942     public void addname(String JavaDoc s) {
943         if (name == null) {
944         name = s;
945         } else if (! name.equals(s))
946         throw new IllegalStateException JavaDoc("2 diffirent names for a var");
947     }
948         
949
950     public boolean equals (Object JavaDoc io) { return (io == this); }
951
952     public void codegen1 (Snippit out) {
953         if (outlvt >= 0) {
954         out.push (new Instruction().setLoad (t, outlvt));
955         }
956         else {
957           throw new IllegalStateException JavaDoc ("load from unallocated var " + toString());
958         }
959     }
960
961     public Type type() { return t; }
962
963     public void findinputs (int[] inputs) {
964         if (outlvt >= 0) {
965         inputs[outlvt]++;
966         }
967     }
968     } // var
969

970     public static Node Constant (Object JavaDoc val) {
971     if (val instanceof String JavaDoc)
972         return new Node.cString ((String JavaDoc) val);
973     else if (val instanceof Integer JavaDoc)
974         return new Node.cint (((Integer JavaDoc)val).intValue());
975     else if (val instanceof Long JavaDoc)
976         return new Node.clong (((Long JavaDoc)val).longValue());
977     else if (val instanceof Float JavaDoc)
978         return new Node.cfloat (((Float JavaDoc)val).floatValue());
979     else if (val instanceof Double JavaDoc)
980         return new Node.cdouble (((Double JavaDoc)val).doubleValue());
981     else
982         throw new IllegalStateException JavaDoc ("no constant type for " + val);
983     }
984
985     public abstract static class constant extends Node
986     {
987     abstract public Object JavaDoc value();
988     }
989
990     /* A constant integer */
991
992     public static class cint extends constant
993     {
994     public int i;
995
996     public cint (int c) { i = c; }
997
998     protected String JavaDoc toString1 (int flags) { return "" + i; }
999     public boolean equals (Object JavaDoc io) {
1000        return io instanceof cint && ((cint)io).i == i && sb==((Node)io).sb &&
1001        toString().equals (io.toString());
1002    }
1003    public int hashCode() { return i; };
1004
1005    public void codegen1 (Snippit out) {
1006        out.push (new Instruction().setIpush ((int)i));
1007    }
1008    public Type type() { return Type.INT; }
1009
1010    public static final cint ONE = new cint (1);
1011    public static final cint ZERO = new cint (0);
1012    public static final cint TWO = new cint (2);
1013
1014    public static cint[] NewX (int[] a)
1015    {
1016        cint[] n = new cint[a.length];
1017        for (int i = 0; i < a.length; i++)
1018        n[i] = new cint (a[i]);
1019        return n;
1020    }
1021
1022    public Object JavaDoc value() { return new Integer JavaDoc (i); }
1023    }
1024
1025    public static class ret extends Node
1026    {
1027    BasicBlock block;
1028
1029    ret (BasicBlock b) { block = b; }
1030
1031    protected String JavaDoc toString1 (int flags) { return "R" ; }
1032    public boolean equals (Object JavaDoc io) {
1033        return io instanceof ret &&
1034        ((ret)io).block == block && sb==((Node)io).sb;
1035    }
1036    public int hashCode() {
1037        return 3;
1038    }
1039    public void codegen1 (Snippit out) {
1040        ; // the exit record does this for us
1041
}
1042    public Type type() { return Type.RETADDR; }
1043    }
1044
1045    /* a constant long */
1046
1047    public static class clong extends constant
1048    {
1049    public long i;
1050
1051    public clong (long c) { i = c; }
1052
1053    protected String JavaDoc toString1 (int flags) { return "" + i + "L"; }
1054    public boolean equals (Object JavaDoc io) {
1055            return io instanceof clong && ((clong)io).i == i && sb==((Node)io).sb;
1056        }
1057    public int hashCode() { return (int) i; }
1058    public void codegen1 (Snippit out) {
1059            out.push (new Instruction().setLpush (i));
1060        }
1061    public Type type() { return Type.LONG; }
1062
1063    public static final clong ONE = new clong (1);
1064    public static final clong ZERO = new clong (0);
1065
1066    public Object JavaDoc value() { return new Long JavaDoc (i); }
1067    }
1068
1069    /* a constant float */
1070
1071    public static class cfloat extends constant
1072    {
1073    public double f;
1074
1075    public cfloat (double c) { f = c; }
1076
1077    protected String JavaDoc toString1 (int flags) { return "" + f + "f"; }
1078    public boolean equals (Object JavaDoc io) {
1079        if ( !(io instanceof cfloat) ) return false;
1080        cfloat i = (cfloat) io;
1081        if (i.sb != sb) return false;
1082        if (Double.isNaN(f) && Double.isNaN(i.f)) return true;
1083        return i.f == f;
1084        // return io instanceof cfloat && ((cfloat)io).f==f && sb==((Node)io).sb;
1085
}
1086    public int hashCode() {
1087        return (int)f;
1088    }
1089    public void codegen1 (Snippit out) {
1090            out.push (new Instruction().setFpush (f));
1091        }
1092    public Type type() { return Type.FLOAT; }
1093
1094    public Object JavaDoc value() { return new Float JavaDoc (f); }
1095    }
1096
1097    /* a constant double */
1098
1099    public static class cdouble extends constant
1100    {
1101    public double d;
1102
1103    public cdouble (double c) { d = c; }
1104
1105    protected String JavaDoc toString1 (int flags) { return "" + d + "d"; }
1106    public boolean equals (Object JavaDoc io) {
1107        if ( !(io instanceof cdouble) ) return false;
1108        cdouble i = (cdouble) io;
1109        if (i.sb != sb) return false;
1110        if (Double.isNaN(d) && Double.isNaN(i.d)) return true;
1111        if (d==0) return Double.doubleToLongBits(d)==
1112              Double.doubleToLongBits(i.d);
1113        return i.d == d;
1114        }
1115    public int hashCode() { return (int) d; }
1116    public void codegen1 (Snippit out) {
1117            out.push (new Instruction().setDpush (d));
1118        }
1119    public Type type() { return Type.DOUBLE; }
1120
1121    public Object JavaDoc value() { return new Double JavaDoc (d); }
1122    }
1123
1124    /* A constant string */
1125
1126    public static class cString extends constant
1127    {
1128    public String JavaDoc s;
1129
1130    public cString (String JavaDoc sin) { s = sin; }
1131
1132    protected String JavaDoc toString1 (int flags) {
1133      
1134      /* don't print absurdly long string constants (for jacks) */
1135      if (s.length() > 100) {
1136        return "<" + s.length() + " chars>";
1137      } else {
1138        return "\"" + s + "\"";
1139      }
1140    }
1141    public boolean equals (Object JavaDoc io) {
1142        return (io instanceof cString) &&
1143        ((cString)io).s.equals (s);
1144    }
1145    public int hashCode() {
1146        return s.hashCode();
1147    }
1148
1149    public void codegen1 (Snippit out) { out.push (new Instruction().setSpush (s)); }
1150    public Type type() { return Type.STRING; }
1151
1152    public Object JavaDoc value() { return s; }
1153    }
1154
1155    /* A constant null */
1156    
1157    public static class cnull extends constant
1158    {
1159    public cnull () {}
1160    protected String JavaDoc toString1 (int flags) { return "null"; }
1161    public boolean equals (Object JavaDoc io) {
1162        return (io instanceof cnull) && ((cnull)io).sb==sb;
1163    }
1164    public int hashCode() { return 33; }
1165    public void codegen1 (Snippit out) { out.push (new Instruction().setAconst_Null()); }
1166    public Type type() { return Type.NULL; }
1167
1168    public Object JavaDoc value() { return null; }
1169    }
1170
1171    /* A JVM new instruction */
1172
1173    public static class New extends Node
1174    {
1175    static int newcount = 0;
1176
1177    public String JavaDoc cname; // class name
1178
public Type t; // Lcname;
1179
int serial; // serial number of new object, for prettier printing
1180

1181    public New (String JavaDoc cn) { cname = cn; t = new Type ('l', 0, cname); clocal = -1; count = 1; serial = ++newcount; }
1182    protected String JavaDoc toString1 (int flags) {
1183        if (0 != (flags & TOSTR_SRC))
1184        return "n" + serial;
1185        else
1186        return "&N" + serial;
1187    }
1188    public boolean equals (Object JavaDoc io) { return io == this; }
1189    public boolean idempotent() { return false; }
1190
1191    public void codegen1 (Snippit out) {
1192        out.push (new Instruction().setNew (cname));
1193    }
1194
1195    public Type type() { return t; }
1196    }
1197
1198    /* A JVM getfield instruction. A static field is represented by a null obj member. */
1199
1200    public static class getfield extends Node
1201    {
1202    public boolean isstatic;
1203    public String JavaDoc cname;
1204    public String JavaDoc field;
1205    public Type t;
1206    public Node obj; // object with field to get
1207
public int ver;
1208
1209    public getfield (String JavaDoc c, String JavaDoc f, Type _t, Node o) {
1210        isstatic = (o==null);
1211        requires.setSize(numParams());
1212        cname = c; field = f;
1213        t = _t;
1214        if (!isstatic) obj = o;
1215        count = 1; clocal = -1;
1216        ver = -1;
1217    }
1218
1219    static { jbet.cmd.property.makeProperty("obj"); }
1220    public Node get__obj() { return isstatic ? null : (Node) usesAt(0); }
1221    public void set__obj(Node n) { requires.setElementAt(n, 0); }
1222    
1223    public int numParams() { return isstatic ? 0 : 1; };
1224
1225    public Type paramType (int i) {
1226        if (isstatic)
1227        throw new IllegalStateException JavaDoc ("getstatic has no params");
1228
1229        return new Type ('L', 0, cname);
1230    }
1231
1232    protected String JavaDoc toString1 (int flags) {
1233      StringBuffer JavaDoc r = new StringBuffer JavaDoc();
1234      r.append (obj != null ? obj.toString (flags) : ((flags & TOSTR_SRC) != 0 ? Util.srcClassName (cname) : cname));
1235      r.append ('.');
1236      r.append (field);
1237
1238      /*if (flags == TOSTR_DFL || flags == TOSTR_EXTRA) {
1239          if (ver >= 0) {
1240          r.append ("__");
1241          r.append (ver);
1242          }
1243          if (clocal >= 0) {
1244          r.append ('!');
1245          r.append (clocal);
1246          }
1247          }*/

1248
1249      return r.toString();
1250    }
1251
1252    public boolean equals (Object JavaDoc io) {
1253        if (this != null)
1254        return io == this;
1255                
1256        /* A getfield is equal to another getfield if there is no
1257               intervening setfield */

1258        if (sb != null && io instanceof getfield) {
1259        getfield o = (getfield) io;
1260
1261        if (ver == -1 || o.ver == -1)
1262            return false;
1263        if (sb != o.sb)
1264            return false;
1265        if (obj != null && o.obj == null)
1266            return false;
1267        if (obj == null && o.obj != null)
1268            return false;
1269        
1270        if (obj == null)
1271            return o.cname.equals (cname) && o.field.equals (field) && ver == o.ver;
1272        else
1273            return o.cname.equals (cname) && o.field.equals (field) && obj.equals (o.obj) && ver == o.ver;
1274        }
1275
1276        return false;
1277    }
1278    public int hashCode() {
1279        return 3*cname.hashCode() + 2*field.hashCode() + 5*ver;
1280    }
1281
1282    public Type type() { return t; }
1283
1284    public boolean idempotent() { return false; }
1285    public void codegen1 (Snippit out) {
1286        if (obj != null) {
1287        out.push (new Instruction().setGetfield (cname, field, t));
1288        } else {
1289        out.push (new Instruction().setGetstatic (cname, field, t));
1290        }
1291    }
1292
1293    public void findinputs (int[] mk) {
1294        if (obj != null)
1295          obj.findinputs (mk);
1296    }
1297    }
1298
1299    /* A field assignment. A static field is represented with a null OBJ. */
1300
1301    public static class setfield extends Node
1302    {
1303    public Node val; // value to assign
1304
public String JavaDoc cname;
1305    public String JavaDoc field;
1306    public Type t;
1307    public Node obj; // object with field to set
1308
public int ver; // version after setting
1309
public boolean isstatic;
1310
1311    public boolean hasSideEffect() { return true; }
1312
1313    public setfield (String JavaDoc c, String JavaDoc f, Type _t, Node o, Node v) {
1314        isstatic = (o == null);
1315        requires.setSize(numParams());
1316        val = v;
1317        if (!isstatic) obj = o;
1318        cname = c; field = f; t = _t;
1319        count = 1;
1320        clocal = -1;
1321        ver = -1;
1322    }
1323
1324    static { jbet.cmd.property.makeProperty("obj"); }
1325    public Node get__obj() { return isstatic ? null : (Node) usesAt(0); }
1326    public void set__obj(Node n) { requires.setElementAt(n, 0); }
1327    static { jbet.cmd.property.makeProperty("val"); }
1328    public Node get__val() { return (Node) usesAt(isstatic ? 0 : 1); }
1329    public void set__val(Node n) { requires.setElementAt(n, isstatic ? 0 : 1); }
1330    
1331    public int numParams() { return isstatic ? 1 : 2; };
1332
1333    public Type paramType (int i) {
1334        if (i == 0) {
1335        if (isstatic)
1336            return t;
1337        else
1338            return new Type ('L', 0, cname);
1339        }
1340        else if (i == 2) {
1341        if (isstatic)
1342            throw new IllegalStateException JavaDoc ("setstatic has only 1 param");
1343        else
1344            return t;
1345        }
1346        else
1347        throw new IllegalStateException JavaDoc ("setfield has 1 or 2 params");
1348    }
1349
1350    protected String JavaDoc toString1 (int flags) {
1351      StringBuffer JavaDoc r = new StringBuffer JavaDoc("(");
1352      r.append (obj != null ? obj.toString (flags) : ((flags & TOSTR_SRC) != 0 ? Util.srcClassName (cname) : cname));
1353      r.append (").");
1354      r.append (field);
1355
1356      if (flags == TOSTR_DFL || flags == TOSTR_EXTRA) {
1357          if (ver >= 0) {
1358          r.append ("__");
1359          r.append (ver);
1360          }
1361          if (clocal >= 0) {
1362          r.append ('!');
1363          r.append (clocal);
1364          }
1365      }
1366      if (clocal >= 0) {
1367        r.append ('!');
1368        r.append (clocal);
1369      }
1370
1371      r.append (" = ");
1372      r.append (val.toString(flags));
1373
1374      return r.toString();
1375    }
1376
1377    public boolean equals (Object JavaDoc io) { return io == this; }
1378                        
1379    public Type type() { return Type.VOID; }
1380
1381    public boolean idempotent() { return false; }
1382
1383    public void codegen1 (Snippit out) {
1384        if (obj != null) {
1385        out.push (new Instruction().setPutfield (cname, field, t));
1386        } else {
1387        out.push (new Instruction().setPutstatic (cname, field, t));
1388        }
1389    }
1390
1391    public void findinputs (int[] mk) {
1392        val.findinputs (mk);
1393        if (obj != null)
1394          obj.findinputs (mk);
1395    }
1396
1397    }
1398
1399    /* A JVM newarray instruction */
1400
1401    public static class NewArray extends Node {
1402    
1403    public boolean hasSideEffect() { return true; }
1404
1405    public int numParams() { return 1; };
1406    public Type paramType (int i) { return Type.INT; }
1407
1408    public Node size; // size of new array
1409
public Type t;
1410    
1411    static { jbet.cmd.property.makeProperty("size"); }
1412    public Node get__size() { return (Node) usesAt(0); }
1413    public void set__size(Node n) { requires.setElementAt(n, 0); }
1414    
1415
1416    public NewArray (Node s, Type arrayType) { requires.setSize (1); size = s; t = arrayType; clocal = -1; count = 1; }
1417    public NewArray (Node s, int nat) {
1418        requires.setSize(1);
1419        size = s; t = Type.newarray (nat); clocal = -1; count = 1;
1420    }
1421    public NewArray (Node s, String JavaDoc cname) {
1422        requires.setSize(1);
1423        size = s; t = new Type ('L', 1, cname); clocal = -1; count = 1;
1424    }
1425
1426    public NewArray (Node s, Object JavaDoc aValue) {
1427        requires.setSize(1);
1428        t = new Type (aValue);
1429        t.arraydepth++;
1430        size = s;
1431        clocal = -1;
1432        count = 1;
1433    }
1434
1435    protected String JavaDoc toString1 (int flags) {
1436        if ((flags & TOSTR_SRC) != 0)
1437        return "new " + t.popbracket().declaration() + " [" + size.toString (flags) + ']';
1438        else
1439        return "new-" + t.popbracket() + "[" + size.toString (flags) + "]";
1440    }
1441
1442    public boolean equals (Object JavaDoc io) { return io == this; }
1443    public boolean idempotent() { return false; }
1444
1445    public void codegen1 (Snippit out) {
1446        //size.codegen (out, cg);
1447
out.push (new Instruction().setNewArray (t));
1448    }
1449
1450    public Type type() { return t; }
1451
1452    public void findinputs (int[] mk) {
1453        size.findinputs (mk);
1454    }
1455
1456    }
1457
1458    /* A JVM multianewarray instruction */
1459
1460    public static class MultiNewArray extends Node
1461    {
1462    public int n;
1463    public Type t;
1464
1465    public boolean hasSideEffect() { return true; }
1466    public int numParams() { return n; };
1467
1468    public Type paramType (int i) { return Type.INT; }
1469
1470    public Node arg (int i) { return (Node)requires.elementAt (i); }
1471    public void setArg (int i, Node o) { requires.setElementAt (o, i); }
1472
1473    public MultiNewArray (Node[] s, Type arrayType) {
1474        n = s.length;
1475        requires.setSize (n);
1476        t = arrayType;
1477        clocal = -1; count = 1;
1478        for (int i = 0; i < n; i++)
1479        requires.setElementAt (s[i], i);
1480    }
1481
1482    public MultiNewArray (Node[] s, String JavaDoc arrayType) {
1483        n = s.length;
1484        requires.setSize (n);
1485        t = new Type (arrayType);
1486        clocal = -1; count = 1;
1487        for (int i = 0; i < n; i++)
1488        requires.setElementAt (s[i], i);
1489    }
1490
1491    public MultiNewArray (int nin, Vector args, Type arrayType) {
1492        n = nin;
1493        requires.setSize (n);
1494        t = arrayType;
1495        clocal = -1; count = 1;
1496        for (int i = 0; i < n; i++)
1497        requires.setElementAt (args.elementAt (i), i);
1498    }
1499
1500    protected String JavaDoc toString1 (int flags) {
1501        StringBuffer JavaDoc out;
1502
1503        if ((flags & TOSTR_SRC) != 0)
1504        out = new StringBuffer JavaDoc ("new " + t.popbrackets().declaration() + " ");
1505        else
1506        out = new StringBuffer JavaDoc ("(newx-" + t.popbrackets());
1507
1508        for (int i = 0; i < n; i++) {
1509        out.append ('[');
1510        out.append (arg (i).toString (flags));
1511        out.append (']');
1512        }
1513        if (!((flags & TOSTR_SRC) != 0))
1514        out.append (')');
1515
1516        return out.toString();
1517    }
1518
1519    public boolean equals (Object JavaDoc io) { return io == this; }
1520    public boolean idempotent() { return false; }
1521
1522    public void codegen1 (Snippit out) {
1523        out.push (new Instruction().setMultiaNewArray (t.toClassRef(), n));
1524    }
1525
1526    public Type type() { return t; }
1527
1528    public void findinputs (int[] mk) {
1529        for (int i = 0; i < n; i++)
1530        arg(i).findinputs (mk);
1531    }
1532    }
1533
1534    /* An array load (?aload) instruction */
1535
1536    public static class aload extends Node
1537    {
1538    public boolean hasSideEffect() { return true; }
1539
1540    public int numParams() { return 2; };
1541
1542    public Type paramType (int i) {
1543        switch (i) {
1544        case 0: return array.type();
1545        case 1: return Type.INT;
1546        default: throw new IllegalStateException JavaDoc ("aload has 2 params");
1547        }
1548    }
1549
1550    public Node array; static{ jbet.cmd.property.makeProperty("array"); }
1551    public Node get__array() { return (Node) usesAt(0); }
1552    public void set__array(Node n) { requires.setElementAt(n, 0); }
1553    public Node index; static{ jbet.cmd.property.makeProperty("index"); }
1554    public Node get__index() { return (Node) usesAt(1); }
1555    public void set__index(Node n) { requires.setElementAt(n, 1); }
1556    
1557    public aload (Node a, Node i) {
1558        requires.setSize(2);
1559        array = a; index = i; count = 1; clocal = -1;
1560    }
1561    protected String JavaDoc toString1 (int flags) {
1562        return array.toString(flags) + '[' + index.toString (flags) + ']';
1563    }
1564    public boolean equals (Object JavaDoc io) { return io == this; }
1565    public Type type() { return array.type().popbracket(); }
1566    public boolean idempotent() { return false; }
1567
1568    public void codegen1 (Snippit out) {
1569        out.push (new Instruction().setArrayLoad (array.type()));
1570    }
1571
1572    public void findinputs (int[] mk) {
1573        array.findinputs (mk);
1574        index.findinputs (mk);
1575    }
1576
1577    }
1578
1579    /* An array store (?astore) instruction */
1580
1581    public static class astore extends Node
1582    {
1583    public boolean hasSideEffect() { return true; }
1584    public int numParams() { return 3; };
1585
1586    public Type paramType (int i) {
1587        switch (i) {
1588        case 0: return array.type();
1589        case 1: return Type.INT;
1590        case 2: return array.type().popbracket();
1591        default: throw new IllegalStateException JavaDoc ("astore has 3 params");
1592        }
1593    }
1594    
1595    public Node array; static{ jbet.cmd.property.makeProperty("array"); }
1596    public Node get__array() { return (Node) usesAt(0); }
1597    public void set__array(Node n) {
1598        requires.setElementAt(n, 0);
1599        if (n.type().arraydepth == 0) throw new IllegalStateException JavaDoc
1600        ("non-array used with astore");
1601    }
1602    public Node index; static{ jbet.cmd.property.makeProperty("index"); }
1603    public Node get__index() { return (Node) usesAt(1); }
1604    public void set__index(Node n) { requires.setElementAt(n, 1); }
1605    public Node val; static{ jbet.cmd.property.makeProperty("val"); }
1606    public Node get__val() { return (Node) usesAt(2); }
1607    public void set__val(Node n) { requires.setElementAt(n, 2); }
1608
1609    
1610    public astore (Node a, Node i, Node v) {
1611        requires.setSize(3);
1612
1613        array = a; index = i; val = v; count = 1; clocal = -1;
1614    }
1615    protected String JavaDoc toString1 (int flags) {
1616        return array.toString(flags) + "[" + index.toString (flags) + "] = " + val.toString (flags);
1617    }
1618    public boolean equals (Object JavaDoc io) { return io == this; }
1619    public Type type() { /*return array.type().popbracket();*/ return Type.VOID; }
1620    public boolean idempotent() { return false; }
1621
1622    public void codegen1 (Snippit out) {
1623        out.push (new Instruction().setArrayStore (array.type()));
1624    }
1625
1626    public void findinputs (int[] mk) {
1627        array.findinputs (mk);
1628        index.findinputs (mk);
1629        val.findinputs (mk);
1630    }
1631    }
1632
1633    /* A two-argument operation (like iadd) */
1634
1635    public static class N2 extends Node
1636    {
1637    public int numParams() { return 2; }
1638
1639    public Type paramType (int i) {
1640        if (i > 2)
1641        throw new IllegalStateException JavaDoc ("N2 has only 2 params");
1642        return op2ptype[ (op-201) * 2 + i];
1643    }
1644
1645    public Node a; static{ jbet.cmd.property.makeProperty("a"); }
1646    public Node get__a() { return (Node) usesAt(0); }
1647    public void set__a(Node n) { requires.setElementAt(n, 0); }
1648    public Node b; static{ jbet.cmd.property.makeProperty("b"); }
1649    public Node get__b() { return (Node) usesAt(1); }
1650    public void set__b(Node n) { requires.setElementAt(n, 1); }
1651 
1652
1653    public N2 (int _op, Node _a, Node _b) {
1654        requires.setSize(2);
1655        op = _op; a = _a; b = _b;
1656    }
1657
1658    protected String JavaDoc toString1 (int flags) {
1659        return "(" + a.toString (flags) + " " +
1660        op2char.substring (op-201, op-200) + " " +
1661        b.toString (flags) + ")"; }
1662
1663    public boolean equals (Object JavaDoc o) {
1664        return o == this ||
1665        (o instanceof N2 &&
1666         op == ((N2)o).op &&
1667         a.equals (((N2)o).a) &&
1668         b.equals (((N2)o).b) && sb==((Node)o).sb);
1669    }
1670    public int hashCode() {
1671        return op * 11 + 13*a.hashCode() + 17*b.hashCode();
1672    }
1673
1674    public void findinputs (int[] mk) { a.findinputs (mk); b.findinputs (mk); }
1675    public void codegen1 (Snippit out) {
1676        //a.codegen (out, cg);
1677
//b.codegen (out, cg);
1678
Instruction ins = new Instruction().setNop();
1679            ins.setOpCode (op2jvm[op-201]);
1680        out.push (ins);
1681    }
1682    public Type type() { return op2type[op-201]; }
1683
1684    }
1685
1686    /* A one-argument operation (like ineg) */
1687
1688    public static class N1 extends Node
1689    {
1690    //static { jbet.cmd.property.makeProperty("in"); }
1691
public Node in; static{ jbet.cmd.property.makeProperty("in"); }
1692    public Node get__in() { return (Node) usesAt(0); }
1693    public void set__in(Node n) { requires.setElementAt(n, 0); }
1694
1695    public int numParams() { return 1; }
1696
1697    public Type paramType (int i) {
1698        if (i != 0)
1699        throw new IllegalStateException JavaDoc ("N1 has only 1 param");
1700        return op1ptype[ op-101];
1701    }
1702
1703    public N1 (int _op, Node _a) { requires.setSize(1); op = _op; in = _a; }
1704    protected String JavaDoc toString1 (int flags) { return "(" + op1char.substring (op-101, op-100) + " " + in.toString (flags) + ")"; }
1705
1706    public boolean equals (Object JavaDoc o) {
1707        return o == this ||
1708        (o instanceof N1 &&
1709         op == ((N1)o).op &&
1710         in.equals (((N1)o).in) &&
1711         sb==((Node)o).sb);
1712    }
1713    public int hashCode() {
1714        return op * 11 + 17*in.hashCode();
1715    }
1716
1717    public void findinputs (int[] mk) { in.findinputs (mk); }
1718    public void codegen1 (Snippit out) {
1719        //in.codegen (out, cg);
1720
Instruction ins = new Instruction().setNop();
1721        ins.setOpCode (op1jvm[op-101]);
1722        out.push (ins);
1723    }
1724    public Type type() { return op1type[op-101]; }
1725
1726    }
1727
1728    /* A virtual method call. The method parameter can be a DagMethodInfo or a MethodInfo.
1729       op can be either invokevirtual or invokeinterface. */

1730
1731    public static class invokev extends Node
1732    {
1733    public boolean hasSideEffect() { return true; }
1734    public MethodSignature method;
1735    public int op;
1736
1737    public int numParams() { return 1 + method.descriptor.args.length; }
1738
1739    public Type paramType (int i) {
1740        if (i == 0)
1741        return new Type ('L', 0, method.classrep().toString ());
1742        else
1743        return method.descriptor.args[i-1];
1744    }
1745
1746    public Node This; static{ jbet.cmd.property.makeProperty("This"); }
1747    public Node get__This() { return (Node) usesAt(0); }
1748    public void set__This(Node n) { requires.setElementAt(n, 0); }
1749
1750    public Node arg(int i) { return (Node) requires.elementAt(i+1); }
1751    Node setArg(int i, Node n) {
1752        requires.setElementAt(n, i+1);
1753        return n;
1754    }
1755    public int argslen() { return numParams() - 1; };
1756
1757    public boolean isinit() {
1758        return op == Instruction.AOP_INVOKEINIT;
1759    }
1760
1761    static int curr_serial = 0;
1762    int serial;
1763
1764    protected invokev () { }
1765
1766    public invokev (MethodSignature mi, Node _this, Vector _args) {
1767        serial = curr_serial++;
1768        method = mi;
1769        requires.setSize( numParams() );
1770        count = 1;
1771        clocal = -1;
1772        op = Instruction.OP_INVOKEVIRTUAL;
1773        This = _this;
1774        for (int i = 0 ; i < _args.size(); i++)
1775        setArg(i, (Node) _args.elementAt(i));
1776    }
1777
1778    public invokev (MethodSignature mi, Node _this, Node[] _args) {
1779        method = mi;
1780        requires.setSize( numParams() );
1781        This = _this;
1782        count = 1;
1783        clocal = -1;
1784        op = Instruction.OP_INVOKEVIRTUAL;
1785        for (int i = 0 ; i < _args.length; i++)
1786        setArg(i, _args[i]);
1787    }
1788
1789    public invokev (MethodSignature mi, Node _this, Node[] _args, int _op) {
1790        method = mi;
1791        requires.setSize( numParams() );
1792        This = _this;
1793        count = 1;
1794        clocal = -1;
1795        op = _op;
1796        for (int i = 0 ; i < _args.length; i++)
1797        setArg(i, _args[i]);
1798    }
1799
1800    public invokev (MethodSignature mi, Node _this, Vector _args, int _op) {
1801        serial = curr_serial++;
1802        method = mi;
1803        requires.setSize( numParams() );
1804        This = _this;
1805        count = 1;
1806        clocal = -1;
1807        op = _op;
1808        for (int i = 0 ; i < _args.size(); i++)
1809        setArg(i, (Node) _args.elementAt(i));
1810    }
1811
1812    public invokev (MethodSignature mi, Node _this, Node _arg0, int _op) {
1813        method = mi;
1814        requires.setSize( numParams() );
1815        This = _this;
1816        count = 1;
1817        clocal = -1;
1818        op = _op;
1819        setArg (0, _arg0);
1820    }
1821
1822    protected String JavaDoc dot () { return "."; }
1823
1824    protected String JavaDoc toString1(int flags)
1825    {
1826        StringBuffer JavaDoc argstr = new StringBuffer JavaDoc();
1827        
1828        for (int i = 0; i < argslen(); i++) {
1829        argstr.append (arg(i).toString (flags));
1830        if (i != argslen() - 1)
1831            argstr.append (",");
1832        }
1833
1834        switch (op) {
1835        case Instruction.OP_INVOKESPECIAL:
1836        case Instruction.AOP_INVOKEINIT:
1837        if (method.name.equals ("<init>") && This instanceof Node.New) {
1838
1839            if ((flags & TOSTR_SRC) != 0)
1840            return "new " + Util.srcClassName (method.classrep().toString()) + " (" + argstr + ')';
1841            else
1842            return This.toString (flags) + " = new " + method.classrep().toString() + "(" + argstr + ")";
1843        }
1844        /*
1845        if ((flags & TOSTR_SRC) != 0) {
1846
1847        }
1848        else*/
{
1849            if ((flags & TOSTR_EXTRA) != 0)
1850            return "(" + This.toString (flags) + ")" + dot() + method.classrep().toString() + "::" + method.name + "(" + argstr + ")__" + serial;
1851            else
1852            return This.toString (flags) + dot() + method.classrep().toString() + "::" + method.name + "(" + argstr + ")";
1853        }
1854        
1855        case Instruction.OP_INVOKEVIRTUAL:
1856        case Instruction.OP_INVOKEINTERFACE:
1857        if ((flags & TOSTR_EXTRA) != 0)
1858            return "(" + This.toString (flags) + ")" + dot() + method.name + "(" + argstr + ")__" + serial;
1859        else
1860            return This.toString (flags) + dot() + method.name + "(" + argstr + ")";
1861        }
1862
1863        throw new IllegalStateException JavaDoc ("invokev with bad op");
1864    }
1865
1866    public boolean equals (Object JavaDoc _o) { return _o == this; }
1867
1868    /* TODO: some methods are idempotent. This should be detected. */
1869    public boolean idempotent() { return false; }
1870
1871    public void findinputs (int[] mk) {
1872        This.findinputs (mk);
1873
1874        for (int i = 0; i < argslen(); i++)
1875        arg(i).findinputs (mk);
1876    }
1877
1878    public void codegen1 (Snippit out) {
1879        out.push (new Instruction().setInvoke
1880              (method.classrep().toString(), method.name, method.descriptor,
1881               isinit () ? Instruction.OP_INVOKESPECIAL : op));
1882    }
1883
1884    public Type type() {
1885        return isinit() ? This.type().initialize() : method.descriptor.ret;
1886    }
1887
1888    public final MethodInfo method() throws ClassFileException, ElementNotFoundException {
1889        return method.resolve();
1890    }
1891    } // invokev
1892

1893
1894    public static class monitorop extends Node
1895    {
1896    public Node objref; static{ jbet.cmd.property.makeProperty("objref"); }
1897    public Node get__objref() { return (Node) usesAt(0); }
1898    public void set__objref(Node n) { requires.setElementAt(n, 0); }
1899
1900    public int numParams() { return 1; }
1901
1902    public Type paramType (int i) {
1903        return Type.OBJECT;
1904    }
1905
1906    monitorop(int _op, Node _objref) {
1907        requires.setSize(1);
1908        count = 1;
1909        clocal = -1;
1910        op = _op;
1911        objref = _objref;
1912    }
1913
1914    protected String JavaDoc toString1 (int flags)
1915    {
1916        return objref + ".monitorenter()";
1917    }
1918
1919    public boolean equals (Object JavaDoc _o) { return _o == this; }
1920
1921    public boolean idempotent() { return false; }
1922
1923    public void findinputs (int[] mk) { objref.findinputs (mk); }
1924
1925    public void codegen1 (Snippit out) {
1926        //objref.codegen(out,cg);
1927
Instruction ins = new Instruction().setNop();
1928        ins.setOpCode(op);
1929        out.push(ins);
1930    }
1931
1932    public Type type() { return Type.VOID; }
1933
1934    };
1935
1936    /* A static method call. The method paramater can be a DagMethodInfo or a MethodInfo. */
1937
1938    public static class invokes extends Node
1939    {
1940    public MethodSignature method;
1941
1942    public int numParams() { return method.descriptor.args.length; }
1943
1944    public Type paramType (int i) {
1945        return method.descriptor.args[i];
1946    }
1947    
1948    public Node arg(int i) { return (Node) requires.elementAt(i); }
1949    Node setArg(int i, Node n) {
1950        requires.setElementAt(n, i);
1951        return n;
1952    }
1953    public int argslen() { return method.descriptor.args.length; }
1954
1955    public Node[] args() {
1956        Node[] a = new Node[argslen()];
1957        for (int i = 0; i < a.length; i++)
1958        a[i] = arg(i);
1959        return a;
1960    }
1961    
1962    static int curr_serial = 0;
1963    public int serial;
1964
1965    protected invokes () { }
1966
1967    public invokes (MethodSignature mi, Vector _args) {
1968        serial = curr_serial++;
1969        method = mi;
1970        requires.setSize( argslen() );
1971        for (int i = 0 ; i < _args.size(); i++)
1972        setArg(i, (Node) _args.elementAt(i));
1973        count = 1;
1974        clocal = -1;
1975    }
1976
1977    public invokes (MethodSignature _mi, Node[] _args) {
1978        serial = curr_serial++;
1979        method = _mi;
1980        requires.setSize( argslen() );
1981        for (int i = 0 ; i < _args.length; i++)
1982        setArg(i, _args[i]);
1983        count = 1;
1984        clocal = -1;
1985    }
1986
1987    public invokes (MethodSignature _mi, Node _arg0) {
1988        serial = curr_serial++;
1989        method = _mi;
1990        requires.setSize( argslen() );
1991        setArg(0, _arg0);
1992        count = 1;
1993        clocal = -1;
1994    }
1995
1996    public invokes (MethodSignature _mi, Node _arg0, Node _arg1) {
1997        serial = curr_serial++;
1998        method = _mi;
1999        requires.setSize( argslen() );
2000        setArg(0, _arg0);
2001        setArg(1, _arg1);
2002        count = 1;
2003        clocal = -1;
2004    }
2005
2006    public invokes (MethodSignature _mi, Node _arg0, Node _arg1, Node _arg2) {
2007        serial = curr_serial++;
2008        method = _mi;
2009        requires.setSize( argslen() );
2010        setArg(0, _arg0);
2011        setArg(1, _arg1);
2012        setArg(2, _arg2);
2013        count = 1;
2014        clocal = -1;
2015    }
2016
2017    protected String JavaDoc dot () { return "."; }
2018
2019    protected String JavaDoc toString1 (int flags)
2020    {
2021        StringBuffer JavaDoc argstr = new StringBuffer JavaDoc();
2022    
2023        for (int i = 0; i < argslen(); i++) {
2024        argstr.append (arg(i).toString (flags));
2025        if (i != argslen() - 1)
2026            argstr.append (",");
2027        }
2028
2029        if ((flags & TOSTR_EXTRA) != 0)
2030        return method.classrep().toString() + dot() + method.name + "(" + argstr + ")" + "__" + serial;
2031        else
2032        return method.classrep().toString() + dot() + method.name + "(" + argstr + ")";
2033    }
2034
2035    public boolean equals (Object JavaDoc _o) { return _o == this; }
2036
2037    public boolean idempotent() { return false; }
2038
2039    public void findinputs (int[] mk) {
2040        for (int i = 0; i < argslen(); i++)
2041        arg(i).findinputs (mk);
2042    }
2043
2044    public void codegen1 (Snippit out) {
2045
2046        out.push (new Instruction().setInvokeStatic
2047        (method.classrep().toString(), method.name,
2048         method.descriptor));
2049    }
2050
2051    public Type type() { return method.descriptor.ret; }
2052
2053    public final MethodInfo method() throws ClassFileException, ElementNotFoundException {
2054        return method.resolve();
2055    }
2056    } // invokes
2057

2058    /* A combination new and invokespecial <init>, so that uninitialized objects are not
2059       ever stored to a temporary local, even with stupid code generators.
2060       The <init> function is defined to return the new object, and not take the uninitialized
2061       "this" reference.
2062    */

2063
2064    public static class invokeinit extends invokes
2065    {
2066    Type thist;
2067
2068    public invokeinit (MethodSignature mi, Node[] _args) {
2069        if (!mi.name.equals ("<init>"))
2070        throw new IllegalStateException JavaDoc ("improper use of Node.invokeinit");
2071        Type t = new Type ('L', 0, mi.classrep().toString());
2072        thist = t;
2073
2074        method = mi;
2075        requires.setSize( numParams() );
2076        count = 1;
2077        clocal = -1;
2078
2079        if (argslen() != _args.length)
2080        throw new IllegalStateException JavaDoc ("incorrect number of arguments");
2081
2082        for (int i = 0 ; i < _args.length; i++)
2083        setArg(i, _args[i]);
2084    }
2085
2086    public invokeinit (MethodSignature mi, Node _arg0) {
2087        if (!mi.name.equals ("<init>"))
2088        throw new IllegalStateException JavaDoc ("improper use of Node.invokeinit");
2089        Type t = new Type ('L', 0, mi.classrep().toString());
2090        thist = t;
2091
2092        method = mi;
2093        requires.setSize( numParams() );
2094        count = 1;
2095        clocal = -1;
2096        setArg (0, _arg0);
2097    }
2098
2099    public Type type() { return thist; }
2100
2101    public void allnodes (Collection v, boolean doRequires) {
2102        v.add (this);
2103
2104        if (doRequires)
2105        for (Iterator i = requires.iterator(); i.hasNext(); )
2106            ((Node)i.next()).allnodes (v, doRequires);
2107        else
2108        for (int i = 1; i < numParams(); i++)
2109            usesAt (i).allnodes (v, doRequires);
2110    }
2111
2112    public void codegen1 (Snippit out) {
2113        out.push (new Instruction().setNew (thist.toClassRef()));
2114        out.push (new Instruction().setDup());
2115        out.moveDown (Type.LONG, method.descriptor.args);
2116        out.push (new Instruction().setInvokeSpecial
2117              (method.classrep().toString(), method.name, method.descriptor));
2118    }
2119    }
2120
2121    /* A cast or instanceof operation */
2122
2123    public static class Cast extends Node
2124    {
2125    public Type t;
2126    public boolean checkcast; // true if this is a checkcast; false for instanceof
2127

2128    public int numParams() { return 1; }
2129
2130    public Type paramType (int i) {
2131        return val.type ();
2132    }
2133
2134    public Node val; static{ jbet.cmd.property.makeProperty("val"); }
2135    public Node get__val() { return (Node) usesAt(0); }
2136    public void set__val(Node n) { requires.setElementAt(n, 0); }
2137
2138    public Cast (String JavaDoc c, Node v, boolean cc) {
2139        requires.setSize(1);
2140        if (c.charAt (0) == '[')
2141        t = new Type (c);
2142        else
2143        t = new Type ('L', 0, c);
2144        val = v; checkcast = cc;
2145    }
2146
2147    public Cast (Type _t, Node v, boolean cc) {
2148        requires.setSize(1);
2149        t = _t;
2150        val = v; checkcast = cc;
2151    }
2152
2153    protected String JavaDoc toString1 (int flags) {
2154        String JavaDoc ts = ((flags & TOSTR_SRC) != 0) ? t.declaration() : t.toClassRef();
2155
2156        if (checkcast) {
2157        return "((" + ts + ") " + val.toString (flags) + ')';
2158        } else {
2159        return "(" + val.toString (flags) + " instanceof " + ts + ")";
2160        }
2161    }
2162
2163    public boolean equals (Object JavaDoc io) {
2164        if (io instanceof Cast) {
2165        Cast o = (Cast) io;
2166        return val.equals (o.val) && t.equals (o.t) &&
2167            checkcast == o.checkcast && sb==o.sb;
2168        }
2169        return false;
2170    }
2171    public int hashCode() {
2172        return 3*t.hashCode() + 2*val.hashCode();
2173    }
2174
2175    public void codegen1 (Snippit out) {
2176        Instruction ins = new Instruction();
2177        if (checkcast) {
2178        ins.setCheckcast (t);
2179        } else {
2180        ins.setInstanceof (t);
2181        }
2182
2183        out.push (ins);
2184    }
2185
2186    public Type type() { return checkcast ? t : Type.INT; }
2187
2188    public void findinputs (int[] mk) {
2189        val.findinputs (mk);
2190    }
2191    }
2192
2193    public static class Label extends Node
2194    {
2195    public int swval;
2196    public cint swvaln; /* nodes that need integer label addresses use this,
2197                      which gets filled in later. */

2198    public BasicBlock swvalb; /* pointer to filler block for this label */
2199    public String JavaDoc name;
2200    public Instruction ip;
2201
2202    static int lastln = 0;
2203
2204    static { jbet.cmd.property.makeProperty("swval"); }
2205
2206    public int get__swval () {
2207        if (swvalb != null)
2208        return swvalb.swval;
2209        else
2210        return -1;
2211    }
2212    public void set__swval (int i) {
2213        throw new IllegalStateException JavaDoc ("attempt to assign to Node$Label.swval");
2214    }
2215
2216    public int numParams() { return 0; }
2217
2218    public Label () {
2219        this ("L" + lastln);
2220        lastln++;
2221    }
2222
2223    public Label (String JavaDoc c) {
2224        requires.setSize (0);
2225        name = c;
2226        swvaln = new Node.cint(-1) {
2227            public boolean equals (Object JavaDoc io) { return io == this; }
2228            public String JavaDoc toString1 (int flags) {
2229            if (swval >= 0)
2230                return "#B" + swval + ':' + name;
2231            else
2232                return '#' + name;
2233            }
2234        };
2235    }
2236
2237    public cint addr() { return swvaln; }
2238
2239    protected String JavaDoc toString1 (int flags) {
2240        if ((flags & TOSTR_SRC) != 0)
2241        return name + ':';
2242        else if (swval >= 0)
2243        return "#B" + swval + " (" + name + "):";
2244        else
2245        return "#B? (" + name + "):";
2246    }
2247
2248    public boolean equals (Object JavaDoc io) {
2249        return io == this;
2250    }
2251
2252    public int hashCode() {
2253        return 37 * swval;
2254    }
2255
2256    public void codegen1 (Snippit out) {
2257    }
2258
2259    public Type type() { return Type.VOID; }
2260
2261    public void findinputs (int[] mk) {
2262    }
2263
2264    public boolean idempotent () { return false; }
2265    public boolean hasSideEffect () { return true; }
2266    }
2267
2268    public static class Goto extends Node
2269    {
2270    public int numparams;
2271    public Node dest;
2272
2273    static{ jbet.cmd.property.makeProperty("dest"); }
2274
2275    public Node get__dest() { return (Node) usesAt(0); }
2276    public void set__dest(Node n) { requires.setElementAt(n, 0); }
2277
2278    public int numParams() { return numparams; }
2279
2280    public Type paramType (int i)
2281    {
2282        if (i == 0)
2283        return Type.INT;
2284        else
2285        return ((Node)requires.elementAt (i)).type();
2286    }
2287
2288    public Goto (Node n) {
2289        numparams = 1;
2290        requires.setSize (1);
2291        dest = n;
2292    }
2293
2294    public Goto (Node n, Node cs) {
2295        numparams = 2;
2296        requires.setSize (2);
2297        dest = n;
2298        requires.setElementAt (cs, 1);
2299    }
2300
2301    public Goto (Goto in) {
2302        numparams = in.numparams;
2303        requires.setSize (numparams);
2304        for (int i = 0; i < numparams; i++)
2305        requires.setElementAt (in.usesAt (i), i);
2306    }
2307
2308    protected String JavaDoc toString1 (int flags) {
2309        if (numparams == 1)
2310        return "goto " + dest.toString (flags);
2311        else {
2312        StringBuffer JavaDoc b = new StringBuffer JavaDoc ("goto ");
2313
2314        b.append (usesAt (0).toString (flags));
2315        b.append (" (");
2316
2317        for (int i = 1; i < numparams; i++) {
2318            b.append (usesAt (i).toString (flags));
2319            if (i != numparams - 1)
2320            b.append (", ");
2321        }
2322        b.append (')');
2323        return b.toString();
2324        }
2325    }
2326
2327    public boolean equals (Object JavaDoc io) {
2328        return io == this;
2329    }
2330
2331    public int hashCode() {
2332        return 3 * dest.hashCode();
2333    }
2334
2335    public void codegenpre (Snippit out, CodeGenerator cg) {
2336        throw new IllegalStateException JavaDoc ("codegen an abstract goto");
2337    }
2338
2339    public void codegen2 (Snippit out, CodeGenerator cg) {
2340        throw new IllegalStateException JavaDoc ("codegen an abstract goto");
2341    }
2342
2343    public Type type() { return Type.VOID; }
2344
2345    public void findinputs (int[] mk) {
2346    }
2347
2348    public boolean idempotent () { return false; }
2349    public boolean hasSideEffect () { return true; }
2350    } // Goto
2351

2352    public static class invokevnoa extends Node.invokev
2353    {
2354    public invokevnoa (MethodSignature mi, Node _this, Vector _args) {
2355        super (mi, _this, _args);
2356    }
2357
2358    public invokevnoa (MethodSignature mi, Node _this, Node[] _args) {
2359        super (mi, _this, _args);
2360    }
2361
2362    public invokevnoa (MethodSignature mi, Node _this, Node[] _args, int _op) {
2363        super (mi, _this, _args, _op);
2364    }
2365
2366    public invokevnoa (MethodSignature mi, Node _this, Vector _args, int _op) {
2367        super (mi, _this, _args, _op);
2368    }
2369
2370    public invokevnoa (MethodSignature mi, Node _this, Node _arg0, int _op) {
2371        super (mi, _this, _arg0, _op);
2372    }
2373
2374    protected String JavaDoc dot () { return ".*"; }
2375
2376    public void codegen1 (Snippit out) {
2377        invokenoa.codegen (out, op, method);
2378    }
2379    }
2380
2381    public static class invokesnoa extends Node.invokes
2382    {
2383    public invokesnoa (MethodSignature mi, Vector _args) {
2384        super (mi, _args);
2385    }
2386
2387    public invokesnoa (MethodSignature _mi, Node[] _args) {
2388        super (_mi, _args);
2389    }
2390
2391    public invokesnoa (MethodSignature _mi, Node _arg0) {
2392        super (_mi, _arg0);
2393    }
2394
2395    public invokesnoa (MethodSignature _mi, Node _arg0, Node _arg1) {
2396        super (_mi, _arg0, _arg1);
2397    }
2398
2399    public invokesnoa (MethodSignature _mi, Node _arg0, Node _arg1, Node _arg2) {
2400        super (_mi, _arg0, _arg1, _arg2);
2401    }
2402
2403    protected String JavaDoc dot () { return ".*"; }
2404
2405    public void codegen1 (Snippit out) {
2406        invokenoa.codegen (out, Instruction.OP_INVOKESTATIC, method);
2407    }
2408    }
2409
2410    public static class invokenoa
2411    {
2412    public static void codegen (Snippit out, int op, MethodSignature mi)
2413    {
2414        Reflection.arguments2array (out, mi.descriptor);
2415
2416        out.push (new Instruction().setSpush (mi.classrep().toString().replace ('/','.')));
2417        out.push (new Instruction().setInvokeStatic ("java/lang/Class", "forName", new Descriptor (Type.STRING, Type.CLASS)));
2418
2419        out.push (new Instruction().setSpush (mi.name));
2420
2421        Reflection.descriptor2classes (out, mi.descriptor);
2422
2423        /* call */
2424        out.push (new Instruction().setInvokeVirtual ("java/lang/Class", "getDeclaredMethod",
2425                              new Descriptor ("(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;")));
2426        if (op == Instruction.OP_INVOKESTATIC)
2427        out.push (new Instruction().setDup_x1());
2428        else
2429        out.push (new Instruction().setDup_x2());
2430
2431        out.push (new Instruction().setIpush (1));
2432        out.push (new Instruction().setInvokeVirtual ("java/lang/reflect/AccessibleObject", "setAccessible",
2433                              new Descriptor (Type.BOOLEAN, Type.VOID)));
2434
2435        if (op == Instruction.OP_INVOKESTATIC)
2436        out.push (new Instruction().setDup());
2437
2438        Instruction call = new Instruction();
2439        call.setInvokeVirtual ("java/lang/reflect/Method", "invoke", new Descriptor ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"));
2440        out.push (call);
2441
2442        /* return value */
2443        Reflection.getReturn (out, mi.descriptor.ret);
2444    }
2445    }
2446
2447}
2448
Popular Tags