KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > cojen > classfile > AbstractCodeAssembler


1 /*
2  * Copyright 2004 Brian S O'Neill
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.cojen.classfile;
18
19 import java.io.InputStream JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.util.MissingResourceException JavaDoc;
25
26 /**
27  *
28  *
29  * @author Brian S O'Neill
30  */

31 public abstract class AbstractCodeAssembler implements CodeAssembler {
32     protected AbstractCodeAssembler() {
33     }
34
35     public void ifComparisonBranch(Location location, String JavaDoc choice, TypeDesc type) {
36         boolean trueBranch = false;
37         int length = choice.length();
38         if (choice.charAt(length - 1) == 't') {
39             trueBranch = true;
40             choice = choice.substring(0, length - 1);
41         }
42
43         choice = choice.intern();
44
45         switch (type.getTypeCode()) {
46         default:
47             if (choice == "==") {
48                 ifEqualBranch(location, true);
49             } else if (choice == "!=") {
50                 ifEqualBranch(location, false);
51             } else {
52                 throw new IllegalArgumentException JavaDoc
53                     ("Comparison not allowed on object types: " + choice);
54             }
55             return;
56
57         case TypeDesc.BOOLEAN_CODE:
58         case TypeDesc.CHAR_CODE:
59         case TypeDesc.BYTE_CODE:
60         case TypeDesc.SHORT_CODE:
61         case TypeDesc.INT_CODE:
62             ifComparisonBranch(location, choice);
63             return;
64
65         case TypeDesc.LONG_CODE:
66             math(Opcode.LCMP);
67             break;
68
69         case TypeDesc.FLOAT_CODE:
70             math((choice == (trueBranch ? "<=" : ">") || choice == (trueBranch ? "<" : ">="))
71                  ? Opcode.FCMPG : Opcode.FCMPL);
72             break;
73
74         case TypeDesc.DOUBLE_CODE:
75             math((choice == (trueBranch ? "<=" : ">") || choice == (trueBranch ? "<" : ">="))
76                  ? Opcode.DCMPG : Opcode.DCMPL);
77             break;
78         }
79
80         ifZeroComparisonBranch(location, choice);
81     }
82
83     public void inline(Object JavaDoc code) {
84         // First load the class for the inlined code.
85

86         Class JavaDoc codeClass = code.getClass();
87         String JavaDoc className = codeClass.getName().replace('.', '/') + ".class";
88         ClassLoader JavaDoc loader = codeClass.getClassLoader();
89
90         InputStream JavaDoc in;
91         if (loader == null) {
92             in = ClassLoader.getSystemResourceAsStream(className);
93         } else {
94             in = loader.getResourceAsStream(className);
95         }
96
97         if (in == null) {
98             throw new MissingResourceException JavaDoc("Unable to find class file", className, null);
99         }
100
101         ClassFile cf;
102         try {
103             cf = ClassFile.readFrom(in);
104         } catch (IOException JavaDoc e) {
105             MissingResourceException JavaDoc e2 = new MissingResourceException JavaDoc
106                 ("Error loading class file: " + e.getMessage(), className, null);
107             try {
108                 e2.initCause(e);
109             } catch (NoSuchMethodError JavaDoc e3) {
110             }
111             throw e2;
112         }
113
114         // Now find the single "define" method.
115
MethodInfo defineMethod = null;
116
117         MethodInfo[] methods = cf.getMethods();
118         for (int i=0; i<methods.length; i++) {
119             MethodInfo method = methods[i];
120             if ("define".equals(method.getName())) {
121                 if (defineMethod != null) {
122                     throw new IllegalArgumentException JavaDoc("Multiple define methods found");
123                 } else {
124                     defineMethod = method;
125                 }
126             }
127         }
128
129         if (defineMethod == null) {
130             throw new IllegalArgumentException JavaDoc("No define method found");
131         }
132
133         // Copy stack arguments to expected local variables.
134
TypeDesc[] paramTypes = defineMethod.getMethodDescriptor().getParameterTypes();
135         LocalVariable[] paramVars = new LocalVariable[paramTypes.length];
136         for (int i=paramVars.length; --i>=0; ) {
137             LocalVariable paramVar = createLocalVariable(null, paramTypes[i]);
138             storeLocal(paramVar);
139             paramVars[i] = paramVar;
140         }
141
142         Label returnLocation = createLabel();
143         CodeDisassembler cd = new CodeDisassembler(defineMethod);
144         cd.disassemble(this, paramVars, returnLocation);
145         returnLocation.setLocation();
146     }
147
148     public void invoke(Method JavaDoc method) {
149         TypeDesc ret = TypeDesc.forClass(method.getReturnType());
150
151         Class JavaDoc[] paramClasses = method.getParameterTypes();
152         TypeDesc[] params = new TypeDesc[paramClasses.length];
153         for (int i=0; i<params.length; i++) {
154             params[i] = TypeDesc.forClass(paramClasses[i]);
155         }
156
157         Class JavaDoc clazz = method.getDeclaringClass();
158
159         if (Modifier.isStatic(method.getModifiers())) {
160             invokeStatic(clazz.getName(),
161                          method.getName(),
162                          ret,
163                          params);
164         } else if (clazz.isInterface()) {
165             invokeInterface(clazz.getName(),
166                             method.getName(),
167                             ret,
168                             params);
169         } else {
170             invokeVirtual(clazz.getName(),
171                           method.getName(),
172                           ret,
173                           params);
174         }
175     }
176
177     public void invokeSuper(Method JavaDoc method) {
178         TypeDesc ret = TypeDesc.forClass(method.getReturnType());
179
180         Class JavaDoc[] paramClasses = method.getParameterTypes();
181         TypeDesc[] params = new TypeDesc[paramClasses.length];
182         for (int i=0; i<params.length; i++) {
183             params[i] = TypeDesc.forClass(paramClasses[i]);
184         }
185
186         invokeSuper(method.getDeclaringClass().getName(),
187                     method.getName(),
188                     ret,
189                     params);
190     }
191
192     public void invoke(Constructor JavaDoc constructor) {
193         Class JavaDoc[] paramClasses = constructor.getParameterTypes();
194         TypeDesc[] params = new TypeDesc[paramClasses.length];
195         for (int i=0; i<params.length; i++) {
196             params[i] = TypeDesc.forClass(paramClasses[i]);
197         }
198
199         invokeConstructor(constructor.getDeclaringClass().getName().toString(), params);
200     }
201 }
202
Popular Tags