<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">

<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>

                                <td>

                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">Community</a></h1>
                                                                </td>

                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px;  -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
    Problem with CodeIterator.newOffset()
</h3>
<span style="margin-bottom: 10px;">
    created by <a href="http://community.jboss.org/people/alasdair">Alasdair Mackintosh</a> in <i>Javassist Development</i> - <a href="http://community.jboss.org/message/547652#547652">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><div id="_mcePaste">I've been having some problems with Javassist which I think I've finally narrowed down to the way that "goto" offsets are updated when you insert new bytecode. It looks as though newOffset is not correctly handling the case when you insert new opcodes at a location which already contains a "goto" opcode.</div><div id="_mcePaste"> </div><div id="_mcePaste"> </div><div><span style="font-family: 'courier new', courier;">&#160;&#160;&#160; private static int newOffset(int i, int offset, int where,</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int gapLength, boolean exclusive) {</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; int target = i + offset;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (i &lt; where) {</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (where &lt; target || (exclusive &amp;&amp; where == target))</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; offset += gapLength;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; else if (i == where) {</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (target &lt; where &amp;&amp; exclusive)</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; offset -= gapLength;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else if (where &lt; target &amp;&amp; !exclusive)</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; offset += gapLength;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; else</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (target &lt; where || (!exclusive &amp;&amp; where == target))</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; offset -= gapLength;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; return offset;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160; }</span></div><div id="_mcePaste"> </div><div id="_mcePaste"> </div><div>And I think the middle clause should look like this:</div><div id="_mcePaste"> </div><div id="_mcePaste"> </div><div><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; else if (i == where) {</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (target &lt; where)</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; offset -= gapLength;</span></div><div id="_mcePaste"><span style="font-family: 'courier new', courier;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span></div><div id="_mcePaste"> </div><div id="_mcePaste"> </div><div>If you insert new bytecode at a location containing a goto (so that the goto opcode is about to be moved forward by n bytes) then you need to modify the offset if it's negative, but keep it the same if it's already positive.</div><div id="_mcePaste">I've made this change and re-run the tests, which all pass, but I wanted to check to see if this fix looks reasonable.</div><div id="_mcePaste">I don't have a simple test case that shows the problem. I found this when I tried to run my testing framework ThreadWeaver (<a class="jive-link-external-small" href="http://code.google.com/p/thread-weaver/">http://code.google.com/p/thread-weaver</a>/) with the latest version of Javassist. The problem can be demonstrated by building ThreadWeaver and running the unit tests.</div><div id="_mcePaste"> </div><div id="_mcePaste"> </div><div>If you want a simpler test case let me know. I think THreadWeaver triggered this because it uses Javassist to insert lots of small code snippets into the instrumented bytecode.</div><div id="_mcePaste"> </div><div id="_mcePaste"> </div><div>Alasdair</div></div>

<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
    <p style="margin: 0;">Reply to this message by <a href="http://community.jboss.org/message/547652#547652">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in Javassist Development at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2063">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


                </td>
            </tr>
        </tbody>
    </table>

</div>

</body>
</html>