1 18 package org.objectweb.speedo.generation.enhancer; 19 20 import org.objectweb.asm.Attribute; 21 import org.objectweb.asm.ClassVisitor; 22 import org.objectweb.asm.CodeVisitor; 23 import org.objectweb.asm.Constants; 24 import org.objectweb.asm.Type; 25 import org.objectweb.speedo.generation.lib.NamingRules; 26 import org.objectweb.speedo.metadata.SpeedoClass; 27 import org.objectweb.speedo.metadata.SpeedoField; 28 import org.objectweb.speedo.metadata.SpeedoModifier; 29 import org.objectweb.util.monolog.api.BasicLevel; 30 import org.objectweb.util.monolog.api.Logger; 31 32 import java.util.Collection ; 33 import java.util.Iterator ; 34 35 40 public class ClassAccessorAdder extends LoggedClassAdapter { 41 42 45 private final SpeedoClass jdoClass; 46 47 50 private final Collection xmlDescriptors; 51 52 58 public ClassAccessorAdder(final ClassVisitor _cv, 59 final SpeedoClass _jdoClass, 60 final Collection _xmlDescriptors, 61 Logger _logger) { 62 super(_cv, _logger); 63 this.jdoClass = _jdoClass; 64 this.xmlDescriptors = _xmlDescriptors; 65 } 66 67 70 public void visit(final int version, 71 final int access, 72 final String name, 73 final String superName, 74 final String [] interfaces, 75 final String sourceFile) { 76 cv.visit(version, access, name, superName, interfaces, sourceFile); 77 78 Iterator i = jdoClass.jdoField.values().iterator(); 80 while (i.hasNext()) { 81 SpeedoField jdoField = (SpeedoField) i.next(); 82 if (jdoField.name == null) { 83 continue; 84 } 85 int acc = jdoField.access; 86 if (jdoField.persistenceModifier >= SpeedoModifier.transactional) { 87 if ((acc & Constants.ACC_STATIC) != 0) { 89 throw new RuntimeException ( 90 "A static field cannot be defined as persistent"); 91 } 92 genSetter(name, jdoField); 93 if (jdoField.persistenceModifier == SpeedoModifier.persistent) { 94 genGetter(name, jdoField); 95 } 96 } else if ((acc & 97 (Constants.ACC_TRANSIENT | Constants.ACC_FINAL)) != 0) { 98 genSetter(name, jdoField); 100 genGetter(name, jdoField); 101 } else if (jdoField.persistenceModifier == SpeedoModifier.missing) { 102 if (Util.isPersistentType(jdoField.desc, xmlDescriptors)) { 103 genSetter(name, jdoField); 105 genGetter(name, jdoField); 106 } 107 } 108 } 109 } 110 111 public CodeVisitor visitMethod(final int access, 112 final String name, 113 final String desc, 114 final String [] exceptions, 115 final Attribute attrs) { 116 return cv.visitMethod(access, name, desc, exceptions, attrs); 119 } 120 121 124 133 private void genGetter(final String owner, final SpeedoField jdoField) { 134 int flags = jdoField.access; 135 String gettername = 136 NamingRules.getterName(jdoField.jdoClass, jdoField.name); 137 if (debug) { 138 logger.log(BasicLevel.DEBUG, "Generate the getter method '" 139 + gettername + "' on the class '" + jdoField.jdoClass.name + "'"); 140 } 141 String desc = jdoField.desc; 142 CodeVisitor _cv = this.cv.visitMethod(flags, gettername, "()" + desc, null, null); 144 145 _cv.visitVarInsn(Constants.ALOAD, 0); 147 148 int idx = (jdoField.number / 64); 150 int arraysize = idx + 1; 151 Util.visitIntConstant(_cv, arraysize); 152 _cv.visitIntInsn(NEWARRAY, 11); 153 for(int i=0; i<idx; i++) { 154 _cv.visitInsn(DUP); 155 Util.visitIntConstant(_cv, i); 156 Util.visitLongConstant(_cv, 0); 157 _cv.visitInsn(LASTORE); 158 } 159 _cv.visitInsn(DUP); 160 Util.visitIntConstant(_cv, idx); 161 Util.visitLongConstant(_cv, 1L << (jdoField.number % 64)); 162 _cv.visitInsn(LASTORE); 163 164 _cv.visitMethodInsn( 166 Constants.INVOKEINTERFACE, 167 "org/objectweb/speedo/mim/api/SpeedoProxy", 168 "jdoReadIntention", 169 "(Lorg/objectweb/speedo/mim/api/SpeedoAccessor;[J)V"); 170 String fieldsOwner = NamingRules.fieldsName(owner); 172 _cv.visitVarInsn(Constants.ALOAD, 1); 173 _cv.visitTypeInsn(Constants.CHECKCAST, fieldsOwner); 174 _cv.visitFieldInsn(Constants.GETFIELD, fieldsOwner, jdoField.name, desc); 175 Type returnType = Type.getType(desc); 176 _cv.visitInsn(returnType.getOpcode(Constants.IRETURN)); 177 _cv.visitMaxs(0, 0); 178 } 179 180 186 private void genSetter(final String owner, final SpeedoField jdoField) { 187 int flags = jdoField.access; 188 String name = 189 NamingRules.setterName(jdoField.jdoClass, jdoField.name); 190 if (debug) { 191 logger.log(BasicLevel.DEBUG, "Generate the setter method '" 192 + name + "' on the class '" + jdoField.jdoClass.name + "'"); 193 } 194 String desc = jdoField.desc; 195 CodeVisitor _cv = 196 this.cv.visitMethod(flags, name, "(" + desc + ")V", null, null); 197 Type type = Type.getType(desc); 198 int params = type.getSize() + 1; 199 _cv.visitVarInsn(Constants.ALOAD, 0); 201 202 int idx = (jdoField.number / 64); 204 int arraysize = idx + 1; 205 Util.visitIntConstant(_cv, arraysize); 206 _cv.visitIntInsn(NEWARRAY, T_LONG); 207 for(int i=0; i<idx; i++) { 208 _cv.visitInsn(DUP); 209 Util.visitIntConstant(_cv, i); 210 Util.visitLongConstant(_cv, 0); 211 _cv.visitInsn(LASTORE); 212 } 213 _cv.visitInsn(DUP); 214 Util.visitIntConstant(_cv, idx); 215 Util.visitLongConstant(_cv, 1L << (jdoField.number % 64)); 216 _cv.visitInsn(LASTORE); 217 218 _cv.visitMethodInsn( 219 Constants.INVOKEINTERFACE, 220 "org/objectweb/speedo/mim/api/SpeedoProxy", 221 "jdoWriteIntention", 222 "[J)V"); 223 String fieldsOwner = NamingRules.fieldsName(owner); 225 _cv.visitVarInsn(Constants.ALOAD, params); 226 _cv.visitTypeInsn(Constants.CHECKCAST, fieldsOwner); 227 _cv.visitVarInsn(type.getOpcode(Constants.ILOAD), 1); 228 _cv.visitFieldInsn(Constants.PUTFIELD, fieldsOwner, jdoField.name, desc); 229 _cv.visitInsn(Constants.RETURN); 230 _cv.visitMaxs(0, 0); 231 } 232 } 233 | Popular Tags |