001 /* Copyright (c) 2005-2008, Torbjorn Ekman 002 * All rights reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * 1. Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 010 * 2. Redistributions in binary form must reproduce the above copyright notice, 011 * this list of conditions and the following disclaimer in the documentation 012 * and/or other materials provided with the distribution. 013 * 014 * 3. Neither the name of the copyright holder nor the names of its 015 * contributors may be used to endorse or promote products derived from this 016 * software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 * POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031 aspect CodeGeneration { 032 033 public void ASTNode.setSourceLineNumber(int i) { 034 setStart(ASTNode.makePosition(i, 1)); 035 } 036 037 syn int ASTNode.sourceLineNumber() = getStart() != 0 ? getLine(getStart()) : -1; 038 eq ReturnStmt.sourceLineNumber() { 039 int num = super.sourceLineNumber(); 040 if (num != -1) { 041 return num; 042 } 043 if (hasResult()) { 044 num = getResult().findFirstSourceLineNumber(); 045 if (num != -1) { 046 return num; 047 } 048 } 049 return getLine(getParent().getParent().getEnd()); 050 } 051 eq ExprStmt.sourceLineNumber() = getExpr().findFirstSourceLineNumber(); 052 eq Access.sourceLineNumber() = findFirstSourceLineNumber(); 053 054 protected int ASTNode.findFirstSourceLineNumber() { 055 if (getStart() != 0) { 056 return getLine(getStart()); 057 } 058 for (int i = 0; i < getNumChild(); i++) { 059 int num = getChild(i).findFirstSourceLineNumber(); 060 if (num != -1) { 061 return num; 062 } 063 } 064 return -1; 065 } 066 067 inh int VariableDeclaration.variableScopeEndLabel(CodeGeneration gen); 068 syn lazy int Block.variableScopeEndLabel(CodeGeneration gen) = gen.variableScopeLabel(); 069 eq Block.getStmt(int i).variableScopeEndLabel(CodeGeneration gen) = variableScopeEndLabel(gen); 070 syn lazy int ForStmt.variableScopeEndLabel(CodeGeneration gen) = gen.variableScopeLabel(); 071 eq ForStmt.getInitStmt(int i).variableScopeEndLabel(CodeGeneration gen) = variableScopeEndLabel(gen); 072 eq Program.getChild(int i).variableScopeEndLabel(CodeGeneration gen) { 073 throw new Error("variableScopeEndLabel not valid from here"); 074 } 075 076 /************************************************************* 077 * Emit methods 078 *************************************************************/ 079 080 // push constants 081 082 public static void IntegerLiteral.push(CodeGeneration gen, int value) { 083 switch(value) { 084 case -1: 085 gen.emit(Bytecode.ICONST_M1); 086 break; 087 case 0: 088 gen.emit(Bytecode.ICONST_0); 089 break; 090 case 1: 091 gen.emit(Bytecode.ICONST_1); 092 break; 093 case 2: 094 gen.emit(Bytecode.ICONST_2); 095 break; 096 case 3: 097 gen.emit(Bytecode.ICONST_3); 098 break; 099 case 4: 100 gen.emit(Bytecode.ICONST_4); 101 break; 102 case 5: 103 gen.emit(Bytecode.ICONST_5); 104 break; 105 default: 106 if (value >= -128 && value <= 127) { 107 gen.emit(Bytecode.BIPUSH).add(value); 108 } else if (value >= -32768 && value <= 32767) { 109 gen.emit(Bytecode.SIPUSH).add2(value); 110 } else { 111 int index = gen.constantPool().addConstant(value); 112 if (index < 256) { 113 gen.emit(Bytecode.LDC).add(index); 114 } else { 115 gen.emit(Bytecode.LDC_W).add2(index); 116 } 117 } 118 } 119 } 120 public static void LongLiteral.push(CodeGeneration gen, long value) { 121 if (value == 0) { 122 gen.emit(Bytecode.LCONST_0); 123 } else if (value == 1) { 124 gen.emit(Bytecode.LCONST_1); 125 } else { 126 int index = gen.constantPool().addConstant(value); 127 gen.emit(Bytecode.LDC2_W).add2(index); 128 } 129 } 130 public static void DoubleLiteral.push(CodeGeneration gen, double value) { 131 if (value == 0) { 132 gen.emit(Bytecode.DCONST_0); 133 } else if (value == 1) { 134 gen.emit(Bytecode.DCONST_1); 135 } else { 136 int index = gen.constantPool().addConstant(value); 137 gen.emit(Bytecode.LDC2_W).add2(index); 138 } 139 } 140 public static void FloatingPointLiteral.push(CodeGeneration gen, float value) { 141 if (value == 0) { 142 gen.emit(Bytecode.FCONST_0); 143 } else if (value == 1) { 144 gen.emit(Bytecode.FCONST_1); 145 } else if (value == 2) { 146 gen.emit(Bytecode.FCONST_2); 147 } else { 148 int index = gen.constantPool().addConstant(value); 149 if (index < 256) { 150 gen.emit(Bytecode.LDC).add(index); 151 } else { 152 gen.emit(Bytecode.LDC_W).add2(index); 153 } 154 } 155 } 156 public static void StringLiteral.push(CodeGeneration gen, String value) { 157 int index = gen.constantPool().addConstant(value); 158 if (index < 256) { 159 gen.emit(Bytecode.LDC).add(index); 160 } else { 161 gen.emit(Bytecode.LDC_W).add2(index); 162 } 163 } 164 165 public static void BooleanLiteral.push(CodeGeneration gen, boolean value) { 166 gen.emit(value ? Bytecode.ICONST_1 : Bytecode.ICONST_0); 167 } 168 169 public void TypeDecl.emitPushConstant(CodeGeneration gen, int value) { } 170 public void IntegralType.emitPushConstant(CodeGeneration gen, int value) { IntegerLiteral.push(gen, value); } 171 public void LongType.emitPushConstant(CodeGeneration gen, int value) { LongLiteral.push(gen, value); } 172 public void DoubleType.emitPushConstant(CodeGeneration gen, int value) { DoubleLiteral.push(gen, value); } 173 public void FloatType.emitPushConstant(CodeGeneration gen, int value) { FloatingPointLiteral.push(gen, value); } 174 175 // push literals 176 177 public void Literal.emitPushConstant(CodeGeneration gen) { 178 System.err.println("ERROR: Tried to generate bytecode for: " + getClass().getName()); 179 } 180 181 public void IntegerLiteral.emitPushConstant(CodeGeneration gen) { 182 type().emitPushConstant(gen, constant().intValue()); 183 } 184 185 public void CharacterLiteral.emitPushConstant(CodeGeneration gen) { 186 type().emitPushConstant(gen, constant().intValue()); 187 } 188 189 public void FloatingPointLiteral.emitPushConstant(CodeGeneration gen) { 190 FloatingPointLiteral.push(gen, constant().floatValue()); 191 } 192 193 public void LongLiteral.emitPushConstant(CodeGeneration gen) { 194 LongLiteral.push(gen, constant().longValue()); 195 } 196 197 public void DoubleLiteral.emitPushConstant(CodeGeneration gen) { 198 DoubleLiteral.push(gen, constant().doubleValue()); 199 } 200 201 public void StringLiteral.emitPushConstant(CodeGeneration gen) { 202 StringLiteral.push(gen, getLITERAL()); 203 } 204 205 public void NullLiteral.emitPushConstant(CodeGeneration gen) { 206 gen.emit(Bytecode.ACONST_NULL); 207 } 208 209 public void BooleanLiteral.emitPushConstant(CodeGeneration gen) { 210 BooleanLiteral.push(gen, constant().booleanValue()); 211 } 212 213 public void ASTNode.error() { 214 Throwable t = new Throwable(); 215 StackTraceElement[] ste = new Throwable().getStackTrace(); 216 String s = ste[1].toString(); 217 throw new Error(s+" Cannot create bytecode for:"+getClass().getName()); 218 } 219 220 public void Constant.createBCode(CodeGeneration gen) { 221 if (this instanceof ConstantInt) { 222 IntegerLiteral.push(gen, intValue()); 223 } else if (this instanceof ConstantLong) { 224 LongLiteral.push(gen, longValue()); 225 } else if (this instanceof ConstantFloat) { 226 FloatingPointLiteral.push(gen, floatValue()); 227 } else if (this instanceof ConstantDouble) { 228 DoubleLiteral.push(gen, doubleValue()); 229 } else if (this instanceof ConstantChar) { 230 IntegerLiteral.push(gen, intValue()); 231 } else if (this instanceof ConstantBoolean) { 232 BooleanLiteral.push(gen, booleanValue()); 233 } else if (this instanceof ConstantString) { 234 StringLiteral.push(gen, stringValue()); 235 } 236 } 237 238 // return 239 240 public void TypeDecl.emitReturn(CodeGeneration gen) { error(); } 241 public void VoidType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.RETURN);} 242 public void PrimitiveType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.IRETURN);} 243 public void LongType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.LRETURN);} 244 public void FloatType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.FRETURN);} 245 public void DoubleType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.DRETURN);} 246 public void ReferenceType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.ARETURN);} 247 public void NullType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.ARETURN);} 248 249 syn byte TypeDecl.arrayLoad() { 250 throw new Error("Cannot create array load for TypeDecl"); 251 } 252 eq ReferenceType.arrayLoad() = Bytecode.AALOAD; 253 eq IntType.arrayLoad() = Bytecode.IALOAD; 254 eq LongType.arrayLoad() = Bytecode.LALOAD; 255 eq FloatType.arrayLoad() = Bytecode.FALOAD; 256 eq DoubleType.arrayLoad() = Bytecode.DALOAD; 257 eq ByteType.arrayLoad() = Bytecode.BALOAD; 258 eq CharType.arrayLoad() = Bytecode.CALOAD; 259 eq ShortType.arrayLoad() = Bytecode.SALOAD; 260 eq BooleanType.arrayLoad() = Bytecode.BALOAD; 261 262 public void TypeDecl.emitLoadLocal(CodeGeneration gen, int pos) {error();} 263 public void PrimitiveType.emitLoadLocal(CodeGeneration gen, int pos) { 264 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 265 if (pos == 0) { 266 gen.emit(Bytecode.ILOAD_0); 267 } else if (pos == 1) { 268 gen.emit(Bytecode.ILOAD_1); 269 } else if (pos == 2) { 270 gen.emit(Bytecode.ILOAD_2); 271 } else if (pos == 3) { 272 gen.emit(Bytecode.ILOAD_3); 273 } else if (pos < 256) { 274 gen.emit(Bytecode.ILOAD).add(pos); 275 } else { 276 gen.emit(Bytecode.WIDE).emit(Bytecode.ILOAD).add2(pos); 277 } 278 } 279 public void LongType.emitLoadLocal(CodeGeneration gen, int pos) { 280 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 281 if (pos == 0) { 282 gen.emit(Bytecode.LLOAD_0); 283 } else if (pos == 1) { 284 gen.emit(Bytecode.LLOAD_1); 285 } else if (pos == 2) { 286 gen.emit(Bytecode.LLOAD_2); 287 } else if (pos == 3) { 288 gen.emit(Bytecode.LLOAD_3); 289 } else if (pos < 256) { 290 gen.emit(Bytecode.LLOAD).add(pos); 291 } else { 292 gen.emit(Bytecode.WIDE).emit(Bytecode.LLOAD).add2(pos); 293 } 294 } 295 public void FloatType.emitLoadLocal(CodeGeneration gen, int pos) { 296 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 297 if (pos == 0) { 298 gen.emit(Bytecode.FLOAD_0); 299 } else if (pos == 1) { 300 gen.emit(Bytecode.FLOAD_1); 301 } else if (pos == 2) { 302 gen.emit(Bytecode.FLOAD_2); 303 } else if (pos == 3) { 304 gen.emit(Bytecode.FLOAD_3); 305 } else if (pos < 256) { 306 gen.emit(Bytecode.FLOAD).add(pos); 307 } else { 308 gen.emit(Bytecode.WIDE).emit(Bytecode.FLOAD).add2(pos); 309 } 310 } 311 public void DoubleType.emitLoadLocal(CodeGeneration gen, int pos) { 312 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 313 if (pos == 0) { 314 gen.emit(Bytecode.DLOAD_0); 315 } else if (pos == 1) { 316 gen.emit(Bytecode.DLOAD_1); 317 } else if (pos == 2) { 318 gen.emit(Bytecode.DLOAD_2); 319 } else if (pos == 3) { 320 gen.emit(Bytecode.DLOAD_3); 321 } else if (pos < 256) { 322 gen.emit(Bytecode.DLOAD).add(pos); 323 } else { 324 gen.emit(Bytecode.WIDE).emit(Bytecode.DLOAD).add2(pos); 325 } 326 } 327 public void ReferenceType.emitLoadLocal(CodeGeneration gen, int pos) { 328 gen.emitLoadReference(pos); 329 } 330 public void NullType.emitLoadLocal(CodeGeneration gen, int pos) { 331 gen.emitLoadReference(pos); 332 } 333 334 public void FieldDeclaration.emitLoadField(CodeGeneration gen, TypeDecl typeDecl) { 335 if (hostType().isArrayDecl() && name().equals("length")) { 336 gen.emit(Bytecode.ARRAYLENGTH); 337 return; 338 } 339 String classname = typeDecl.constantPoolName(); 340 String desc = type().typeDescriptor(); 341 String name = name(); 342 int index = gen.constantPool().addFieldref(classname, name, desc); 343 if (isStatic()) { 344 gen.emit(Bytecode.GETSTATIC, type().variableSize()).add2(index); 345 } else { 346 gen.emit(Bytecode.GETFIELD, type().variableSize() - 1).add2(index); 347 } 348 } 349 350 351 // emit store 352 353 public void Expr.emitStore(CodeGeneration gen) { error("emitStore called with " + getClass().getName()); } 354 public void AbstractDot.emitStore(CodeGeneration gen) { lastAccess().emitStore(gen); } 355 356 public void VarAccess.emitStore(CodeGeneration gen) { 357 Variable v = decl(); 358 if (v instanceof VariableDeclaration) { 359 VariableDeclaration decl = (VariableDeclaration) v; 360 if (isDUbefore(v)) { 361 gen.addLocalVariableEntryAtCurrentPC(decl.name(), decl.type().typeDescriptor(), decl.localNum(), decl.variableScopeEndLabel(gen)); 362 } 363 decl.type().emitStoreLocal(gen, decl.localNum()); 364 } else if (v instanceof ParameterDeclaration) { 365 ParameterDeclaration decl = (ParameterDeclaration) v; 366 decl.type().emitStoreLocal(gen, decl.localNum()); 367 } else if (v instanceof FieldDeclaration) { 368 FieldDeclaration f = (FieldDeclaration) v; 369 if (f.isPrivate() && !hostType().hasField(v.name())) { 370 f.createAccessorWrite(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType()); 371 } else { 372 f.emitStoreField(gen, fieldQualifierType()); 373 } 374 } 375 } 376 377 public void ArrayAccess.emitStore(CodeGeneration gen) { 378 gen.emit(type().arrayStore()); 379 } 380 syn byte TypeDecl.arrayStore() { 381 throw new Error("Cannot create array load for TypeDecl"); 382 } 383 eq ReferenceType.arrayStore() = Bytecode.AASTORE; 384 eq IntType.arrayStore() = Bytecode.IASTORE; 385 eq LongType.arrayStore() = Bytecode.LASTORE; 386 eq FloatType.arrayStore() = Bytecode.FASTORE; 387 eq DoubleType.arrayStore() = Bytecode.DASTORE; 388 eq ByteType.arrayStore() = Bytecode.BASTORE; 389 eq CharType.arrayStore() = Bytecode.CASTORE; 390 eq ShortType.arrayStore() = Bytecode.SASTORE; 391 eq BooleanType.arrayStore() = Bytecode.BASTORE; 392 393 public void FieldDeclaration.emitStoreField(CodeGeneration gen, TypeDecl typeDecl) { 394 String classname = typeDecl.constantPoolName(); 395 String desc = type().typeDescriptor(); 396 String name = name(); 397 int index = gen.constantPool().addFieldref(classname, name, desc); 398 if (isStatic()) { 399 gen.emit(Bytecode.PUTSTATIC, -type().variableSize()).add2(index); 400 } else { 401 gen.emit(Bytecode.PUTFIELD, -type().variableSize() - 1).add2(index); 402 } 403 } 404 405 public void TypeDecl.emitStoreLocal(CodeGeneration gen, int pos) {error();} 406 public void PrimitiveType.emitStoreLocal(CodeGeneration gen, int pos) { 407 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 408 if (pos == 0) { 409 gen.emit(Bytecode.ISTORE_0); 410 } else if (pos == 1) { 411 gen.emit(Bytecode.ISTORE_1); 412 } else if (pos == 2) { 413 gen.emit(Bytecode.ISTORE_2); 414 } else if (pos == 3) { 415 gen.emit(Bytecode.ISTORE_3); 416 } else if (pos < 256) { 417 gen.emit(Bytecode.ISTORE).add(pos); 418 } else { 419 gen.emit(Bytecode.WIDE).emit(Bytecode.ISTORE).add2(pos); 420 } 421 } 422 public void LongType.emitStoreLocal(CodeGeneration gen, int pos) { 423 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 424 if (pos == 0) { 425 gen.emit(Bytecode.LSTORE_0); 426 } else if (pos == 1) { 427 gen.emit(Bytecode.LSTORE_1); 428 } else if (pos == 2) { 429 gen.emit(Bytecode.LSTORE_2); 430 } else if (pos == 3) { 431 gen.emit(Bytecode.LSTORE_3); 432 } else if (pos < 256) { 433 gen.emit(Bytecode.LSTORE).add(pos); 434 } else { 435 gen.emit(Bytecode.WIDE).emit(Bytecode.LSTORE).add2(pos); 436 } 437 } 438 public void FloatType.emitStoreLocal(CodeGeneration gen, int pos) { 439 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 440 if (pos == 0) { 441 gen.emit(Bytecode.FSTORE_0); 442 } else if (pos == 1) { 443 gen.emit(Bytecode.FSTORE_1); 444 } else if (pos == 2) { 445 gen.emit(Bytecode.FSTORE_2); 446 } else if (pos == 3) { 447 gen.emit(Bytecode.FSTORE_3); 448 } else if (pos < 256) { 449 gen.emit(Bytecode.FSTORE).add(pos); 450 } else { 451 gen.emit(Bytecode.WIDE).emit(Bytecode.FSTORE).add2(pos); 452 } 453 } 454 public void DoubleType.emitStoreLocal(CodeGeneration gen, int pos) { 455 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 456 if (pos == 0) { 457 gen.emit(Bytecode.DSTORE_0); 458 } else if (pos == 1) { 459 gen.emit(Bytecode.DSTORE_1); 460 } else if (pos == 2) { 461 gen.emit(Bytecode.DSTORE_2); 462 } else if (pos == 3) { 463 gen.emit(Bytecode.DSTORE_3); 464 } else if (pos < 256) { 465 gen.emit(Bytecode.DSTORE).add(pos); 466 } else { 467 gen.emit(Bytecode.WIDE).emit(Bytecode.DSTORE).add2(pos); 468 } 469 } 470 public void ReferenceType.emitStoreLocal(CodeGeneration gen, int pos) { 471 gen.emitStoreReference(pos); 472 } 473 public void NullType.emitStoreLocal(CodeGeneration gen, int pos) { 474 gen.emitStoreReference(pos); 475 } 476 477 // exceptions 478 479 inh TypeDecl TryStmt.typeThrowable(); 480 481 public void TypeDecl.emitDup(CodeGeneration gen) { gen.emit(Bytecode.DUP); } 482 public void VoidType.emitDup(CodeGeneration gen) { } 483 public void DoubleType.emitDup(CodeGeneration gen) { gen.emit(Bytecode.DUP2); } 484 public void LongType.emitDup(CodeGeneration gen) { gen.emit(Bytecode.DUP2); } 485 486 public void TypeDecl.emitDup_x1(CodeGeneration gen) { gen.emit(Bytecode.DUP_X1); } 487 public void VoidType.emitDup_x1(CodeGeneration gen) { } 488 public void DoubleType.emitDup_x1(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X1); } 489 public void LongType.emitDup_x1(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X1); } 490 491 public void TypeDecl.emitDup_x2(CodeGeneration gen) { gen.emit(Bytecode.DUP_X2); } 492 public void VoidType.emitDup_x2(CodeGeneration gen) { } 493 public void DoubleType.emitDup_x2(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X2); } 494 public void LongType.emitDup_x2(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X2); } 495 496 public void TypeDecl.emitPop(CodeGeneration gen) { gen.emit(Bytecode.POP); } 497 public void VoidType.emitPop(CodeGeneration gen) { } 498 public void DoubleType.emitPop(CodeGeneration gen) { gen.emit(Bytecode.POP2); } 499 public void LongType.emitPop(CodeGeneration gen) { gen.emit(Bytecode.POP2); } 500 501 502 // emitInvoke 503 504 public void MethodDecl.emitInvokeMethod(CodeGeneration gen, TypeDecl hostType) { 505 if (hostType.isInterfaceDecl()) { 506 String classname = hostType.constantPoolName(); 507 String desc = descName(); 508 String name = name(); 509 int index = gen.constantPool().addInterfaceMethodref(classname, name, desc); 510 int numArg = 1; // instance 511 for (int i = 0; i < getNumParameter(); i++) { 512 numArg += getParameter(i).type().variableSize(); 513 } 514 int stackChange = type().variableSize() - numArg; 515 gen.emit(Bytecode.INVOKEINTERFACE, stackChange) 516 .add2(index).add(numArg).add(0); 517 } else { 518 String classname = hostType.constantPoolName(); 519 String desc = descName(); 520 String name = name(); 521 int index = gen.constantPool().addMethodref(classname, name, desc); 522 int stackChange = type().variableSize(); 523 for (int i = 0; i < getNumParameter(); i++) { 524 stackChange -= getParameter(i).type().variableSize(); 525 } 526 if (isStatic()) { 527 gen.emit(Bytecode.INVOKESTATIC, stackChange).add2(index); 528 } else { 529 stackChange -= 1; 530 gen.emit(Bytecode.INVOKEVIRTUAL, stackChange).add2(index); 531 } 532 } 533 } 534 535 public void MethodDecl.emitInvokeSpecialMethod(CodeGeneration gen, TypeDecl hostType) { 536 String classname = hostType.constantPoolName(); 537 String desc = descName(); 538 String name = name(); 539 int index = gen.constantPool().addMethodref(classname, name, desc); 540 int stackChange = type().variableSize() - 1; 541 for (int i = 0; i < getNumParameter(); i++) { 542 stackChange -= getParameter(i).type().variableSize(); 543 } 544 gen.emit(Bytecode.INVOKESPECIAL, stackChange).add2(index); 545 } 546 547 public void ConstructorDecl.emitInvokeConstructor(CodeGeneration gen) { 548 int stackChange = -1; 549 for (int i = 0; i < getNumParameter(); i++) { 550 stackChange -= getParameter(i).type().variableSize(); 551 } 552 if (hostType().needsEnclosing()) { 553 stackChange -= 1; 554 } 555 if (hostType().needsSuperEnclosing()) { 556 stackChange -= 1; 557 } 558 String classname = hostType().constantPoolName(); 559 String desc = descName(); 560 String name = "<init>"; 561 int index = gen.constantPool().addMethodref(classname, name, desc); 562 gen.emit(Bytecode.INVOKESPECIAL, stackChange).add2(index); 563 } 564 565 // emitNew 566 567 public void TypeDecl.emitNew(CodeGeneration gen) { 568 int index = gen.constantPool().addClass(constantPoolName()); 569 gen.emit(Bytecode.NEW).add2(index); 570 } 571 } 572 aspect CodeGenerationConversions { 573 void TypeDecl.emitAssignConvTo(CodeGeneration gen, TypeDecl type) { 574 if (!type.isIntegralType() || !isIntegralType() || type.isLong()) { 575 emitCastTo(gen, type); 576 } 577 } 578 579 void TypeDecl.emitCastTo(CodeGeneration gen, TypeDecl type) { throw new Error("CastTo not implemented for " + getClass().getName()); } 580 void ReferenceType.emitCastTo(CodeGeneration gen, TypeDecl type) { if (!instanceOf(type) && !type.isNull()) gen.emitCheckCast(type); } 581 void IntType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.intToThis(gen); } 582 void FloatType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.floatToThis(gen); } 583 void DoubleType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.doubleToThis(gen); } 584 void LongType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.longToThis(gen); } 585 void ByteType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.byteToThis(gen); } 586 void ShortType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.shortToThis(gen); } 587 void CharType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.charToThis(gen); } 588 void BooleanType.emitCastTo(CodeGeneration gen, TypeDecl type) { } 589 void NullType.emitCastTo(CodeGeneration gen, TypeDecl type) { } 590 591 void TypeDecl.intToThis(CodeGeneration gen) { throw new Error("intToThis not implemented for " + getClass().getName()); } 592 void IntType.intToThis(CodeGeneration gen) { } 593 void LongType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 594 void FloatType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 595 void DoubleType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D); } 596 void ByteType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2B); } 597 void CharType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2C); } 598 void ShortType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2S); } 599 600 void TypeDecl.floatToThis(CodeGeneration gen) { throw new Error("floatToThis not implemented for " + getClass().getName()); } 601 void IntType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I); } 602 void ByteType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I).emit(Bytecode.I2B); } 603 void ShortType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I).emit(Bytecode.I2S); } 604 void CharType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I).emit(Bytecode.I2C); } 605 void FloatType.floatToThis(CodeGeneration gen) { } 606 void LongType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2L); } 607 void DoubleType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2D); } 608 609 void TypeDecl.doubleToThis(CodeGeneration gen) { throw new Error("doubleToThis not implemented for " + getClass().getName()); } 610 void IntType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I); } 611 void ByteType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I).emit(Bytecode.I2B); } 612 void ShortType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I).emit(Bytecode.I2S); } 613 void CharType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I).emit(Bytecode.I2C); } 614 void FloatType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2F); } 615 void LongType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2L); } 616 void DoubleType.doubleToThis(CodeGeneration gen) { } 617 618 void TypeDecl.longToThis(CodeGeneration gen) { throw new Error("longToThis not implemented for " + getClass().getName()); } 619 void IntType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I); } 620 void ByteType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I).emit(Bytecode.I2B); } 621 void ShortType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I).emit(Bytecode.I2S); } 622 void CharType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I).emit(Bytecode.I2C); } 623 void FloatType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2F); } 624 void LongType.longToThis(CodeGeneration gen) { } 625 void DoubleType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2D); } 626 627 void TypeDecl.byteToThis(CodeGeneration gen) { throw new Error("byteToThis not implemented for " + getClass().getName()); } 628 void IntegralType.byteToThis(CodeGeneration gen) { } 629 void CharType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2C); } 630 void FloatType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 631 void LongType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 632 void DoubleType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D);} 633 634 void TypeDecl.charToThis(CodeGeneration gen) { throw new Error("charToThis not implemented for " + getClass().getName()); } 635 void IntegralType.charToThis(CodeGeneration gen) { } 636 void ByteType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2B); } 637 void ShortType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2S); } 638 void FloatType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 639 void LongType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 640 void DoubleType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D);} 641 642 void TypeDecl.shortToThis(CodeGeneration gen) { throw new Error("shortToThis not implemented for " + getClass().getName()); } 643 void IntegralType.shortToThis(CodeGeneration gen) { } 644 void ByteType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2B); } 645 void CharType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2C); } 646 void FloatType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 647 void LongType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 648 void DoubleType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D); } 649 650 } 651 652 aspect CodeGenerationBinaryOperations { 653 // emit the desired operation on the operand(s) on the stack 654 void Expr.emitOperation(CodeGeneration gen) {error();} 655 // unary 656 void MinusExpr.emitOperation(CodeGeneration gen) { type().neg(gen); } 657 void PlusExpr.emitOperation(CodeGeneration gen) { } 658 void BitNotExpr.emitOperation(CodeGeneration gen) { type().bitNot(gen); } 659 void LogNotExpr.emitOperation(CodeGeneration gen) { type().logNot(gen); } 660 661 // binary 662 void AddExpr.emitOperation(CodeGeneration gen) { type().add(gen); } 663 void SubExpr.emitOperation(CodeGeneration gen) { type().sub(gen); } 664 void MulExpr.emitOperation(CodeGeneration gen) { type().mul(gen); } 665 void DivExpr.emitOperation(CodeGeneration gen) { type().div(gen); } 666 void ModExpr.emitOperation(CodeGeneration gen) { type().rem(gen); } 667 668 void LShiftExpr.emitOperation(CodeGeneration gen) { type().shl(gen); } 669 void RShiftExpr.emitOperation(CodeGeneration gen) { type().shr(gen); } 670 void URShiftExpr.emitOperation(CodeGeneration gen) { type().ushr(gen); } 671 void OrBitwiseExpr.emitOperation(CodeGeneration gen) { type().bitor(gen); } 672 void AndBitwiseExpr.emitOperation(CodeGeneration gen) { type().bitand(gen); } 673 void XorBitwiseExpr.emitOperation(CodeGeneration gen) { type().bitxor(gen); } 674 675 void TypeDecl.neg(CodeGeneration gen) { error(); } 676 void IntegralType.neg(CodeGeneration gen) { gen.emit(Bytecode.INEG); } 677 void LongType.neg(CodeGeneration gen) { gen.emit(Bytecode.LNEG); } 678 void FloatType.neg(CodeGeneration gen) { gen.emit(Bytecode.FNEG); } 679 void DoubleType.neg(CodeGeneration gen) { gen.emit(Bytecode.DNEG); } 680 681 void TypeDecl.bitNot(CodeGeneration gen) { error(); } 682 void IntegralType.bitNot(CodeGeneration gen) { gen.emit(Bytecode.ICONST_M1).emit(Bytecode.IXOR); } 683 void LongType.bitNot(CodeGeneration gen) { emitPushConstant(gen, -1); gen.emit(Bytecode.LXOR); } 684 685 void TypeDecl.logNot(CodeGeneration gen) { error();} 686 void BooleanType.logNot(CodeGeneration gen) { gen.emit(Bytecode.ICONST_1).emit(Bytecode.IXOR); } 687 688 void TypeDecl.add(CodeGeneration gen) {error();} 689 void LongType.add(CodeGeneration gen) {gen.emit(Bytecode.LADD);} 690 void FloatType.add(CodeGeneration gen) {gen.emit(Bytecode.FADD);} 691 void DoubleType.add(CodeGeneration gen) {gen.emit(Bytecode.DADD);} 692 void IntegralType.add(CodeGeneration gen) {gen.emit(Bytecode.IADD);} 693 694 void TypeDecl.sub(CodeGeneration gen) {error();} 695 void LongType.sub(CodeGeneration gen) {gen.emit(Bytecode.LSUB);} 696 void FloatType.sub(CodeGeneration gen) {gen.emit(Bytecode.FSUB);} 697 void DoubleType.sub(CodeGeneration gen) {gen.emit(Bytecode.DSUB);} 698 void IntegralType.sub(CodeGeneration gen) {gen.emit(Bytecode.ISUB);} 699 700 void TypeDecl.mul(CodeGeneration gen) {error();} 701 void LongType.mul(CodeGeneration gen) {gen.emit(Bytecode.LMUL);} 702 void FloatType.mul(CodeGeneration gen) {gen.emit(Bytecode.FMUL);} 703 void DoubleType.mul(CodeGeneration gen) {gen.emit(Bytecode.DMUL);} 704 void IntegralType.mul(CodeGeneration gen) {gen.emit(Bytecode.IMUL);} 705 706 void TypeDecl.div(CodeGeneration gen) {error();} 707 void LongType.div(CodeGeneration gen) {gen.emit(Bytecode.LDIV);} 708 void FloatType.div(CodeGeneration gen) {gen.emit(Bytecode.FDIV);} 709 void DoubleType.div(CodeGeneration gen) {gen.emit(Bytecode.DDIV);} 710 void IntegralType.div(CodeGeneration gen) {gen.emit(Bytecode.IDIV);} 711 712 void TypeDecl.rem(CodeGeneration gen) {error();} 713 void LongType.rem(CodeGeneration gen) {gen.emit(Bytecode.LREM);} 714 void FloatType.rem(CodeGeneration gen) {gen.emit(Bytecode.FREM);} 715 void DoubleType.rem(CodeGeneration gen) {gen.emit(Bytecode.DREM);} 716 void IntegralType.rem(CodeGeneration gen) {gen.emit(Bytecode.IREM);} 717 718 void TypeDecl.shl(CodeGeneration gen) {error();} 719 void LongType.shl(CodeGeneration gen) {gen.emit(Bytecode.LSHL);} 720 void IntegralType.shl(CodeGeneration gen) {gen.emit(Bytecode.ISHL);} 721 722 void TypeDecl.shr(CodeGeneration gen) {error();} 723 void LongType.shr(CodeGeneration gen) {gen.emit(Bytecode.LSHR);} 724 void IntegralType.shr(CodeGeneration gen) {gen.emit(Bytecode.ISHR);} 725 726 void TypeDecl.ushr(CodeGeneration gen) {error();} 727 void LongType.ushr(CodeGeneration gen) {gen.emit(Bytecode.LUSHR);} 728 void IntegralType.ushr(CodeGeneration gen) {gen.emit(Bytecode.IUSHR);} 729 730 void TypeDecl.bitand(CodeGeneration gen) {error();} 731 void LongType.bitand(CodeGeneration gen) {gen.emit(Bytecode.LAND);} 732 void IntegralType.bitand(CodeGeneration gen) {gen.emit(Bytecode.IAND);} 733 void BooleanType.bitand(CodeGeneration gen) {gen.emit(Bytecode.IAND);} 734 735 void TypeDecl.bitor(CodeGeneration gen) {error();} 736 void LongType.bitor(CodeGeneration gen) {gen.emit(Bytecode.LOR);} 737 void IntegralType.bitor(CodeGeneration gen) {gen.emit(Bytecode.IOR);} 738 void BooleanType.bitor(CodeGeneration gen) {gen.emit(Bytecode.IOR);} 739 740 void TypeDecl.bitxor(CodeGeneration gen) {error();} 741 void LongType.bitxor(CodeGeneration gen) {gen.emit(Bytecode.LXOR);} 742 void IntegralType.bitxor(CodeGeneration gen) {gen.emit(Bytecode.IXOR);} 743 void BooleanType.bitxor(CodeGeneration gen) {gen.emit(Bytecode.IXOR);} 744 } 745 746 aspect CodeGenerationBranch { 747 public void TypeDecl.branchLT(CodeGeneration gen, int label) { throw new Error("branchLT not supported for " + getClass().getName()); } 748 public void DoubleType.branchLT(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPG).emitCompare(Bytecode.IFLT, label); } 749 public void FloatType.branchLT(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPG).emitCompare(Bytecode.IFLT, label); } 750 public void LongType.branchLT(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFLT, label); } 751 public void IntegralType.branchLT(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPLT, label); } 752 753 public void TypeDecl.branchLTInv(CodeGeneration gen, int label) { branchLT(gen, label); } 754 public void DoubleType.branchLTInv(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFLT, label); } 755 public void FloatType.branchLTInv(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFLT, label); } 756 757 public void TypeDecl.branchLE(CodeGeneration gen, int label) { throw new Error("branchLE not supported for " + getClass().getName()); } 758 public void DoubleType.branchLE(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPG).emitCompare(Bytecode.IFLE, label); } 759 public void FloatType.branchLE(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPG).emitCompare(Bytecode.IFLE, label); } 760 public void LongType.branchLE(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFLE, label); } 761 public void IntegralType.branchLE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPLE, label); } 762 763 public void TypeDecl.branchLEInv(CodeGeneration gen, int label) { branchLE(gen, label); } 764 public void DoubleType.branchLEInv(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFLE, label); } 765 public void FloatType.branchLEInv(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFLE, label); } 766 767 public void TypeDecl.branchGE(CodeGeneration gen, int label) { throw new Error("branchGE not supported for " + getClass().getName()); } 768 public void DoubleType.branchGE(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFGE, label); } 769 public void FloatType.branchGE(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFGE, label); } 770 public void LongType.branchGE(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFGE, label); } 771 public void IntegralType.branchGE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPGE, label); } 772 773 public void TypeDecl.branchGEInv(CodeGeneration gen, int label) { branchGE(gen, label); } 774 public void DoubleType.branchGEInv(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPG).emitCompare(Bytecode.IFGE, label); } 775 public void FloatType.branchGEInv(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPG).emitCompare(Bytecode.IFGE, label); } 776 777 public void TypeDecl.branchGT(CodeGeneration gen, int label) { throw new Error("branchGT not supported for " + getClass().getName()); } 778 public void DoubleType.branchGT(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFGT, label); } 779 public void FloatType.branchGT(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFGT, label); } 780 public void LongType.branchGT(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFGT, label); } 781 public void IntegralType.branchGT(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPGT, label); } 782 783 public void TypeDecl.branchGTInv(CodeGeneration gen, int label) { branchGT(gen, label); } 784 public void DoubleType.branchGTInv(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPG).emitCompare(Bytecode.IFGT, label); } 785 public void FloatType.branchGTInv(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPG).emitCompare(Bytecode.IFGT, label); } 786 787 public void TypeDecl.branchEQ(CodeGeneration gen, int label) { throw new Error("branchEQ not supported for " + getClass().getName()); } 788 public void DoubleType.branchEQ(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFEQ, label); } 789 public void FloatType.branchEQ(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFEQ, label); } 790 public void LongType.branchEQ(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFEQ, label); } 791 public void IntegralType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPEQ, label); } 792 public void BooleanType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPEQ, label); } 793 public void ReferenceType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPEQ, label); } 794 public void NullType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPEQ, label); } 795 796 public void TypeDecl.branchNE(CodeGeneration gen, int label) { throw new Error("branchNE not supported for " + getClass().getName()); } 797 public void DoubleType.branchNE(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFNE, label); } 798 public void FloatType.branchNE(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFNE, label); } 799 public void LongType.branchNE(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFNE, label); } 800 public void IntegralType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPNE, label); } 801 public void BooleanType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPNE, label); } 802 public void ReferenceType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPNE, label); } 803 public void NullType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPNE, label); } 804 }