001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.utils.bytecode;
022
023/**
024 * Interface which encapsulates the stream to which Java bytecode can
025 * be written.
026 *
027 * <p>
028 * The context takes care of all the book-keeping tasks associated with emitting
029 * well-formed byte code. For example, the context manages jumps and local
030 * variables.
031 * </p>
032 *
033 * <p>
034 * Most of the funcionality here is very low level. You will almost certainly
035 * want to use CodeGenerator instances to manipulate a CodeContext, rather than
036 * writing to it yourself.
037 * </p>
038 *
039 * @author Thomas Down
040 * @author Matthew Pocock
041 */
042
043public interface CodeContext {
044  /**
045   * Get the class for which a method is being generated.
046   *
047   * @return the current class
048   */
049  public CodeClass getCodeClass();
050
051  /**
052   * Get the method which is being generated.
053   *
054   * @return the current method
055   */
056  public CodeMethod getCodeMethod();
057
058  /**
059   * Get the constants pool for this context.
060   *
061   * @return the contant pool
062   */
063  public ConstantPool getConstants();
064
065  // Write methods.
066
067  /**
068   * Write a single byte to the context.
069   *
070   * <p>
071   * This can be used both to write opcodes and to write byte data to the
072   * context.
073   * </p>
074   *
075   * @param  b the byte to write
076   */
077  public void writeByte(byte b) throws CodeException;
078
079  /**
080   * Write a short (2 bytes) to the context.
081   *
082   * @param i  the short to write
083   */
084  public void writeShort(int i) throws CodeException;
085
086  /**
087   * Write the offset of a Label to the context.
088   *
089   * <p>This can be called before or after markLabel is invoked for the
090   * corresponding label. The context will ensure that the offset is
091   * correctly written before the method is fully emitted.</p>
092   *
093   * @param lab  the Label to write
094   */
095  public void writeLabel(Label lab) throws CodeException;
096
097  /**
098   * Resolve a local variable to the local variable slot assigned to it.
099   *
100   * <p>The context will ensure that local variables are stored in their
101   * own bits of the local variable area. It may chose to re-use portions
102   * of this area as local variables go out of scope.</p>
103   *
104   * @param lv  the LocalVariable to resolve
105   * @return the index of the local variable slot
106   */
107  public int resolveLocal(LocalVariable lv) throws CodeException;
108
109  /**
110   * Mark a label at the current point in the stream.
111   *
112   * <p>This can be used as the target for branching instructions, such as
113   * GOTO and IF.</p>
114   *
115   * @param lab the Label to mark
116   * @throws CodeException if the label has previously been marked
117   */
118  public void markLabel(Label lab) throws CodeException;
119
120  /**
121   * Register a concrete type for a parametric type.
122   *
123   * <p>This is the mechanism where-by real CodeClass types are associated
124   * with the virtual ParametricType types. If type pubishes that it
125   * is a primative, an object or an array, then the concreteType must be
126   * compattible. It's an error to bind the VOID type.</p>
127   *
128   * @for.developer
129   *  You should probably call
130   * <code>ParametricType.canAccept(concreteType)</code> to make sure of this.
131   * This implementation will shield you from any modifications to the exact
132   * semantics of ParametricType.
133   *
134   * @param type  ParametricType the parametric type to register
135   * @param concreteType  the CodeClass that it resolves to
136   * @throws CodeException if the type has already been registered or if the
137   *   guarantees about type made in the parametric type are violated
138   */
139  public void registerParametricType(ParametricType type, CodeClass concreteType)
140          throws CodeException;
141
142  /**
143   * Resolve a parametric type to a concrete class.
144   *
145   * <p>The type will be resolved by first searching through all those
146   * registered with this context. If it found there, this value is returned.
147   * If it is not, then the emediate parent context is searched. This parent
148   * is responsible for searching its parent and so on. If a context has no
149   * parent and the type is not registered with this context, it should raise
150   * a CodeException.</p>
151   *
152   * @param type  the ParametricType to resolve
153   * @return the  ColdeClass associated with that parametric type
154   * @throws CodeException if the type has not been registered
155   */
156  public CodeClass resolveParametricType(ParametricType type)
157          throws CodeException;
158
159  /**
160   * Open a sub context.
161   *
162   * <p>The sub context should inherit all the state of the parent context.
163   * Modifications to the state of the child (for example, local variable
164   * management or registered labels) should not be propogated to the parent.
165   * Modifications to the parent should not be propogated to the child.
166   * However, contexts should be used serialy, and only one context should be
167   * accessible to a code generator at a time, so in practice, there should be
168   * no way for a code generator using a child context to alter the state of
169   * or discover the state of the parent context.</p>
170   */
171  public CodeContext subContext();
172
173  /**
174   * Open the context for writing.
175   *
176   * <p>This must be called before any code writing methods are called. It
177   * can not be called more than once.</p>
178   */
179  public void open() throws CodeException;
180
181  /**
182   * Close the context for writing. It is at this point that any process
183   * necisary for comitting the bytecode will be executed.
184   *
185   * <p>This must be called after all code writing methods have been called.
186   * It can not be called more than once.</p>
187   */
188  public void close() throws CodeException;
189
190  // Exception tables
191
192  /**
193   * Add an exception table entry.
194   *
195   * @param startHandled    the beginning of the try block
196   * @param endHandled      the end of the try block
197   * @param eClass          the exception class
198   * @param handler         the beginning of the exception handler
199   * @throws CodeException
200   */ 
201  public void addExceptionTableEntry(Label startHandled,
202                                     Label endHandled,
203                                     CodeClass eClass,
204                                     Label handler)
205          throws CodeException;
206
207}