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}