View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2001-2004 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  /*
21   * $Id: ReferenceType.java,v 1.2.4.1 2005/09/05 11:29:12 pvedula Exp $
22   */
23  
24  package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
25  
26  import com.sun.org.apache.bcel.internal.generic.PUSH;
27  import com.sun.org.apache.bcel.internal.generic.ALOAD;
28  import com.sun.org.apache.bcel.internal.generic.ASTORE;
29  import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
30  import com.sun.org.apache.bcel.internal.generic.IFEQ;
31  import com.sun.org.apache.bcel.internal.generic.ILOAD;
32  import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
33  import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
34  import com.sun.org.apache.bcel.internal.generic.Instruction;
35  import com.sun.org.apache.bcel.internal.generic.InstructionList;
36  
37  import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
38  import com.sun.org.apache.xalan.internal.xsltc.compiler.FlowList;
39  
40  import com.sun.org.apache.xml.internal.dtm.DTM;
41  
42  /**
43   * @author Jacek Ambroziak
44   * @author Santiago Pericas-Geertsen
45   * @author Erwin Bolwidt <ejb@klomp.org>
46   */
47  public final class ReferenceType extends Type {
48      protected ReferenceType() {}
49  
50      public String toString() {
51          return "reference";
52      }
53  
54      public boolean identicalTo(Type other) {
55          return this == other;
56      }
57  
58      public String toSignature() {
59          return "Ljava/lang/Object;";
60      }
61  
62      public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
63          return com.sun.org.apache.bcel.internal.generic.Type.OBJECT;
64      }
65  
66      /**
67       * Translates a reference to an object of internal type <code>type</code>.
68       * The translation to int is undefined since references
69       * are always converted to reals in arithmetic expressions.
70       *
71       * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
72       */
73      public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
74                              Type type) {
75          if (type == Type.String) {
76              translateTo(classGen, methodGen, (StringType) type);
77          }
78          else if (type == Type.Real) {
79              translateTo(classGen, methodGen, (RealType) type);
80          }
81          else if (type == Type.Boolean) {
82              translateTo(classGen, methodGen, (BooleanType) type);
83          }
84          else if (type == Type.NodeSet) {
85              translateTo(classGen, methodGen, (NodeSetType) type);
86          }
87          else if (type == Type.Node) {
88              translateTo(classGen, methodGen, (NodeType) type);
89          }
90          else if (type == Type.ResultTree) {
91              translateTo(classGen, methodGen, (ResultTreeType) type);
92          }
93          else if (type == Type.Object) {
94              translateTo(classGen, methodGen, (ObjectType) type);
95          }
96          else if (type == Type.Reference ) {
97          }
98          else {
99              ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, type.toString());
100             classGen.getParser().reportError(Constants.FATAL, err);
101         }
102     }
103 
104     /**
105      * Translates reference into object of internal type <code>type</code>.
106      *
107      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
108      */
109     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
110                             StringType type) {
111         final int current = methodGen.getLocalIndex("current");
112         ConstantPoolGen cpg = classGen.getConstantPool();
113         InstructionList il = methodGen.getInstructionList();
114 
115         // If no current, conversion is a top-level
116         if (current < 0) {
117             il.append(new PUSH(cpg, DTM.ROOT_NODE));  // push root node
118         }
119         else {
120             il.append(new ILOAD(current));
121         }
122         il.append(methodGen.loadDOM());
123         final int stringF = cpg.addMethodref(BASIS_LIBRARY_CLASS,
124                                              "stringF",
125                                              "("
126                                              + OBJECT_SIG
127                                              + NODE_SIG
128                                              + DOM_INTF_SIG
129                                              + ")" + STRING_SIG);
130         il.append(new INVOKESTATIC(stringF));
131     }
132 
133     /**
134      * Translates a reference into an object of internal type <code>type</code>.
135      *
136      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
137      */
138     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
139                             RealType type) {
140         final ConstantPoolGen cpg = classGen.getConstantPool();
141         final InstructionList il = methodGen.getInstructionList();
142 
143         il.append(methodGen.loadDOM());
144         int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "numberF",
145                                      "("
146                                      + OBJECT_SIG
147                                      + DOM_INTF_SIG
148                                      + ")D");
149         il.append(new INVOKESTATIC(index));
150     }
151 
152     /**
153      * Translates a reference to an object of internal type <code>type</code>.
154      *
155      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
156      */
157     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
158                             BooleanType type) {
159         final ConstantPoolGen cpg = classGen.getConstantPool();
160         final InstructionList il = methodGen.getInstructionList();
161 
162         int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "booleanF",
163                                      "("
164                                      + OBJECT_SIG
165                                      + ")Z");
166         il.append(new INVOKESTATIC(index));
167     }
168 
169     /**
170      * Casts a reference into a NodeIterator.
171      *
172      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
173      */
174     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
175                             NodeSetType type) {
176         final ConstantPoolGen cpg = classGen.getConstantPool();
177         final InstructionList il = methodGen.getInstructionList();
178         int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "referenceToNodeSet",
179                                      "("
180                                      + OBJECT_SIG
181                                      + ")"
182                                      + NODE_ITERATOR_SIG);
183         il.append(new INVOKESTATIC(index));
184 
185         // Reset this iterator
186         index = cpg.addInterfaceMethodref(NODE_ITERATOR, RESET, RESET_SIG);
187         il.append(new INVOKEINTERFACE(index, 1));
188     }
189 
190     /**
191      * Casts a reference into a Node.
192      *
193      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
194      */
195     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
196                             NodeType type) {
197         translateTo(classGen, methodGen, Type.NodeSet);
198         Type.NodeSet.translateTo(classGen, methodGen, type);
199     }
200 
201     /**
202      * Casts a reference into a ResultTree.
203      *
204      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
205      */
206     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
207                             ResultTreeType type) {
208         final ConstantPoolGen cpg = classGen.getConstantPool();
209         final InstructionList il = methodGen.getInstructionList();
210         int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "referenceToResultTree",
211                                      "(" + OBJECT_SIG + ")" + DOM_INTF_SIG);
212         il.append(new INVOKESTATIC(index));
213     }
214 
215     /**
216      * Subsume reference into ObjectType.
217      *
218      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
219      */
220     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
221                             ObjectType type) {
222         methodGen.getInstructionList().append(NOP);
223     }
224 
225     /**
226      * Translates a reference into the Java type denoted by <code>clazz</code>.
227      */
228     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
229                             Class clazz) {
230         final ConstantPoolGen cpg = classGen.getConstantPool();
231         final InstructionList il = methodGen.getInstructionList();
232 
233         int referenceToLong = cpg.addMethodref(BASIS_LIBRARY_CLASS,
234                                                "referenceToLong",
235                                                "(" + OBJECT_SIG + ")J");
236         int referenceToDouble = cpg.addMethodref(BASIS_LIBRARY_CLASS,
237                                                  "referenceToDouble",
238                                                 "(" + OBJECT_SIG + ")D");
239         int referenceToBoolean = cpg.addMethodref(BASIS_LIBRARY_CLASS,
240                                                   "referenceToBoolean",
241                                                  "(" + OBJECT_SIG + ")Z");
242 
243         if (clazz.getName().equals("java.lang.Object")) {
244             il.append(NOP);
245         }
246         else if (clazz == Double.TYPE) {
247             il.append(new INVOKESTATIC(referenceToDouble));
248         }
249         else if (clazz.getName().equals("java.lang.Double")) {
250             il.append(new INVOKESTATIC(referenceToDouble));
251             Type.Real.translateTo(classGen, methodGen, Type.Reference);
252         }
253         else if (clazz == Float.TYPE) {
254             il.append(new INVOKESTATIC(referenceToDouble));
255             il.append(D2F);
256         }
257         else if (clazz.getName().equals("java.lang.String")) {
258             int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "referenceToString",
259                                          "("
260                                          + OBJECT_SIG
261                                          + DOM_INTF_SIG
262                                          + ")"
263                                          + "Ljava/lang/String;");
264             il.append(methodGen.loadDOM());
265             il.append(new INVOKESTATIC(index));
266         }
267         else if (clazz.getName().equals("org.w3c.dom.Node")) {
268             int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "referenceToNode",
269                                          "("
270                                          + OBJECT_SIG
271                                          + DOM_INTF_SIG
272                                          + ")"
273                                          + "Lorg/w3c/dom/Node;");
274             il.append(methodGen.loadDOM());
275             il.append(new INVOKESTATIC(index));
276         }
277         else if (clazz.getName().equals("org.w3c.dom.NodeList")) {
278             int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "referenceToNodeList",
279                                          "("
280                                          + OBJECT_SIG
281                                          + DOM_INTF_SIG
282                                          + ")"
283                                          + "Lorg/w3c/dom/NodeList;");
284             il.append(methodGen.loadDOM());
285             il.append(new INVOKESTATIC(index));
286         }
287         else if (clazz.getName().equals("com.sun.org.apache.xalan.internal.xsltc.DOM")) {
288             translateTo(classGen, methodGen, Type.ResultTree);
289         }
290         else if (clazz == Long.TYPE) {
291             il.append(new INVOKESTATIC(referenceToLong));
292         }
293         else if (clazz == Integer.TYPE) {
294             il.append(new INVOKESTATIC(referenceToLong));
295             il.append(L2I);
296         }
297         else if (clazz == Short.TYPE) {
298             il.append(new INVOKESTATIC(referenceToLong));
299             il.append(L2I);
300             il.append(I2S);
301         }
302         else if (clazz == Byte.TYPE) {
303             il.append(new INVOKESTATIC(referenceToLong));
304             il.append(L2I);
305             il.append(I2B);
306         }
307         else if (clazz == Character.TYPE) {
308             il.append(new INVOKESTATIC(referenceToLong));
309             il.append(L2I);
310             il.append(I2C);
311         }
312         else if (clazz == java.lang.Boolean.TYPE) {
313             il.append(new INVOKESTATIC(referenceToBoolean));
314         }
315         else if (clazz.getName().equals("java.lang.Boolean")) {
316             il.append(new INVOKESTATIC(referenceToBoolean));
317             Type.Boolean.translateTo(classGen, methodGen, Type.Reference);
318         }
319         else {
320             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
321                                         toString(), clazz.getName());
322             classGen.getParser().reportError(Constants.FATAL, err);
323         }
324     }
325 
326     /**
327      * Translates an external Java type into a reference. Only conversion
328      * allowed is from java.lang.Object.
329      */
330     public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen,
331                               Class clazz) {
332         if (clazz.getName().equals("java.lang.Object")) {
333             methodGen.getInstructionList().append(NOP);
334         }
335         else {
336             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
337                                 toString(), clazz.getName());
338             classGen.getParser().reportError(Constants.FATAL, err);
339         }
340     }
341 
342     /**
343      * Expects a reference on the stack and translates it to a non-synthesized
344      * boolean. It does not push a 0 or a 1 but instead returns branchhandle
345      * list to be appended to the false list.
346      *
347      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized
348      */
349     public FlowList translateToDesynthesized(ClassGenerator classGen,
350                                              MethodGenerator methodGen,
351                                              BooleanType type) {
352         InstructionList il = methodGen.getInstructionList();
353         translateTo(classGen, methodGen, type);
354         return new FlowList(il.append(new IFEQ(null)));
355     }
356 
357     /**
358      * Translates an object of this type to its boxed representation.
359      */
360     public void translateBox(ClassGenerator classGen,
361                              MethodGenerator methodGen) {
362     }
363 
364     /**
365      * Translates an object of this type to its unboxed representation.
366      */
367     public void translateUnBox(ClassGenerator classGen,
368                                MethodGenerator methodGen) {
369     }
370 
371 
372     public Instruction LOAD(int slot) {
373         return new ALOAD(slot);
374     }
375 
376     public Instruction STORE(int slot) {
377         return new ASTORE(slot);
378     }
379 }