KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > expr > ConsumerTarget


1 // Copyright (c) 2000, 2001 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.expr;
5 import gnu.bytecode.*;
6 import gnu.kawa.reflect.OccurrenceType;
7
8 /**
9  * A Target which is some variable that implements gnu.lists.Consumer.
10  */

11
12 public class ConsumerTarget extends Target
13 {
14   Variable consumer;
15   boolean isContextTarget;
16
17   public ConsumerTarget(Variable consumer)
18   {
19     this.consumer = consumer;
20   }
21
22   public Variable getConsumerVariable() { return consumer; }
23
24   /** True iff this target is the current CallContext's current Consumer. */
25   public final boolean isContextTarget () { return isContextTarget; }
26
27   /** Make a Target that uses the current CallContext's current Consumer. */
28   public static Target makeContextTarget (Compilation comp)
29   {
30     CodeAttr code = comp.getCode();
31     comp.loadCallContext();
32     code.emitGetField(Compilation.typeCallContext
33               .getDeclaredField("consumer"));
34     Scope scope = code.getCurrentScope();
35     Variable result
36       = scope.addVariable(code, Compilation.typeConsumer, "$result");
37     code.emitStore(result);
38     ConsumerTarget target = new ConsumerTarget(result);
39     target.isContextTarget = true;
40     return target;
41   }
42
43   /** Compile an expression using a temporary Consumer, if needed. */
44   public static void compileUsingConsumer(Expression exp,
45                       Compilation comp, Target target)
46   {
47     if (target instanceof ConsumerTarget || target instanceof IgnoreTarget)
48       exp.compile(comp, target);
49     else
50       {
51     ClassType typeValues = Compilation.typeValues;
52     compileUsingConsumer(exp, comp, target,
53                  typeValues.getDeclaredMethod("make", 0),
54                  typeValues.getDeclaredMethod("canonicalize", 0));
55       }
56   }
57
58   public static void compileUsingConsumer (Expression exp, Compilation comp,
59                        Target target,
60                        Method makeMethod,
61                        Method resultMethod)
62   {
63     CodeAttr code = comp.getCode();
64     Scope scope = code.pushScope();
65     Type ctype;
66     if (makeMethod.getName() == "<init>")
67       {
68     ClassType cltype = makeMethod.getDeclaringClass();
69     ctype = cltype;
70     code.emitNew(cltype);
71     code.emitDup(ctype);
72     code.emitInvoke(makeMethod);
73       }
74     else
75       {
76     ctype = makeMethod.getReturnType();
77     code.emitInvokeStatic(makeMethod);
78       }
79     Variable consumer = scope.addVariable(code, ctype, null);
80     ConsumerTarget ctarget = new ConsumerTarget(consumer);
81     code.emitStore(consumer);
82     exp.compile(comp, ctarget);
83     code.emitLoad(consumer);
84     if (resultMethod != null)
85       code.emitInvoke(resultMethod);
86     code.popScope();
87     target.compileFromStack(comp, resultMethod == null ? ctype
88                 : resultMethod.getReturnType());
89   }
90
91
92   public void compileFromStack(Compilation comp, Type stackType)
93   {
94     compileFromStack(comp, stackType, -1);
95   }
96
97   /** Write stack value to Consumer.
98    * @param consumerPushed if -1, then Consumer has not been pushed;
99    * if 1, Consumer was pushed before value, and value is a known singleton;
100    * if 0, Consumer was pushed before value, otherwise.
101    */

102   void compileFromStack(Compilation comp,
103                         Type stackType, int consumerPushed)
104   {
105     CodeAttr code = comp.getCode();
106     String JavaDoc methodName = null;
107     Method method = null;
108     boolean islong = false;
109     stackType = stackType.getImplementationType();
110     char sig;
111     if (stackType instanceof PrimType)
112       {
113     sig = stackType.getSignature().charAt(0);
114     switch (sig)
115       {
116       case 'B': case 'S': case 'I':
117         methodName = "writeInt"; break;
118       case 'J': methodName = "writeLong"; islong = true; break;
119       case 'F': methodName = "writeFloat"; break;
120       case 'D': methodName = "writeDouble"; islong = true; break;
121       case 'C': methodName = "append"; break;
122       case 'Z': methodName = "writeBoolean"; break;
123       case 'V': return;
124       }
125       }
126     else
127       {
128         sig = '\0';
129     if (consumerPushed == 1 || OccurrenceType.itemCountIsOne(stackType))
130       methodName = "writeObject";
131     else
132       {
133         method = (Compilation.typeValues
134               .getDeclaredMethod("writeValues", 2));
135         code.emitLoad(consumer);
136             if (consumerPushed == 0)
137               code.emitSwap();
138         code.emitInvokeStatic(method);
139         return;
140       }
141       }
142     if (consumerPushed >= 0)
143       ;
144     else if (islong)
145       {
146     code.pushScope();
147     Variable temp = code.addLocal(stackType);
148     code.emitStore(temp);
149     code.emitLoad(consumer);
150     code.emitLoad(temp);
151     code.popScope();
152       }
153     else
154       {
155     code.emitLoad(consumer);
156     code.emitSwap();
157       }
158     if (method == null && methodName != null)
159       method = Compilation.typeConsumer.getDeclaredMethod(methodName, 1);
160     if (method != null)
161       code.emitInvokeInterface(method);
162     if (sig == 'C')
163       code.emitPop(1); // Pop consumer result.
164
}
165
166   public boolean compileWrite (Expression exp, Compilation comp)
167   {
168     Type stackType = exp.getType();
169     Type implType = stackType.getImplementationType();
170     if ((implType instanceof PrimType && ! implType.isVoid())
171         || gnu.kawa.reflect.OccurrenceType.itemCountIsOne(implType))
172       {
173         // Optimization to avoid a 'swap'.
174
comp.getCode().emitLoad(this.consumer);
175         Target starget = StackTarget.getInstance(implType);
176         exp.compile(comp, starget);
177         compileFromStack(comp, implType, 1);
178         return true;
179       }
180     return false;
181    }
182
183   public Type getType() { return Compilation.scmSequenceType; }
184 }
185
Popular Tags