📄 manual.html
字号:
<div align="left"> <table cellspacing="4" cellpadding="0" border="0"> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#ffffff"><pre> Type return_type = Type.VOID; Type[] arg_types = new Type[] { new ArrayType(Type.STRING, 1) }; </pre></td> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> </table> </div> <p> <tt>Type</tt> also contains methods to convert types into textual signatures and vice versa. The sub-classes contain implementations of the routines and constraints specified by the Java Language Specification. </p> </blockquote> </p> </td></tr> <tr><td><br/></td></tr> </table> <table border="0" cellspacing="0" cellpadding="2" width="100%"> <tr><td bgcolor="#525D76"> <font color="#ffffff" face="arial,helvetica,sanserif"> <a name="3.3.2 Generic fields and methods"><strong>3.3.2 Generic fields and methods</strong></a> </font> </td></tr> <tr><td> <blockquote> <p> Fields are represented by <tt>FieldGen</tt> objects, which may be freely modified by the user. If they have the access rights <tt>static final</tt>, i.e., are constants and of basic type, they may optionally have an initializing value. </p> <p> Generic methods contain methods to add exceptions the method may throw, local variables, and exception handlers. The latter two are represented by user-configurable objects as well. Because exception handlers and local variables contain references to byte code addresses, they also take the role of an <em>instruction targeter</em> in our terminology. Instruction targeters contain a method <tt>updateTarget()</tt> to redirect a reference. This is somewhat related to the Observer design pattern. Generic (non-abstract) methods refer to <em>instruction lists</em> that consist of instruction objects. References to byte code addresses are implemented by handles to instruction objects. If the list is updated the instruction targeters will be informed about it. This is explained in more detail in the following sections. </p> <p> The maximum stack size needed by the method and the maximum number of local variables used may be set manually or computed via the <tt>setMaxStack()</tt> and <tt>setMaxLocals()</tt> methods automatically. </p> </blockquote> </p> </td></tr> <tr><td><br/></td></tr> </table> <table border="0" cellspacing="0" cellpadding="2" width="100%"> <tr><td bgcolor="#525D76"> <font color="#ffffff" face="arial,helvetica,sanserif"> <a name="3.3.3 Instructions"><strong>3.3.3 Instructions</strong></a> </font> </td></tr> <tr><td> <blockquote> <p> Modeling instructions as objects may look somewhat odd at first sight, but in fact enables programmers to obtain a high-level view upon control flow without handling details like concrete byte code offsets. Instructions consist of an opcode (sometimes called tag), their length in bytes and an offset (or index) within the byte code. Since many instructions are immutable (stack operators, e.g.), the <tt>InstructionConstants</tt> interface offers shareable predefined "fly-weight" constants to use. </p> <p> Instructions are grouped via sub-classing, the type hierarchy of instruction classes is illustrated by (incomplete) figure in the appendix. The most important family of instructions are the <em>branch instructions</em>, e.g., <tt>goto</tt>, that branch to targets somewhere within the byte code. Obviously, this makes them candidates for playing an <tt>InstructionTargeter</tt> role, too. Instructions are further grouped by the interfaces they implement, there are, e.g., <tt>TypedInstruction</tt>s that are associated with a specific type like <tt>ldc</tt>, or <tt>ExceptionThrower</tt> instructions that may raise exceptions when executed. </p> <p> All instructions can be traversed via <tt>accept(Visitor v)</tt> methods, i.e., the Visitor design pattern. There is however some special trick in these methods that allows to merge the handling of certain instruction groups. The <tt>accept()</tt> do not only call the corresponding <tt>visit()</tt> method, but call <tt>visit()</tt> methods of their respective super classes and implemented interfaces first, i.e., the most specific <tt>visit()</tt> call is last. Thus one can group the handling of, say, all <tt>BranchInstruction</tt>s into one single method. </p> <p> For debugging purposes it may even make sense to "invent" your own instructions. In a sophisticated code generator like the one used as a backend of the <a href="http://barat.sourceforge.net">Barat framework</a> for static analysis one often has to insert temporary <tt>nop</tt> (No operation) instructions. When examining the produced code it may be very difficult to track back where the <tt>nop</tt> was actually inserted. One could think of a derived <tt>nop2</tt> instruction that contains additional debugging information. When the instruction list is dumped to byte code, the extra data is simply dropped. </p> <p> One could also think of new byte code instructions operating on complex numbers that are replaced by normal byte code upon load-time or are recognized by a new JVM. </p> </blockquote> </p> </td></tr> <tr><td><br/></td></tr> </table> <table border="0" cellspacing="0" cellpadding="2" width="100%"> <tr><td bgcolor="#525D76"> <font color="#ffffff" face="arial,helvetica,sanserif"> <a name="3.3.4 Instruction lists"><strong>3.3.4 Instruction lists</strong></a> </font> </td></tr> <tr><td> <blockquote> <p> An <em>instruction list</em> is implemented by a list of <em>instruction handles</em> encapsulating instruction objects. References to instructions in the list are thus not implemented by direct pointers to instructions but by pointers to instruction <em>handles</em>. This makes appending, inserting and deleting areas of code very simple and also allows us to reuse immutable instruction objects (fly-weight objects). Since we use symbolic references, computation of concrete byte code offsets does not need to occur until finalization, i.e., until the user has finished the process of generating or transforming code. We will use the term instruction handle and instruction synonymously throughout the rest of the paper. Instruction handles may contain additional user-defined data using the <tt>addAttribute()</tt> method. </p> <p> <b>Appending:</b> One can append instructions or other instruction lists anywhere to an existing list. The instructions are appended after the given instruction handle. All append methods return a new instruction handle which may then be used as the target of a branch instruction, e.g.: </p> <div align="left"> <table cellspacing="4" cellpadding="0" border="0"> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#ffffff"><pre> InstructionList il = new InstructionList(); ... GOTO g = new GOTO(null); il.append(g); ... // Use immutable fly-weight object InstructionHandle ih = il.append(InstructionConstants.ACONST_NULL); g.setTarget(ih); </pre></td> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> </table> </div> <p> <b>Inserting:</b> Instructions may be inserted anywhere into an existing list. They are inserted before the given instruction handle. All insert methods return a new instruction handle which may then be used as the start address of an exception handler, for example. </p> <div align="left"> <table cellspacing="4" cellpadding="0" border="0"> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#ffffff"><pre> InstructionHandle start = il.insert(insertion_point, InstructionConstants.NOP); ... mg.addExceptionHandler(start, end, handler, "java.io.IOException"); </pre></td> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> </table> </div> <p> <b>Deleting:</b> Deletion of instructions is also very straightforward; all instruction handles and the contained instructions within a given range are removed from the instruction list and disposed. The <tt>delete()</tt> method may however throw a <tt>TargetLostException</tt> when there are instruction targeters still referencing one of the deleted instructions. The user is forced to handle such exceptions in a <tt>try-catch</tt> clause and redirect these references elsewhere. The <em>peep hole</em> optimizer described in the appendix gives a detailed example for this. </p> <div align="left"> <table cellspacing="4" cellpadding="0" border="0"> <tr> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> </tr> <tr> <td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> <td bgcolor="#ffffff"><pre> try { il.delete(first, last); } catch(TargetLostException e) { InstructionHandle[] targets = e.getTargets(); for(int i=0; i < targets.length; i++) { InstructionTargeter[] targeters = targets[i].getTargeters(); for(int j=0; j < targeters.length; j++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -