KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > query > mem > ByteCodeQVisitor


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo.query.mem;
13
14 import com.versant.core.jdo.query.*;
15 import com.versant.core.jdo.query.MemVisitor;
16 import com.versant.core.common.NotImplementedException;
17 import com.versant.core.common.OID;
18 import com.versant.core.metadata.FieldMetaData;
19 import com.versant.core.metadata.ClassMetaData;
20 import com.versant.core.metadata.MDStatics;
21 import com.versant.core.metadata.MDStaticUtils;
22
23 import java.util.*;
24 import java.math.BigInteger JavaDoc;
25 import java.math.BigDecimal JavaDoc;
26 import java.lang.Integer JavaDoc;
27
28 import com.versant.lib.bcel.generic.*;
29 import com.versant.lib.bcel.Constants;
30
31 import com.versant.core.common.BindingSupportImpl;
32 import com.versant.core.jdo.QueryStateWrapper;
33
34 /**
35  * Walks Node tree generating bytecode for the filter.
36  */

37 public class ByteCodeQVisitor implements MemVisitor {
38
39     private ClassMetaData candidateClass;
40     private ClassGen cg;
41     private ConstantPoolGen cp;
42     private InstructionList il;
43     private MethodGen mg;
44     private InstructionFactory factory;
45     private Map paramMap;
46
47     private int valueLVCount;
48
49     private final Map varToIndexMap = new HashMap();
50
51     private boolean first = true;
52
53     private static final int COMP_EQ = 1;
54     private static final int COMP_GE = 2;
55     private static final int COMP_LT = 3;
56     private static final int COMP_GT = 4;
57     private static final int COMP_LE = 5;
58     private static final int COMP_NE = 6;
59
60     private CompiledMemQuery compiledMemQuery;
61     private static final String JavaDoc NAME_Q_STATE_WRAPPER = QueryStateWrapper.class.getName();
62     private static final String JavaDoc M_NAME_GETSTATE = "getState";
63     private static final String JavaDoc NAME_COLLECTION = Collection.class.getName();
64     private static final String JavaDoc NAME_ITERATOR = Iterator.class.getName();
65
66
67     private static final String JavaDoc NAME_COMPARABLE = Comparable JavaDoc.class.getName();
68     private static final String JavaDoc NAME_OBJECT = Object JavaDoc.class.getName();
69     private static final String JavaDoc NAME_NUMBER = Number JavaDoc.class.getName();
70
71     private static final ObjectType OBJECT_TYPE_COLLECTION = new ObjectType(NAME_COLLECTION);
72     private static final ObjectType OBJECT_TYPE_ITERATOR = new ObjectType(NAME_ITERATOR);
73     private static final ObjectType OBJECT_TYPE_NUMBER = new ObjectType(NAME_NUMBER);
74     private static final Type[] ARG_TYPES_INT = new Type[] {Type.INT};
75     private static final Type[] ARG_TYPES_OBJECT = new Type[] {Type.OBJECT};
76     private static final Type[] ARG_TYPES_STRING = new Type[] {Type.STRING};
77     private static final String JavaDoc NAME_STRING = String JavaDoc.class.getName();
78     private static final ObjectType OBJECT_TYPE_STRING = new ObjectType(NAME_STRING);
79     private static final ObjectType OBJECT_TYPE_OID = new ObjectType(OID.class.getName());
80     private static final String JavaDoc NAME_STRING_BUFFER = StringBuffer JavaDoc.class.getName();
81     private static final ObjectType OBJECT_TYPE_STRING_BUFFER = new ObjectType(NAME_STRING_BUFFER);
82     private static final String JavaDoc NAME_BIG_INT = BigInteger JavaDoc.class.getName();
83
84     private static final ObjectType RET_TYPE_BIG_INT = new ObjectType(NAME_BIG_INT);
85     private static final Type[] ARG_TYPES_BIG_INT = new Type[] {RET_TYPE_BIG_INT};
86     private static final String JavaDoc NAME_BIG_DEC = BigDecimal JavaDoc.class.getName();
87     private static final ObjectType RET_TYPE_BIG_DEC = new ObjectType(NAME_BIG_DEC);
88     private static final Type[] ARG_TYPES_BIG_DEC = new Type[] {RET_TYPE_BIG_DEC};
89
90     public ByteCodeQVisitor(ClassGen classGen, InstructionFactory instructionFactory, String JavaDoc name, ClassMetaData candidateClass, CompiledMemQuery compiledMemQuery) {
91         this.compiledMemQuery = compiledMemQuery;
92         this.candidateClass = candidateClass;
93
94         cg = classGen;
95         factory = instructionFactory;
96         cp = cg.getConstantPool();
97         this.il = new InstructionList();
98         mg = new MethodGen(Constants.ACC_PUBLIC, // access flags
99
Type.BOOLEAN, // return type
100
new Type[] {new ObjectType(NAME_Q_STATE_WRAPPER), new ArrayType(Type.OBJECT, 1)},
101                                         new String JavaDoc[] {"state", "params"}, // arg names
102
"exec", name, // method, class
103
il, cp);
104     }
105
106     public void setParamMap(Map paramMap) {
107         this.paramMap = paramMap;
108     }
109
110     public void finish() {
111         il.append(InstructionConstants.IRETURN);
112         mg.removeNOPs();
113         mg.setMaxLocals();
114         mg.setMaxStack();
115         cg.addMethod(mg.getMethod());
116         il.dispose();
117     }
118
119     public Field visitNode(Node node, Object JavaDoc obj) {
120         throw new NotImplementedException();
121     }
122
123
124     /**
125      * Find the variable with name or null if none.
126      */

127     private VarNode findVar(String JavaDoc name) {
128         VarNode[] vars = compiledMemQuery.vars;
129         if (vars == null) return null;
130         for (int i = vars.length - 1; i >= 0; i--) {
131             VarNode v = vars[i];
132             if (v.getIdentifier().equals(name)) return v;
133         }
134         return null;
135     }
136
137     /**
138      * Must refactor
139      * @param node
140      * @param obj
141      * @return
142      */

143     public Field visitLiteralNode(LiteralNode node, Object JavaDoc obj) {
144         BCField f = new BCField();
145         switch(node.type){
146             case LiteralNode.TYPE_STRING:
147                 f.bcType = MDStatics.STRING;
148                 f.classType = String JavaDoc.class;
149                 f.ih = il.append(new PUSH(cp, node.value));
150                 break;
151             case LiteralNode.TYPE_BOOLEAN:
152                 f.bcType = MDStatics.BOOLEAN;
153                 f.classType = Boolean.TYPE;
154                 f.ih = il.append(new PUSH(cp, Boolean.valueOf(node.value)));
155                 break;
156             case LiteralNode.TYPE_CHAR:
157                 f.bcType = MDStatics.CHAR;
158                 f.classType = Character.TYPE;
159                 f.ih = il.append(new PUSH(cp, node.value.toCharArray()[0]));
160                 break;
161             case LiteralNode.TYPE_LONG:
162                 f.bcType = MDStatics.LONG;
163                 f.classType = Long.TYPE;
164                 f.ih = il.append(new PUSH(cp, Long.parseLong(node.value)));
165                 break;
166             case LiteralNode.TYPE_DOUBLE:
167                 f.bcType = MDStatics.DOUBLE;
168                 f.classType = Double.TYPE;
169                 f.ih = il.append(new PUSH(cp, Double.parseDouble(node.value)));
170                 break;
171             case LiteralNode.TYPE_NULL:
172             case LiteralNode.TYPE_OTHER:
173                 f.bcType = MDStatics.NULL;
174                 f.classType = Object JavaDoc.class;
175 // f.ih = il.append(InstructionConstants.ACONST_NULL);
176
// /**
177
// * This will probally be nulls
178
// */
179
// throw new NotImplementedException();
180
break;
181             default:
182                 throw BindingSupportImpl.getInstance().runtime("Unkown literal type "+node.type);
183         }
184         return f;
185     }
186
187     /**
188      * This may be an state field on a state eg person.person
189      * @param node
190      * @param obj
191      * @return
192      */

193     public Field visitFieldNavNode(FieldNavNode node, Object JavaDoc obj) {
194         return visitStateFieldNavNodeRoot(node, candidateClass);
195     }
196
197     private Field visitStateFieldNavNodeRoot(FieldNavNode node, ClassMetaData currentClass) {
198         Field result = null;
199         FieldMetaData f = null;
200
201         VarNode varNode = findVar(node.lexeme);
202         if (varNode != null) {
203             first = false;
204             Object JavaDoc o = varToIndexMap.get(varNode.getIdentifier());
205             il.append(new ALOAD(((Integer JavaDoc)o).intValue()));
206             if (node.childList instanceof FieldNavNode) {
207                 result = visitStateFieldNavNode((FieldNavNode) node.childList, varNode.getCmd(), null);
208             } else {
209                 result = visitFieldNode((FieldNode) node.childList, varNode.getCmd());
210             }
211         } else {
212             f = currentClass.getFieldMetaData(node.lexeme);
213             if(f == null){
214                 throw BindingSupportImpl.getInstance().runtime("Class "+currentClass+
215                         " does not have a field "+ node.lexeme);
216             }
217             switch(f.category){
218                 case FieldMetaData.CATEGORY_SIMPLE:
219                     break;
220                 case FieldMetaData.CATEGORY_REF:
221                     InstructionHandle ih = null;
222                     il.append(new ALOAD(1));//load the state
223
il.append(new PUSH(cp, f.stateFieldNo));
224                     il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, M_NAME_GETSTATE,
225                             new ObjectType(NAME_Q_STATE_WRAPPER), ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
226                     first = false;
227                     if (node.childList instanceof FieldNavNode) {
228                         result = visitStateFieldNavNode((FieldNavNode) node.childList, f.typeMetaData, ih);
229                     } else {
230                         result = visitFieldNode((FieldNode) node.childList, f.typeMetaData);
231                     }
232                 case FieldMetaData.CATEGORY_MAP:
233                     break;
234                 case FieldMetaData.CATEGORY_COLLECTION:
235                     break;
236                 case FieldMetaData.CATEGORY_TRANSACTIONAL:
237                     break;
238                 case FieldMetaData.CATEGORY_ARRAY:
239                     break;
240             }
241         }
242         return result;
243     }
244
245     private Field visitStateFieldNavNode(FieldNavNode node, ClassMetaData currentClass, InstructionHandle ih) {
246         Field result = null;
247         FieldMetaData f = currentClass.getFieldMetaData(node.lexeme);
248         if(f == null){
249             throw BindingSupportImpl.getInstance().runtime("Class "+currentClass+
250                     " does not have a field "+ node.lexeme);
251         }
252         switch(f.category){
253             case FieldMetaData.CATEGORY_SIMPLE:
254                 break;
255             case FieldMetaData.CATEGORY_REF:
256                 il.append(new PUSH(cp, f.stateFieldNo));
257                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, M_NAME_GETSTATE,
258                         new ObjectType(NAME_Q_STATE_WRAPPER), ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
259                 if (node.childList instanceof FieldNavNode) {
260                     result = visitStateFieldNavNode((FieldNavNode) node.childList, f.typeMetaData, ih);
261                 } else {
262                     result = visitFieldNode((FieldNode) node.childList, f.typeMetaData);
263                 }
264             case FieldMetaData.CATEGORY_MAP:
265                 break;
266             case FieldMetaData.CATEGORY_COLLECTION:
267                 break;
268             case FieldMetaData.CATEGORY_TRANSACTIONAL:
269                 break;
270             case FieldMetaData.CATEGORY_ARRAY:
271                 break;
272         }
273         return result;
274     }
275
276     /**
277      * This is used from a methodNode to deduce the name of a var node.
278      * @param mNode
279      * @return
280      */

281     private String JavaDoc getLVName(MethodNode mNode) {
282         return ((VarNode)mNode.childList.next).getIdentifier();
283     }
284
285     public Field visitMethodNode(MethodNode node, Object JavaDoc obj) {
286         Field result = null;
287         switch (node.getMethod()) {
288             case MethodNode.CONTAINS:
289                 if (node.childList.next instanceof VarNode) {
290                     doContainsMethod(node);
291                 } else {
292                     doContainMethodParam(node);
293                 }
294                 break;
295             case MethodNode.ENDS_WITH:
296             case MethodNode.STARTS_WITH:
297                 doStringWithMethod(node);
298                 break;
299             case MethodNode.IS_EMPTY:
300                 doIsEmpty(node);
301                 break;
302             case MethodNode.CONTAINS_KEY:
303                 doContainsKey(node);
304                 break;
305             case MethodNode.TO_LOWER_CASE:
306                 result = toLowerCase(node);
307                 break;
308             default:
309                 throw new NotImplementedException();
310         }
311         return result;
312     }
313
314     private BCField toLowerCase(MethodNode node) {
315         first = true;
316         BCField f = (BCField) node.childList.visit(this, null);
317         il.append(factory.createInvoke(NAME_STRING, "toLowerCase", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
318         return f;
319     }
320
321     private boolean isVarContainsMethodNode(MethodNode node) {
322         if ((node.getMethod() == MethodNode.CONTAINS)
323                 && (node.childList.next instanceof VarNode)) {
324                 return true;
325         }
326         return false;
327     }
328
329     private void doStringWithMethod(MethodNode node) {
330         String JavaDoc name = node.getName();
331         BCField fl = (BCField) node.childList.visit(this, null);
332         if (fl.bcType != MDStatics.STRING) {
333             throw BindingSupportImpl.getInstance().invalidOperation("The " + name + " may only be used on a String field");
334         }
335         node.childList.next.visit(this, null);
336         il.append(factory.createCheckCast(OBJECT_TYPE_STRING));
337         il.append(factory.createInvoke(NAME_STRING, name, Type.BOOLEAN, ARG_TYPES_STRING, Constants.INVOKEVIRTUAL));
338     }
339
340     private void doIsEmpty(MethodNode node) {
341         first = true;
342         node.childList.visit(this, null);
343         il.append(factory.createCheckCast(OBJECT_TYPE_COLLECTION));
344         il.append(factory.createInvoke(NAME_COLLECTION, "isEmpty", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
345     }
346
347     private void doContainsKey(MethodNode node) {
348         first = true;
349         node.childList.visit(this, null);
350         try {
351             il.delete(il.getEnd());
352         } catch (TargetLostException e) {
353             throw BindingSupportImpl.getInstance().internal(e.getMessage(), e);
354         }
355         node.childList.next.visit(this, null);
356         il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, "containsKey", Type.BOOLEAN, new Type[] {Type.INT, Type.OBJECT}, Constants.INVOKEVIRTUAL));
357     }
358
359     private void doContainMethodParam(MethodNode node) {
360         first = true;
361         BCField bcField = (BCField) node.childList.visit(this, null);
362         if (Map.class.isAssignableFrom(bcField.classType)) {
363             if (bcField.getFMD().isElementTypePC()) {
364                 try {
365                     il.delete(il.getEnd());
366                 } catch (TargetLostException e) {
367                     throw BindingSupportImpl.getInstance().internal(e.getMessage(), e);
368                 }
369                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, "getInternalOIDValueCollectionForMap", OBJECT_TYPE_COLLECTION,
370                     ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
371             } else {
372                 try {
373                     il.delete(il.getEnd());
374                 } catch (TargetLostException e) {
375                     throw BindingSupportImpl.getInstance().internal(e.getMessage(), e);
376                 }
377                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, "getInternalValueCollectionForMap", OBJECT_TYPE_COLLECTION,
378                     ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
379             }
380             bcField = (BCField) node.childList.next.visit(this, null);
381             if (bcField.bcType == MDStatics.NULL) {
382                 il.append(InstructionConstants.ACONST_NULL);
383             }
384             il.append(factory.createInvoke(NAME_COLLECTION, "contains", Type.BOOLEAN, ARG_TYPES_OBJECT, Constants.INVOKEINTERFACE));
385         } else {
386             if (bcField.getFMD().isElementTypePC()) {
387                 try {
388                     il.delete(il.getEnd());
389                 } catch (TargetLostException e) {
390                     throw BindingSupportImpl.getInstance().internal(e.getMessage(), e);
391                 }
392                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, "getInternalOIDCollection", OBJECT_TYPE_COLLECTION,
393                     ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
394             } else {
395                 il.append(factory.createCheckCast(OBJECT_TYPE_COLLECTION));
396             }
397             bcField = (BCField) node.childList.next.visit(this, null);
398             if (bcField.bcType == MDStatics.NULL) {
399                 il.append(InstructionConstants.ACONST_NULL);
400             }
401             il.append(factory.createInvoke(NAME_COLLECTION, "contains", Type.BOOLEAN, ARG_TYPES_OBJECT, Constants.INVOKEINTERFACE));
402         }
403     }
404
405     private void doContainsMethod(MethodNode node) {
406         GOTO gotoEnd = new GOTO(null);
407         String JavaDoc lv = getLVName(node);
408
409         //create localVar for declared var
410
il.append(InstructionConstants.ACONST_NULL);
411         LocalVariableGen var1 = mg.addLocalVariable(lv,
412                 new ObjectType(NAME_Q_STATE_WRAPPER), null, null);
413         int var1Index = var1.getIndex();
414         varToIndexMap.put(lv, new Integer JavaDoc(var1Index));
415         il.append(new ASTORE(var1Index));
416         var1.setStart(il.append(new NOP()));
417
418         first = true;
419         node.childList.visit(this, null);
420         //cast to collection
421
il.append(factory.createCheckCast(OBJECT_TYPE_COLLECTION));
422
423         //create a localvar for the collection by name col
424
LocalVariableGen colLV = mg.addLocalVariable(lv + "Col", OBJECT_TYPE_COLLECTION, null, null);
425         int colLVIndex = colLV.getIndex();
426         colLV.setStart(il.append(new ASTORE(colLVIndex)));
427
428         il.append(new ALOAD(colLVIndex));
429         il.append(factory.createInvoke(NAME_COLLECTION, "isEmpty", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
430
431         InstructionHandle end = null;
432
433         if (node.next == null) {
434             il.append(InstructionConstants.ICONST_1);
435             il.append(InstructionConstants.IXOR);
436         } else {
437             il.append(InstructionConstants.DUP);
438             IFEQ ifNotEmpty = new IFEQ(null);
439             il.append(ifNotEmpty);
440             // else jump to end
441
il.append(InstructionConstants.POP);
442             il.append(InstructionConstants.ICONST_0);
443             il.append(gotoEnd);
444
445             //create the iterator
446
InstructionHandle createIter = il.append(new ALOAD(colLVIndex));
447             il.append(factory.createInvoke(NAME_COLLECTION, "iterator", OBJECT_TYPE_ITERATOR, Type.NO_ARGS, Constants.INVOKEINTERFACE));
448             LocalVariableGen itLV = mg.addLocalVariable(lv + "Iter", OBJECT_TYPE_ITERATOR, null, null);
449             int itLVIndex = itLV.getIndex();
450             itLV.setStart(il.append(new ASTORE(itLVIndex)));
451
452             GOTO gotoHasNext = new GOTO(null);
453             il.append(gotoHasNext);
454
455             InstructionHandle loadIterForNext = il.append(new ALOAD(itLVIndex));
456             il.append(factory.createInvoke(NAME_ITERATOR, "next",
457                     Type.OBJECT, Type.NO_ARGS, Constants.INVOKEINTERFACE));
458             il.append(factory.createCheckCast(new ObjectType(NAME_Q_STATE_WRAPPER)));
459             il.append(new ASTORE(var1Index));
460
461             //visit the expr
462
//This must leave a 1 or 0 on the stack
463
il.append(InstructionConstants.POP);
464             node.next.visit(this, null);
465             il.append(InstructionConstants.DUP);
466             IFEQ ifNonTrue = new IFEQ(null);
467             il.append(ifNonTrue);
468             GOTO gotoEnd2 = new GOTO(null);
469             il.append(gotoEnd2);
470
471             //createthe hasNext of the iter
472
InstructionHandle loadIterForHasNext = il.append(new ALOAD(itLVIndex));
473             il.append(factory.createInvoke(NAME_ITERATOR, "hasNext",
474                     Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
475             IFNE ifMore = new IFNE(loadIterForNext);
476             il.append(ifMore);
477
478             gotoHasNext.setTarget(loadIterForHasNext);
479             ifNonTrue.setTarget(loadIterForHasNext);
480             ifNotEmpty.setTarget(createIter);
481
482             end = il.append(new NOP());
483             gotoEnd2.setTarget(end);
484             gotoEnd.setTarget(end);
485         }
486
487     }
488
489     public Field visitPrimaryExprNode(PrimaryExprNode node, Object JavaDoc obj) {
490         return null;
491     }
492
493     public Field visitFieldNode(FieldNode node, ClassMetaData cmd) {
494         if (cmd == null) {
495             return visitFieldNodeImp(candidateClass.getFieldMetaData(node.lexeme), node);
496         } else {
497             return visitFieldNodeImp(cmd.getFieldMetaData(node.lexeme), node);
498         }
499     }
500
501     private Field visitFieldNodeImp(FieldMetaData fmd, FieldNode node) {
502         BCField field;
503         if (fmd == null) {
504             throw BindingSupportImpl.getInstance().runtime("Class " + candidateClass.qname + " does not have a field: " + node.lexeme);
505         }
506         field = new BCStateField(fmd);
507         if (first) {
508             field.ih = il.append(new ALOAD(1));//load state on stack
509
first = false;
510             il.append(new PUSH(cp, fmd.stateFieldNo));
511         } else {
512             field.ih = il.append(new PUSH(cp, fmd.stateFieldNo));
513         }
514         if (fmd.typeMetaData == null) {
515             if (!fmd.isElementTypePC()) {
516                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, fmd.stateGetMethodName, getBCellStateFieldType(fmd),
517                         ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
518             } else {
519                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, "getInternalStateCollection", OBJECT_TYPE_COLLECTION,
520                         ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
521             }
522         } else {
523             il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, "getOID", OBJECT_TYPE_OID,
524                     ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
525         }
526         return field;
527     }
528
529     public Field visitFieldNode(FieldNode node, Object JavaDoc obj) {
530         return visitFieldNodeImp(candidateClass.getFieldMetaData(node.lexeme), node);
531     }
532
533     private static final Type getBCellStateFieldType(FieldMetaData fmd) {
534         switch (fmd.category) {
535             case MDStatics.CATEGORY_SIMPLE:
536                 return getTypeFromTypeCode(fmd.typeCode);
537             default:
538                 return Type.OBJECT;
539         }
540     }
541
542     private static Type getTypeFromTypeCode(int typeCode) {
543         switch (typeCode) {
544             case MDStatics.INT:
545                 return Type.INT;
546             case MDStatics.LONG:
547                 return Type.LONG;
548             case MDStatics.SHORT:
549                 return Type.SHORT;
550             case MDStatics.STRING:
551                 return Type.STRING;
552             case MDStatics.BOOLEAN:
553                 return Type.BOOLEAN;
554             case MDStatics.BYTE:
555                 return Type.BYTE;
556             case MDStatics.CHAR:
557                 return Type.CHAR;
558             case MDStatics.DOUBLE:
559                 return Type.DOUBLE;
560             case MDStatics.FLOAT:
561                 return Type.FLOAT;
562             default:
563                 return Type.OBJECT;
564         }
565     }
566
567     private Field doCompare(BinaryNode node, int type) {
568         Object JavaDoc obj = null;
569         first = true;
570         BCField fl = (BCField) node.getLeft().visit(this, obj);
571         first = true;
572         BCField fr = (BCField) node.getRight().visit(this, obj);
573         InstructionHandle nopHandle = il.append(InstructionConstants.NOP);
574         int widestType = getWidestType(fl.bcType, fr.bcType);
575
576         if (fl.isPrimitive() && fr.isPrimitive()) {
577             promotePrimToPrim(widestType, fl, fr.ih);
578             promotePrimToPrim(widestType, fr, nopHandle);
579             switch (widestType) {
580                 case MDStatics.BYTE:
581                 case MDStatics.SHORT:
582                 case MDStatics.CHAR:
583                 case MDStatics.INT:
584                     writeIIEq(type);
585                     break;
586                 case MDStatics.LONG:
587                     writeLLEq(type);
588                     break;
589                 case MDStatics.FLOAT:
590                     writeFFEq(type);
591                     break;
592                 case MDStatics.DOUBLE:
593                     writeDDEq(type);
594                     break;
595                 case MDStatics.BOOLEAN:
596                     writeIIEq(type);
597                     break;
598                 default:
599                     throw BindingSupportImpl.getInstance().internal("Comparing field type'" + MDStaticUtils.toSimpleName(fl.bcType) + "' to"
600                             + " field type '" + MDStaticUtils.toSimpleName(fl.bcType) + "' is not implemented correctly.");
601             }
602         } else if (!fl.isPrimitive() && !fr.isPrimitive()) {
603             promoteToObjects(widestType, fl, fr.ih);
604             promoteToObjects(widestType, fr, nopHandle);
605             if (fl.bcType == MDStatics.NULL || fr.bcType == MDStatics.NULL) {
606                 if (type == COMP_EQ) {
607                     IFNONNULL ifnull = new IFNONNULL(null);
608                     il.append(ifnull);
609                     il.append(InstructionConstants.ICONST_1);
610                     GOTO gotoEnd = new GOTO(null);
611                     il.append(gotoEnd);
612                     InstructionHandle falseHandle = il.append(InstructionConstants.ICONST_0);
613                     InstructionHandle endHandle = il.append(InstructionConstants.NOP);
614                     ifnull.setTarget(falseHandle);
615                     gotoEnd.setTarget(endHandle);
616                 } else if (type == COMP_NE) {
617                     IFNULL ifnull = new IFNULL(null);
618                     il.append(ifnull);
619                     il.append(InstructionConstants.ICONST_1);
620                     GOTO gotoEnd = new GOTO(null);
621                     il.append(gotoEnd);
622                     InstructionHandle falseHandle = il.append(InstructionConstants.ICONST_0);
623                     InstructionHandle endHandle = il.append(InstructionConstants.NOP);
624                     ifnull.setTarget(falseHandle);
625                     gotoEnd.setTarget(endHandle);
626                 } else {
627                     throw BindingSupportImpl.getInstance().invalidOperation("Only '==' and '!=' operators is implemented for comparing to a null value");
628                 }
629             } else if (Comparable JavaDoc.class.isAssignableFrom(fl.classType)) {
630                 writeComparable(type);
631             } else {
632                il.append(factory.createInvoke(NAME_OBJECT, "equals", Type.BOOLEAN,
633                        ARG_TYPES_OBJECT, Constants.INVOKEVIRTUAL));
634             }
635         } else {
636             if (widestType == MDStatics.BIGDECIMAL || widestType == MDStatics.BIGINTEGER) {
637                 if (fl.isPrimitive()) {
638                     promotePrimToBig(widestType, fl, fr.ih);
639                 } else {
640                     promotePrimToBig(widestType, fr, nopHandle);
641                 }
642                 writeComparable(type);
643             } else {
644                 promoteAllToPrim(widestType, fl, fr.ih);
645                 promoteAllToPrim(widestType, fr, nopHandle);
646                 switch (widestType) {
647                     case MDStatics.BOOLEAN:
648                     case MDStatics.BOOLEANW:
649                     case MDStatics.BYTE:
650                     case MDStatics.BYTEW:
651                     case MDStatics.SHORT:
652                     case MDStatics.SHORTW:
653                     case MDStatics.CHAR:
654                     case MDStatics.CHARW:
655                     case MDStatics.INT:
656                     case MDStatics.INTW:
657                         writeIIEq(type);
658                         break;
659                     case MDStatics.LONG:
660                     case MDStatics.LONGW:
661                         writeLLEq(type);
662                         break;
663                     case MDStatics.FLOAT:
664                     case MDStatics.FLOATW:
665                         writeFFEq(type);
666                         break;
667                     case MDStatics.DOUBLE:
668                     case MDStatics.DOUBLEW:
669                         writeDDEq(type);
670                         break;
671                     default:
672                         throw BindingSupportImpl.getInstance().internal("Comparing field type'" + MDStaticUtils.toSimpleName(fl.bcType) + "' to"
673                             + " field type '" + MDStaticUtils.toSimpleName(fl.bcType) + "' is not implemented correctly.");
674                 }
675             }
676         }
677         return null;
678     }
679
680
681
682     private void writeComparable(int type) {
683         il.append(factory.createInvoke(NAME_COMPARABLE, "compareTo", Type.INT,
684                 ARG_TYPES_OBJECT, Constants.INVOKEINTERFACE));
685         BranchInstruction bInstr = null;
686         switch (type) {
687             case COMP_EQ:
688                 bInstr = new IFNE(null);
689                 break;
690             case COMP_GE:
691                 bInstr = new IFLT(null);
692                 break;
693             case COMP_LT:
694                 bInstr = new IFGE(null);
695                 break;
696             case COMP_GT:
697                 bInstr = new IFLE(null);
698                 break;
699             case COMP_LE:
700                 bInstr = new IFGT(null);
701                 break;
702             case COMP_NE:
703                 bInstr = new IFEQ(null);
704                 break;
705             default:
706                 throw BindingSupportImpl.getInstance().internal("No operator of type '" + type + "'");
707         }
708         il.append(bInstr);
709         il.append(InstructionConstants.ICONST_1);
710         GOTO gotoEnd = new GOTO(null);
711         il.append(gotoEnd);
712         //goto end
713
InstructionHandle loadFalse = il.append(InstructionConstants.ICONST_0);
714         InstructionHandle endHandle = il.append(InstructionConstants.NOP);
715
716         bInstr.setTarget(loadFalse);
717         gotoEnd.setTarget(endHandle);
718     }
719
720     public Field visitEqualNode(EqualNode node, Object JavaDoc obj) {
721         return doCompare(node, COMP_EQ);
722     }
723
724     public Field visitNotEqualNode(NotEqualNode node, Object JavaDoc obj) {
725         return doCompare(node, COMP_NE);
726     }
727
728     public Field visitLikeNode(LikeNode node, Object JavaDoc obj) {
729         return null;
730     }
731
732     private void writeIIEq(int compType) {
733         BranchInstruction bInstr = null;
734         switch (compType) {
735             case COMP_EQ:
736                 bInstr = new IF_ICMPNE(null);
737                 break;
738             case COMP_GE:
739                 bInstr = new IF_ICMPLT(null);
740                 break;
741             case COMP_LT:
742                 bInstr = new IF_ICMPGE(null);
743                 break;
744             case COMP_GT:
745                 bInstr = new IF_ICMPLE(null);
746                 break;
747             case COMP_LE:
748                 bInstr = new IF_ICMPGT(null);
749                 break;
750             case COMP_NE:
751                 bInstr = new IF_ICMPEQ(null);
752                 break;
753             default:
754                 throw BindingSupportImpl.getInstance().internal("No operator of type '" + compType + "'");
755         }
756         il.append(bInstr);
757         il.append(InstructionConstants.ICONST_1);
758         GOTO gotoEnd = new GOTO(null);
759         il.append(gotoEnd);
760         //goto end
761
InstructionHandle loadFalse = il.append(InstructionConstants.ICONST_0);
762         InstructionHandle endHandle = il.append(InstructionConstants.NOP);
763
764         bInstr.setTarget(loadFalse);
765         gotoEnd.setTarget(endHandle);
766     }
767
768     private void writeDDEq(int compType) {
769         BranchInstruction bInstr = null;
770         il.append(new DCMPL());
771         switch (compType) {
772             case COMP_EQ:
773                 bInstr = new IFNE(null);
774                 break;
775             case COMP_GE:
776                 bInstr = new IFLT(null);
777                 break;
778             case COMP_LT:
779                 bInstr = new IFGE(null);
780                 break;
781             case COMP_GT:
782                 bInstr = new IFLE(null);
783                 break;
784             case COMP_LE:
785                 bInstr = new IFGT(null);
786                 break;
787             case COMP_NE:
788                 bInstr = new IFEQ(null);
789                 break;
790             default:
791                 throw BindingSupportImpl.getInstance().internal("No operator of type '" + compType + "'");
792         }
793         il.append(bInstr);
794         il.append(InstructionConstants.ICONST_1);
795         GOTO gotoEnd = new GOTO(null);
796         il.append(gotoEnd);
797         //goto end
798
InstructionHandle loadFalse = il.append(InstructionConstants.ICONST_0);
799         InstructionHandle endHandle = il.append(InstructionConstants.NOP);
800
801         bInstr.setTarget(loadFalse);
802         gotoEnd.setTarget(endHandle);
803     }
804
805     private void writeFFEq(int compType) {
806         BranchInstruction bInstr = null;
807         il.append(new FCMPL());
808         switch (compType) {
809             case COMP_EQ:
810                 bInstr = new IFNE(null);
811                 break;
812             case COMP_GE:
813                 bInstr = new IFLT(null);
814                 break;
815             case COMP_LT:
816                 bInstr = new IFGE(null);
817                 break;
818             case COMP_GT:
819                 bInstr = new IFLE(null);
820                 break;
821             case COMP_LE:
822                 bInstr = new IFGT(null);
823                 break;
824             case COMP_NE:
825                 bInstr = new IFEQ(null);
826                 break;
827             default:
828                 throw BindingSupportImpl.getInstance().internal("No operator of type '" + compType + "'");
829         }
830         il.append(bInstr);
831         il.append(InstructionConstants.ICONST_1);
832         GOTO gotoEnd = new GOTO(null);
833         il.append(gotoEnd);
834         //goto end
835
InstructionHandle loadFalse = il.append(InstructionConstants.ICONST_0);
836         InstructionHandle endHandle = il.append(InstructionConstants.NOP);
837
838         bInstr.setTarget(loadFalse);
839         gotoEnd.setTarget(endHandle);
840     }
841
842     private void writeLLEq(int type) {
843         BranchInstruction bInstr = null;
844         switch (type) {
845             case COMP_EQ:
846                 il.append(new LCMP());
847                 bInstr = new IFNE(null);
848                 break;
849             case COMP_GE:
850                 il.append(new LCMP());
851                 bInstr = new IFLT(null);
852                 break;
853             case COMP_GT:
854                 il.append(new LCMP());
855                 bInstr = new IFLE(null);
856                 break;
857             case COMP_LE:
858                 il.append(new LCMP());
859                 bInstr = new IFGT(null);
860                 break;
861             case COMP_LT:
862                 il.append(new LCMP());
863                 bInstr = new IFGE(null);
864                 break;
865             case COMP_NE:
866                 il.append(new LCMP());
867                 bInstr = new IFEQ(null);
868                 break;
869             default:
870                 throw BindingSupportImpl.getInstance().internal("No operator of type '" + type + "'");
871         }
872         il.append(bInstr);
873         il.append(InstructionConstants.ICONST_1);
874         GOTO gotoEnd = new GOTO(null);
875         il.append(gotoEnd);
876         //goto end
877
InstructionHandle loadFalse = il.append(InstructionConstants.ICONST_0);
878         InstructionHandle endHandle = il.append(InstructionConstants.NOP);
879
880         bInstr.setTarget(loadFalse);
881         gotoEnd.setTarget(endHandle);
882     }
883
884     public Field visitAndNode(AndNode node, Object JavaDoc obj) {
885         List ifFalseList = new ArrayList();
886         first = true;
887         node.childList.visit(this, obj);
888
889         //leave if the child is an methodNode
890
if (node.childList instanceof MethodNode) {
891             MethodNode mNode = (MethodNode)node.childList;
892             if (isVarContainsMethodNode(mNode)) return null;
893         }
894
895         il.append(InstructionConstants.DUP);
896         IFEQ ifFalse = new IFEQ(null);
897         il.append(ifFalse);
898
899         IFEQ ifFalseVar = null;
900         Node n = node.childList.next;
901         while (n != null) {
902             first = true;
903             //pop the uncesc value
904
il.append(InstructionConstants.POP);
905             n.visit(this, obj);
906             il.append(InstructionConstants.DUP);
907             ifFalseVar = new IFEQ(null);
908             ifFalseList.add(ifFalseVar);
909             il.append(ifFalseVar);
910             n = n.next;
911         }
912
913         InstructionHandle endHandle = il.append(new NOP());
914         ifFalse.setTarget(endHandle);
915
916         for (int i = 0; i < ifFalseList.size(); i++) {
917             ((IFEQ) ifFalseList.get(i)).setTarget(endHandle);
918         }
919         return null;
920     }
921
922     public Field visitOrNode(OrNode node, Object JavaDoc obj) {
923         List ifFalseList = new ArrayList();
924         node.childList.visit(this, obj);
925
926         il.append(InstructionConstants.DUP);
927         IFNE ifTrue = new IFNE(null);
928         il.append(ifTrue);
929 //
930
IFNE ifTrueVar = null;
931         Node n = node.childList.next;
932
933         while (n != null) {
934             first = true;
935             //pop the uncesc value
936
il.append(InstructionConstants.POP);
937             n.visit(this, obj);
938             il.append(InstructionConstants.DUP);
939             ifTrueVar = new IFNE(null);
940             ifFalseList.add(ifTrueVar);
941             il.append(ifTrueVar);
942             n = n.next;
943         }
944
945         InstructionHandle endHandle = il.append(new NOP());
946         ifTrue.setTarget(endHandle);
947
948         for (int i = 0; i < ifFalseList.size(); i++) {
949             ((BranchInstruction) ifFalseList.get(i)).setTarget(endHandle);
950         }
951         return null;
952     }
953
954     public Field visitMultiplyNode(MultiplyNode node, Object JavaDoc obj) {
955         BCField result = null;
956         BCField f = (BCField)node.childList.visit(this,obj);
957         BCField fnNext = null;
958         int widestType = 0;
959
960         List fieldsToPromote = new ArrayList();
961         fieldsToPromote.add(f);
962         for(Node n = node.childList.next ; n != null; n = n.next) {
963             first = true;
964             fnNext = (BCField)n.visit(this, null);
965             fieldsToPromote.add(fnNext);
966             widestType = getWidestType(f.bcType, fnNext.bcType);
967             f = fnNext;
968         }
969         InstructionHandle nopHandle = il.append(InstructionConstants.NOP);
970         int n = fieldsToPromote.size();
971         int lastIndex = n - 1;
972         for (int i = 0; i < n; i++) {
973             BCField bcField1 = (BCField) fieldsToPromote.get(i);
974             BCField bcField2 = (i == lastIndex) ? null : (BCField) fieldsToPromote.get(i + 1);
975             if (bcField2 == null) {
976                 promoteTo(widestType, bcField1, nopHandle);
977             } else {
978                 promoteTo(widestType, bcField1, bcField2.ih);
979             }
980         }
981
982         if (fieldsToPromote.size() == 2) {
983             insertMultiply(widestType, nopHandle, node.ops[0]);
984         } else {
985             for (int i = 1; i < n; i++) {
986                 if (i == lastIndex) {
987                     insertMultiply(widestType, nopHandle, node.ops[i -1]);
988                 } else {
989                     BCField bcField2 = (BCField) fieldsToPromote.get(i + 1);
990                     insertMultiply(widestType, bcField2.ih, node.ops[i -1]);
991                 }
992             }
993         }
994         result = new BCField();
995         result.bcType = widestType;
996         result.classType = MDStaticUtils.toSimpleClass(MDStaticUtils.toSimpleName(widestType));
997         return result;
998     }
999
1000    public Field visitAddNode(AddNode node, Object JavaDoc obj) {
1001        BCField result = null;
1002        first = true;
1003        BCField f = (BCField)node.childList.visit(this,obj);
1004        BCField fnNext = null;
1005        int widestType = 0;
1006        if (f.bcType == MDStatics.STRING) {
1007            il.append(factory.createNew(NAME_STRING_BUFFER));
1008            il.append(InstructionConstants.DUP);
1009            il.append(factory.createInvoke(NAME_STRING_BUFFER, "<init>",
1010                                 Type.VOID, Type.NO_ARGS,
1011                                 Constants.INVOKESPECIAL));
1012            LocalVariableGen lg = mg.addLocalVariable("buffer",
1013                    OBJECT_TYPE_STRING_BUFFER, null, null);
1014            int bufferIndex = lg.getIndex();
1015            lg.setStart(il.append(new ASTORE(bufferIndex)));
1016            il.append(new ALOAD(bufferIndex));
1017            il.append(InstructionConstants.SWAP);
1018            il.append(factory.createInvoke(NAME_STRING_BUFFER, "append", OBJECT_TYPE_STRING_BUFFER,
1019                    ARG_TYPES_STRING, Constants.INVOKEVIRTUAL));
1020
1021            for(Node n = node.childList.next ; n != null; n = n.next) {
1022                first = true;
1023                n.visit(this, null);
1024                il.append(factory.createInvoke(NAME_STRING_BUFFER, "append", OBJECT_TYPE_STRING_BUFFER,
1025                    ARG_TYPES_STRING, Constants.INVOKEVIRTUAL));
1026            }
1027            il.append(factory.createInvoke(NAME_STRING_BUFFER, "toString", Type.STRING,
1028                        Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1029            result = new BCField();
1030            result.setBcType(MDStatics.STRING);
1031            result.classType = String JavaDoc.class;
1032        } else {
1033            List fieldsToPromote = new ArrayList();
1034            fieldsToPromote.add(f);
1035            for(Node n = node.childList.next ; n != null; n = n.next) {
1036                first = true;
1037                fnNext = (BCField)n.visit(this, null);
1038                fieldsToPromote.add(fnNext);
1039                widestType = getWidestType(f.bcType, fnNext.bcType);
1040                f = fnNext;
1041            }
1042            InstructionHandle nopHandle = il.append(InstructionConstants.NOP);
1043            int n = fieldsToPromote.size();
1044            int lastIndex = n - 1;
1045            for (int i = 0; i < n; i++) {
1046                BCField bcField1 = (BCField) fieldsToPromote.get(i);
1047                BCField bcField2 = (i == lastIndex) ? null : (BCField) fieldsToPromote.get(i + 1);
1048                if (bcField2 == null) {
1049                    promoteTo(widestType, bcField1, nopHandle);
1050                } else {
1051                    promoteTo(widestType, bcField1, bcField2.ih);
1052                }
1053            }
1054
1055            if (fieldsToPromote.size() == 2) {
1056                insertAddOp(widestType, nopHandle, node.ops[0]);
1057            } else {
1058                for (int i = 1; i < n; i++) {
1059                    if (i == lastIndex) {
1060                        insertAddOp(widestType, nopHandle, node.ops[i -1]);
1061                    } else {
1062                        BCField bcField2 = (BCField) fieldsToPromote.get(i + 1);
1063                        insertAddOp(widestType, bcField2.ih, node.ops[i -1]);
1064                    }
1065                }
1066            }
1067            result = new BCField();
1068            result.bcType = widestType;
1069            result.classType = MDStaticUtils.toSimpleClass(MDStaticUtils.toSimpleName(widestType));
1070        }
1071        return result;
1072    }
1073
1074    private void insertMultiply(int widestType, InstructionHandle insertHandle, int type) {
1075        if (type == MultiplyNode.OP_TIMES) {
1076            switch (widestType) {
1077                case MDStatics.BYTE:
1078                case MDStatics.SHORT:
1079                case MDStatics.CHAR:
1080                case MDStatics.INT:
1081                    il.insert(insertHandle, InstructionConstants.IMUL);
1082                    break;
1083                case MDStatics.LONG:
1084                    il.insert(insertHandle, InstructionConstants.LMUL);
1085                    break;
1086                case MDStatics.FLOAT:
1087                    il.insert(insertHandle, InstructionConstants.FMUL);
1088                    break;
1089                case MDStatics.DOUBLE:
1090                    il.insert(insertHandle, InstructionConstants.DMUL);
1091                    break;
1092                case MDStatics.BIGINTEGER:
1093                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_INT, "multiply",
1094                            RET_TYPE_BIG_INT, ARG_TYPES_BIG_INT, Constants.INVOKEVIRTUAL));
1095                    break;
1096                case MDStatics.BIGDECIMAL:
1097                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_DEC, "multiply",
1098                            RET_TYPE_BIG_DEC, ARG_TYPES_BIG_DEC, Constants.INVOKEVIRTUAL));
1099                    break;
1100                default:
1101                    throw BindingSupportImpl.getInstance().internal("The '*' operator is not implemented correctly for type '"
1102                            + MDStaticUtils.toSimpleName(widestType) + "'");
1103            }
1104        } else {
1105            switch (widestType) {
1106                case MDStatics.BYTE:
1107                case MDStatics.SHORT:
1108                case MDStatics.CHAR:
1109                case MDStatics.INT:
1110                    il.insert(insertHandle, InstructionConstants.IDIV);
1111                    break;
1112                case MDStatics.LONG:
1113                    il.insert(insertHandle, InstructionConstants.LDIV);
1114                    break;
1115                case MDStatics.FLOAT:
1116                    il.insert(insertHandle, InstructionConstants.FDIV);
1117                    break;
1118                case MDStatics.DOUBLE:
1119                    il.insert(insertHandle, InstructionConstants.DDIV);
1120                    break;
1121                case MDStatics.BIGINTEGER:
1122                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_INT, "divide",
1123                            RET_TYPE_BIG_INT, ARG_TYPES_BIG_INT, Constants.INVOKEVIRTUAL));
1124                    break;
1125                case MDStatics.BIGDECIMAL:
1126                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_DEC, "divide",
1127                            RET_TYPE_BIG_DEC, ARG_TYPES_BIG_DEC, Constants.INVOKEVIRTUAL));
1128                    break;
1129                default:
1130                    throw BindingSupportImpl.getInstance().internal("The '/' operator is not implemented correctly for type '"
1131                            + MDStaticUtils.toSimpleName(widestType) + "'");
1132            }
1133        }
1134    }
1135
1136    private void insertAddOp(int widestType, InstructionHandle insertHandle, int type) {
1137        if (type == AddNode.OP_PLUS) {
1138            switch (widestType) {
1139                case MDStatics.BYTE:
1140                case MDStatics.SHORT:
1141                case MDStatics.CHAR:
1142                case MDStatics.INT:
1143                    il.insert(insertHandle, InstructionConstants.IADD);
1144                    break;
1145                case MDStatics.LONG:
1146                    il.insert(insertHandle, InstructionConstants.LADD);
1147                    break;
1148                case MDStatics.FLOAT:
1149                    il.insert(insertHandle, InstructionConstants.FADD);
1150                    break;
1151                case MDStatics.DOUBLE:
1152                    il.insert(insertHandle, InstructionConstants.DADD);
1153                    break;
1154                case MDStatics.BIGINTEGER:
1155                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_INT, "add",
1156                            RET_TYPE_BIG_INT, ARG_TYPES_BIG_INT, Constants.INVOKEVIRTUAL));
1157                    break;
1158                case MDStatics.BIGDECIMAL:
1159                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_DEC, "add",
1160                            RET_TYPE_BIG_DEC, ARG_TYPES_BIG_DEC, Constants.INVOKEVIRTUAL));
1161                    break;
1162                default:
1163                    throw BindingSupportImpl.getInstance().internal("The '+' operator is not implemented correctly for type '"
1164                            + MDStaticUtils.toSimpleName(widestType) + "'");
1165            }
1166        } else {
1167            switch (widestType) {
1168                case MDStatics.BYTE:
1169                case MDStatics.SHORT:
1170                case MDStatics.CHAR:
1171                case MDStatics.INT:
1172                    il.insert(insertHandle, InstructionConstants.ISUB);
1173                    break;
1174                case MDStatics.LONG:
1175                    il.insert(insertHandle, InstructionConstants.LSUB);
1176                    break;
1177                case MDStatics.FLOAT:
1178                    il.insert(insertHandle, InstructionConstants.FSUB);
1179                    break;
1180                case MDStatics.DOUBLE:
1181                    il.insert(insertHandle, InstructionConstants.DSUB);
1182                    break;
1183                case MDStatics.BIGINTEGER:
1184                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_INT, "subtract",
1185                            RET_TYPE_BIG_INT, ARG_TYPES_BIG_INT, Constants.INVOKEVIRTUAL));
1186                    break;
1187                case MDStatics.BIGDECIMAL:
1188                    il.insert(insertHandle, factory.createInvoke(NAME_BIG_DEC, "subtract",
1189                            RET_TYPE_BIG_DEC, ARG_TYPES_BIG_DEC, Constants.INVOKEVIRTUAL));
1190                    break;
1191                default:
1192                    throw BindingSupportImpl.getInstance().internal("The '-' operator is not implemented correctly for type '"
1193                            + MDStaticUtils.toSimpleName(widestType) + "'");
1194            }
1195        }
1196    }
1197
1198    private void promoteTo(int typePromoteTo, BCField otherType, InstructionHandle insertHandle) {
1199        if (otherType.bcType == typePromoteTo) {
1200            if (otherType.bcType == MDStatics.BIGINTEGER) {
1201                //add a cast
1202
il.insert(insertHandle, factory.createCheckCast(RET_TYPE_BIG_INT));
1203            } else if (otherType.bcType == MDStatics.BIGDECIMAL) {
1204                //add a cast
1205
il.insert(insertHandle, factory.createCheckCast(RET_TYPE_BIG_DEC));
1206            }
1207            return;
1208        }
1209        switch (typePromoteTo) {
1210            case MDStatics.BYTE:
1211            case MDStatics.SHORT:
1212            case MDStatics.CHAR:
1213            case MDStatics.INT:
1214                if (!otherType.isPrimitive()) {
1215                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1216                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "intValue",
1217                            Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1218                }
1219                break;
1220            case MDStatics.LONG:
1221                if (!otherType.isPrimitive()) {
1222                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1223                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "longValue",
1224                            Type.LONG, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1225                } else {
1226                    il.insert(insertHandle, InstructionConstants.I2L);
1227                }
1228                break;
1229            case MDStatics.FLOAT:
1230                if (!otherType.isPrimitive()) {
1231                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1232                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "floatValue",
1233                            Type.FLOAT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1234                } else {
1235                    if (otherType.bcType == MDStatics.LONG) {
1236                        il.insert(insertHandle, InstructionConstants.L2F);
1237                    } else {
1238                        il.insert(insertHandle, InstructionConstants.I2F);
1239                    }
1240                }
1241                break;
1242            case MDStatics.DOUBLE:
1243                if (!otherType.isPrimitive()) {
1244                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1245                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "doubleValue",
1246                            Type.DOUBLE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1247                } else {
1248                    switch (otherType.bcType) {
1249                        case MDStatics.BYTE:
1250                        case MDStatics.SHORT:
1251                        case MDStatics.CHAR:
1252                        case MDStatics.INT:
1253                            il.insert(insertHandle, InstructionConstants.I2D);
1254                            break;
1255                        case MDStatics.LONG:
1256                            il.insert(insertHandle, InstructionConstants.L2D);
1257                            break;
1258                        case MDStatics.FLOAT:
1259                            il.insert(insertHandle, InstructionConstants.F2D);
1260                            break;
1261                    }
1262                }
1263                break;
1264            case MDStatics.BIGINTEGER:
1265                insertBigTypeFromPrim(insertHandle, otherType, NAME_BIG_INT);
1266                break;
1267            case MDStatics.BIGDECIMAL:
1268                insertBigTypeFromPrim(insertHandle, otherType, NAME_BIG_DEC);
1269                break;
1270            default:
1271                throw BindingSupportImpl.getInstance().internal("Promoting to type '" + MDStaticUtils.toSimpleName(typePromoteTo) + "' is not supported");
1272        }
1273
1274    }
1275
1276    private void insertBigTypeFromObject(InstructionHandle insertHandle, String JavaDoc typeName) {
1277        LocalVariableGen valueOfLV = null;
1278        int colLVIndex;
1279
1280        il.insert(insertHandle, factory.createInvoke(NAME_OBJECT, "toString",
1281                        OBJECT_TYPE_STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1282
1283        //create a localvar for the string
1284
valueOfLV = mg.addLocalVariable("valueOfString" + valueLVCount++, Type.STRING, null, null);
1285        colLVIndex = valueOfLV.getIndex();
1286        valueOfLV.setStart(il.insert(insertHandle, new ASTORE(colLVIndex)));
1287
1288        il.insert(insertHandle, factory.createNew(typeName));
1289        il.insert(insertHandle, InstructionConstants.DUP);
1290        il.insert(insertHandle, new ALOAD(colLVIndex));
1291        il.insert(insertHandle, factory.createInvoke(typeName, "<init>",
1292                Type.VOID, ARG_TYPES_STRING, Constants.INVOKESPECIAL));
1293    }
1294
1295    private void insertBigTypeFromPrim(InstructionHandle insertHandle, BCField otherType, String JavaDoc typeName) {
1296        LocalVariableGen valueOfLV;
1297        int colLVIndex;
1298
1299        il.insert(insertHandle, factory.createInvoke(NAME_STRING, "valueOf" ,
1300                OBJECT_TYPE_STRING, new Type[] {getTypeFromTypeCode(otherType.bcType)}, Constants.INVOKESTATIC));
1301
1302        //create a localvar for the string
1303
valueOfLV = mg.addLocalVariable("valueOfString" + valueLVCount++, Type.STRING, null, null);
1304        colLVIndex = valueOfLV.getIndex();
1305        valueOfLV.setStart(il.insert(insertHandle, new ASTORE(colLVIndex)));
1306
1307        il.insert(insertHandle, factory.createNew(typeName));
1308        il.insert(insertHandle, InstructionConstants.DUP);
1309        il.insert(insertHandle, new ALOAD(colLVIndex));
1310        il.insert(insertHandle, factory.createInvoke(typeName, "<init>",
1311                Type.VOID, ARG_TYPES_STRING, Constants.INVOKESPECIAL));
1312    }
1313
1314    /**
1315     * This will check if the type to promote to is either a BigInteger or a BigDecimal. If either is true
1316     * the the other type must be converted to a the corresponding type.
1317     *
1318     * @param typePromoteTo
1319     * @param otherType
1320     * @param insertHandle
1321     */

1322    private void promoteToObjects(int typePromoteTo, BCField otherType, InstructionHandle insertHandle) {
1323        if (typePromoteTo == otherType.bcType) {
1324            return;
1325        }
1326        switch (typePromoteTo) {
1327            case MDStatics.BIGINTEGER:
1328                insertBigTypeFromObject(insertHandle, NAME_BIG_INT);
1329                break;
1330            case MDStatics.BIGDECIMAL:
1331                insertBigTypeFromObject(insertHandle, NAME_BIG_DEC);
1332                break;
1333            default:
1334                //do nothing. This is a no-op
1335
}
1336
1337    }
1338
1339    /**
1340     * This must promote a prim to an big type.
1341     *
1342     * @param typePromoteTo
1343     * @param otherType
1344     * @param insertHandle
1345     */

1346    private void promotePrimToBig(int typePromoteTo, BCField otherType, InstructionHandle insertHandle) {
1347        if (typePromoteTo == otherType.bcType) {
1348            return;
1349        }
1350        switch (typePromoteTo) {
1351            case MDStatics.BIGINTEGER:
1352                insertBigTypeFromPrim(insertHandle, otherType, NAME_BIG_INT);
1353                break;
1354            case MDStatics.BIGDECIMAL:
1355                insertBigTypeFromPrim(insertHandle, otherType, NAME_BIG_DEC);
1356                break;
1357            default:
1358                throw BindingSupportImpl.getInstance().internal("Only 'BigInteger' and 'BigDecimal' is supported");
1359        }
1360
1361    }
1362
1363    /**
1364     * This will promote a primitive to a bigger primitive.
1365     *
1366     * @param typePromoteTo
1367     * @param otherType
1368     * @param insertHandle
1369     */

1370    private void promotePrimToPrim(int typePromoteTo, BCField otherType, InstructionHandle insertHandle) {
1371        if (otherType.bcType == typePromoteTo) {
1372            return;
1373        }
1374        switch (typePromoteTo) {
1375            case MDStatics.BYTE:
1376            case MDStatics.SHORT:
1377            case MDStatics.CHAR:
1378            case MDStatics.INT:
1379                break;
1380            case MDStatics.LONG:
1381                il.insert(insertHandle, InstructionConstants.I2L);
1382                break;
1383            case MDStatics.FLOAT:
1384                if (otherType.bcType == MDStatics.LONG) {
1385                    il.insert(insertHandle, InstructionConstants.L2F);
1386                } else {
1387                    il.insert(insertHandle, InstructionConstants.I2F);
1388                }
1389                break;
1390            case MDStatics.DOUBLE:
1391                switch (otherType.bcType) {
1392                    case MDStatics.BYTE:
1393                    case MDStatics.SHORT:
1394                    case MDStatics.CHAR:
1395                    case MDStatics.INT:
1396                        il.insert(insertHandle, InstructionConstants.I2D);
1397                        break;
1398                    case MDStatics.LONG:
1399                        il.insert(insertHandle, InstructionConstants.L2D);
1400                        break;
1401                    case MDStatics.FLOAT:
1402                        il.insert(insertHandle, InstructionConstants.F2D);
1403                        break;
1404                }
1405                break;
1406            case MDStatics.BOOLEAN:
1407                throw BindingSupportImpl.getInstance().invalidOperation("Promoting between primitives and boolean's is not allowed");
1408            default:
1409                throw BindingSupportImpl.getInstance().internal("Promoting from type '"
1410                        + MDStaticUtils.toSimpleName(otherType.bcType) + "'"
1411                        + " to type '" + MDStaticUtils.toSimpleName(typePromoteTo) + "' is not implemented correctly");
1412        }
1413
1414    }
1415
1416    /**
1417     * Promote all to primitives
1418     * @param typePromoteTo
1419     * @param otherType
1420     * @param insertHandle
1421     */

1422    private void promoteAllToPrim(int typePromoteTo, BCField otherType, InstructionHandle insertHandle) {
1423        if (otherType.bcType == typePromoteTo && otherType.isPrimitive()) {
1424            return;
1425        }
1426        switch (typePromoteTo) {
1427            case MDStatics.BYTE:
1428            case MDStatics.SHORT:
1429            case MDStatics.CHAR:
1430            case MDStatics.INT:
1431            case MDStatics.INTW:
1432                if (!otherType.isPrimitive()) {
1433                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1434                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "intValue",
1435                            Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1436                }
1437                break;
1438            case MDStatics.LONG:
1439            case MDStatics.LONGW:
1440                if (!otherType.isPrimitive()) {
1441                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1442                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "longValue",
1443                            Type.LONG, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1444                } else {
1445                    il.insert(insertHandle, InstructionConstants.I2L);
1446                }
1447                break;
1448            case MDStatics.FLOAT:
1449            case MDStatics.FLOATW:
1450                if (!otherType.isPrimitive()) {
1451                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1452                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "floatValue",
1453                            Type.FLOAT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1454                } else {
1455                    if (otherType.bcType == MDStatics.LONG) {
1456                        il.insert(insertHandle, InstructionConstants.L2F);
1457                    } else {
1458                        il.insert(insertHandle, InstructionConstants.I2F);
1459                    }
1460                }
1461                break;
1462            case MDStatics.DOUBLE:
1463            case MDStatics.DOUBLEW:
1464                if (!otherType.isPrimitive()) {
1465                    il.insert(insertHandle, factory.createCheckCast(OBJECT_TYPE_NUMBER));
1466                    il.insert(insertHandle, factory.createInvoke(NAME_NUMBER, "doubleValue",
1467                            Type.DOUBLE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1468                } else {
1469                    switch (otherType.bcType) {
1470                        case MDStatics.BYTE:
1471                        case MDStatics.SHORT:
1472                        case MDStatics.CHAR:
1473                        case MDStatics.INT:
1474                            il.insert(insertHandle, InstructionConstants.I2D);
1475                            break;
1476                        case MDStatics.LONG:
1477                            il.insert(insertHandle, InstructionConstants.L2D);
1478                            break;
1479                        case MDStatics.FLOAT:
1480                            il.insert(insertHandle, InstructionConstants.F2D);
1481                            break;
1482                    }
1483                }
1484                break;
1485            case MDStatics.BOOLEAN:
1486            case MDStatics.BOOLEANW:
1487                if (!otherType.isPrimitive()) {
1488                    il.insert(insertHandle, factory.createCheckCast(new ObjectType(Boolean JavaDoc.class.getName())));
1489                    il.insert(insertHandle, factory.createInvoke(Boolean JavaDoc.class.getName(), "booleanValue",
1490                            Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1491                }
1492                break;
1493            default:
1494                throw BindingSupportImpl.getInstance().internal("Promoting from type '"
1495                        + MDStaticUtils.toSimpleName(otherType.bcType) + "'"
1496                        + " to type '" + MDStaticUtils.toSimpleName(typePromoteTo) + "' is not implemented correctly");
1497        }
1498
1499    }
1500
1501    /**
1502     * This must check the types and determine the wider of the 2.
1503     * @param typeL
1504     * @param typeR
1505     * @return
1506     */

1507    private int getWidestType(int typeL, int typeR) {
1508        if (typeL == typeR) {
1509            return typeL;
1510        }
1511        int lValue = getWidth(typeL);
1512        int rValue = getWidth(typeR);
1513        if (lValue < rValue) {
1514            return typeR;
1515        } else {
1516            return typeL;
1517        }
1518    }
1519
1520    private int getWidth(int type) {
1521        switch (type) {
1522            case MDStatics.BOOLEAN:
1523            case MDStatics.BOOLEANW:
1524            case MDStatics.BYTE:
1525            case MDStatics.BYTEW:
1526                return 1;
1527            case MDStatics.SHORT:
1528            case MDStatics.SHORTW:
1529                return 1;
1530            case MDStatics.CHAR:
1531            case MDStatics.CHARW:
1532                return 1;
1533            case MDStatics.INT:
1534            case MDStatics.INTW:
1535                return 1;
1536            case MDStatics.LONG:
1537            case MDStatics.LONGW:
1538                return 2;
1539            case MDStatics.FLOAT:
1540            case MDStatics.FLOATW:
1541                return 3;
1542            case MDStatics.DOUBLE:
1543            case MDStatics.DOUBLEW:
1544                return 4;
1545            case MDStatics.BIGINTEGER:
1546                return 8;
1547            case MDStatics.BIGDECIMAL:
1548                return 16;
1549            case MDStatics.NULL:
1550                return -1;
1551            default:
1552                return -1;
1553        }
1554    }
1555
1556    public Field visitUnaryOpNode(UnaryOpNode node, Object JavaDoc obj) {
1557        BCField result = null;
1558        switch (node.op) {
1559            case UnaryOpNode.OP_BANG:
1560                node.childList.visit(this, null);
1561                IFNE ifTrue = new IFNE(null);
1562                il.append(ifTrue);
1563                il.append(InstructionConstants.ICONST_1);
1564                GOTO gotoEnd = new GOTO(null);
1565                il.append(gotoEnd);
1566                InstructionHandle toFalseHandle = il.append(InstructionConstants.ICONST_0);
1567                ifTrue.setTarget(toFalseHandle);
1568                gotoEnd.setTarget(il.append(InstructionConstants.NOP));
1569                break;
1570            case UnaryOpNode.OP_MINUS:
1571                result = (BCField) node.childList.visit(this, null);
1572                switch (result.bcType) {
1573                    case MDStatics.BYTE:
1574                    case MDStatics.CHAR:
1575                    case MDStatics.SHORT:
1576                    case MDStatics.INT:
1577                        il.append(InstructionConstants.INEG);
1578                        break;
1579                    case MDStatics.BYTEW:
1580                    case MDStatics.CHARW:
1581                    case MDStatics.SHORTW:
1582                    case MDStatics.INTW:
1583                        il.append(factory.createCheckCast(OBJECT_TYPE_NUMBER));
1584                        il.append(factory.createInvoke(NAME_NUMBER, "intValue",
1585                            Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1586                        il.append(InstructionConstants.INEG);
1587                        result = new BCField();
1588                        result.classType = Integer.TYPE;
1589                        result.bcType = MDStatics.INT;
1590                        break;
1591                    case MDStatics.LONGW:
1592                        il.append(factory.createCheckCast(OBJECT_TYPE_NUMBER));
1593                        il.append(factory.createInvoke(NAME_NUMBER, "longValue",
1594                            Type.LONG, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1595                        result = new BCField();
1596                        result.classType = Long.TYPE;
1597                        result.bcType = MDStatics.LONG;
1598                    case MDStatics.LONG:
1599                        il.append(InstructionConstants.LNEG);
1600                        break;
1601                    case MDStatics.FLOATW:
1602                        il.append(factory.createCheckCast(OBJECT_TYPE_NUMBER));
1603                        il.append(factory.createInvoke(NAME_NUMBER, "floatValue",
1604                            Type.FLOAT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1605                        result = new BCField();
1606                        result.classType = Float.TYPE;
1607                        result.bcType = MDStatics.FLOAT;
1608                    case MDStatics.FLOAT:
1609                        il.append(InstructionConstants.FNEG);
1610                        break;
1611                    case MDStatics.DOUBLEW:
1612                        il.append(factory.createCheckCast(OBJECT_TYPE_NUMBER));
1613                        il.append(factory.createInvoke(NAME_NUMBER, "doubleValue",
1614                            Type.DOUBLE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
1615                        result = new BCField();
1616                        result.classType = Double.TYPE;
1617                        result.bcType = MDStatics.DOUBLE;
1618                    case MDStatics.DOUBLE:
1619                        il.append(InstructionConstants.DNEG);
1620                        break;
1621                    default:
1622                        throw new NotImplementedException();
1623                }
1624                break;
1625            case UnaryOpNode.OP_PLUS:
1626                result = (BCField) node.childList.visit(this, null);
1627                break;
1628            case UnaryOpNode.OP_TILDE:
1629                result = (BCField) node.childList.visit(this, null);
1630                InstructionHandle nopHandle = il.append(InstructionConstants.NOP);
1631                promoteAllToPrim(result.bcType, result, nopHandle);
1632                switch (result.bcType) {
1633                    case MDStatics.BYTE:
1634                    case MDStatics.CHAR:
1635                    case MDStatics.SHORT:
1636                    case MDStatics.INT:
1637                    case MDStatics.BYTEW:
1638                    case MDStatics.CHARW:
1639                    case MDStatics.SHORTW:
1640                    case MDStatics.INTW:
1641                        if (result.bcType != MDStatics.INT) {
1642                            result = new BCField();
1643                            result.bcType = MDStatics.INT;
1644                            result.classType = Integer.TYPE;
1645                        }
1646                        il.append(InstructionConstants.ICONST_M1);
1647                        il.append(InstructionConstants.IXOR);
1648                        break;
1649                    case MDStatics.LONG:
1650                    case MDStatics.LONGW:
1651                        if (result.bcType != MDStatics.LONG) {
1652                            result = new BCField();
1653                            result.bcType = MDStatics.LONG;
1654                            result.classType = Long.TYPE;
1655                        }
1656                        il.append(new PUSH(cp, -1l));
1657                        il.append(InstructionConstants.LXOR);
1658                        break;
1659                    default:
1660                        throw new NotImplementedException();
1661                }
1662                break;
1663            default:
1664                throw new NotImplementedException("UnaryNode type '" + node.op + "' is not implemented correctly");
1665        }
1666        return result;
1667    }
1668
1669    public Field visitCompareOpNode(CompareOpNode node, Object JavaDoc obj) {
1670        return doCompare(node, getCompType(node));
1671    }
1672
1673    private final int getCompType(CompareOpNode node) {
1674        switch (node.op) {
1675            case CompareOpNode.GT:
1676                return COMP_GT;
1677            case CompareOpNode.LT:
1678                return COMP_LT;
1679            case CompareOpNode.GE:
1680                return COMP_GE;
1681            case CompareOpNode.LE:
1682                return COMP_LE;
1683            default:
1684                 throw BindingSupportImpl.getInstance().internal("No operator of type '" + node.op + "'");
1685        }
1686    }
1687
1688    public Field visitUnaryNode(UnaryNode node, Object JavaDoc obj) {
1689        node.childList.visit(this,obj);
1690        return null;
1691    }
1692
1693    public Field visitBinaryNode(BinaryNode node, Object JavaDoc obj) {
1694        return null;
1695    }
1696
1697    public Field visitMultiNode(Node node, Object JavaDoc obj) {
1698        return null;
1699    }
1700
1701    public Field visitCastNode(CastNode node, Object JavaDoc obj) {
1702        return null;
1703    }
1704
1705    public Field visitParamNode(ParamNode node, Object JavaDoc obj) {
1706        BCField field = null;
1707        Object JavaDoc paramValue = paramMap.get(node.getIdentifier());
1708        if (paramValue == null) {
1709            field = new BCField();
1710            field.bcType = MDStatics.NULL;
1711            field.classType = Object JavaDoc.class;
1712        } else {
1713            Class JavaDoc clazz = paramValue.getClass();
1714            if(OID.class.isAssignableFrom(clazz)) {
1715                field = new BCField();
1716                field.classType = clazz;
1717                field.bcType = MDStaticUtils.toTypeCode(clazz);
1718                field.ih = il.append(new ALOAD(2));
1719                il.append(new PUSH(cp, node.getIndex()));
1720                il.append(new AALOAD());
1721            } else {
1722                field = new BCField();
1723                field.classType = clazz;
1724                field.bcType = MDStaticUtils.toTypeCode(clazz);
1725                field.ih = il.append(new ALOAD(2));
1726                il.append(new PUSH(cp, node.getIndex()));
1727                il.append(new AALOAD());
1728            }
1729        }
1730        return field;
1731    }
1732
1733    public Field visitParamNodeProxy(ParamNodeProxy node, Object JavaDoc obj) {
1734        return node.getParamNode().visit(this, obj);
1735    }
1736
1737    public Field visitArgNode(ArgNode node, Object JavaDoc obj) {
1738        return null;
1739    }
1740
1741    public Field visitArrayNode(ArrayNode node, Object JavaDoc obj) {
1742        return null;
1743    }
1744
1745    public Field visitImportNode(ImportNode node, Object JavaDoc obj) {
1746        return null;
1747    }
1748
1749    public Field visitLeafNode(LeafNode node, Object JavaDoc obj) {
1750        return null;
1751    }
1752
1753    public Field visitOrderNode(OrderNode node, Object JavaDoc obj) {
1754        return null;
1755    }
1756
1757    public Field visitVarNode(VarNode node, Object JavaDoc obj) {
1758        return null;
1759    }
1760
1761    public Field visitVarNodeProxy(VarNodeProxy node, Object JavaDoc obj) {
1762        return node.getVarNode().visit(this, obj);
1763    }
1764
1765    public Field visitReservedFieldNode(ReservedFieldNode node, Object JavaDoc obj) {
1766        return null;
1767    }
1768
1769
1770    private class BCStateField extends BCField {
1771        private InstructionHandle ih;
1772        private FieldMetaData fmd;
1773
1774        public BCStateField(FieldMetaData fmd) {
1775            this.fmd = fmd;
1776            initFromFMD(fmd);
1777        }
1778
1779        private void initFromFMD(FieldMetaData fmd) {
1780            this.classType = fmd.type;
1781            bcType = fmd.typeCode;
1782
1783        }
1784
1785        public BCStateField(InstructionHandle ih) {
1786            this.ih = ih;
1787        }
1788
1789        public InstructionHandle getIh() {
1790            return ih;
1791        }
1792
1793        public void setIh(InstructionHandle ih) {
1794            this.ih = ih;
1795        }
1796
1797        public FieldMetaData getFMD() {
1798            return fmd;
1799        }
1800    }
1801}
1802
Popular Tags