001: /*
002: * @(#)Label.java 1.2 04/12/06
003: *
004: * Copyright (c) 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution of
007: * this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.compiler;
010:
011: public class Label {
012:
013: ClassFile cf;
014: int target_pc = -1;
015: IntArray pc = new IntArray();
016: int size;
017:
018: Label(ClassFile cf) {
019: this .cf = cf;
020: }
021:
022: Label(ClassFile cf, int pc) {
023: this .cf = cf;
024: this .target_pc = pc;
025: }
026:
027: /**
028: * Fixes the position to which the label points as the current position in
029: * the code buffer
030: */
031: public void fix() {
032: target_pc = cf.codeBuffer.size();
033: setRelativePosition(target_pc);
034: }
035:
036: public Label shift(int offset) {
037: return new Label(this .cf, this .target_pc + offset);
038: }
039:
040: void setOffset(int offset) {
041: setRelativePosition(target_pc + offset);
042: }
043:
044: /**
045: * Fixes the position to which the label points
046: *
047: * @param tgt
048: * the relative position to which the label points
049: */
050: public void setRelativePosition(int tgt) {
051: int array[] = pc.getArray();
052: int sz = pc.size();
053: for (int i = 0; i < sz; i++) {
054: if (size == 2) {
055: cf.codeBuffer.set((short) (tgt - array[i]),
056: array[i] + 1);
057: } else if (size == 4) {
058: cf.codeBuffer.set((int) (tgt - array[i]), array[i] + 1);
059: }
060: }
061: }
062:
063: /**
064: * Fixes the position to which the label points
065: *
066: * @param tgt
067: * the absolute position to which the label points
068: */
069: public void setPosition(int tgt) {
070: int array[] = pc.getArray();
071: int sz = pc.size();
072: for (int i = 0; i < sz; i++) {
073: if (size == 2) {
074: cf.codeBuffer.set((short) tgt, array[i]);
075: } else if (size == 4) {
076: cf.codeBuffer.set((int) tgt, array[i]);
077: }
078: }
079: }
080:
081: short getPC() {
082: return (short) target_pc;
083: }
084:
085: void setPC(short pos) {
086: target_pc = pos;
087: }
088:
089: /**
090: * Registers the label and allocate 2 or 4 bytes in the code buffer.
091: */
092: public void register(int pos, int size) {
093: pc.add(pos);
094: this .size = size;
095: if (target_pc > 0) {
096: setRelativePosition(target_pc);
097: } else {
098: if (size == 2) {
099: cf.codeBuffer.add((short) 0);
100: } else if (size == 4) {
101: cf.codeBuffer.add((int) 0);
102: }
103: }
104: }
105: }
|