001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 aspect CodeGeneration { 011 public void ASTNode.setSourceLineNumber(int i) { 012 setStart(ASTNode.makePosition(i, 1)); 013 } 014 015 syn int ASTNode.sourceLineNumber() = getStart() != 0 ? getLine(getStart()) : -1; 016 eq ReturnStmt.sourceLineNumber() { 017 int num = super.sourceLineNumber(); 018 if(num != -1) 019 return num; 020 if(hasResult()) { 021 num = getResult().findFirstSourceLineNumber(); 022 if(num != -1) 023 return num; 024 } 025 return getLine(getParent().getParent().getEnd()); 026 } 027 eq ExprStmt.sourceLineNumber() = getExpr().findFirstSourceLineNumber(); 028 eq Access.sourceLineNumber() = findFirstSourceLineNumber(); 029 030 protected int ASTNode.findFirstSourceLineNumber() { 031 if(getStart() != 0) 032 return getLine(getStart()); 033 for(int i = 0; i < getNumChild(); i++) { 034 int num = getChild(i).findFirstSourceLineNumber(); 035 if(num != -1) 036 return num; 037 } 038 return -1; 039 } 040 041 042 inh int VariableDeclaration.variableScopeEndLabel(CodeGeneration gen); 043 syn lazy int Block.variableScopeEndLabel(CodeGeneration gen) = gen.variableScopeLabel(); 044 eq Block.getStmt(int i).variableScopeEndLabel(CodeGeneration gen) = variableScopeEndLabel(gen); 045 syn lazy int ForStmt.variableScopeEndLabel(CodeGeneration gen) = gen.variableScopeLabel(); 046 eq ForStmt.getInitStmt(int i).variableScopeEndLabel(CodeGeneration gen) = variableScopeEndLabel(gen); 047 eq Program.getChild(int i).variableScopeEndLabel(CodeGeneration gen) { 048 throw new Error("variableScopeEndLabel not valid from here"); 049 } 050 051 class CodeGeneration { 052 private ByteArray bytes = new ByteArray(); 053 private ConstantPool constantPool; 054 055 public void clearCodeGeneration() { 056 bytes = null; 057 constantPool = null; 058 variableScopeLabelAddress = null; 059 variableScopeLabelUses = null; 060 localVariableTable = null; 061 lineNumberTable = null; 062 exceptions = null; 063 address = null; 064 uses = null; 065 } 066 067 private boolean wideGoto = false; 068 069 private boolean numberFormatError = false; 070 public boolean numberFormatError() { return numberFormatError; } 071 072 public CodeGeneration(ConstantPool constantPool) { 073 this.constantPool = constantPool; 074 } 075 076 public CodeGeneration(ConstantPool constantPool, boolean wideGoto) { 077 this.constantPool = constantPool; 078 this.wideGoto = wideGoto; 079 } 080 081 public ConstantPool constantPool() { 082 return constantPool; 083 } 084 085 private int variableScopeLabel = 1; 086 public int variableScopeLabel() { 087 return variableScopeLabel++; 088 } 089 public void addVariableScopeLabel(int label) { 090 Integer label_object = new Integer(label); 091 variableScopeLabelAddress.put(label_object, new Integer(pos())); 092 // Update all reference to this label 093 if(variableScopeLabelUses.containsKey(label_object)) { 094 ArrayList array = (ArrayList)variableScopeLabelUses.get(label_object); 095 for(Iterator iter = array.iterator(); iter.hasNext(); ) { 096 LocalVariableEntry e = (LocalVariableEntry)iter.next(); 097 e.length = pos() - e.start_pc; 098 } 099 } 100 } 101 private HashMap variableScopeLabelAddress = new HashMap(); 102 private HashMap variableScopeLabelUses = new HashMap(); 103 104 class LocalVariableEntry { 105 int start_pc; 106 int length; 107 int name_index; 108 int descriptor_index; 109 int index; 110 } 111 public Collection localVariableTable = new ArrayList(); 112 public void addLocalVariableEntryAtCurrentPC(String name, String typeDescriptor, int localNum, int variableScopeEndLabel) { 113 LocalVariableEntry e = new LocalVariableEntry(); 114 e.start_pc = pos(); 115 e.length = 0; 116 e.name_index = constantPool().addUtf8(name); 117 e.descriptor_index = constantPool().addUtf8(typeDescriptor); 118 e.index = localNum; 119 localVariableTable.add(e); 120 Integer label_object = new Integer(variableScopeEndLabel); 121 if(!variableScopeLabelUses.containsKey(label_object)) 122 variableScopeLabelUses.put(label_object, new ArrayList()); 123 Collection c = (Collection)variableScopeLabelUses.get(label_object); 124 c.add(e); 125 } 126 127 // at each variable declaration and parameter declaration 128 // inh int VariableDeclaration.variableScopeEndLabel(CodeGeneration gen); 129 // addLocalVariableEntryAtCurrentPC(this, variableScopeEndLabel()); 130 // syn lazy int Block.variableScopeEndLabel(CodeGeneration gen) = gen.variableScopeLabel(); 131 // Block.createBCode() { ... gen.addLabel(variableScopeLabel()); 132 133 class LineNumberEntry { 134 int start_pc; 135 int line_number; 136 } 137 public Collection lineNumberTable = new ArrayList(); 138 public void addLineNumberEntryAtCurrentPC(ASTNode node) { 139 LineNumberEntry e = new LineNumberEntry(); 140 e.start_pc = pos(); 141 e.line_number = node.sourceLineNumber(); 142 if(e.line_number != -1 && e.line_number != 65535) 143 lineNumberTable.add(e); 144 } 145 146 public Collection exceptions = new ArrayList(); 147 public void addException(int start_pc, int end_pc, int handler_pc, int catch_type) { 148 ExceptionEntry e = new ExceptionEntry(); 149 e.start_pc = start_pc; 150 e.end_pc = end_pc; 151 e.handler_pc = handler_pc; 152 e.catch_type = catch_type; 153 if(e.start_pc != e.end_pc) 154 exceptions.add(e); 155 } 156 class ExceptionEntry { 157 int start_pc; 158 int end_pc; 159 int handler_pc; 160 int catch_type; 161 } 162 public void createExceptionTable(TryStmt tryStmt) { 163 for(int i = 0; i < tryStmt.getNumCatchClause(); i++) { 164 tryStmt.getCatchClause(i).exceptionTableEntries(this, tryStmt); 165 } 166 if(tryStmt.hasFinally()) { 167 addException( 168 addressOf(tryStmt.label_begin()), 169 addressOf(tryStmt.label_finally()), 170 addressOf(tryStmt.label_exception_handler()), 171 0 172 ); 173 } 174 } 175 public void createExceptionTable(SynchronizedStmt stmt) { 176 addException( 177 addressOf(stmt.label_begin()), 178 addressOf(stmt.label_finally()), 179 addressOf(stmt.label_exception_handler()), 180 0 181 ); 182 } 183 184 public int maxLocals() { 185 return maxLocals+1; 186 } 187 int maxLocals = 0; 188 189 /* 190 public int label() { 191 return labelCounter++; 192 } 193 private static int labelCounter = 1; 194 */ 195 private HashMap address = new HashMap(); 196 private HashMap uses = new HashMap(); 197 public void addLabel(int label) { 198 Integer label_object = new Integer(label); 199 /* 200 if(pos() - 3 == bytes.lastGotoPos() && bytes.get(pos() - 3) == Bytecode.GOTO) { 201 if(uses.containsKey(label_object)) { 202 ArrayList array = (ArrayList)uses.get(label_object); 203 for(int i = 0; i < array.size(); i++) { 204 int p = ((Integer)array.get(i)).intValue(); 205 if(pos() - 3 == p) { 206 //System.out.println("Found direct branch"); 207 array.remove(i); 208 i--; 209 } 210 } 211 bytes.setPos(pos() - 3); 212 } 213 } 214 */ 215 address.put(label_object, new Integer(pos())); 216 // Update all reference to this label 217 if(uses.containsKey(label_object)) { 218 ArrayList array = (ArrayList)uses.get(label_object); 219 for(int i = 0; i < array.size(); i++) { 220 int p = ((Integer)array.get(i)).intValue(); 221 if(bytes.get(p) == Bytecode.GOTO_W) 222 setAddress32(p + 1, pos() - p); 223 else 224 setAddress(p + 1, pos() - p); 225 } 226 } 227 } 228 public int addressOf(int label) { 229 Integer label_object = new Integer(label); 230 if(!address.containsKey(label_object)) 231 throw new Error("Can not compute address of unplaced label"); 232 return ((Integer)address.get(label_object)).intValue(); 233 } 234 private int jump(int label) { 235 Integer label_object = new Integer(label); 236 if(!uses.containsKey(label_object)) 237 uses.put(label_object, new ArrayList()); 238 ArrayList a = (ArrayList)uses.get(label_object); 239 a.add(new Integer(pos())); // position of the 16-bits reference 240 Integer val = (Integer)address.get(label_object); 241 if(val != null) 242 return val.intValue() - pos(); 243 return 0; // a position of 0 means not calculated yet 244 } 245 private void setAddress(int position, int address) { 246 if(address > Short.MAX_VALUE || address < Short.MIN_VALUE) 247 numberFormatError = true; 248 bytes.set(position + 0, (byte)((address&0xff00)>>8)); 249 bytes.set(position + 1, (byte)(address&0xff)); 250 } 251 private void setAddress32(int position, int address) { 252 bytes.set(position + 0, (byte)(address >> 24 & 0xff)); 253 bytes.set(position + 1, (byte)(address >> 16 & 0xff)); 254 bytes.set(position + 2, (byte)(address >> 8 & 0xff)); 255 bytes.set(position + 3, (byte)(address & 0xff)); 256 } 257 258 259 public void emitStoreReference(int pos) { 260 maxLocals = Math.max(maxLocals, pos+1); 261 if(pos == 0) emit(Bytecode.ASTORE_0); 262 else if(pos == 1) emit(Bytecode.ASTORE_1); 263 else if(pos == 2) emit(Bytecode.ASTORE_2); 264 else if(pos == 3) emit(Bytecode.ASTORE_3); 265 else if(pos < 256) emit(Bytecode.ASTORE).add(pos); 266 else emit(Bytecode.WIDE).emit(Bytecode.ASTORE).add2(pos); 267 } 268 public void emitLoadReference(int pos) { 269 maxLocals = Math.max(maxLocals, pos+1); 270 if(pos == 0) emit(Bytecode.ALOAD_0); 271 else if(pos == 1) emit(Bytecode.ALOAD_1); 272 else if(pos == 2) emit(Bytecode.ALOAD_2); 273 else if(pos == 3) emit(Bytecode.ALOAD_3); 274 else if(pos < 256) emit(Bytecode.ALOAD).add(pos); 275 else emit(Bytecode.WIDE).emit(Bytecode.ALOAD).add2(pos); 276 } 277 278 public void emitReturn() { 279 bytes.emit(Bytecode.RETURN); 280 } 281 282 public void emitThrow() { 283 bytes.emit(Bytecode.ATHROW); 284 } 285 286 public void emitInstanceof(TypeDecl type) { 287 int p = constantPool().addClass(type.isArrayDecl() ? type.typeDescriptor() : type.constantPoolName()); 288 bytes.emit(Bytecode.INSTANCEOF).add2(p); 289 } 290 public void emitCheckCast(TypeDecl type) { 291 int p = constantPool().addClass(type.isArrayDecl() ? type.typeDescriptor() : type.constantPoolName()); 292 bytes.emit(Bytecode.CHECKCAST).add2(p); 293 } 294 295 public void emitDup() { 296 bytes.emit(Bytecode.DUP); 297 } 298 public void emitDup2() { 299 bytes.emit(Bytecode.DUP2); 300 } 301 302 public void emitPop() { 303 bytes.emit(Bytecode.POP); 304 } 305 306 public void emitSwap() { 307 bytes.emit(Bytecode.SWAP); 308 } 309 310 public void emitBranchNonNull(int label) { 311 int p = jump(label); 312 bytes.emit(Bytecode.IFNONNULL).add2(p); 313 } 314 315 public void emitGoto(int label) { 316 int p = jump(label); 317 if(wideGoto) 318 bytes.emitGoto(Bytecode.GOTO_W).add4(p); 319 else { 320 if(p > Short.MAX_VALUE || p < Short.MIN_VALUE) 321 numberFormatError = true; 322 bytes.emitGoto(Bytecode.GOTO).add2(p); 323 } 324 } 325 326 public void emitJsr(int label) { 327 int p = jump(label); 328 bytes.emit(Bytecode.JSR).add2(p); 329 } 330 331 public void emitCompare(byte bytecode, int label) { 332 int p = jump(label); 333 bytes.emit(bytecode).add2(p); 334 } 335 336 public String toString() { 337 return bytes.toString(); 338 } 339 public int size() {return bytes.size();} 340 public int pos() {return bytes.pos();} 341 public byte[] toArray() {return bytes.toArray();} 342 CodeGeneration add(int i) { return add((byte)i); } 343 CodeGeneration add(byte b) { bytes.add(b); return this; } 344 CodeGeneration add2(int index) { 345 bytes.add2(index); 346 return this; 347 } 348 CodeGeneration add4(int index) { 349 bytes.add4(index); 350 return this; 351 } 352 CodeGeneration emit(byte b) { 353 bytes.emit(b); 354 return this; 355 } 356 CodeGeneration emit(byte b, int stackChange) { 357 bytes.emit(b, stackChange); 358 return this; 359 } 360 public int maxStackDepth() { 361 return bytes.maxStackDepth(); 362 } 363 public int stackDepth() { 364 return bytes.stackDepth(); 365 } 366 public void changeStackDepth(int i) { 367 bytes.changeStackDepth(i); 368 } 369 } 370 /************************************************************* 371 * Auxiliary class 372 *************************************************************/ 373 class ByteArray { 374 private int stackDepth = 0; 375 private int maxStackDepth = 0; 376 private int size = 64; 377 private byte[] bytes = new byte[size]; 378 private int pos = 0; 379 private int lastGotoPos = 0; 380 ByteArray add(int i) {return add((byte)i);} 381 ByteArray add(byte b) { 382 if(pos >= size) { 383 byte[] ba = new byte[size * 2]; 384 System.arraycopy(bytes, 0, ba, 0, size); 385 size *= 2; 386 bytes = ba; 387 } 388 bytes[pos++] = b; 389 return this; 390 } 391 ByteArray add4(int i) { 392 add(i >> 24 & 0xff); 393 add(i >> 16 & 0xff); 394 add(i >> 8 & 0xff); 395 add(i & 0xff); 396 return this; 397 } 398 ByteArray add2(int index) { 399 add(index >> 8 & 0xff); 400 add(index & 0xff); 401 return this; 402 } 403 ByteArray emit(byte b) { 404 changeStackDepth(BytecodeDebug.stackChange(b)); 405 add(b); 406 return this; 407 } 408 ByteArray emitGoto(byte b) { 409 changeStackDepth(BytecodeDebug.stackChange(b)); 410 lastGotoPos = pos; 411 add(b); 412 return this; 413 } 414 ByteArray emit(byte b, int stackChange) { 415 changeStackDepth(stackChange); 416 add(b); 417 return this; 418 } 419 420 public int maxStackDepth() { 421 return maxStackDepth; 422 } 423 public int stackDepth() { 424 return stackDepth; 425 } 426 public void changeStackDepth(int i) { 427 stackDepth += i; 428 if(stackDepth > maxStackDepth) 429 maxStackDepth = stackDepth; 430 } 431 432 public int pos() {return pos;} 433 public int lastGotoPos() {return lastGotoPos;} 434 public void setPos(int index) { pos = index; } 435 public int size() {return pos;} 436 public byte get(int index) {return bytes[index];} 437 public void set(int index, byte value) {bytes[index] = value;} 438 public String toString() { 439 StringBuffer b = new StringBuffer(); 440 for(int i = 0; i < pos; i++) b.append(" " + bytes[i]); 441 return b.toString(); 442 } 443 public byte[] toArray() { 444 byte[] b = new byte[pos]; 445 System.arraycopy(bytes, 0, b, 0, pos); 446 return b; 447 } 448 } 449 450 /************************************************************* 451 * Emit methods 452 *************************************************************/ 453 454 // push constants 455 456 public static void IntegerLiteral.push(CodeGeneration gen, int value) { 457 switch(value) { 458 case -1: 459 gen.emit(Bytecode.ICONST_M1); 460 break; 461 case 0: 462 gen.emit(Bytecode.ICONST_0); 463 break; 464 case 1: 465 gen.emit(Bytecode.ICONST_1); 466 break; 467 case 2: 468 gen.emit(Bytecode.ICONST_2); 469 break; 470 case 3: 471 gen.emit(Bytecode.ICONST_3); 472 break; 473 case 4: 474 gen.emit(Bytecode.ICONST_4); 475 break; 476 case 5: 477 gen.emit(Bytecode.ICONST_5); 478 break; 479 default: 480 if(value >= -128 && value <= 127) { 481 gen.emit(Bytecode.BIPUSH).add(value); 482 } 483 else if(value >= -32768 && value <= 32767) { 484 gen.emit(Bytecode.SIPUSH).add2(value); 485 } 486 else { 487 int index = gen.constantPool().addConstant(value); 488 if(index < 256) 489 gen.emit(Bytecode.LDC).add(index); 490 else 491 gen.emit(Bytecode.LDC_W).add2(index); 492 } 493 } 494 } 495 public static void LongLiteral.push(CodeGeneration gen, long value) { 496 if(value == 0) 497 gen.emit(Bytecode.LCONST_0); 498 else if(value == 1) 499 gen.emit(Bytecode.LCONST_1); 500 else { 501 int index = gen.constantPool().addConstant(value); 502 gen.emit(Bytecode.LDC2_W).add2(index); 503 } 504 } 505 public static void DoubleLiteral.push(CodeGeneration gen, double value) { 506 if(value == 0) 507 gen.emit(Bytecode.DCONST_0); 508 else if(value == 1) 509 gen.emit(Bytecode.DCONST_1); 510 else { 511 int index = gen.constantPool().addConstant(value); 512 gen.emit(Bytecode.LDC2_W).add2(index); 513 } 514 } 515 public static void FloatingPointLiteral.push(CodeGeneration gen, float value) { 516 if(value == 0) 517 gen.emit(Bytecode.FCONST_0); 518 else if(value == 1) 519 gen.emit(Bytecode.FCONST_1); 520 else if(value == 2) 521 gen.emit(Bytecode.FCONST_2); 522 else { 523 int index = gen.constantPool().addConstant(value); 524 if(index < 256) 525 gen.emit(Bytecode.LDC).add(index); 526 else 527 gen.emit(Bytecode.LDC_W).add2(index); 528 } 529 } 530 public static void StringLiteral.push(CodeGeneration gen, String value) { 531 int index = gen.constantPool().addConstant(value); 532 if(index < 256) 533 gen.emit(Bytecode.LDC).add(index); 534 else 535 gen.emit(Bytecode.LDC_W).add2(index); 536 } 537 538 public static void BooleanLiteral.push(CodeGeneration gen, boolean value) { 539 gen.emit(value ? Bytecode.ICONST_1 : Bytecode.ICONST_0); 540 } 541 542 public void TypeDecl.emitPushConstant(CodeGeneration gen, int value) { } 543 public void IntegralType.emitPushConstant(CodeGeneration gen, int value) { IntegerLiteral.push(gen, value); } 544 public void LongType.emitPushConstant(CodeGeneration gen, int value) { LongLiteral.push(gen, value); } 545 public void DoubleType.emitPushConstant(CodeGeneration gen, int value) { DoubleLiteral.push(gen, value); } 546 public void FloatType.emitPushConstant(CodeGeneration gen, int value) { FloatingPointLiteral.push(gen, value); } 547 548 // push literals 549 550 public void Literal.emitPushConstant(CodeGeneration gen) { 551 System.out.println("ERROR: Tried to generate bytecode for: " + getClass().getName()); 552 } 553 554 public void IntegerLiteral.emitPushConstant(CodeGeneration gen) { 555 type().emitPushConstant(gen, constant().intValue()); 556 } 557 558 public void CharacterLiteral.emitPushConstant(CodeGeneration gen) { 559 type().emitPushConstant(gen, constant().intValue()); 560 } 561 562 public void FloatingPointLiteral.emitPushConstant(CodeGeneration gen) { 563 FloatingPointLiteral.push(gen, constant().floatValue()); 564 } 565 566 public void LongLiteral.emitPushConstant(CodeGeneration gen) { 567 LongLiteral.push(gen, constant().longValue()); 568 } 569 570 public void DoubleLiteral.emitPushConstant(CodeGeneration gen) { 571 DoubleLiteral.push(gen, constant().doubleValue()); 572 } 573 574 public void StringLiteral.emitPushConstant(CodeGeneration gen) { 575 StringLiteral.push(gen, getLITERAL()); 576 } 577 578 public void NullLiteral.emitPushConstant(CodeGeneration gen) { 579 gen.emit(Bytecode.ACONST_NULL); 580 } 581 582 public void BooleanLiteral.emitPushConstant(CodeGeneration gen) { 583 BooleanLiteral.push(gen, constant().booleanValue()); 584 } 585 586 public void ASTNode.error() { 587 Throwable t = new Throwable(); 588 StackTraceElement[] ste = new Throwable().getStackTrace(); 589 String s = ste[1].toString(); 590 throw new Error(s+" Cannot create bytecode for:"+getClass().getName()); 591 } 592 593 public void Constant.createBCode(CodeGeneration gen) { 594 if(this instanceof ConstantInt) 595 IntegerLiteral.push(gen, intValue()); 596 else if(this instanceof ConstantLong) 597 LongLiteral.push(gen, longValue()); 598 else if(this instanceof ConstantFloat) 599 FloatingPointLiteral.push(gen, floatValue()); 600 else if(this instanceof ConstantDouble) 601 DoubleLiteral.push(gen, doubleValue()); 602 else if(this instanceof ConstantChar) 603 IntegerLiteral.push(gen, intValue()); 604 else if(this instanceof ConstantBoolean) 605 BooleanLiteral.push(gen, booleanValue()); 606 else if(this instanceof ConstantString) 607 StringLiteral.push(gen, stringValue()); 608 } 609 610 // return 611 612 public void TypeDecl.emitReturn(CodeGeneration gen) { error(); } 613 public void VoidType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.RETURN);} 614 public void PrimitiveType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.IRETURN);} 615 public void LongType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.LRETURN);} 616 public void FloatType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.FRETURN);} 617 public void DoubleType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.DRETURN);} 618 public void ReferenceType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.ARETURN);} 619 public void NullType.emitReturn(CodeGeneration gen) { gen.emit(Bytecode.ARETURN);} 620 621 syn byte TypeDecl.arrayLoad() { 622 throw new Error("Cannot create array load for TypeDecl"); 623 } 624 eq ReferenceType.arrayLoad() = Bytecode.AALOAD; 625 eq IntType.arrayLoad() = Bytecode.IALOAD; 626 eq LongType.arrayLoad() = Bytecode.LALOAD; 627 eq FloatType.arrayLoad() = Bytecode.FALOAD; 628 eq DoubleType.arrayLoad() = Bytecode.DALOAD; 629 eq ByteType.arrayLoad() = Bytecode.BALOAD; 630 eq CharType.arrayLoad() = Bytecode.CALOAD; 631 eq ShortType.arrayLoad() = Bytecode.SALOAD; 632 eq BooleanType.arrayLoad() = Bytecode.BALOAD; 633 634 public void TypeDecl.emitLoadLocal(CodeGeneration gen, int pos) {error();} 635 public void PrimitiveType.emitLoadLocal(CodeGeneration gen, int pos) { 636 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 637 if(pos == 0) gen.emit(Bytecode.ILOAD_0); 638 else if(pos == 1) gen.emit(Bytecode.ILOAD_1); 639 else if(pos == 2) gen.emit(Bytecode.ILOAD_2); 640 else if(pos == 3) gen.emit(Bytecode.ILOAD_3); 641 else if(pos < 256) gen.emit(Bytecode.ILOAD).add(pos); 642 else gen.emit(Bytecode.WIDE).emit(Bytecode.ILOAD).add2(pos); 643 } 644 public void LongType.emitLoadLocal(CodeGeneration gen, int pos) { 645 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 646 if(pos == 0) gen.emit(Bytecode.LLOAD_0); 647 else if(pos == 1) gen.emit(Bytecode.LLOAD_1); 648 else if(pos == 2) gen.emit(Bytecode.LLOAD_2); 649 else if(pos == 3) gen.emit(Bytecode.LLOAD_3); 650 else if(pos < 256) gen.emit(Bytecode.LLOAD).add(pos); 651 else gen.emit(Bytecode.WIDE).emit(Bytecode.LLOAD).add2(pos); 652 } 653 public void FloatType.emitLoadLocal(CodeGeneration gen, int pos) { 654 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 655 if(pos == 0) gen.emit(Bytecode.FLOAD_0); 656 else if(pos == 1) gen.emit(Bytecode.FLOAD_1); 657 else if(pos == 2) gen.emit(Bytecode.FLOAD_2); 658 else if(pos == 3) gen.emit(Bytecode.FLOAD_3); 659 else if(pos < 256) gen.emit(Bytecode.FLOAD).add(pos); 660 else gen.emit(Bytecode.WIDE).emit(Bytecode.FLOAD).add2(pos); 661 } 662 public void DoubleType.emitLoadLocal(CodeGeneration gen, int pos) { 663 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 664 if(pos == 0) gen.emit(Bytecode.DLOAD_0); 665 else if(pos == 1) gen.emit(Bytecode.DLOAD_1); 666 else if(pos == 2) gen.emit(Bytecode.DLOAD_2); 667 else if(pos == 3) gen.emit(Bytecode.DLOAD_3); 668 else if(pos < 256) gen.emit(Bytecode.DLOAD).add(pos); 669 else gen.emit(Bytecode.WIDE).emit(Bytecode.DLOAD).add2(pos); 670 } 671 public void ReferenceType.emitLoadLocal(CodeGeneration gen, int pos) { 672 gen.emitLoadReference(pos); 673 } 674 public void NullType.emitLoadLocal(CodeGeneration gen, int pos) { 675 gen.emitLoadReference(pos); 676 } 677 678 public void FieldDeclaration.emitLoadField(CodeGeneration gen, TypeDecl typeDecl) { 679 if(hostType().isArrayDecl() && name().equals("length")) { 680 gen.emit(Bytecode.ARRAYLENGTH); 681 return; 682 } 683 String classname = typeDecl.constantPoolName(); 684 String desc = type().typeDescriptor(); 685 String name = name(); 686 int index = gen.constantPool().addFieldref(classname, name, desc); 687 if(isStatic()) 688 gen.emit(Bytecode.GETSTATIC, type().variableSize()).add2(index); 689 else 690 gen.emit(Bytecode.GETFIELD, type().variableSize() - 1).add2(index); 691 } 692 693 694 // emit store 695 696 public void Expr.emitStore(CodeGeneration gen) { error("emitStore called with " + getClass().getName()); } 697 public void AbstractDot.emitStore(CodeGeneration gen) { lastAccess().emitStore(gen); } 698 699 public void VarAccess.emitStore(CodeGeneration gen) { 700 Variable v = decl(); 701 if(v instanceof VariableDeclaration) { 702 VariableDeclaration decl = (VariableDeclaration)v; 703 if(isDUbefore(v)) 704 gen.addLocalVariableEntryAtCurrentPC(decl.name(), decl.type().typeDescriptor(), decl.localNum(), decl.variableScopeEndLabel(gen)); 705 decl.type().emitStoreLocal(gen, decl.localNum()); 706 } 707 else if(v instanceof ParameterDeclaration) { 708 ParameterDeclaration decl = (ParameterDeclaration)v; 709 decl.type().emitStoreLocal(gen, decl.localNum()); 710 } 711 else if(v instanceof FieldDeclaration) { 712 FieldDeclaration f = (FieldDeclaration)v; 713 if(f.isPrivate() && !hostType().hasField(v.name())) 714 f.createAccessorWrite(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType()); 715 else 716 f.emitStoreField(gen, fieldQualifierType()); 717 } 718 } 719 720 public void ArrayAccess.emitStore(CodeGeneration gen) { 721 gen.emit(type().arrayStore()); 722 } 723 syn byte TypeDecl.arrayStore() { 724 throw new Error("Cannot create array load for TypeDecl"); 725 } 726 eq ReferenceType.arrayStore() = Bytecode.AASTORE; 727 eq IntType.arrayStore() = Bytecode.IASTORE; 728 eq LongType.arrayStore() = Bytecode.LASTORE; 729 eq FloatType.arrayStore() = Bytecode.FASTORE; 730 eq DoubleType.arrayStore() = Bytecode.DASTORE; 731 eq ByteType.arrayStore() = Bytecode.BASTORE; 732 eq CharType.arrayStore() = Bytecode.CASTORE; 733 eq ShortType.arrayStore() = Bytecode.SASTORE; 734 eq BooleanType.arrayStore() = Bytecode.BASTORE; 735 736 public void FieldDeclaration.emitStoreField(CodeGeneration gen, TypeDecl typeDecl) { 737 String classname = typeDecl.constantPoolName(); 738 String desc = type().typeDescriptor(); 739 String name = name(); 740 int index = gen.constantPool().addFieldref(classname, name, desc); 741 if(isStatic()) 742 gen.emit(Bytecode.PUTSTATIC, -type().variableSize()).add2(index); 743 else 744 gen.emit(Bytecode.PUTFIELD, -type().variableSize() - 1).add2(index); 745 } 746 747 public void TypeDecl.emitStoreLocal(CodeGeneration gen, int pos) {error();} 748 public void PrimitiveType.emitStoreLocal(CodeGeneration gen, int pos) { 749 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 750 if(pos == 0) gen.emit(Bytecode.ISTORE_0); 751 else if(pos == 1) gen.emit(Bytecode.ISTORE_1); 752 else if(pos == 2) gen.emit(Bytecode.ISTORE_2); 753 else if(pos == 3) gen.emit(Bytecode.ISTORE_3); 754 else if(pos < 256) gen.emit(Bytecode.ISTORE).add(pos); 755 else gen.emit(Bytecode.WIDE).emit(Bytecode.ISTORE).add2(pos); 756 } 757 public void LongType.emitStoreLocal(CodeGeneration gen, int pos) { 758 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 759 if(pos == 0) gen.emit(Bytecode.LSTORE_0); 760 else if(pos == 1) gen.emit(Bytecode.LSTORE_1); 761 else if(pos == 2) gen.emit(Bytecode.LSTORE_2); 762 else if(pos == 3) gen.emit(Bytecode.LSTORE_3); 763 else if(pos < 256) gen.emit(Bytecode.LSTORE).add(pos); 764 else gen.emit(Bytecode.WIDE).emit(Bytecode.LSTORE).add2(pos); 765 } 766 public void FloatType.emitStoreLocal(CodeGeneration gen, int pos) { 767 gen.maxLocals = Math.max(gen.maxLocals, pos+1); 768 if(pos == 0) gen.emit(Bytecode.FSTORE_0); 769 else if(pos == 1) gen.emit(Bytecode.FSTORE_1); 770 else if(pos == 2) gen.emit(Bytecode.FSTORE_2); 771 else if(pos == 3) gen.emit(Bytecode.FSTORE_3); 772 else if(pos < 256) gen.emit(Bytecode.FSTORE).add(pos); 773 else gen.emit(Bytecode.WIDE).emit(Bytecode.FSTORE).add2(pos); 774 } 775 public void DoubleType.emitStoreLocal(CodeGeneration gen, int pos) { 776 gen.maxLocals = Math.max(gen.maxLocals, pos+2); 777 if(pos == 0) gen.emit(Bytecode.DSTORE_0); 778 else if(pos == 1) gen.emit(Bytecode.DSTORE_1); 779 else if(pos == 2) gen.emit(Bytecode.DSTORE_2); 780 else if(pos == 3) gen.emit(Bytecode.DSTORE_3); 781 else if(pos < 256) gen.emit(Bytecode.DSTORE).add(pos); 782 else gen.emit(Bytecode.WIDE).emit(Bytecode.DSTORE).add2(pos); 783 } 784 public void ReferenceType.emitStoreLocal(CodeGeneration gen, int pos) { 785 gen.emitStoreReference(pos); 786 } 787 public void NullType.emitStoreLocal(CodeGeneration gen, int pos) { 788 gen.emitStoreReference(pos); 789 } 790 791 // exceptions 792 793 inh TypeDecl TryStmt.typeThrowable(); 794 795 public void TryStmt.emitExceptionHandler(CodeGeneration gen) { 796 // add 1 to stack depth 797 gen.changeStackDepth(1); 798 int num = localNum(); 799 gen.emitStoreReference(num); 800 gen.emitJsr(label_finally_block()); 801 gen.emitLoadReference(num); 802 gen.emit(Bytecode.ATHROW); 803 } 804 805 public void TryStmt.emitFinallyBlock(CodeGeneration gen) { 806 // add 1 to stack depth 807 gen.changeStackDepth(1); 808 int num = localNum()+1; 809 gen.emitStoreReference(num); 810 getFinally().createBCode(gen); 811 if(num < 256) 812 gen.emit(Bytecode.RET).add(num); 813 else 814 gen.emit(Bytecode.WIDE).emit(Bytecode.RET).add2(num); 815 } 816 817 public void SynchronizedStmt.emitMonitorEnter(CodeGeneration gen) { 818 gen.emitDup(); 819 int num = localNum(); 820 gen.emitStoreReference(num); 821 gen.emit(Bytecode.MONITORENTER); 822 } 823 public void SynchronizedStmt.emitExceptionHandler(CodeGeneration gen) { 824 // add 1 to stack depth 825 gen.changeStackDepth(1); 826 int num = localNum() + 1; 827 gen.emitStoreReference(num); 828 gen.emitJsr(label_finally_block()); 829 gen.emitLoadReference(num); 830 gen.emit(Bytecode.ATHROW); 831 } 832 public void SynchronizedStmt.emitFinallyBlock(CodeGeneration gen) { 833 // add 1 to stack depth 834 gen.changeStackDepth(1); 835 int num = localNum() + 2; 836 gen.emitStoreReference(num); 837 gen.emitLoadReference(localNum()); // monitor 838 gen.emit(Bytecode.MONITOREXIT); 839 gen.emit(Bytecode.RET).add(num); 840 } 841 842 // dup 843 844 public void TypeDecl.emitDup(CodeGeneration gen) { gen.emit(Bytecode.DUP); } 845 public void VoidType.emitDup(CodeGeneration gen) { } 846 public void DoubleType.emitDup(CodeGeneration gen) { gen.emit(Bytecode.DUP2); } 847 public void LongType.emitDup(CodeGeneration gen) { gen.emit(Bytecode.DUP2); } 848 849 public void TypeDecl.emitDup_x1(CodeGeneration gen) { gen.emit(Bytecode.DUP_X1); } 850 public void VoidType.emitDup_x1(CodeGeneration gen) { } 851 public void DoubleType.emitDup_x1(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X1); } 852 public void LongType.emitDup_x1(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X1); } 853 854 public void TypeDecl.emitDup_x2(CodeGeneration gen) { gen.emit(Bytecode.DUP_X2); } 855 public void VoidType.emitDup_x2(CodeGeneration gen) { } 856 public void DoubleType.emitDup_x2(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X2); } 857 public void LongType.emitDup_x2(CodeGeneration gen) { gen.emit(Bytecode.DUP2_X2); } 858 859 public void TypeDecl.emitPop(CodeGeneration gen) { gen.emit(Bytecode.POP); } 860 public void VoidType.emitPop(CodeGeneration gen) { } 861 public void DoubleType.emitPop(CodeGeneration gen) { gen.emit(Bytecode.POP2); } 862 public void LongType.emitPop(CodeGeneration gen) { gen.emit(Bytecode.POP2); } 863 864 865 // emitInvoke 866 867 public void MethodDecl.emitInvokeMethod(CodeGeneration gen, TypeDecl hostType) { 868 if(hostType.isInterfaceDecl()) { 869 int size = type().variableSize() - 1; 870 for(int i = 0; i < getNumParameter(); i++) 871 size -= getParameter(i).type().variableSize(); 872 String classname = hostType.constantPoolName(); 873 String desc = descName(); 874 String name = name(); 875 int index = gen.constantPool().addInterfaceMethodref(classname, name, desc); 876 int numArg = 1; // instance 877 for(int i = 0; i < getNumParameter(); i++) 878 numArg += getParameter(i).type().variableSize(); 879 gen.emit(Bytecode.INVOKEINTERFACE, size).add2(index).add(numArg).add(0); 880 } 881 else { 882 String classname = hostType.constantPoolName(); 883 String desc = descName(); 884 String name = name(); 885 int index = gen.constantPool().addMethodref(classname, name, desc); 886 if(isStatic()) { 887 int size = type().variableSize(); 888 for(int i = 0; i < getNumParameter(); i++) 889 size -= getParameter(i).type().variableSize(); 890 gen.emit(Bytecode.INVOKESTATIC, size).add2(index); 891 } 892 else { 893 int size = type().variableSize() - 1; 894 for(int i = 0; i < getNumParameter(); i++) 895 size -= getParameter(i).type().variableSize(); 896 gen.emit(Bytecode.INVOKEVIRTUAL, size).add2(index); 897 } 898 } 899 } 900 901 public void MethodDecl.emitInvokeSpecialMethod(CodeGeneration gen, TypeDecl hostType) { 902 String classname = hostType.constantPoolName(); 903 String desc = descName(); 904 String name = name(); 905 int index = gen.constantPool().addMethodref(classname, name, desc); 906 int size = type().variableSize() - 1; 907 for(int i = 0; i < getNumParameter(); i++) 908 size -= getParameter(i).type().variableSize(); 909 gen.emit(Bytecode.INVOKESPECIAL, size).add2(index); 910 } 911 912 public void ConstructorDecl.emitInvokeConstructor(CodeGeneration gen) { 913 int size = -1; 914 for(int i = 0; i < getNumParameter(); i++) 915 size -= getParameter(i).type().variableSize(); 916 if(hostType().needsEnclosing()) 917 size--; 918 if(hostType().needsSuperEnclosing()) { 919 size--; 920 } 921 String classname = hostType().constantPoolName(); 922 String desc = descName(); 923 String name = "<init>"; 924 int index = gen.constantPool().addMethodref(classname, name, desc); 925 gen.emit(Bytecode.INVOKESPECIAL, size).add2(index); 926 } 927 928 // emitNew 929 930 public void TypeDecl.emitNew(CodeGeneration gen) { 931 int index = gen.constantPool().addClass(constantPoolName()); 932 gen.emit(Bytecode.NEW).add2(index); 933 } 934 } 935 aspect CodeGenerationConversions { 936 void TypeDecl.emitAssignConvTo(CodeGeneration gen, TypeDecl type) { 937 if(!type.isIntegralType() || !isIntegralType() || type.isLong()) 938 emitCastTo(gen, type); 939 } 940 941 void TypeDecl.emitCastTo(CodeGeneration gen, TypeDecl type) { throw new Error("CastTo not implemented for " + getClass().getName()); } 942 void ReferenceType.emitCastTo(CodeGeneration gen, TypeDecl type) { if(!instanceOf(type) && !type.isNull()) gen.emitCheckCast(type); } 943 void IntType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.intToThis(gen); } 944 void FloatType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.floatToThis(gen); } 945 void DoubleType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.doubleToThis(gen); } 946 void LongType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.longToThis(gen); } 947 void ByteType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.byteToThis(gen); } 948 void ShortType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.shortToThis(gen); } 949 void CharType.emitCastTo(CodeGeneration gen, TypeDecl type) { type.charToThis(gen); } 950 void BooleanType.emitCastTo(CodeGeneration gen, TypeDecl type) { } 951 void NullType.emitCastTo(CodeGeneration gen, TypeDecl type) { } 952 953 void TypeDecl.intToThis(CodeGeneration gen) { throw new Error("intToThis not implemented for " + getClass().getName()); } 954 void IntType.intToThis(CodeGeneration gen) { } 955 void LongType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 956 void FloatType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 957 void DoubleType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D); } 958 void ByteType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2B); } 959 void CharType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2C); } 960 void ShortType.intToThis(CodeGeneration gen) { gen.emit(Bytecode.I2S); } 961 962 void TypeDecl.floatToThis(CodeGeneration gen) { throw new Error("floatToThis not implemented for " + getClass().getName()); } 963 void IntType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I); } 964 void ByteType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I).emit(Bytecode.I2B); } 965 void ShortType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I).emit(Bytecode.I2S); } 966 void CharType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2I).emit(Bytecode.I2C); } 967 void FloatType.floatToThis(CodeGeneration gen) { } 968 void LongType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2L); } 969 void DoubleType.floatToThis(CodeGeneration gen) { gen.emit(Bytecode.F2D); } 970 971 void TypeDecl.doubleToThis(CodeGeneration gen) { throw new Error("doubleToThis not implemented for " + getClass().getName()); } 972 void IntType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I); } 973 void ByteType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I).emit(Bytecode.I2B); } 974 void ShortType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I).emit(Bytecode.I2S); } 975 void CharType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2I).emit(Bytecode.I2C); } 976 void FloatType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2F); } 977 void LongType.doubleToThis(CodeGeneration gen) { gen.emit(Bytecode.D2L); } 978 void DoubleType.doubleToThis(CodeGeneration gen) { } 979 980 void TypeDecl.longToThis(CodeGeneration gen) { throw new Error("longToThis not implemented for " + getClass().getName()); } 981 void IntType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I); } 982 void ByteType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I).emit(Bytecode.I2B); } 983 void ShortType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I).emit(Bytecode.I2S); } 984 void CharType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2I).emit(Bytecode.I2C); } 985 void FloatType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2F); } 986 void LongType.longToThis(CodeGeneration gen) { } 987 void DoubleType.longToThis(CodeGeneration gen) { gen.emit(Bytecode.L2D); } 988 989 void TypeDecl.byteToThis(CodeGeneration gen) { throw new Error("byteToThis not implemented for " + getClass().getName()); } 990 void IntegralType.byteToThis(CodeGeneration gen) { } 991 void CharType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2C); } 992 void FloatType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 993 void LongType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 994 void DoubleType.byteToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D);} 995 996 void TypeDecl.charToThis(CodeGeneration gen) { throw new Error("charToThis not implemented for " + getClass().getName()); } 997 void IntegralType.charToThis(CodeGeneration gen) { } 998 void ByteType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2B); } 999 void ShortType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2S); } 1000 void FloatType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 1001 void LongType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 1002 void DoubleType.charToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D);} 1003 1004 void TypeDecl.shortToThis(CodeGeneration gen) { throw new Error("shortToThis not implemented for " + getClass().getName()); } 1005 void IntegralType.shortToThis(CodeGeneration gen) { } 1006 void ByteType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2B); } 1007 void CharType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2C); } 1008 void FloatType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2F); } 1009 void LongType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2L); } 1010 void DoubleType.shortToThis(CodeGeneration gen) { gen.emit(Bytecode.I2D); } 1011 1012 } 1013 1014 aspect CodeGenerationBinaryOperations { 1015 // emit the desired operation on the operand(s) on the stack 1016 void Expr.emitOperation(CodeGeneration gen) {error();} 1017 // unary 1018 void MinusExpr.emitOperation(CodeGeneration gen) { type().neg(gen); } 1019 void PlusExpr.emitOperation(CodeGeneration gen) { } 1020 void BitNotExpr.emitOperation(CodeGeneration gen) { type().bitNot(gen); } 1021 void LogNotExpr.emitOperation(CodeGeneration gen) { type().logNot(gen); } 1022 1023 // binary 1024 void AddExpr.emitOperation(CodeGeneration gen) { type().add(gen); } 1025 void SubExpr.emitOperation(CodeGeneration gen) { type().sub(gen); } 1026 void MulExpr.emitOperation(CodeGeneration gen) { type().mul(gen); } 1027 void DivExpr.emitOperation(CodeGeneration gen) { type().div(gen); } 1028 void ModExpr.emitOperation(CodeGeneration gen) { type().rem(gen); } 1029 1030 void LShiftExpr.emitOperation(CodeGeneration gen) { type().shl(gen); } 1031 void RShiftExpr.emitOperation(CodeGeneration gen) { type().shr(gen); } 1032 void URShiftExpr.emitOperation(CodeGeneration gen) { type().ushr(gen); } 1033 void OrBitwiseExpr.emitOperation(CodeGeneration gen) { type().bitor(gen); } 1034 void AndBitwiseExpr.emitOperation(CodeGeneration gen) { type().bitand(gen); } 1035 void XorBitwiseExpr.emitOperation(CodeGeneration gen) { type().bitxor(gen); } 1036 1037 void TypeDecl.neg(CodeGeneration gen) { error(); } 1038 void IntegralType.neg(CodeGeneration gen) { gen.emit(Bytecode.INEG); } 1039 void LongType.neg(CodeGeneration gen) { gen.emit(Bytecode.LNEG); } 1040 void FloatType.neg(CodeGeneration gen) { gen.emit(Bytecode.FNEG); } 1041 void DoubleType.neg(CodeGeneration gen) { gen.emit(Bytecode.DNEG); } 1042 1043 void TypeDecl.bitNot(CodeGeneration gen) { error(); } 1044 void IntegralType.bitNot(CodeGeneration gen) { gen.emit(Bytecode.ICONST_M1).emit(Bytecode.IXOR); } 1045 void LongType.bitNot(CodeGeneration gen) { emitPushConstant(gen, -1); gen.emit(Bytecode.LXOR); } 1046 1047 void TypeDecl.logNot(CodeGeneration gen) { error();} 1048 void BooleanType.logNot(CodeGeneration gen) { gen.emit(Bytecode.ICONST_1).emit(Bytecode.IXOR); } 1049 1050 void TypeDecl.add(CodeGeneration gen) {error();} 1051 void LongType.add(CodeGeneration gen) {gen.emit(Bytecode.LADD);} 1052 void FloatType.add(CodeGeneration gen) {gen.emit(Bytecode.FADD);} 1053 void DoubleType.add(CodeGeneration gen) {gen.emit(Bytecode.DADD);} 1054 void IntegralType.add(CodeGeneration gen) {gen.emit(Bytecode.IADD);} 1055 1056 void TypeDecl.sub(CodeGeneration gen) {error();} 1057 void LongType.sub(CodeGeneration gen) {gen.emit(Bytecode.LSUB);} 1058 void FloatType.sub(CodeGeneration gen) {gen.emit(Bytecode.FSUB);} 1059 void DoubleType.sub(CodeGeneration gen) {gen.emit(Bytecode.DSUB);} 1060 void IntegralType.sub(CodeGeneration gen) {gen.emit(Bytecode.ISUB);} 1061 1062 void TypeDecl.mul(CodeGeneration gen) {error();} 1063 void LongType.mul(CodeGeneration gen) {gen.emit(Bytecode.LMUL);} 1064 void FloatType.mul(CodeGeneration gen) {gen.emit(Bytecode.FMUL);} 1065 void DoubleType.mul(CodeGeneration gen) {gen.emit(Bytecode.DMUL);} 1066 void IntegralType.mul(CodeGeneration gen) {gen.emit(Bytecode.IMUL);} 1067 1068 void TypeDecl.div(CodeGeneration gen) {error();} 1069 void LongType.div(CodeGeneration gen) {gen.emit(Bytecode.LDIV);} 1070 void FloatType.div(CodeGeneration gen) {gen.emit(Bytecode.FDIV);} 1071 void DoubleType.div(CodeGeneration gen) {gen.emit(Bytecode.DDIV);} 1072 void IntegralType.div(CodeGeneration gen) {gen.emit(Bytecode.IDIV);} 1073 1074 void TypeDecl.rem(CodeGeneration gen) {error();} 1075 void LongType.rem(CodeGeneration gen) {gen.emit(Bytecode.LREM);} 1076 void FloatType.rem(CodeGeneration gen) {gen.emit(Bytecode.FREM);} 1077 void DoubleType.rem(CodeGeneration gen) {gen.emit(Bytecode.DREM);} 1078 void IntegralType.rem(CodeGeneration gen) {gen.emit(Bytecode.IREM);} 1079 1080 void TypeDecl.shl(CodeGeneration gen) {error();} 1081 void LongType.shl(CodeGeneration gen) {gen.emit(Bytecode.LSHL);} 1082 void IntegralType.shl(CodeGeneration gen) {gen.emit(Bytecode.ISHL);} 1083 1084 void TypeDecl.shr(CodeGeneration gen) {error();} 1085 void LongType.shr(CodeGeneration gen) {gen.emit(Bytecode.LSHR);} 1086 void IntegralType.shr(CodeGeneration gen) {gen.emit(Bytecode.ISHR);} 1087 1088 void TypeDecl.ushr(CodeGeneration gen) {error();} 1089 void LongType.ushr(CodeGeneration gen) {gen.emit(Bytecode.LUSHR);} 1090 void IntegralType.ushr(CodeGeneration gen) {gen.emit(Bytecode.IUSHR);} 1091 1092 void TypeDecl.bitand(CodeGeneration gen) {error();} 1093 void LongType.bitand(CodeGeneration gen) {gen.emit(Bytecode.LAND);} 1094 void IntegralType.bitand(CodeGeneration gen) {gen.emit(Bytecode.IAND);} 1095 void BooleanType.bitand(CodeGeneration gen) {gen.emit(Bytecode.IAND);} 1096 1097 void TypeDecl.bitor(CodeGeneration gen) {error();} 1098 void LongType.bitor(CodeGeneration gen) {gen.emit(Bytecode.LOR);} 1099 void IntegralType.bitor(CodeGeneration gen) {gen.emit(Bytecode.IOR);} 1100 void BooleanType.bitor(CodeGeneration gen) {gen.emit(Bytecode.IOR);} 1101 1102 void TypeDecl.bitxor(CodeGeneration gen) {error();} 1103 void LongType.bitxor(CodeGeneration gen) {gen.emit(Bytecode.LXOR);} 1104 void IntegralType.bitxor(CodeGeneration gen) {gen.emit(Bytecode.IXOR);} 1105 void BooleanType.bitxor(CodeGeneration gen) {gen.emit(Bytecode.IXOR);} 1106 } 1107 1108 aspect CodeGenerationBranch { 1109 public void TypeDecl.branchLT(CodeGeneration gen, int label) { throw new Error("branchLT not supported for " + getClass().getName()); } 1110 public void DoubleType.branchLT(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPG).emitCompare(Bytecode.IFLT, label); } 1111 public void FloatType.branchLT(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPG).emitCompare(Bytecode.IFLT, label); } 1112 public void LongType.branchLT(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFLT, label); } 1113 public void IntegralType.branchLT(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPLT, label); } 1114 1115 public void TypeDecl.branchLE(CodeGeneration gen, int label) { throw new Error("branchLE not supported for " + getClass().getName()); } 1116 public void DoubleType.branchLE(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPG).emitCompare(Bytecode.IFLE, label); } 1117 public void FloatType.branchLE(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPG).emitCompare(Bytecode.IFLE, label); } 1118 public void LongType.branchLE(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFLE, label); } 1119 public void IntegralType.branchLE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPLE, label); } 1120 1121 public void TypeDecl.branchGE(CodeGeneration gen, int label) { throw new Error("branchGE not supported for " + getClass().getName()); } 1122 public void DoubleType.branchGE(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFGE, label); } 1123 public void FloatType.branchGE(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFGE, label); } 1124 public void LongType.branchGE(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFGE, label); } 1125 public void IntegralType.branchGE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPGE, label); } 1126 1127 public void TypeDecl.branchGT(CodeGeneration gen, int label) { throw new Error("branchGT not supported for " + getClass().getName()); } 1128 public void DoubleType.branchGT(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFGT, label); } 1129 public void FloatType.branchGT(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFGT, label); } 1130 public void LongType.branchGT(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFGT, label); } 1131 public void IntegralType.branchGT(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPGT, label); } 1132 1133 public void TypeDecl.branchEQ(CodeGeneration gen, int label) { throw new Error("branchEQ not supported for " + getClass().getName()); } 1134 public void DoubleType.branchEQ(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFEQ, label); } 1135 public void FloatType.branchEQ(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFEQ, label); } 1136 public void LongType.branchEQ(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFEQ, label); } 1137 public void IntegralType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPEQ, label); } 1138 public void BooleanType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPEQ, label); } 1139 public void ReferenceType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPEQ, label); } 1140 public void NullType.branchEQ(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPEQ, label); } 1141 1142 public void TypeDecl.branchNE(CodeGeneration gen, int label) { throw new Error("branchNE not supported for " + getClass().getName()); } 1143 public void DoubleType.branchNE(CodeGeneration gen, int label) { gen.emit(Bytecode.DCMPL).emitCompare(Bytecode.IFNE, label); } 1144 public void FloatType.branchNE(CodeGeneration gen, int label) { gen.emit(Bytecode.FCMPL).emitCompare(Bytecode.IFNE, label); } 1145 public void LongType.branchNE(CodeGeneration gen, int label) { gen.emit(Bytecode.LCMP).emitCompare(Bytecode.IFNE, label); } 1146 public void IntegralType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPNE, label); } 1147 public void BooleanType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ICMPNE, label); } 1148 public void ReferenceType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPNE, label); } 1149 public void NullType.branchNE(CodeGeneration gen, int label) { gen.emitCompare(Bytecode.IF_ACMPNE, label); } 1150 }