1 21 22 package org.apache.derby.impl.services.bytecode; 23 24 import org.apache.derby.iapi.services.compiler.ClassBuilder; 25 import org.apache.derby.iapi.services.compiler.MethodBuilder; 26 import org.apache.derby.iapi.services.compiler.LocalField; 27 28 import org.apache.derby.iapi.services.classfile.ClassHolder; 29 import org.apache.derby.iapi.services.classfile.ClassMember; 30 import org.apache.derby.iapi.services.classfile.ClassFormatOutput; 31 import org.apache.derby.iapi.services.loader.ClassFactory; 32 33 import org.apache.derby.iapi.services.monitor.Monitor; 34 35 import org.apache.derby.iapi.error.StandardException; 36 import org.apache.derby.iapi.reference.Property; 37 import org.apache.derby.iapi.reference.SQLState; 38 39 import org.apache.derby.iapi.util.ByteArray; 40 import org.apache.derby.iapi.services.classfile.VMOpcode; 41 42 import java.lang.reflect.Modifier ; 43 44 import org.apache.derby.iapi.services.sanity.SanityManager; 45 import org.apache.derby.iapi.services.classfile.VMDescriptor; 46 47 import org.apache.derby.impl.services.bytecode.GClass; 48 49 import java.io.IOException ; 50 51 82 class BCClass extends GClass { 83 84 88 String limitMsg; 89 90 102 public LocalField addField(String javaType, String name, int modifiers) { 103 104 Type type = factory.type(javaType); 105 ClassMember field = classHold.addMember(name, type.vmName(), modifiers); 107 int cpi = classHold.addFieldReference(field); 108 109 return new BCLocalField(type, cpi); 110 } 111 112 117 public ByteArray getClassBytecode() throws StandardException { 118 119 if (bytecode != null) return bytecode; 121 122 try { 123 124 if (SanityManager.DEBUG) { 125 if (SanityManager.DEBUG_ON("ClassLineNumbers")) { 126 127 ClassFormatOutput sout = new ClassFormatOutput(2); 128 129 int cpiUTF = classHold.addUtf8("GC.java"); 130 131 sout.putU2(cpiUTF); 132 133 classHold.addAttribute("SourceFile", sout); 134 } 135 } 136 137 bytecode = classHold.getFileFormat(); 139 140 } catch (IOException ioe) { 141 throw StandardException.newException( 142 SQLState.GENERATED_CLASS_LINKAGE_ERROR, ioe, getFullName()); 143 } 144 145 classHold = null; 148 149 if (SanityManager.DEBUG) { 150 if (SanityManager.DEBUG_ON("DumpClassFile")) { 151 152 String systemHome = System.getProperty(Property.SYSTEM_HOME_PROPERTY,"."); 153 writeClassFile(systemHome,false,null); 154 } 155 } 156 157 if (SanityManager.DEBUG) { 158 if (SanityManager.DEBUG_ON("ByteCodeGenInstr")) { 159 SanityManager.DEBUG("ByteCodeGenInstr", 160 "GEN complete for class "+name); 161 } 162 } 163 164 if (limitMsg != null) 165 throw StandardException.newException( 166 SQLState.GENERATED_CLASS_LIMIT_EXCEEDED, getFullName(), limitMsg); 167 return bytecode; 168 } 169 170 171 174 public String getName() { 175 return name; 176 } 177 178 202 public MethodBuilder newMethodBuilder(int modifiers, String returnType, 203 String methodName) { 204 205 return newMethodBuilder(modifiers, returnType, 206 methodName, (String []) null); 207 208 } 209 210 211 237 public MethodBuilder newMethodBuilder(int modifiers, String returnType, 238 String methodName, String [] parms) { 239 240 if (SanityManager.DEBUG) { 241 SanityManager.ASSERT(returnType!=null); 242 } 243 244 BCMethod m = new BCMethod(this, 245 returnType, 246 methodName, 247 modifiers, 248 parms, 249 factory); 250 251 return m; 252 253 } 254 255 256 278 public MethodBuilder newConstructorBuilder(int modifiers) { 279 280 BCMethod m = new BCMethod(this, "void", "<init>", 281 modifiers, 282 (String []) null, 283 factory); 284 285 return m; 286 } 287 291 String getSuperClassName() { 292 return superClassName; 293 } 294 295 299 ClassHolder modify() { 300 return classHold; 301 } 302 303 306 307 BCClass(ClassFactory cf, String packageName, int classModifiers, 308 String className, String superClassName, 309 BCJava factory) { 310 311 super(cf, packageName.concat(className)); 312 313 if (SanityManager.DEBUG) { 314 if (SanityManager.DEBUG_ON("ByteCodeGenInstr")) { 315 SanityManager.DEBUG("ByteCodeGenInstr", 316 "GEN starting for class "+className); 317 } 318 } 319 320 327 name = className; 328 if (superClassName == null) 329 superClassName = "java.lang.Object"; 330 this.superClassName = superClassName; 331 332 classType = factory.type(getFullName()); 333 334 classHold = new ClassHolder(qualifiedName, factory.type(superClassName).vmNameSimple, classModifiers); 335 336 this.factory = factory; 337 } 338 339 protected ClassHolder classHold; 340 341 protected String superClassName; 342 protected String name; 343 344 BCJava factory; 345 final Type classType; 346 347 ClassFactory getClassFactory() { 348 return cf; 349 } 350 351 public void newFieldWithAccessors(String getter, String setter, 352 int methodModifers, 353 boolean staticField, String type) { 354 355 String vmType = factory.type(type).vmName(); 356 methodModifers |= Modifier.FINAL; 357 358 359 int fieldModifiers = Modifier.PRIVATE; 361 if (staticField) 362 fieldModifiers |= Modifier.STATIC; 363 364 ClassMember field = classHold.addMember(getter, vmType, fieldModifiers); 365 int cpi = classHold.addFieldReference(field); 366 367 370 371 String sig = BCMethodDescriptor.get(BCMethodDescriptor.EMPTY, vmType, factory); 372 373 ClassMember method = classHold.addMember(getter, sig, methodModifers); 374 375 CodeChunk chunk = new CodeChunk(this); 376 377 if (!staticField) 379 chunk.addInstr(VMOpcode.ALOAD_0); 381 chunk.addInstrU2((staticField ? VMOpcode.GETSTATIC : VMOpcode.GETFIELD), cpi); 383 384 short vmTypeId = BCJava.vmTypeId(vmType); 386 387 chunk.addInstr(CodeChunk.RETURN_OPCODE[vmTypeId]); 388 389 int typeWidth = Type.width(vmTypeId); 390 chunk.complete(null, classHold, method, typeWidth, 1); 391 392 395 String [] pda = new String [1]; 396 pda[0] = vmType; 397 sig = new BCMethodDescriptor(pda, VMDescriptor.VOID, factory).toString(); 398 method = classHold.addMember(setter, sig, methodModifers); 399 chunk = new CodeChunk(this); 400 401 if (!staticField) 403 chunk.addInstr(VMOpcode.ALOAD_0); chunk.addInstr((short) (CodeChunk.LOAD_VARIABLE_FAST[vmTypeId] + 1)); 406 407 chunk.addInstrU2((staticField ? VMOpcode.PUTSTATIC : VMOpcode.PUTFIELD), cpi); 409 410 chunk.addInstr(VMOpcode.RETURN); 411 412 chunk.complete(null, classHold, method, typeWidth + (staticField ? 0 : 1), 1 + typeWidth); 413 } 414 415 424 void addLimitExceeded(BCMethod mb, String limitName, int limit, int value) 425 { 426 StringBuffer sb = new StringBuffer (); 427 if (limitMsg != null) 428 { 429 sb.append(limitMsg); 430 sb.append(", "); 431 } 432 433 sb.append("method:"); 434 sb.append(mb.getName()); 435 sb.append(" "); 436 sb.append(limitName); 437 sb.append(" ("); 438 sb.append(value); 439 sb.append(" > "); 440 sb.append(limit); 441 sb.append(")"); 442 443 limitMsg = sb.toString(); 444 } 445 446 453 void addLimitExceeded(String rawText) 454 { 455 if (limitMsg != null) 456 { 457 limitMsg = limitMsg + ", " + rawText; 458 } 459 else 460 { 461 limitMsg = rawText; 462 } 463 } 464 465 } 466 | Popular Tags |