0001: /*
0002: * $Id: Code.java,v 1.8 2002/09/16 08:05:02 jkl Exp $
0003: *
0004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
0005: *
0006: * Use is subject to license terms, as defined in
0007: * Anvil Sofware License, Version 1.1. See LICENSE
0008: * file, or http://njet.org/license-1.1.txt
0009: */
0010: package anvil.codec;
0011:
0012: import java.util.ArrayList;
0013: import java.io.ByteArrayOutputStream;
0014: import java.io.DataOutputStream;
0015: import java.io.IOException;
0016:
0017: public class Code extends Attribute {
0018:
0019: protected Method _method;
0020: protected int _codeindex;
0021: protected Bytes _bytes;
0022: protected DataOutputStream _code;
0023: protected ExceptionHandler _current = null;
0024: protected ArrayList _exceptions = new ArrayList();
0025: protected int _maxlocals = 0;
0026: protected int[] _local = new int[8];
0027: protected int _locals = 0;
0028: protected int _stack = 0;
0029: protected int _maxstack = 0;
0030:
0031: public Code(Method method, ConstantPool pool) {
0032: super (pool);
0033: _method = method;
0034: _codeindex = pool.addUtf8(ATTR_Code);
0035: _bytes = new Bytes();
0036: _code = new DataOutputStream(_bytes);
0037: if ((_method.getFlags() & ACC_STATIC) == 0) {
0038: _maxlocals++;
0039: }
0040: }
0041:
0042: public Method getMethod() {
0043: return _method;
0044: }
0045:
0046: public void pushop() {
0047: _stack++;
0048: if (_stack > _maxstack) {
0049: _maxstack = _stack;
0050: }
0051: }
0052:
0053: public void pushop(int amount) {
0054: _stack += amount;
0055: if (_stack > _maxstack) {
0056: _maxstack = _stack;
0057: }
0058: }
0059:
0060: public void popop() {
0061: _stack--;
0062: }
0063:
0064: public void popop(int amount) {
0065: _stack -= amount;
0066: if (_stack < 0) {
0067: _stack = 0;
0068: } else if (_stack > _maxstack) {
0069: _maxstack = _stack;
0070: }
0071: }
0072:
0073: public int size() {
0074: return _bytes.size();
0075: }
0076:
0077: protected boolean isByte(int i) {
0078: return i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE;
0079: }
0080:
0081: protected boolean isShort(int i) {
0082: return i >= Short.MIN_VALUE && i <= Short.MAX_VALUE;
0083: }
0084:
0085: public String getName() {
0086: return ATTR_Code;
0087: }
0088:
0089: public Target getTarget() {
0090: return new Target(address());
0091: }
0092:
0093: public Source getSource() {
0094: return new Source(this );
0095: }
0096:
0097: public int address() {
0098: return _bytes.address();
0099: }
0100:
0101: public int getFirstLocal() {
0102: return ((_method.getFlags() & ACC_STATIC) != 0) ? 0 : 1;
0103: }
0104:
0105: public Code aload_first() {
0106: aload(getFirstLocal());
0107: return this ;
0108: }
0109:
0110: public int addLocal() {
0111: int size = _locals;
0112: if (size > 0) {
0113: return _local[--_locals];
0114: }
0115: return _maxlocals++;
0116: }
0117:
0118: public void endLocal(int releasedLocal) {
0119: int length = _local.length;
0120: int size = _locals;
0121: if (size >= length) {
0122: int[] local = new int[length + 8];
0123: System.arraycopy(_local, 0, local, 0, length);
0124: _local = local;
0125: }
0126: _local[_locals++] = releasedLocal;
0127: }
0128:
0129: public void addLocals(int amount) {
0130: while (amount-- > 0) {
0131: addLocal();
0132: }
0133: }
0134:
0135: public ExceptionHandler getCurrentHandler() {
0136: return _current;
0137: }
0138:
0139: public ExceptionHandler startExceptionHandler(boolean withfinally) {
0140: _current = new ExceptionHandler(this , _current, withfinally);
0141: return _current;
0142: }
0143:
0144: public void endExceptionHandler(ExceptionHandler handler) {
0145: if (_current != handler) {
0146: //throw new RuntimeException("Current exception handler is different than the one being closed");
0147: }
0148: _current = handler.getParent();
0149: _exceptions.add(handler);
0150: }
0151:
0152: public Code writeShort(int address, short s) {
0153: _bytes.setShort(address, s);
0154: return this ;
0155: }
0156:
0157: public Code writeInt(int address, int i) {
0158: _bytes.setInt(address, i);
0159: return this ;
0160: }
0161:
0162: protected Code writeByte(int b) {
0163: try {
0164: _code.writeByte(b);
0165: } catch (IOException e) {
0166: }
0167: return this ;
0168: }
0169:
0170: protected Code writeShort(int s) {
0171: try {
0172: _code.writeShort(s);
0173: } catch (IOException e) {
0174: }
0175: return this ;
0176: }
0177:
0178: protected Code writeInt(int s) {
0179: try {
0180: _code.writeInt(s);
0181: } catch (IOException e) {
0182: }
0183: return this ;
0184: }
0185:
0186: public Code arraylength() {
0187: writeByte(190);
0188: return this ;
0189: }
0190:
0191: public Code anewarray(int index) {
0192: writeByte(189);
0193: writeShort(index);
0194: return this ;
0195: }
0196:
0197: public Code anewarray(String classname) {
0198: writeByte(189);
0199: writeShort(_pool.addClass(classname));
0200: return this ;
0201: }
0202:
0203: public Code anewarray(Info clazz) {
0204: writeByte(189);
0205: writeShort(clazz.getIndex());
0206: return this ;
0207: }
0208:
0209: public Code anewarray(int index, int dims) {
0210: writeByte(197);
0211: writeShort(index);
0212: writeByte(dims);
0213: return this ;
0214: }
0215:
0216: public Code anewarray(String classname, int dims) {
0217: writeByte(197);
0218: writeShort(_pool.addClass(classname));
0219: writeByte(dims);
0220: return this ;
0221: }
0222:
0223: public Code anewarray(Info clazz, int dims) {
0224: writeByte(197);
0225: writeShort(clazz.getIndex());
0226: writeByte(dims);
0227: return this ;
0228: }
0229:
0230: public Code aastore() {
0231: popop(3);
0232: writeByte(83);
0233: return this ;
0234: }
0235:
0236: public Code aaload() {
0237: popop();
0238: writeByte(50);
0239: return this ;
0240: }
0241:
0242: public Code newarray(int type) {
0243: writeByte(188);
0244: writeByte(type);
0245: return this ;
0246: }
0247:
0248: public Code newarray(Info info) {
0249: writeByte(188);
0250: writeByte(info.getIndex());
0251: return this ;
0252: }
0253:
0254: public Code checkcast(int type) {
0255: writeByte(192);
0256: writeShort(type);
0257: return this ;
0258: }
0259:
0260: public Code checkcast(String classname) {
0261: return checkcast(_pool.addClass(classname));
0262: }
0263:
0264: public Code instance_of(int type) {
0265: writeByte(193);
0266: writeShort(type);
0267: return this ;
0268: }
0269:
0270: public Code instance_of(String classname) {
0271: return instance_of(_pool.addClass(classname));
0272: }
0273:
0274: public Code laload() {
0275: writeByte(47);
0276: return this ;
0277: }
0278:
0279: public Code lastore() {
0280: popop(4);
0281: writeByte(80);
0282: return this ;
0283: }
0284:
0285: public Code faload() {
0286: popop();
0287: writeByte(48);
0288: return this ;
0289: }
0290:
0291: public Code fastore() {
0292: popop(3);
0293: writeByte(81);
0294: return this ;
0295: }
0296:
0297: public Code daload() {
0298: writeByte(49);
0299: return this ;
0300: }
0301:
0302: public Code dastore() {
0303: popop(4);
0304: writeByte(82);
0305: return this ;
0306: }
0307:
0308: public Code baload() {
0309: popop();
0310: writeByte(51);
0311: return this ;
0312: }
0313:
0314: public Code bastore() {
0315: popop(3);
0316: writeByte(84);
0317: return this ;
0318: }
0319:
0320: public Code caload() {
0321: popop();
0322: writeByte(52);
0323: return this ;
0324: }
0325:
0326: public Code castore() {
0327: popop(3);
0328: writeByte(85);
0329: return this ;
0330: }
0331:
0332: public Code saload() {
0333: popop();
0334: writeByte(53);
0335: return this ;
0336: }
0337:
0338: public Code sastore() {
0339: popop(3);
0340: writeByte(86);
0341: return this ;
0342: }
0343:
0344: public Code iaload() {
0345: popop();
0346: writeByte(46);
0347: return this ;
0348: }
0349:
0350: public Code iastore() {
0351: popop(3);
0352: writeByte(79);
0353: return this ;
0354: }
0355:
0356: public Code aconst_null() {
0357: pushop();
0358: return writeByte(1);
0359: }
0360:
0361: public Code astring(String str) {
0362: if (str == null) {
0363: return aconst_null();
0364: } else {
0365: return ldc(_pool.addString(str));
0366: }
0367: }
0368:
0369: public Code aload(int local) {
0370: pushop();
0371: if (0 <= local && local <= 3) {
0372: writeByte(42 + local);
0373: } else {
0374: if (isByte(local)) {
0375: writeByte(25);
0376: writeByte(local);
0377: } else {
0378: writeByte(196);
0379: writeByte(25);
0380: writeShort(local);
0381: }
0382: }
0383: return this ;
0384: }
0385:
0386: public Code astore(int local) {
0387: popop();
0388: if (0 <= local && local <= 3) {
0389: writeByte(75 + local);
0390: } else {
0391: if (isByte(local)) {
0392: writeByte(58);
0393: writeByte(local);
0394: } else {
0395: writeByte(196);
0396: writeByte(58);
0397: writeShort(local);
0398: }
0399: }
0400: return this ;
0401: }
0402:
0403: public Code iload(int local) {
0404: pushop();
0405: if (0 <= local && local <= 3) {
0406: writeByte(26 + local);
0407: } else {
0408: if (isByte(local)) {
0409: writeByte(21);
0410: writeByte(local);
0411: } else {
0412: writeByte(196);
0413: writeByte(21);
0414: writeShort(local);
0415: }
0416: }
0417: return this ;
0418: }
0419:
0420: public Code istore(int local) {
0421: popop();
0422: if (0 <= local && local <= 3) {
0423: writeByte(59 + local);
0424: } else {
0425: if (isByte(local)) {
0426: writeByte(54);
0427: writeByte(local);
0428: } else {
0429: writeByte(196);
0430: writeByte(54);
0431: writeShort(local);
0432: }
0433: }
0434: return this ;
0435: }
0436:
0437: public Code iadd() {
0438: popop();
0439: return writeByte(96);
0440: }
0441:
0442: public Code athrow() {
0443: popop();
0444: return writeByte(191);
0445: }
0446:
0447: public Code ireturn() {
0448: popop();
0449: return writeByte(172);
0450: }
0451:
0452: public Code areturn() {
0453: popop();
0454: return writeByte(176);
0455: }
0456:
0457: public Code vreturn() {
0458: return writeByte(177);
0459: }
0460:
0461: public Code ldc(int index) {
0462: return ldc(_pool.get(index));
0463: }
0464:
0465: public Code ldc(Info info) {
0466: int index = info.getIndex();
0467: if (info.getWidth() == 2) {
0468: pushop(2);
0469: writeByte(20);
0470: writeShort(index);
0471: } else {
0472: pushop();
0473: if (index < 256) {
0474: writeByte(18);
0475: writeByte(index);
0476: } else {
0477: writeByte(19);
0478: writeShort(index);
0479: }
0480: }
0481: return this ;
0482: }
0483:
0484: public Code invokevirtual(int index) {
0485: return invokevirtual(_pool.get(index));
0486: }
0487:
0488: public Code invokevirtual(Info info) {
0489: MethodRefInfo methodinfo = (MethodRefInfo) info;
0490: int retw = methodinfo.getReturnWidth();
0491: int argc = methodinfo.getArgumentCount();
0492: popop(argc + 1 - retw);
0493: writeByte(182);
0494: writeShort(info.getIndex());
0495: return this ;
0496: }
0497:
0498: public Code invokespecial(int index) {
0499: return invokespecial(_pool.get(index));
0500: }
0501:
0502: public Code invokespecial(Info info) {
0503: MethodRefInfo methodinfo = (MethodRefInfo) info;
0504: int retw = methodinfo.getReturnWidth();
0505: int argc = methodinfo.getArgumentCount();
0506: popop(argc + 1 - retw);
0507: writeByte(183);
0508: writeShort(info.getIndex());
0509: return this ;
0510: }
0511:
0512: public Code invokestatic(int index) {
0513: return invokestatic(_pool.get(index));
0514: }
0515:
0516: public Code invokestatic(Info info) {
0517: MethodRefInfo methodinfo = (MethodRefInfo) info;
0518: int retw = methodinfo.getReturnWidth();
0519: int argc = methodinfo.getArgumentCount();
0520: popop(argc - retw);
0521: writeByte(184);
0522: writeShort(info.getIndex());
0523: return this ;
0524: }
0525:
0526: public Code invokeinterface(int index) {
0527: return invokeinterface(_pool.get(index));
0528: }
0529:
0530: public Code invokeinterface(Info info) {
0531: MethodRefInfo methodinfo = (MethodRefInfo) info;
0532: int retw = methodinfo.getReturnWidth();
0533: int argc = methodinfo.getArgumentCount();
0534: popop(1 + argc - retw);
0535: writeByte(185);
0536: writeShort(info.getIndex());
0537: writeByte(1 + argc);
0538: writeByte(0);
0539: return this ;
0540: }
0541:
0542: public Code self() {
0543: pushop();
0544: return writeByte(42);
0545: }
0546:
0547: public Code getfield(int index) {
0548: pushop(((FieldRefInfo) _pool.get(index)).getFieldWidth() - 1);
0549: writeByte(180);
0550: writeShort(index);
0551: return this ;
0552: }
0553:
0554: public Code getstatic(int index) {
0555: pushop(((FieldRefInfo) _pool.get(index)).getFieldWidth());
0556: writeByte(178);
0557: writeShort(index);
0558: return this ;
0559: }
0560:
0561: public Code putfield(int index) {
0562: popop(1 + ((FieldRefInfo) _pool.get(index)).getFieldWidth());
0563: writeByte(181);
0564: writeShort(index);
0565: return this ;
0566: }
0567:
0568: public Code putstatic(int index) {
0569: popop(((FieldRefInfo) _pool.get(index)).getFieldWidth());
0570: writeByte(179);
0571: writeShort(index);
0572: return this ;
0573: }
0574:
0575: public Code getfield(Info info) {
0576: pushop(((FieldRefInfo) info).getFieldWidth() - 1);
0577: writeByte(180);
0578: writeShort(info.getIndex());
0579: return this ;
0580: }
0581:
0582: public Code getstatic(Info info) {
0583: pushop(((FieldRefInfo) info).getFieldWidth());
0584: writeByte(178);
0585: writeShort(info.getIndex());
0586: return this ;
0587: }
0588:
0589: public Code putfield(Info info) {
0590: popop(((FieldRefInfo) info).getFieldWidth() + 1);
0591: writeByte(181);
0592: writeShort(info.getIndex());
0593: return this ;
0594: }
0595:
0596: public Code putstatic(Info info) {
0597: popop(((FieldRefInfo) info).getFieldWidth());
0598: writeByte(179);
0599: writeShort(info.getIndex());
0600: return this ;
0601: }
0602:
0603: public Code getfield(Field field) {
0604: pushop(field.getWidth() - 1);
0605: writeByte(180);
0606: writeShort(field.getIndex());
0607: return this ;
0608: }
0609:
0610: public Code getstatic(Field field) {
0611: pushop(field.getWidth());
0612: writeByte(178);
0613: writeShort(field.getIndex());
0614: return this ;
0615: }
0616:
0617: public Code putfield(Field field) {
0618: popop(field.getWidth() + 1);
0619: writeByte(181);
0620: writeShort(field.getIndex());
0621: return this ;
0622: }
0623:
0624: public Code putstatic(Field field) {
0625: popop(field.getWidth());
0626: writeByte(179);
0627: writeShort(field.getIndex());
0628: return this ;
0629: }
0630:
0631: public Code anew(int index) {
0632: pushop();
0633: writeByte(187);
0634: writeShort(index);
0635: return this ;
0636: }
0637:
0638: public Code anew(Info info) {
0639: pushop();
0640: writeByte(187);
0641: writeShort(info.getIndex());
0642: return this ;
0643: }
0644:
0645: public Code dup() {
0646: pushop();
0647: return writeByte(89);
0648: }
0649:
0650: public Code dup_x1() {
0651: pushop();
0652: return writeByte(90);
0653: }
0654:
0655: public Code dup_x2() {
0656: pushop();
0657: return writeByte(91);
0658: }
0659:
0660: public Code dup2() {
0661: pushop(2);
0662: return writeByte(92);
0663: }
0664:
0665: public Code dup2_x1() {
0666: pushop(2);
0667: return writeByte(93);
0668: }
0669:
0670: public Code dup2_x2() {
0671: pushop(2);
0672: return writeByte(94);
0673: }
0674:
0675: public Code pop() {
0676: popop();
0677: return writeByte(87);
0678: }
0679:
0680: public Code iconst(boolean b) {
0681: return iconst(b ? 1 : 0);
0682: }
0683:
0684: public Code iconst(int i) {
0685: if (i >= -1 && i <= 5) {
0686: pushop();
0687: writeByte(2 + (i + 1));
0688: } else if (isByte(i)) {
0689: pushop();
0690: writeByte(16);
0691: writeByte((byte) i);
0692: } else if (isShort(i)) {
0693: pushop();
0694: writeByte(17);
0695: writeShort((short) i);
0696: } else {
0697: return ldc(_pool.addInt(i));
0698: }
0699: return this ;
0700: }
0701:
0702: public Code lconst(long l) {
0703: if (l == 0) {
0704: pushop(2);
0705: writeByte(9);
0706: return this ;
0707: } else if (l == 1) {
0708: pushop(2);
0709: writeByte(10);
0710: return this ;
0711: }
0712: return ldc(_pool.addLong(l));
0713: }
0714:
0715: public Code fconst(float f) {
0716: if (f == 0.0) {
0717: pushop();
0718: writeByte(11);
0719: return this ;
0720: } else if (f == 1.0) {
0721: pushop();
0722: writeByte(12);
0723: return this ;
0724: } else if (f == 2.0) {
0725: pushop();
0726: writeByte(13);
0727: return this ;
0728: }
0729: return ldc(_pool.addFloat(f));
0730: }
0731:
0732: public Code dconst(double d) {
0733: if (d == 0.0) {
0734: pushop(2);
0735: writeByte(14);
0736: return this ;
0737: } else if (d == 1.0) {
0738: pushop(2);
0739: writeByte(15);
0740: return this ;
0741: }
0742: return ldc(_pool.addDouble(d));
0743: }
0744:
0745: public Code go_to(Target target) {
0746: int address = address();
0747: writeByte(167);
0748: writeShort(target.getAddress() - address);
0749: return this ;
0750: }
0751:
0752: public Code go_to(Source source) {
0753: int address = address();
0754: writeByte(167);
0755: writeShort(0x7fff);
0756: source.add(address, address + 1);
0757: return this ;
0758: }
0759:
0760: public Source go_to() {
0761: int address = address();
0762: writeByte(167);
0763: writeShort(0x7fff);
0764: return new Source(this , address, address + 1);
0765: }
0766:
0767: public Code if_null(Target target) {
0768: popop();
0769: int address = address();
0770: writeByte(198);
0771: writeShort(target.getAddress() - address);
0772: return this ;
0773: }
0774:
0775: public Code if_null(Source source) {
0776: popop();
0777: int address = address();
0778: writeByte(198);
0779: writeShort(0x7ff);
0780: source.add(address, address + 1);
0781: return this ;
0782: }
0783:
0784: public Source if_null() {
0785: popop();
0786: int address = address();
0787: writeByte(198);
0788: writeShort(0x7fff);
0789: return new Source(this , address, address + 1);
0790: }
0791:
0792: public Code if_nonnull(Target target) {
0793: popop();
0794: int address = address();
0795: writeByte(199);
0796: writeShort(target.getAddress() - address);
0797: return this ;
0798: }
0799:
0800: public Code if_nonnull(Source source) {
0801: popop();
0802: int address = address();
0803: writeByte(199);
0804: writeShort(0x7ff);
0805: source.add(address, address + 1);
0806: return this ;
0807: }
0808:
0809: public Source if_nonnull() {
0810: popop();
0811: int address = address();
0812: writeByte(199);
0813: writeShort(0x7fff);
0814: return new Source(this , address, address + 1);
0815: }
0816:
0817: public Code if_icmpeq(Target target) {
0818: popop(2);
0819: int address = address();
0820: writeByte(159);
0821: writeShort(target.getAddress() - address);
0822: return this ;
0823: }
0824:
0825: public Code if_icmpeq(Source source) {
0826: popop(2);
0827: int address = address();
0828: writeByte(159);
0829: writeShort(0x7ff);
0830: source.add(address, address + 1);
0831: return this ;
0832: }
0833:
0834: public Source if_icmpeq() {
0835: popop(2);
0836: int address = address();
0837: writeByte(159);
0838: writeShort(0x7fff);
0839: return new Source(this , address, address + 1);
0840: }
0841:
0842: public Code if_icmpne(Target target) {
0843: popop(2);
0844: int address = address();
0845: writeByte(160);
0846: writeShort(target.getAddress() - address);
0847: return this ;
0848: }
0849:
0850: public Code if_icmpne(Source source) {
0851: popop(2);
0852: int address = address();
0853: writeByte(160);
0854: writeShort(0x7ff);
0855: source.add(address, address + 1);
0856: return this ;
0857: }
0858:
0859: public Source if_icmpne() {
0860: popop(2);
0861: int address = address();
0862: writeByte(160);
0863: writeShort(0x7fff);
0864: return new Source(this , address, address + 1);
0865: }
0866:
0867: public Code if_icmpge(Target target) {
0868: popop(2);
0869: int address = address();
0870: writeByte(162);
0871: writeShort(target.getAddress() - address);
0872: return this ;
0873: }
0874:
0875: public Code if_icmpge(Source source) {
0876: popop(2);
0877: int address = address();
0878: writeByte(162);
0879: writeShort(0x7ff);
0880: source.add(address, address + 1);
0881: return this ;
0882: }
0883:
0884: public Source if_icmpge() {
0885: popop(2);
0886: int address = address();
0887: writeByte(162);
0888: writeShort(0x7fff);
0889: return new Source(this , address, address + 1);
0890: }
0891:
0892: public Code if_eq(Target target) {
0893: popop();
0894: int address = address();
0895: writeByte(153);
0896: writeShort(target.getAddress() - address);
0897: return this ;
0898: }
0899:
0900: public Code if_eq(Source source) {
0901: popop();
0902: int address = address();
0903: writeByte(153);
0904: writeShort(0x7ff);
0905: source.add(address, address + 1);
0906: return this ;
0907: }
0908:
0909: public Source if_eq() {
0910: popop();
0911: int address = address();
0912: writeByte(153);
0913: writeShort(0x7fff);
0914: return new Source(this , address, address + 1);
0915: }
0916:
0917: public Code if_ne(Target target) {
0918: popop();
0919: int address = address();
0920: writeByte(154);
0921: writeShort(target.getAddress() - address);
0922: return this ;
0923: }
0924:
0925: public Code if_ne(Source source) {
0926: popop();
0927: int address = address();
0928: writeByte(154);
0929: writeShort(0x7ff);
0930: source.add(address, address + 1);
0931: return this ;
0932: }
0933:
0934: public Source if_ne() {
0935: popop();
0936: int address = address();
0937: writeByte(154);
0938: writeShort(0x7fff);
0939: return new Source(this , address, address + 1);
0940: }
0941:
0942: public Code if_lt(Target target) {
0943: popop();
0944: int address = address();
0945: writeByte(155);
0946: writeShort(target.getAddress() - address);
0947: return this ;
0948: }
0949:
0950: public Code if_lt(Source source) {
0951: popop();
0952: int address = address();
0953: writeByte(155);
0954: writeShort(0x7ff);
0955: source.add(address, address + 1);
0956: return this ;
0957: }
0958:
0959: public Source if_lt() {
0960: popop();
0961: int address = address();
0962: writeByte(155);
0963: writeShort(0x7fff);
0964: return new Source(this , address, address + 1);
0965: }
0966:
0967: public Code if_le(Target target) {
0968: popop();
0969: int address = address();
0970: writeByte(158);
0971: writeShort(target.getAddress() - address);
0972: return this ;
0973: }
0974:
0975: public Code if_le(Source source) {
0976: popop();
0977: int address = address();
0978: writeByte(158);
0979: writeShort(0x7ff);
0980: source.add(address, address + 1);
0981: return this ;
0982: }
0983:
0984: public Source if_le() {
0985: popop();
0986: int address = address();
0987: writeByte(158);
0988: writeShort(0x7fff);
0989: return new Source(this , address, address + 1);
0990: }
0991:
0992: public Code if_gt(Target target) {
0993: popop();
0994: int address = address();
0995: writeByte(157);
0996: writeShort(target.getAddress() - address);
0997: return this ;
0998: }
0999:
1000: public Code if_gt(Source source) {
1001: popop();
1002: int address = address();
1003: writeByte(157);
1004: writeShort(0x7fff);
1005: source.add(address, address + 1);
1006: return this ;
1007: }
1008:
1009: public Source if_gt() {
1010: popop();
1011: int address = address();
1012: writeByte(157);
1013: writeShort(0x7fff);
1014: return new Source(this , address, address + 1);
1015: }
1016:
1017: public Code if_ge(Target target) {
1018: popop();
1019: int address = address();
1020: writeByte(156);
1021: writeShort(target.getAddress() - address);
1022: return this ;
1023: }
1024:
1025: public Code if_ge(Source source) {
1026: popop();
1027: int address = address();
1028: writeByte(156);
1029: writeShort(0x7fff);
1030: source.add(address, address + 1);
1031: return this ;
1032: }
1033:
1034: public Source if_ge() {
1035: popop();
1036: int address = address();
1037: writeByte(156);
1038: writeShort(0x7fff);
1039: return new Source(this , address, address + 1);
1040: }
1041:
1042: public Code ixor() {
1043: popop();
1044: writeByte(130);
1045: return this ;
1046: }
1047:
1048: public Code iinc(int local, int amount) {
1049: if (isByte(amount) && local < 0xff) {
1050: writeByte(132);
1051: writeByte((byte) local);
1052: writeByte((byte) amount);
1053: return this ;
1054: }
1055: writeShort(196);
1056: writeByte(132);
1057: writeShort((short) local);
1058: writeShort((short) amount);
1059: return this ;
1060: }
1061:
1062: public Code jsr(Target target) {
1063: int address = address();
1064: writeByte(168);
1065: writeShort(target.getAddress() - address);
1066: return this ;
1067: }
1068:
1069: public Code jsr(Source source) {
1070: int address = address();
1071: writeByte(168);
1072: writeShort(0);
1073: source.add(address, address + 1);
1074: return this ;
1075: }
1076:
1077: public Source jsr() {
1078: int address = address();
1079: writeByte(168);
1080: writeShort(0x7fff);
1081: return new Source(this , address, address + 1);
1082: }
1083:
1084: public Code ret(int local) {
1085: writeShort(169);
1086: writeByte(local);
1087: return this ;
1088: }
1089:
1090: public Code monitorenter() {
1091: popop();
1092: writeByte(194);
1093: return this ;
1094: }
1095:
1096: public Code monitorexit() {
1097: popop();
1098: writeByte(195);
1099: return this ;
1100: }
1101:
1102: public Code swap() {
1103: writeByte(95);
1104: return this ;
1105: }
1106:
1107: public Code nop() {
1108: writeByte(0);
1109: return this ;
1110: }
1111:
1112: public Code print(String text) {
1113: getstatic(_pool.addFieldRef("java/lang/System", "out",
1114: "Ljava/io/PrintStream;"));
1115: astring(text);
1116: invokevirtual(_pool.addMethodRef("java/io/PrintStream",
1117: "print", "(Ljava/lang/String;)V"));
1118: return this ;
1119: }
1120:
1121: public Code println(String text) {
1122: getstatic(_pool.addFieldRef("java/lang/System", "out",
1123: "Ljava/io/PrintStream;"));
1124: astring(text);
1125: invokevirtual(_pool.addMethodRef("java/io/PrintStream",
1126: "println", "(Ljava/lang/String;)V"));
1127: return this ;
1128: }
1129:
1130: public Switch select() {
1131: popop();
1132: return new Switch(this );
1133: }
1134:
1135: public int getExceptionTableSize() {
1136: int count = 0;
1137: int size = _exceptions.size();
1138: for (int i = 0; i < size; i++) {
1139: ExceptionHandler h = (ExceptionHandler) _exceptions.get(i);
1140: count += h.getTableSize();
1141: }
1142: return count;
1143: }
1144:
1145: public void write(DataOutputStream output) throws IOException {
1146: if (_stack != 0) {
1147: System.out.println("Code stack integrity failed: " + _stack
1148: + " operands at the end of method");
1149: //throw new RuntimeException("Code stack integrity failed: "+_stack+" operands at the end of method");
1150: }
1151: int exsize = getExceptionTableSize();
1152: int size = _bytes.size() + 12 + exsize * 4 * 2;
1153: output.writeShort(_codeindex);
1154: output.writeInt(size);
1155: output.writeShort(_maxstack);
1156: output.writeShort(_maxlocals);
1157:
1158: output.writeInt(_bytes.size());
1159: _bytes.writeTo(output);
1160:
1161: output.writeShort(exsize);
1162: int n = _exceptions.size();
1163: for (int i = 0; i < n; i++) {
1164: ((ExceptionHandler) _exceptions.get(i)).write(output);
1165: }
1166:
1167: output.writeShort(0);
1168: }
1169: }
|