KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > eval > CodeSnippetCodeStream


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

11 package org.eclipse.jdt.internal.eval;
12
13 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
14 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
15 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
16 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
17 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
18 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
19 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
20 import org.eclipse.jdt.internal.compiler.lookup.Scope;
21 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
22 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
23
24 public class CodeSnippetCodeStream extends CodeStream {
25     static InvocationSite NO_INVOCATION_SITE =
26         new InvocationSite(){
27             public TypeBinding[] genericTypeArguments() { return null; }
28             public boolean isSuperAccess(){ return false; }
29             public boolean isTypeAccess() { return false; }
30             public void setActualReceiverType(ReferenceBinding receiverType) {}
31             public void setDepth(int depth) {}
32             public void setFieldIndex(int depth){}
33             public int sourceStart() { return 0; }
34             public int sourceEnd() { return 0; }
35         };
36 /**
37  * CodeSnippetCodeStream constructor comment.
38  * @param classFile org.eclipse.jdt.internal.compiler.ClassFile
39  */

40 public CodeSnippetCodeStream(org.eclipse.jdt.internal.compiler.ClassFile classFile) {
41     super(classFile, JDK1_4);
42 }
43 protected void checkcast(int baseId) {
44     this.countLabels = 0;
45     if (classFileOffset + 2 >= bCodeStream.length) {
46         resizeByteArray();
47     }
48     this.position++;
49     this.bCodeStream[this.classFileOffset++] = OPC_checkcast;
50     switch (baseId) {
51         case T_byte :
52             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
53             break;
54         case T_short :
55             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
56             break;
57         case T_char :
58             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
59             break;
60         case T_int :
61             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
62             break;
63         case T_long :
64             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
65             break;
66         case T_float :
67             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
68             break;
69         case T_double :
70             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
71             break;
72         case T_boolean :
73             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
74     }
75 }
76 public void generateEmulatedAccessForMethod(Scope scope, MethodBinding methodBinding) {
77     CodeSnippetCodeStream localCodeStream = this;
78     localCodeStream.generateEmulationForMethod(scope, methodBinding);
79     localCodeStream.invokeJavaLangReflectMethodInvoke();
80 }
81 public void generateEmulatedReadAccessForField(FieldBinding fieldBinding) {
82     CodeSnippetCodeStream localCodeStream = this;
83     localCodeStream.generateEmulationForField(fieldBinding);
84     // swap the field with the receiver
85
this.swap();
86     localCodeStream.invokeJavaLangReflectFieldGetter(fieldBinding.type.id);
87     if (!fieldBinding.type.isBaseType()) {
88         this.checkcast(fieldBinding.type);
89     }
90 }
91 public void generateEmulatedWriteAccessForField(FieldBinding fieldBinding) {
92     CodeSnippetCodeStream localCodeStream = this;
93     localCodeStream.invokeJavaLangReflectFieldSetter(fieldBinding.type.id);
94 }
95 public void generateEmulationForConstructor(Scope scope, MethodBinding methodBinding) {
96     // leave a java.lang.reflect.Field object on the stack
97
CodeSnippetCodeStream localCodeStream = this;
98     this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
99     this.invokeClassForName();
100     int paramLength = methodBinding.parameters.length;
101     this.generateInlinedValue(paramLength);
102     this.newArray(scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1));
103     if (paramLength > 0) {
104         this.dup();
105         for (int i = 0; i < paramLength; i++) {
106             this.generateInlinedValue(i);
107             TypeBinding parameter = methodBinding.parameters[i];
108             if (parameter.isBaseType()) {
109                 this.getTYPE(parameter.id);
110             } else if (parameter.isArrayType()) {
111                 ArrayBinding array = (ArrayBinding)parameter;
112                 if (array.leafComponentType.isBaseType()) {
113                     this.getTYPE(array.leafComponentType.id);
114                 } else {
115                     this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.'));
116                     this.invokeClassForName();
117                 }
118                 int dimensions = array.dimensions;
119                 this.generateInlinedValue(dimensions);
120                 this.newarray(T_int);
121                 this.invokeArrayNewInstance();
122                 this.invokeObjectGetClass();
123             } else {
124                 // parameter is a reference binding
125
this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
126                 this.invokeClassForName();
127             }
128             this.aastore();
129             if (i < paramLength - 1) {
130                 this.dup();
131             }
132         }
133     }
134     localCodeStream.invokeClassGetDeclaredConstructor();
135     this.dup();
136     this.iconst_1();
137     localCodeStream.invokeAccessibleObjectSetAccessible();
138 }
139 public void generateEmulationForField(FieldBinding fieldBinding) {
140     // leave a java.lang.reflect.Field object on the stack
141
CodeSnippetCodeStream localCodeStream = this;
142     this.ldc(String.valueOf(fieldBinding.declaringClass.constantPoolName()).replace('/', '.'));
143     this.invokeClassForName();
144     this.ldc(String.valueOf(fieldBinding.name));
145     localCodeStream.invokeClassGetDeclaredField();
146     this.dup();
147     this.iconst_1();
148     localCodeStream.invokeAccessibleObjectSetAccessible();
149 }
150 public void generateEmulationForMethod(Scope scope, MethodBinding methodBinding) {
151     // leave a java.lang.reflect.Field object on the stack
152
CodeSnippetCodeStream localCodeStream = this;
153     this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
154     this.invokeClassForName();
155     this.ldc(String.valueOf(methodBinding.selector));
156     int paramLength = methodBinding.parameters.length;
157     this.generateInlinedValue(paramLength);
158     this.newArray(scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1));
159     if (paramLength > 0) {
160         this.dup();
161         for (int i = 0; i < paramLength; i++) {
162             this.generateInlinedValue(i);
163             TypeBinding parameter = methodBinding.parameters[i];
164             if (parameter.isBaseType()) {
165                 this.getTYPE(parameter.id);
166             } else if (parameter.isArrayType()) {
167                 ArrayBinding array = (ArrayBinding)parameter;
168                 if (array.leafComponentType.isBaseType()) {
169                     this.getTYPE(array.leafComponentType.id);
170                 } else {
171                     this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.'));
172                     this.invokeClassForName();
173                 }
174                 int dimensions = array.dimensions;
175                 this.generateInlinedValue(dimensions);
176                 this.newarray(T_int);
177                 this.invokeArrayNewInstance();
178                 this.invokeObjectGetClass();
179             } else {
180                 // parameter is a reference binding
181
this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
182                 this.invokeClassForName();
183             }
184             this.aastore();
185             if (i < paramLength - 1) {
186                 this.dup();
187             }
188         }
189     }
190     localCodeStream.invokeClassGetDeclaredMethod();
191     this.dup();
192     this.iconst_1();
193     localCodeStream.invokeAccessibleObjectSetAccessible();
194 }
195 public void generateObjectWrapperForType(TypeBinding valueType) {
196
197     /* The top of stack must be encapsulated inside
198      * a wrapper object if it corresponds to a base type
199      */

200     TypeBinding wrapperType = this.methodDeclaration.scope.boxing(valueType);
201     new_(wrapperType);
202     if (valueType.id == T_long || valueType.id == T_double) {
203         dup_x2();
204         dup_x2();
205         pop();
206     } else {
207         dup_x1();
208         swap();
209     }
210     MethodBinding methodBinding = this.methodDeclaration.scope.getMethod(
211                 wrapperType,
212                 ConstantPool.Init,
213                 new TypeBinding[] {valueType},
214                 NO_INVOCATION_SITE);
215     invokespecial(methodBinding);
216 }
217 public void getBaseTypeValue(int baseTypeID) {
218     switch (baseTypeID) {
219         case T_byte :
220             // invokevirtual: byteValue()
221
this.invoke(
222                     OPC_invokevirtual,
223                     0, // argCount
224
1, // return type size
225
ConstantPool.JavaLangByteConstantPoolName,
226                     ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
227                     ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
228             break;
229         case T_short :
230             // invokevirtual: shortValue()
231
this.invoke(
232                     OPC_invokevirtual,
233                     0, // argCount
234
1, // return type size
235
ConstantPool.JavaLangShortConstantPoolName,
236                     ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
237                     ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
238             break;
239         case T_char :
240             // invokevirtual: charValue()
241
this.invoke(
242                     OPC_invokevirtual,
243                     0, // argCount
244
1, // return type size
245
ConstantPool.JavaLangCharacterConstantPoolName,
246                     ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
247                     ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
248             break;
249         case T_int :
250             // invokevirtual: intValue()
251
this.invoke(
252                     OPC_invokevirtual,
253                     0, // argCount
254
1, // return type size
255
ConstantPool.JavaLangIntegerConstantPoolName,
256                     ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
257                     ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
258             break;
259         case T_long :
260             // invokevirtual: longValue()
261
this.invoke(
262                     OPC_invokevirtual,
263                     0, // argCount
264
2, // return type size
265
ConstantPool.JavaLangLongConstantPoolName,
266                     ConstantPool.LONGVALUE_LONG_METHOD_NAME,
267                     ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
268             break;
269         case T_float :
270             // invokevirtual: floatValue()
271
this.invoke(
272                     OPC_invokevirtual,
273                     0, // argCount
274
1, // return type size
275
ConstantPool.JavaLangFloatConstantPoolName,
276                     ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
277                     ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
278             break;
279         case T_double :
280             // invokevirtual: doubleValue()
281
this.invoke(
282                     OPC_invokevirtual,
283                     0, // argCount
284
2, // return type size
285
ConstantPool.JavaLangDoubleConstantPoolName,
286                     ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
287                     ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
288             break;
289         case T_boolean :
290             // invokevirtual: booleanValue()
291
this.invoke(
292                     OPC_invokevirtual,
293                     0, // argCount
294
1, // return type size
295
ConstantPool.JavaLangBooleanConstantPoolName,
296                     ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
297                     ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
298     }
299 }
300 protected void invokeAccessibleObjectSetAccessible() {
301     // invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
302
this.invoke(
303             OPC_invokevirtual,
304             1, // argCount
305
0, // return type size
306
ConstantPool.JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME,
307             ConstantPool.SETACCESSIBLE_NAME,
308             ConstantPool.SETACCESSIBLE_SIGNATURE);
309 }
310 protected void invokeArrayNewInstance() {
311     // invokestatic: java.lang.reflect.Array.newInstance(Ljava.lang.Class;int[])Ljava.lang.Object;
312
this.invoke(
313             OPC_invokestatic,
314             2, // argCount
315
1, // return type size
316
ConstantPool.JAVALANGREFLECTARRAY_CONSTANTPOOLNAME,
317             ConstantPool.NewInstance,
318             ConstantPool.NewInstanceSignature);
319 }
320 protected void invokeClassGetDeclaredConstructor() {
321     // invokevirtual: java.lang.Class getDeclaredConstructor([Ljava.lang.Class)Ljava.lang.reflect.Constructor;
322
this.invoke(
323             OPC_invokevirtual,
324             1, // argCount
325
1, // return type size
326
ConstantPool.JavaLangClassConstantPoolName,
327             ConstantPool.GETDECLAREDCONSTRUCTOR_NAME,
328             ConstantPool.GETDECLAREDCONSTRUCTOR_SIGNATURE);
329 }
330 protected void invokeClassGetDeclaredField() {
331     // invokevirtual: java.lang.Class.getDeclaredField(Ljava.lang.String)Ljava.lang.reflect.Field;
332
this.invoke(
333             OPC_invokevirtual,
334             1, // argCount
335
1, // return type size
336
ConstantPool.JavaLangClassConstantPoolName,
337             ConstantPool.GETDECLAREDFIELD_NAME,
338             ConstantPool.GETDECLAREDFIELD_SIGNATURE);
339 }
340 protected void invokeClassGetDeclaredMethod() {
341     // invokevirtual: java.lang.Class getDeclaredMethod(Ljava.lang.String, [Ljava.lang.Class)Ljava.lang.reflect.Method;
342
this.invoke(
343             OPC_invokevirtual,
344             2, // argCount
345
1, // return type size
346
ConstantPool.JavaLangClassConstantPoolName,
347             ConstantPool.GETDECLAREDMETHOD_NAME,
348             ConstantPool.GETDECLAREDMETHOD_SIGNATURE);
349 }
350 protected void invokeJavaLangReflectConstructorNewInstance() {
351     // invokevirtual: java.lang.reflect.Constructor.newInstance([Ljava.lang.Object;)Ljava.lang.Object;
352
this.invoke(
353             OPC_invokevirtual,
354             1, // argCount
355
1, // return type size
356
ConstantPool.JavaLangReflectConstructor,
357             ConstantPool.NewInstance,
358             ConstantPool.JavaLangReflectConstructorNewInstanceSignature);
359 }
360 protected void invokeJavaLangReflectFieldGetter(int typeID) {
361     int returnTypeSize = 1;
362     char[] signature = null;
363     char[] selector = null;
364     switch (typeID) {
365         case T_int :
366             selector = ConstantPool.GET_INT_METHOD_NAME;
367             signature = ConstantPool.GET_INT_METHOD_SIGNATURE;
368             break;
369         case T_byte :
370             selector = ConstantPool.GET_BYTE_METHOD_NAME;
371             signature = ConstantPool.GET_BYTE_METHOD_SIGNATURE;
372             break;
373         case T_short :
374             selector = ConstantPool.GET_SHORT_METHOD_NAME;
375             signature = ConstantPool.GET_SHORT_METHOD_SIGNATURE;
376             break;
377         case T_long :
378             selector = ConstantPool.GET_LONG_METHOD_NAME;
379             signature = ConstantPool.GET_LONG_METHOD_SIGNATURE;
380             returnTypeSize = 2;
381             break;
382         case T_float :
383             selector = ConstantPool.GET_FLOAT_METHOD_NAME;
384             signature = ConstantPool.GET_FLOAT_METHOD_SIGNATURE;
385             break;
386         case T_double :
387             selector = ConstantPool.GET_DOUBLE_METHOD_NAME;
388             signature = ConstantPool.GET_DOUBLE_METHOD_SIGNATURE;
389             returnTypeSize = 2;
390             break;
391         case T_char :
392             selector = ConstantPool.GET_CHAR_METHOD_NAME;
393             signature = ConstantPool.GET_CHAR_METHOD_SIGNATURE;
394             break;
395         case T_boolean :
396             selector = ConstantPool.GET_BOOLEAN_METHOD_NAME;
397             signature = ConstantPool.GET_BOOLEAN_METHOD_SIGNATURE;
398             break;
399         default :
400             selector = ConstantPool.GET_OBJECT_METHOD_NAME;
401             signature = ConstantPool.GET_OBJECT_METHOD_SIGNATURE;
402             break;
403     }
404     this.invoke(
405             OPC_invokevirtual,
406             1, // argCount
407
returnTypeSize, // return type size
408
ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
409             selector,
410             signature);
411 }
412 protected void invokeJavaLangReflectFieldSetter(int typeID) {
413     int argCount = 2;
414     char[] signature = null;
415     char[] selector = null;
416     switch (typeID) {
417         case T_int :
418             selector = ConstantPool.SET_INT_METHOD_NAME;
419             signature = ConstantPool.SET_INT_METHOD_SIGNATURE;
420             break;
421         case T_byte :
422             selector = ConstantPool.SET_BYTE_METHOD_NAME;
423             signature = ConstantPool.SET_BYTE_METHOD_SIGNATURE;
424             break;
425         case T_short :
426             selector = ConstantPool.SET_SHORT_METHOD_NAME;
427             signature = ConstantPool.SET_SHORT_METHOD_SIGNATURE;
428             break;
429         case T_long :
430             selector = ConstantPool.SET_LONG_METHOD_NAME;
431             signature = ConstantPool.SET_LONG_METHOD_SIGNATURE;
432             argCount = 3;
433             break;
434         case T_float :
435             selector = ConstantPool.SET_FLOAT_METHOD_NAME;
436             signature = ConstantPool.SET_FLOAT_METHOD_SIGNATURE;
437             break;
438         case T_double :
439             selector = ConstantPool.SET_DOUBLE_METHOD_NAME;
440             signature = ConstantPool.SET_DOUBLE_METHOD_SIGNATURE;
441             argCount = 3;
442             break;
443         case T_char :
444             selector = ConstantPool.SET_CHAR_METHOD_NAME;
445             signature = ConstantPool.SET_CHAR_METHOD_SIGNATURE;
446             break;
447         case T_boolean :
448             selector = ConstantPool.SET_BOOLEAN_METHOD_NAME;
449             signature = ConstantPool.SET_BOOLEAN_METHOD_SIGNATURE;
450             break;
451         default :
452             selector = ConstantPool.SET_OBJECT_METHOD_NAME;
453             signature = ConstantPool.SET_OBJECT_METHOD_SIGNATURE;
454             break;
455     }
456     this.invoke(
457             OPC_invokevirtual,
458             argCount, // argCount
459
0, // return type size
460
ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
461             selector,
462             signature);
463 }
464 protected void invokeJavaLangReflectMethodInvoke() {
465     // invokevirtual: java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;
466
this.invoke(
467             OPC_invokevirtual,
468             2, // argCount
469
1, // return type size
470
ConstantPool.JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME,
471             ConstantPool.INVOKE_METHOD_METHOD_NAME,
472             ConstantPool.INVOKE_METHOD_METHOD_SIGNATURE);
473 }
474 private final void resizeByteArray() {
475     int length = bCodeStream.length;
476     int requiredSize = length + length;
477     if (classFileOffset > requiredSize) {
478         // must be sure to grow by enough
479
requiredSize = classFileOffset + length;
480     }
481     System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
482 }
483 }
484
Popular Tags