1 23 24 package org.objectweb.fractal.julia.asm; 25 26 import org.objectweb.fractal.api.control.AttributeController; 27 28 import org.objectweb.fractal.julia.control.attribute.CloneableAttributeController; 29 import org.objectweb.fractal.julia.loader.Tree; 30 31 import org.objectweb.asm.CodeVisitor; 32 import org.objectweb.asm.Label; 33 import org.objectweb.asm.Type; 34 35 import java.lang.reflect.Method ; 36 import java.util.ArrayList ; 37 import java.util.Arrays ; 38 import java.util.HashSet ; 39 import java.util.List ; 40 import java.util.Set ; 41 42 86 87 public class AttributeControllerClassGenerator extends AbstractClassGenerator { 88 89 92 93 private Set fields = new HashSet (); 94 95 99 100 private CodeVisitor imv; 101 102 106 107 private Label endLabel; 108 109 117 118 protected void parseArgs (final Tree args) { 119 superClass = "java/lang/Object"; 120 interfaces = new ArrayList (Arrays.asList(args.getSubTree(1).getSubTrees())); 121 for (int i = 0; i < interfaces.size(); ++i) { 122 interfaces.set(i, interfaces.get(i).toString().replace('.', '/')); 123 } 124 } 125 126 133 134 protected List getImplementedInterfaces () throws ClassGenerationException { 135 List itfs = super.getImplementedInterfaces(); 136 itfs.add(Type.getInternalName(CloneableAttributeController.class)); 137 return itfs; 138 } 139 140 146 147 protected void generateDefaultMethods () throws ClassGenerationException { 148 super.generateDefaultMethods(); 149 imv = cw.visitMethod( 150 ACC_PUBLIC, 151 "cloneFcAttributes", 152 "(" + Type.getDescriptor(AttributeController.class) + ")V", 153 null, 154 null); 155 } 156 157 163 164 protected void generateInterfaceMethods () throws ClassGenerationException { 165 super.generateInterfaceMethods(); 166 if (endLabel != null) { 167 imv.visitLabel(endLabel); 168 } 169 imv.visitInsn(RETURN); 170 imv.visitMaxs(3, 3); 171 } 172 173 182 183 protected void generateMethod (final Method m) { 184 String mName = m.getName(); 186 String mDesc = Type.getMethodDescriptor(m); 187 CodeVisitor mv = cw.visitMethod(ACC_PUBLIC, mName, mDesc, null, null); 188 String fieldName = mName.substring(3); 190 String iFieldName = "_" + fieldName; 191 Class fieldType; 192 if (mName.startsWith("get")) { 193 fieldType = m.getReturnType(); 194 } else { 195 fieldType = m.getParameterTypes()[0]; 196 } 197 String fieldDesc = Type.getDescriptor(fieldType); 198 if (!fields.contains(fieldName)) { 199 cw.visitField(ACC_PRIVATE, fieldName, fieldDesc, null, null); 200 cw.visitField(ACC_PRIVATE, iFieldName, "Z", null, null); 201 fields.add(fieldName); 202 } 203 if (mName.startsWith("get")) { 204 mv.visitVarInsn(ALOAD, 0); 206 mv.visitFieldInsn(GETFIELD, name, fieldName, fieldDesc); 207 mv.visitInsn(IRETURN + getOpcodeOffset(fieldType)); 208 } else { 209 mv.visitVarInsn(ALOAD, 0); 211 mv.visitVarInsn(ILOAD + getOpcodeOffset(fieldType), 1); 212 mv.visitFieldInsn(PUTFIELD, name, fieldName, fieldDesc); 213 mv.visitVarInsn(ALOAD, 0); 215 mv.visitInsn(ICONST_1); 216 mv.visitFieldInsn(PUTFIELD, name, iFieldName, "Z"); 217 mv.visitInsn(RETURN); 218 generateInitMethod(fieldName, fieldDesc, iFieldName, m); 220 } 221 mv.visitMaxs(Math.max(2, 1 + getSize(fieldType)), 1 + getSize(fieldType)); 222 } 223 224 236 237 private void generateInitMethod ( 238 final String fieldName, 239 final String fieldDesc, 240 final String iFieldName, 241 final Method m) 242 { 243 if (endLabel != null) { 244 imv.visitLabel(endLabel); 245 } 246 endLabel = new Label(); 247 String owner = Type.getInternalName(m.getDeclaringClass()); 248 String desc = Type.getMethodDescriptor(m); 249 imv.visitVarInsn(ALOAD, 0); 251 imv.visitFieldInsn(GETFIELD, name, iFieldName, "Z"); 252 imv.visitJumpInsn(IFEQ, endLabel); 253 imv.visitVarInsn(ALOAD, 1); 255 imv.visitTypeInsn(CHECKCAST, owner); 256 imv.visitVarInsn(ALOAD, 0); 258 imv.visitFieldInsn(GETFIELD, name, fieldName, fieldDesc); 259 imv.visitMethodInsn(INVOKEINTERFACE, owner, m.getName(), desc); 260 } 261 } 262 | Popular Tags |