1 16 17 package org.cojen.classfile; 18 19 import java.io.InputStream ; 20 import java.io.IOException ; 21 import java.lang.reflect.Constructor ; 22 import java.lang.reflect.Method ; 23 import java.lang.reflect.Modifier ; 24 import java.util.MissingResourceException ; 25 26 31 public abstract class AbstractCodeAssembler implements CodeAssembler { 32 protected AbstractCodeAssembler() { 33 } 34 35 public void ifComparisonBranch(Location location, String 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 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 code) { 84 86 Class codeClass = code.getClass(); 87 String className = codeClass.getName().replace('.', '/') + ".class"; 88 ClassLoader loader = codeClass.getClassLoader(); 89 90 InputStream 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 ("Unable to find class file", className, null); 99 } 100 101 ClassFile cf; 102 try { 103 cf = ClassFile.readFrom(in); 104 } catch (IOException e) { 105 MissingResourceException e2 = new MissingResourceException 106 ("Error loading class file: " + e.getMessage(), className, null); 107 try { 108 e2.initCause(e); 109 } catch (NoSuchMethodError e3) { 110 } 111 throw e2; 112 } 113 114 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 ("Multiple define methods found"); 123 } else { 124 defineMethod = method; 125 } 126 } 127 } 128 129 if (defineMethod == null) { 130 throw new IllegalArgumentException ("No define method found"); 131 } 132 133 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 method) { 149 TypeDesc ret = TypeDesc.forClass(method.getReturnType()); 150 151 Class [] 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 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 method) { 178 TypeDesc ret = TypeDesc.forClass(method.getReturnType()); 179 180 Class [] 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 constructor) { 193 Class [] 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 |