-<HTML>\r
-<HEAD>\r
-<TITLE>Javassist License</TITLE>\r
-</HEAD>\r
-\r
-<BODY text=#000000 vLink=#551a8b aLink=#ff0000 link=#0000ee bgColor=#ffffff>\r
-<p>\r
-Javassist, a Java-bytecode translator toolkit.\r
-Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.\r
-</p>\r
-<p>\r
-This library is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU Lesser General Public\r
-License as published by the Free Software Foundation; either\r
-version 2.1 of the License, or (at your option) any later version.\r
-</p>\r
-</BODY>\r
-</HTML>\r
+<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU Lesser General Public License - GNU Project - Free Software Foundation (FSF)</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#1F00FF" ALINK="#FF0000" VLINK="#9900DD">
+<H1>GNU Lesser General Public License</H1>
+
+<P>
+This GNU Lesser General Public License counts as the successor
+of the GNU Library General Public License.
+<P>
+
+<H2>Table of Contents</H2>
+<UL>
+<LI><A NAME="TOC1" HREF="#SEC1">GNU LESSER GENERAL PUBLIC LICENSE</A>
+<UL>
+<LI><A NAME="TOC2" HREF="#SEC2">Preamble</A>
+<LI><A NAME="TOC3" HREF="#SEC3">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</A>
+<LI><A NAME="TOC4" HREF="#SEC4">How to Apply These Terms to Your New Libraries</A>
+</UL>
+</UL>
+
+<P>
+
+<HR>
+
+<P>
+
+
+
+<H2><A NAME="SEC1" HREF="#TOC1">GNU LESSER GENERAL PUBLIC LICENSE</A></H2>
+<P>
+Version 2.1, February 1999
+
+<P>
+<PRE>
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+</PRE>
+
+
+<H2><A NAME="SEC2" HREF="#TOC2">Preamble</A></H2>
+
+<P>
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+<P>
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+<P>
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+<P>
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+<P>
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+<P>
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+<P>
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+<P>
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+<P>
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+<P>
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+<P>
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+<P>
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+<P>
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+<P>
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+<P>
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+<P>
+
+<H2><A NAME="SEC3" HREF="#TOC3">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</A></H2>
+
+
+<P>
+<STRONG>0.</STRONG>
+This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+<P>
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+<P>
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+<P>
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+<P>
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+<P>
+<STRONG>1.</STRONG>
+You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+<P>
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+<P>
+<STRONG>2.</STRONG>
+You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+<P>
+<UL>
+ <LI><STRONG>a)</STRONG>
+ The modified work must itself be a software library.
+ <LI><STRONG>b)</STRONG>
+ You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ <LI><STRONG>c)</STRONG>
+ You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ <LI><STRONG>d)</STRONG>
+ If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+ <P>
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+ <P>
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.
+ <P>
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.
+ <P>
+ In addition, mere aggregation of another work not based on the Library
+ with the Library (or with a work based on the Library) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+</UL>
+<P>
+<STRONG>3.</STRONG>
+You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+<P>
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+<P>
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+<P>
+<STRONG>4.</STRONG>
+You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+<P>
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+<P>
+<STRONG>5.</STRONG>
+A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+<P>
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+<P>
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+<P>
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+<P>
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+<P>
+<STRONG>6.</STRONG>
+As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+<P>
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+<P>
+<UL>
+ <LI><STRONG>a)</STRONG> Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ <LI><STRONG>b)</STRONG> Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ <LI><STRONG>c)</STRONG> Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ <LI><STRONG>d)</STRONG> If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ <LI><STRONG>e)</STRONG> Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+</UL>
+<P>
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+<P>
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+<P>
+<STRONG>7.</STRONG> You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+<P>
+<UL>
+ <LI><STRONG>a)</STRONG> Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ <LI><STRONG>b)</STRONG> Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+</UL>
+<P>
+<STRONG>8.</STRONG> You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+<P>
+<STRONG>9.</STRONG>
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+<P>
+<STRONG>10.</STRONG>
+Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+<P>
+<STRONG>11.</STRONG>
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+<P>
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+<P>
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+<P>
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+<P>
+<STRONG>12.</STRONG>
+If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+<P>
+<STRONG>13.</STRONG>
+The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+<P>
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+<P>
+<STRONG>14.</STRONG>
+If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+<P>
+<STRONG>NO WARRANTY</STRONG>
+<P>
+<STRONG>15.</STRONG>
+BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+<P>
+<STRONG>16.</STRONG>
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+<P>
+<H2>END OF TERMS AND CONDITIONS</H2>
+
+<H2><A NAME="SEC4" HREF="#TOC4">How to Apply These Terms to Your New Libraries</A></H2>
+<P>
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+<P>
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+<P>
+
+<PRE>
+<VAR>one line to give the library's name and an idea of what it does.</VAR>
+Copyright (C) <VAR>year</VAR> <VAR>name of author</VAR>
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+</PRE>
+
+<P>
+Also add information on how to contact you by electronic and paper mail.
+
+<P>
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+<P>
+<PRE>
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+<VAR>signature of Ty Coon</VAR>, 1 April 1990
+Ty Coon, President of Vice
+</PRE>
+
+<P>
+That's all there is to it!
+
+<HR>
+
+Copyright notice above.<BR>
+Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111, USA
+<P>
+Updated:
+<!-- timestamp start -->
+$Date: 2003-04-23 17:07:51 $ $Author: chiba $
+<!-- timestamp end -->
+<HR>
+</BODY>
+</HTML>
<h1>Javassist version 2</h1>
-<h3>in February, 2003.
+<h3>in April, 2003.
<br>Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved.</h3>
<p><br></p>
<p>Javassist (JAVA programming ASSISTant) is yet another reflective
system for Java. It is a class library for editing bytecodes in Java;
it enables Java programs to define a new class at runtime and to
-modify a class file when the JVM loads it. Unlike other
-similar bytecode editors, Javassist provides two levels of API:
-source level and bytecode level. If the users use the source-level
-API, they can edit a class file without knowledge of the specifications
-of the Java bytecode. The whole API is designed with only the vocabulary
-of the Java language. On the other hand, the bytecode-level API allows
-the users to directly edit a class file.
+modify a class file when the JVM loads it. Unlike other similar
+bytecode editors, Javassist provides two levels of API: source level
+and bytecode level. If the users use the source-level API, they can
+edit a class file without knowledge of the specifications of the Java
+bytecode. The whole API is designed with only the vocabulary of the
+Java language. You can even specify inserted bytecode in the form of
+source text; Javassist compiles it on the fly. On the other hand, the
+bytecode-level API allows the users to directly edit a class file.
<p><br>
</tr>
<tr>
-<td><li><tt>./javassist-src.zip</tt></td>
-<td>The source archive</td>
+<td><li><tt>./src/main</tt></td>
+<td>The source files</td>
</tr>
<tr>
<h2>Changes</h2>
+<p>- version 2.5 in April, 2003.
+<br>From this version, Javassist is part of the JBoss project.
+<ul>
+ <li>The license was changed from MPL to LGPL.
+ <li>ClassPool.removeClassPath() and ClassPath.close() have been added.
+ <li>ClassPool.makeClass(InputStream) has been added.
+ <li>javassist.expr.Handler has been added.
+ <li>CtMethod.isEmpty() and CtConstructor.isEmpty() have been added.
+ <li>LoaderClassPath has been implemented.
+</ul>
+
<p>- version 2.4 in February, 2003.
<ul>
<li>The compiler included in Javassist did not correctly work with
<h2>Copyright notices</h2>
-<p>
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-</p>
-
-<p>Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
+<p>Javassist, a Java-bytecode translator toolkit.
+<br>Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
-<p>The Original Code is Javassist.
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of
+<a href="License.html">the GNU Lesser General Public
+License</a> as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
-<p>The Initial Developer of the Original Code is Shigeru Chiba.
-<br>Portions
-created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
-All Rights Reserved.
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See <a href="License.html">the GNU Lesser General Public License</a>
+for more details.
<p><br>
<h2>Acknowledgments</h2>
<p>The development of this software is sponsored in part by the PRESTO
-program (Sakigake Kenkyu 21) of <a href="http://www.jst.go.jp/">Japan
+programs of <a href="http://www.jst.go.jp/">Japan
Science and Technology Corporation</a>.
<p>I'd like to thank Michiaki Tatsubori, Johan Cloetens,
Marc Segura-Devillechaise, Jan Baudisch, Julien Blass, Yoshiki Sato,
Fabian Crabus, Bo Norregaard Jorgensen, Bob Lee, Bill Burke,
Remy Sanlaville, Muga Nishizawa, Alexey Loubyansky, Saori Oki,
-Andreas Salathe, and Dante Torres estrada for their contributions.
+Andreas Salathe, Dante Torres estrada, S. Pam, Nuno Santos,
+Denis Taye, and Colin Sampaleanu
+for their contributions.
<p><br>
\r
<target name="javadocs">\r
<javadoc packagenames="javassist.*"\r
+ excludepackagenames="javassist.compiler.*,javassist.convert.*"\r
sourcepath="src/main"\r
defaultexcludes="yes"\r
destdir="html"\r
author="true"\r
version="true"\r
use="true"\r
+ Locale="en_US"\r
+ Public="true"\r
+ nohelp="true"\r
windowtitle="Javassist API">\r
<doctitle><![CDATA[<h1>Javassist</h1>]]></doctitle>\r
<bottom><![CDATA[<i>Javassist, a Java-bytecode translator toolkit. \r
Specification-Title: Javassist\r
Created-By: Shigeru Chiba, Tokyo Institute of Technology\r
Specification-Vendor: Shigeru Chiba, Tokyo Institute of Technology\r
-Specification-Version: 2.4\r
+Specification-Version: 2.5\r
Name: javassist/\r
\r
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
* Creates a <code>ByteArrayClassPath</code> containing the given
* bytes.
*
- * @param name a fully qualified class name
- * @param classfile the contents of a class file.
+ * @param name a fully qualified class name
+ * @param classfile the contents of a class file.
*/
public ByteArrayClassPath(String name, byte[] classfile) {
- this.classname = name;
- this.classfile = classfile;
+ this.classname = name;
+ this.classfile = classfile;
}
+ /**
+ * Closes this class path.
+ */
+ public void close() {}
+
public String toString() {
- return "byte[]:" + classname;
+ return "byte[]:" + classname;
}
/**
* Opens a class file.
*/
public InputStream openClassfile(String classname) {
- if(this.classname.equals(classname))
- return new ByteArrayInputStream(classfile);
- else
- return null;
+ if(this.classname.equals(classname))
+ return new ByteArrayInputStream(classfile);
+ else
+ return null;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.compiler.CompileError;
private String message;
public String getReason() {
- if (message != null)
- return message;
- else
- return this.toString();
+ if (message != null)
+ return message;
+ else
+ return this.toString();
}
/**
* Constructs a CannotCompileException with a message.
*/
public CannotCompileException(String msg) {
- super(msg);
- message = msg;
+ super(msg);
+ message = msg;
}
/**
* Constructs a CannotCompileException with an <code>Exception</code>.
*/
public CannotCompileException(Exception e) {
- super("by " + e.toString());
- message = null;
+ super("by " + e.toString());
+ message = null;
}
/**
* <code>NotFoundException</code>.
*/
public CannotCompileException(NotFoundException e) {
- this("cannot find " + e.getMessage());
+ this("cannot find " + e.getMessage());
}
/**
* Constructs a CannotCompileException with an <code>CompileError</code>.
*/
public CannotCompileException(CompileError e) {
- super("[source error] " + e.getMessage());
- message = null;
+ super("[source error] " + e.getMessage());
+ message = null;
}
/**
* with a <code>ClassNotFoundException</code>.
*/
public CannotCompileException(ClassNotFoundException e, String name) {
- this("cannot find " + name);
+ this("cannot find " + name);
}
/**
* Constructs a CannotCompileException with a ClassFormatError.
*/
public CannotCompileException(ClassFormatError e, String name) {
- this("invalid class format: " + name);
+ this("invalid class format: " + name);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.Descriptor;
* internal form used in the JVM before putting it in
* the hashtable.
*
- * @param oldname the original class name
- * @param newname the substituted class name.
+ * @param oldname the original class name
+ * @param newname the substituted class name.
*/
public void put(CtClass oldname, CtClass newname) {
- put(oldname.getName(), newname.getName());
+ put(oldname.getName(), newname.getName());
}
/**
* internal form used in the JVM before putting it in
* the hashtable.
*
- * @param oldname the original class name
- * @param newname the substituted class name.
+ * @param oldname the original class name
+ * @param newname the substituted class name.
*/
public void put(String oldname, String newname) {
- if (oldname == newname)
- return;
+ if (oldname == newname)
+ return;
- String oldname2 = toJvmName(oldname);
- String s = (String)get(oldname2);
- if (s == null || !s.equals(oldname2))
- super.put(oldname2, toJvmName(newname));
+ String oldname2 = toJvmName(oldname);
+ String s = (String)get(oldname2);
+ if (s == null || !s.equals(oldname2))
+ super.put(oldname2, toJvmName(newname));
}
protected final void put0(Object oldname, Object newname) {
- super.put(oldname, newname);
+ super.put(oldname, newname);
}
/**
* @see #toJavaName(String)
*/
public Object get(Object jvmClassName) {
- return super.get(jvmClassName);
+ return super.get(jvmClassName);
}
/**
* Prevents a mapping from the specified class name to another name.
*/
public void fix(CtClass clazz) {
- fix(clazz.getName());
+ fix(clazz.getName());
}
/**
* Prevents a mapping from the specified class name to another name.
*/
public void fix(String name) {
- String name2 = toJvmName(name);
- super.put(name2, name2);
+ String name2 = toJvmName(name);
+ super.put(name2, name2);
}
/**
* the JVM.
*/
public static String toJvmName(String classname) {
- return Descriptor.toJvmName(classname);
+ return Descriptor.toJvmName(classname);
}
/**
* the JVM to the normal one used in Java.
*/
public static String toJavaName(String classname) {
- return Descriptor.toJavaName(classname);
+ return Descriptor.toJavaName(classname);
}
}
/*
- * This file is part of the Javassist toolkit.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.InputStream;
*
* @see ClassPool#insertClassPath(ClassPath)
* @see ClassPool#appendClassPath(ClassPath)
- * @see javassist.URLClassPath
+ * @see ClassPool#removeClassPath(ClassPath)
*/
public interface ClassPath {
/**
*
* <p>This method should not modify the contents of the class file.
*
- * @param classname a fully-qualified class name
- * @return the input stream for reading a class file
+ * @param classname a fully-qualified class name
+ * @return the input stream for reading a class file
*/
InputStream openClassfile(String classname) throws NotFoundException;
+
+ /**
+ * This method is invoked when the <code>ClassPath</code> object is
+ * detached from the search path. It will be an empty method in most of
+ * classes.
+ */
+ void close();
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
protected Translator translator;
- protected Hashtable classes; // should be synchronous
+ protected Hashtable classes; // should be synchronous
/**
* Creates a class pool.
*
- * @param src the source of class files. If it is null,
- * the class search path is initially null.
+ * @param src the source of class files. If it is null,
+ * the class search path is initially null.
* @see javassist.ClassPool#getDefault()
*/
public ClassPool(ClassPool src) {
- this(src, null);
+ this(src, null);
}
/**
* Creates a class pool.
*
- * @param src the source of class files. If it is null,
- * the class search path is initially null.
- * @param trans the translator linked to this class pool.
- * It may be null.
+ * @param src the source of class files. If it is null,
+ * the class search path is initially null.
+ * @param trans the translator linked to this class pool.
+ * It may be null.
* @see javassist.ClassPool#getDefault()
*/
public ClassPool(ClassPool src, Translator trans)
- throws RuntimeException
+ throws RuntimeException
{
- classes = new Hashtable();
- CtClass[] pt = CtClass.primitiveTypes;
- for (int i = 0; i < pt.length; ++i)
- classes.put(pt[i].getName(), pt[i]);
-
- if (src != null)
- source = src;
- else
- source = new ClassPoolTail();
-
- translator = trans;
- if (trans != null)
- try {
- trans.start(this);
- }
- catch (Exception e) {
- throw new RuntimeException(
- "Translator.start() throws an exception: "
- + e.toString());
- }
+ classes = new Hashtable();
+ CtClass[] pt = CtClass.primitiveTypes;
+ for (int i = 0; i < pt.length; ++i)
+ classes.put(pt[i].getName(), pt[i]);
+
+ if (src != null)
+ source = src;
+ else
+ source = new ClassPoolTail();
+
+ translator = trans;
+ if (trans != null)
+ try {
+ trans.start(this);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(
+ "Translator.start() throws an exception: "
+ + e.toString());
+ }
}
protected ClassPool() {
- source = null;
- classes = null;
- translator = null;
+ source = null;
+ classes = null;
+ translator = null;
}
/**
* <code>-classpath</code> option or the <code>CLASSPATH</code>
* environment variable.
*
- * @param t null or the translator linked to the class pool.
+ * @param t null or the translator linked to the class pool.
*/
public static synchronized ClassPool getDefault(Translator t) {
- if (defaultPool == null) {
- ClassPoolTail tail = new ClassPoolTail();
- tail.appendSystemPath();
- defaultPool = new ClassPool(tail, t);
- }
+ if (defaultPool == null) {
+ ClassPoolTail tail = new ClassPoolTail();
+ tail.appendSystemPath();
+ defaultPool = new ClassPool(tail, t);
+ }
- return defaultPool;
+ return defaultPool;
}
private static ClassPool defaultPool = null;
* @see #getDefault(Translator)
*/
public static ClassPool getDefault() {
- return getDefault(null);
+ return getDefault(null);
}
/**
* Returns the class search path.
*/
public String toString() {
- return source.toString();
+ return source.toString();
}
/**
/**
* Table of registered cflow variables.
*/
- private Hashtable cflow = null; // should be synchronous.
+ private Hashtable cflow = null; // should be synchronous.
/**
* Records the <code>$cflow</code> variable for the field specified
* by <code>cname</code> and <code>fname</code>.
*
- * @param name variable name
- * @param cname class name
- * @param fname field name
+ * @param name variable name
+ * @param cname class name
+ * @param fname field name
*/
void recordCflow(String name, String cname, String fname) {
- if (cflow == null)
- cflow = new Hashtable();
+ if (cflow == null)
+ cflow = new Hashtable();
- cflow.put(name, new Object[] { cname, fname });
+ cflow.put(name, new Object[] { cname, fname });
}
/**
* Undocumented method. Do not use; internal-use only.
*
- * @param name the name of <code>$cflow</code> variable
+ * @param name the name of <code>$cflow</code> variable
*/
public Object[] lookupCflow(String name) {
- if (cflow == null)
- cflow = new Hashtable();
+ if (cflow == null)
+ cflow = new Hashtable();
- return (Object[])cflow.get(name);
+ return (Object[])cflow.get(name);
}
/**
* It never calls <code>onWrite()</code> on a translator.
* It is provided for debugging.
*
- * @param classname the name of the class written on a local disk.
+ * @param classname the name of the class written on a local disk.
*/
public void debugWriteFile(String classname)
- throws NotFoundException, CannotCompileException, IOException
+ throws NotFoundException, CannotCompileException, IOException
{
- debugWriteFile(classname, ".");
+ debugWriteFile(classname, ".");
}
/**
* It never calls <code>onWrite()</code> on a translator.
* It is provided for debugging.
*
- * @param classname the name of the class written on a local disk.
- * @param directoryName it must end without a directory separator.
+ * @param classname the name of the class written on a local disk.
+ * @param directoryName it must end without a directory separator.
*/
public void debugWriteFile(String classname, String directoryName)
- throws NotFoundException, CannotCompileException, IOException
+ throws NotFoundException, CannotCompileException, IOException
{
- writeFile(classname, directoryName, false);
+ writeFile(classname, directoryName, false);
}
/* void writeFile(CtClass) should not be defined since writeFile()
* in the current directory.
* It calls <code>onWrite()</code> on a translator.
*
- * @param classname the name of the class written on a local disk.
+ * @param classname the name of the class written on a local disk.
*/
public void writeFile(String classname)
- throws NotFoundException, CannotCompileException, IOException
+ throws NotFoundException, CannotCompileException, IOException
{
- writeFile(classname, ".");
+ writeFile(classname, ".");
}
/**
* on a local disk.
* It calls <code>onWrite()</code> on a translator.
*
- * @param classname the name of the class written on a local disk.
- * @param directoryName it must end without a directory separator.
+ * @param classname the name of the class written on a local disk.
+ * @param directoryName it must end without a directory separator.
*/
public void writeFile(String classname, String directoryName)
- throws NotFoundException, CannotCompileException, IOException
+ throws NotFoundException, CannotCompileException, IOException
{
- writeFile(classname, directoryName, true);
+ writeFile(classname, directoryName, true);
}
private void writeFile(String classname, String directoryName,
- boolean callback)
- throws NotFoundException, CannotCompileException, IOException
+ boolean callback)
+ throws NotFoundException, CannotCompileException, IOException
{
- String filename = directoryName + File.separatorChar
- + classname.replace('.', File.separatorChar) + ".class";
- int pos = filename.lastIndexOf(File.separatorChar);
- if (pos > 0) {
- String dir = filename.substring(0, pos);
- if (!dir.equals("."))
- new File(dir).mkdirs();
- }
-
- DataOutputStream out
- = new DataOutputStream(new BufferedOutputStream(
- new DelayedFileOutputStream(filename)));
- write(classname, out, callback);
- out.close();
+ String filename = directoryName + File.separatorChar
+ + classname.replace('.', File.separatorChar) + ".class";
+ int pos = filename.lastIndexOf(File.separatorChar);
+ if (pos > 0) {
+ String dir = filename.substring(0, pos);
+ if (!dir.equals("."))
+ new File(dir).mkdirs();
+ }
+
+ DataOutputStream out
+ = new DataOutputStream(new BufferedOutputStream(
+ new DelayedFileOutputStream(filename)));
+ write(classname, out, callback);
+ out.close();
}
static class DelayedFileOutputStream extends OutputStream {
- private FileOutputStream file;
- private String filename;
+ private FileOutputStream file;
+ private String filename;
- DelayedFileOutputStream(String name) {
- file = null;
- filename = name;
- }
+ DelayedFileOutputStream(String name) {
+ file = null;
+ filename = name;
+ }
- private void init() throws IOException {
- if (file == null)
- file = new FileOutputStream(filename);
- }
+ private void init() throws IOException {
+ if (file == null)
+ file = new FileOutputStream(filename);
+ }
- public void write(int b) throws IOException {
- init();
- file.write(b);
- }
+ public void write(int b) throws IOException {
+ init();
+ file.write(b);
+ }
- public void write(byte[] b) throws IOException {
- init();
- file.write(b);
- }
+ public void write(byte[] b) throws IOException {
+ init();
+ file.write(b);
+ }
- public void write(byte[] b, int off, int len) throws IOException {
- init();
- file.write(b, off, len);
+ public void write(byte[] b, int off, int len) throws IOException {
+ init();
+ file.write(b, off, len);
- }
+ }
- public void flush() throws IOException {
- init();
- file.flush();
- }
+ public void flush() throws IOException {
+ init();
+ file.flush();
+ }
- public void close() throws IOException {
- init();
- file.close();
- }
+ public void close() throws IOException {
+ init();
+ file.close();
+ }
}
static class LocalClassLoader extends ClassLoader {
- public Class loadClass(String name, byte[] classfile)
- throws ClassFormatError
- {
- Class c = defineClass(name, classfile, 0, classfile.length);
- resolveClass(c);
- return c;
- }
+ public Class loadClass(String name, byte[] classfile)
+ throws ClassFormatError
+ {
+ Class c = defineClass(name, classfile, 0, classfile.length);
+ resolveClass(c);
+ return c;
+ }
};
private static LocalClassLoader classLoader = new LocalClassLoader();
* @see javassist.CtClass#toClass()
*/
public static Class forName(String name) throws ClassNotFoundException {
- return classLoader.loadClass(name);
+ return classLoader.loadClass(name);
}
/**
* loader refers to a class <code>Y</code>, then the class
* <code>Y</code> is loaded by the parent class loader.
*
- * @param classname a fully-qualified class name.
+ * @param classname a fully-qualified class name.
*
* @see #forName(String)
* @see javassist.CtClass#toClass()
* @see javassist.Loader
*/
public Class writeAsClass(String classname)
- throws NotFoundException, IOException, CannotCompileException
+ throws NotFoundException, IOException, CannotCompileException
{
- try {
- return classLoader.loadClass(classname, write(classname));
- }
- catch (ClassFormatError e) {
- throw new CannotCompileException(e, classname);
- }
+ try {
+ return classLoader.loadClass(classname, write(classname));
+ }
+ catch (ClassFormatError e) {
+ throw new CannotCompileException(e, classname);
+ }
}
/**
* Returns a byte array representing the class file.
* It calls <code>onWrite()</code> on a translator.
*
- * @param classname a fully-qualified class name.
+ * @param classname a fully-qualified class name.
*/
public byte[] write(String classname)
- throws NotFoundException, IOException, CannotCompileException
+ throws NotFoundException, IOException, CannotCompileException
{
- ByteArrayOutputStream barray = new ByteArrayOutputStream();
- DataOutputStream out = new DataOutputStream(barray);
- write(classname, out, true);
- out.close();
- return barray.toByteArray();
+ ByteArrayOutputStream barray = new ByteArrayOutputStream();
+ DataOutputStream out = new DataOutputStream(barray);
+ write(classname, out, true);
+ out.close();
+ return barray.toByteArray();
}
/**
*
* <p>This method does not close the output stream in the end.
*
- * @param classname a fully-qualified class name.
- * @param out an output stream
+ * @param classname a fully-qualified class name.
+ * @param out an output stream
*/
public void write(String classname, DataOutputStream out)
- throws NotFoundException, CannotCompileException, IOException
+ throws NotFoundException, CannotCompileException, IOException
{
- write(classname, out, true);
+ write(classname, out, true);
}
private void write(String classname, DataOutputStream out,
- boolean callback)
- throws NotFoundException, CannotCompileException, IOException
+ boolean callback)
+ throws NotFoundException, CannotCompileException, IOException
{
- CtClass clazz = (CtClass)classes.get(classname);
- if (callback && translator != null
- && (clazz == null || !clazz.isFrozen())) {
- translator.onWrite(this, classname);
- // The CtClass object might be overwritten.
- clazz = (CtClass)classes.get(classname);
- }
+ CtClass clazz = (CtClass)classes.get(classname);
+ if (callback && translator != null
+ && (clazz == null || !clazz.isFrozen())) {
+ translator.onWrite(this, classname);
+ // The CtClass object might be overwritten.
+ clazz = (CtClass)classes.get(classname);
+ }
+
+ if (clazz == null || !clazz.isModified()) {
+ if (clazz != null)
+ clazz.freeze();
- if (clazz == null || !clazz.isModified())
- source.write(classname, out);
- else
- clazz.toBytecode(out);
+ source.write(classname, out);
+ }
+ else
+ clazz.toBytecode(out);
}
/* for CtClassType.getClassFile2()
*/
byte[] readSource(String classname)
- throws NotFoundException, IOException, CannotCompileException
+ throws NotFoundException, IOException, CannotCompileException
{
- return source.write(classname);
+ return source.write(classname);
}
/*
* Is invoked by CtClassType.setName().
*/
synchronized void classNameChanged(String oldname, CtClass clazz) {
- CtClass c = (CtClass)classes.get(oldname);
- if (c == clazz) // must check this equation
- classes.remove(c);
+ CtClass c = (CtClass)classes.get(oldname);
+ if (c == clazz) // must check this equation
+ classes.remove(c);
- String newName = clazz.getName();
- checkNotFrozen(newName, "the class with the new name is frozen.");
- classes.put(newName, clazz);
+ String newName = clazz.getName();
+ checkNotFrozen(newName, "the class with the new name is frozen.");
+ classes.put(newName, clazz);
}
/*
* Is invoked by CtClassType.setName() and methods in this class.
*/
void checkNotFrozen(String classname, String errmsg)
- throws RuntimeException
+ throws RuntimeException
{
- CtClass c = (CtClass)classes.get(classname);
- if (c != null && c.isFrozen())
- throw new RuntimeException(errmsg);
+ CtClass c = (CtClass)classes.get(classname);
+ if (c != null && c.isFrozen())
+ throw new RuntimeException(errmsg);
}
/**
* This method is useful if that class file has been already
* loaded and the resulting class is frozen.
*
- * @param orgName the original (fully-qualified) class name
- * @param newName the new class name
+ * @param orgName the original (fully-qualified) class name
+ * @param newName the new class name
*/
public CtClass getAndRename(String orgName, String newName)
- throws NotFoundException
+ throws NotFoundException
{
- CtClass clazz = get0(orgName);
- clazz.setName(newName); // indirectly calls
- // classNameChanged() in this class
- return clazz;
+ CtClass clazz = get0(orgName);
+ clazz.setName(newName); // indirectly calls
+ // classNameChanged() in this class
+ return clazz;
}
/**
* <p>If <code>classname</code> ends with "[]", then this method
* returns a <code>CtClass</code> object for that array type.
*
- * @param classname a fully-qualified class name.
+ * @param classname a fully-qualified class name.
*/
public synchronized CtClass get(String classname)
- throws NotFoundException
+ throws NotFoundException
{
- CtClass clazz = (CtClass)classes.get(classname);
- if (clazz == null) {
- clazz = get0(classname);
- classes.put(classname, clazz);
- }
+ CtClass clazz = (CtClass)classes.get(classname);
+ if (clazz == null) {
+ clazz = get0(classname);
+ classes.put(classname, clazz);
+ }
- return clazz;
+ return clazz;
}
private CtClass get0(String classname) throws NotFoundException {
- if (classname.endsWith("[]"))
- return new CtArray(classname, this);
- else {
- checkClassName(classname);
- return new CtClassType(classname, this);
- }
+ if (classname.endsWith("[]"))
+ return new CtArray(classname, this);
+ else {
+ checkClassName(classname);
+ return new CtClassType(classname, this);
+ }
}
/**
* then this method
* returns a <code>CtClass</code> object for that array type.
*
- * @param classnames an array of fully-qualified class name.
+ * @param classnames an array of fully-qualified class name.
*/
public CtClass[] get(String[] classnames) throws NotFoundException {
- if (classnames == null)
- return new CtClass[0];
+ if (classnames == null)
+ return new CtClass[0];
- int num = classnames.length;
- CtClass[] result = new CtClass[num];
- for (int i = 0; i < num; ++i)
- result[i] = get(classnames[i]);
+ int num = classnames.length;
+ CtClass[] result = new CtClass[num];
+ for (int i = 0; i < num; ++i)
+ result[i] = get(classnames[i]);
- return result;
+ return result;
}
/**
* Reads a class file and obtains a compile-time method.
*
- * @param classname the class name
- * @param methodname the method name
+ * @param classname the class name
+ * @param methodname the method name
*
* @see CtClass#getDeclaredMethod(String)
*/
public CtMethod getMethod(String classname, String methodname)
- throws NotFoundException
+ throws NotFoundException
+ {
+ CtClass c = get(classname);
+ return c.getDeclaredMethod(methodname);
+ }
+
+ /**
+ * Creates a new class from the given class file.
+ * If there already exists a class with the same name, the new class
+ * overwrites that previous class.
+ *
+ * <p>This method is used for creating a <code>CtClass</code> object
+ * directly from a class file. The qualified class name is obtained
+ * from the class file; you do not have to explicitly give the name.
+ *
+ * @param classfile class file.
+ * @exception RuntimeException if there is a frozen class with the
+ * the same name.
+ */
+ public CtClass makeClass(InputStream classfile)
+ throws IOException, RuntimeException
{
- CtClass c = get(classname);
- return c.getDeclaredMethod(methodname);
+ CtClass clazz = new CtClassType(classfile, this);
+ clazz.checkModify();
+ String classname = clazz.getName();
+ checkNotFrozen(classname,
+ "there is a frozen class with the same name.");
+ classes.put(classname, clazz);
+ return clazz;
}
/**
* If there already exists a class with the same name, the new class
* overwrites that previous class.
*
- * @param classname a fully-qualified class name.
- * @exception RuntimeException if the existing class is frozen.
+ * @param classname a fully-qualified class name.
+ * @exception RuntimeException if the existing class is frozen.
*/
public CtClass makeClass(String classname) throws RuntimeException {
- return makeClass(classname, null);
+ return makeClass(classname, null);
}
/**
* If there already exists a class/interface with the same name,
* the new class overwrites that previous class.
*
- * @param classname a fully-qualified class name.
- * @param superclass the super class.
- * @exception RuntimeException if the existing class is frozen.
+ * @param classname a fully-qualified class name.
+ * @param superclass the super class.
+ * @exception RuntimeException if the existing class is frozen.
*/
public synchronized CtClass makeClass(String classname, CtClass superclass)
- throws RuntimeException
+ throws RuntimeException
{
- checkNotFrozen(classname,
- "the class with the given name is frozen.");
- CtClass clazz = new CtNewClass(classname, this, false, superclass);
- classes.put(classname, clazz);
- return clazz;
+ checkNotFrozen(classname,
+ "the class with the given name is frozen.");
+ CtClass clazz = new CtNewClass(classname, this, false, superclass);
+ classes.put(classname, clazz);
+ return clazz;
}
/**
* If there already exists a class/interface with the same name,
* the new interface overwrites that previous one.
*
- * @param name a fully-qualified interface name.
- * @exception RuntimeException if the existing interface is frozen.
+ * @param name a fully-qualified interface name.
+ * @exception RuntimeException if the existing interface is frozen.
*/
public CtClass makeInterface(String name) throws RuntimeException {
- return makeInterface(name, null);
+ return makeInterface(name, null);
}
/**
* If there already exists a class/interface with the same name,
* the new interface overwrites that previous one.
*
- * @param name a fully-qualified interface name.
- * @param superclass the super interface.
- * @exception RuntimeException if the existing interface is frozen.
+ * @param name a fully-qualified interface name.
+ * @param superclass the super interface.
+ * @exception RuntimeException if the existing interface is frozen.
*/
public synchronized CtClass makeInterface(String name, CtClass superclass)
- throws RuntimeException
+ throws RuntimeException
{
- checkNotFrozen(name,
- "the interface with the given name is frozen.");
- CtClass clazz = new CtNewClass(name, this, true, superclass);
- classes.put(name, clazz);
- return clazz;
+ checkNotFrozen(name,
+ "the interface with the given name is frozen.");
+ CtClass clazz = new CtNewClass(name, this, true, superclass);
+ classes.put(name, clazz);
+ return clazz;
}
/**
* exist.
*/
void checkClassName(String classname)
- throws NotFoundException
+ throws NotFoundException
{
- source.checkClassName(classname);
+ source.checkClassName(classname);
}
/**
* libraries, and the search path specified by the
* <code>-classpath</code> option or the <code>CLASSPATH</code>
* environment variable.
+ *
+ * @return the appended class path.
*/
- public void appendSystemPath() {
- source.appendSystemPath();
+ public ClassPath appendSystemPath() {
+ return source.appendSystemPath();
}
/**
* Insert a <code>ClassPath</code> object at the head of the
* search path.
*
+ * @return the inserted class path.
+ *
* @see javassist.ClassPath
* @see javassist.URLClassPath
* @see javassist.ByteArrayClassPath
*/
- public void insertClassPath(ClassPath cp) {
- source.insertClassPath(cp);
+ public ClassPath insertClassPath(ClassPath cp) {
+ return source.insertClassPath(cp);
}
/**
* Appends a <code>ClassPath</code> object to the end of the
* search path.
*
+ * @return the appended class path.
+ *
* @see javassist.ClassPath
* @see javassist.URLClassPath
* @see javassist.ByteArrayClassPath
*/
- public void appendClassPath(ClassPath cp) {
- source.appendClassPath(cp);
+ public ClassPath appendClassPath(ClassPath cp) {
+ return source.appendClassPath(cp);
}
/**
* Inserts a directory or a jar (or zip) file at the head of the
* search path.
*
- * @param pathname the path name of the directory or jar file.
- * It must not end with a path separator ("/").
- * @exception NotFoundException if the jar file is not found.
+ * @param pathname the path name of the directory or jar file.
+ * It must not end with a path separator ("/").
+ * @return the inserted class path.
+ * @exception NotFoundException if the jar file is not found.
*/
- public void insertClassPath(String pathname)
- throws NotFoundException
+ public ClassPath insertClassPath(String pathname)
+ throws NotFoundException
{
- source.insertClassPath(pathname);
+ return source.insertClassPath(pathname);
}
/**
* Appends a directory or a jar (or zip) file to the end of the
* search path.
*
- * @param pathname the path name of the directory or jar file.
- * It must not end with a path separator ("/").
- * @exception NotFoundException if the jar file is not found.
+ * @param pathname the path name of the directory or jar file.
+ * It must not end with a path separator ("/").
+ * @return the appended class path.
+ * @exception NotFoundException if the jar file is not found.
*/
- public void appendClassPath(String pathname)
- throws NotFoundException
+ public ClassPath appendClassPath(String pathname)
+ throws NotFoundException
{
- source.appendClassPath(pathname);
+ return source.appendClassPath(pathname);
+ }
+
+ /**
+ * Detatches the <code>ClassPath</code> object from the search path.
+ * The detached <code>ClassPath</code> object cannot be added
+ * to the pathagain.
+ */
+ public synchronized void removeClassPath(ClassPath cp) {
+ source.removeClassPath(cp);
}
/**
* <p>The elements of the given path list must be separated by colons
* in Unix or semi-colons in Windows.
*
- * @param pathlist a (semi)colon-separated list of
- * the path names of directories and jar files.
- * The directory name must not end with a path
- * separator ("/").
+ * @param pathlist a (semi)colon-separated list of
+ * the path names of directories and jar files.
+ * The directory name must not end with a path
+ * separator ("/").
*
- * @exception NotFoundException if a jar file is not found.
+ * @exception NotFoundException if a jar file is not found.
*/
public void appendPathList(String pathlist) throws NotFoundException {
- char sep = File.pathSeparatorChar;
- int i = 0;
- for (;;) {
- int j = pathlist.indexOf(sep, i);
- if (j < 0) {
- appendClassPath(pathlist.substring(i));
- break;
- }
- else {
- appendClassPath(pathlist.substring(i, j));
- i = j + 1;
- }
- }
+ char sep = File.pathSeparatorChar;
+ int i = 0;
+ for (;;) {
+ int j = pathlist.indexOf(sep, i);
+ if (j < 0) {
+ appendClassPath(pathlist.substring(i));
+ break;
+ }
+ else {
+ appendClassPath(pathlist.substring(i, j));
+ i = j + 1;
+ }
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
ClassPath path;
ClassPathList(ClassPath p, ClassPathList n) {
- next = n;
- path = p;
+ next = n;
+ path = p;
}
}
Class thisClass;
SystemClassPath() {
- /* The value of thisClass was this.getClass() in early versions:
- *
- * thisClass = this.getClass();
- *
- * However, this made openClassfile() not search all the system
- * class paths if javassist.jar is put in jre/lib/ext/
- * (with JDK1.4).
- */
- thisClass = java.lang.Object.class;
+ /* The value of thisClass was this.getClass() in early versions:
+ *
+ * thisClass = this.getClass();
+ *
+ * However, this made openClassfile() not search all the system
+ * class paths if javassist.jar is put in jre/lib/ext/
+ * (with JDK1.4).
+ */
+ thisClass = java.lang.Object.class;
}
public InputStream openClassfile(String classname) {
- String jarname = "/" + classname.replace('.', '/') + ".class";
- return thisClass.getResourceAsStream(jarname);
+ String jarname = "/" + classname.replace('.', '/') + ".class";
+ return thisClass.getResourceAsStream(jarname);
}
+ public void close() {}
+
public String toString() {
- return "*system class path*";
+ return "*system class path*";
}
}
String directory;
DirClassPath(String dirName) {
- directory = dirName;
+ directory = dirName;
}
public InputStream openClassfile(String classname) {
- try {
- char sep = File.separatorChar;
- String filename = directory + sep
- + classname.replace('.', sep) + ".class";
- return new FileInputStream(filename.toString());
- }
- catch (FileNotFoundException e) {}
- catch (SecurityException e) {}
- return null;
+ try {
+ char sep = File.separatorChar;
+ String filename = directory + sep
+ + classname.replace('.', sep) + ".class";
+ return new FileInputStream(filename.toString());
+ }
+ catch (FileNotFoundException e) {}
+ catch (SecurityException e) {}
+ return null;
}
+ public void close() {}
+
public String toString() {
- return directory;
+ return directory;
}
}
ZipFile jarfile;
JarClassPath(String pathname) throws NotFoundException {
- try {
- jarfile = new ZipFile(pathname);
- return;
- }
- catch (ZipException e) {}
- catch (IOException e) {}
- throw new NotFoundException(pathname);
+ try {
+ jarfile = new ZipFile(pathname);
+ return;
+ }
+ catch (ZipException e) {}
+ catch (IOException e) {}
+ throw new NotFoundException(pathname);
}
public InputStream openClassfile(String classname)
- throws NotFoundException
+ throws NotFoundException
{
- try {
- String jarname = classname.replace('.', '/') + ".class";
- ZipEntry ze = jarfile.getEntry(jarname);
- if (ze != null)
- return jarfile.getInputStream(ze);
- else
- return null; // not found
- }
- catch (ZipException e) {}
- catch (IOException e) {}
- throw new NotFoundException("broken jar file?: "
- + jarfile.getName());
+ try {
+ String jarname = classname.replace('.', '/') + ".class";
+ ZipEntry ze = jarfile.getEntry(jarname);
+ if (ze != null)
+ return jarfile.getInputStream(ze);
+ else
+ return null; // not found
+ }
+ catch (ZipException e) {}
+ catch (IOException e) {}
+ throw new NotFoundException("broken jar file?: "
+ + jarfile.getName());
+ }
+
+ public void close() {
+ try {
+ jarfile.close();
+ jarfile = null;
+ }
+ catch (IOException e) {}
}
public String toString() {
- return jarfile.toString();
+ return jarfile == null ? "<null>" : jarfile.toString();
}
}
private Class thisClass;
public ClassPoolTail() {
- pathList = null;
- thisClass = getClass();
+ pathList = null;
+ thisClass = getClass();
}
public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("[class path: ");
- ClassPathList list = pathList;
- while (list != null) {
- buf.append(list.path.toString());
- buf.append(File.pathSeparatorChar);
- list = list.next;
- }
-
- buf.append(']');
- return buf.toString();
+ StringBuffer buf = new StringBuffer();
+ buf.append("[class path: ");
+ ClassPathList list = pathList;
+ while (list != null) {
+ buf.append(list.path.toString());
+ buf.append(File.pathSeparatorChar);
+ list = list.next;
+ }
+
+ buf.append(']');
+ return buf.toString();
}
public byte[] write(String classname)
- throws NotFoundException, IOException
+ throws NotFoundException, IOException
{
- return readClassfile(classname);
+ return readClassfile(classname);
}
public void write(String classname, DataOutputStream out)
- throws NotFoundException, CannotCompileException, IOException
+ throws NotFoundException, CannotCompileException, IOException
{
- byte[] b = write(classname);
- out.write(b, 0, b.length);
+ byte[] b = write(classname);
+ out.write(b, 0, b.length);
}
public CtClass get(String classname) throws NotFoundException {
- throw new RuntimeException("fatal error");
+ throw new RuntimeException("fatal error");
}
public CtClass makeClass(String classname) {
- throw new RuntimeException("fatal error");
+ throw new RuntimeException("fatal error");
}
void checkClassName(String classname)
- throws NotFoundException
+ throws NotFoundException
{
- InputStream fin = openClassfile(classname);
- try {
- fin.close();
- }
- catch (IOException e) { /* ignore */ }
+ InputStream fin = openClassfile(classname);
+ try {
+ fin.close();
+ }
+ catch (IOException e) { /* ignore */ }
+ }
+
+ public synchronized ClassPath insertClassPath(ClassPath cp) {
+ pathList = new ClassPathList(cp, pathList);
+ return cp;
}
- public synchronized void insertClassPath(ClassPath cp) {
- pathList = new ClassPathList(cp, pathList);
+ public synchronized ClassPath appendClassPath(ClassPath cp) {
+ ClassPathList tail = new ClassPathList(cp, null);
+ ClassPathList list = pathList;
+ if (list == null)
+ pathList = tail;
+ else {
+ while (list.next != null)
+ list = list.next;
+
+ list.next = tail;
+ }
+
+ return cp;
}
- public synchronized void appendClassPath(ClassPath cp) {
- ClassPathList tail = new ClassPathList(cp, null);
- ClassPathList list = pathList;
- if (list == null)
- pathList = tail;
- else {
- while (list.next != null)
- list = list.next;
-
- list.next = tail;
- }
+ public synchronized void removeClassPath(ClassPath cp) {
+ ClassPathList list = pathList;
+ if (list != null)
+ if (list.path == cp)
+ pathList = list.next;
+ else {
+ while (list.next != null)
+ if (list.next.path == cp)
+ list.next = list.next.next;
+ else
+ list = list.next;
+ }
+
+ cp.close();
}
- public void appendSystemPath() {
- appendClassPath(new SystemClassPath());
+ public ClassPath appendSystemPath() {
+ return appendClassPath(new SystemClassPath());
}
- public void insertClassPath(String pathname)
- throws NotFoundException
+ public ClassPath insertClassPath(String pathname)
+ throws NotFoundException
{
- insertClassPath(makePathObject(pathname));
+ return insertClassPath(makePathObject(pathname));
}
- public void appendClassPath(String pathname)
- throws NotFoundException
+ public ClassPath appendClassPath(String pathname)
+ throws NotFoundException
{
- appendClassPath(makePathObject(pathname));
+ return appendClassPath(makePathObject(pathname));
}
private static ClassPath makePathObject(String pathname)
- throws NotFoundException
+ throws NotFoundException
{
- if (pathname.endsWith(".jar") || pathname.endsWith(".zip")
- || pathname.endsWith(".JAR") || pathname.endsWith(".ZIP"))
- return new JarClassPath(pathname);
- else
- return new DirClassPath(pathname);
+ int i = pathname.lastIndexOf('.');
+ if (i >= 0) {
+ String ext = pathname.substring(i).toLowerCase();
+ if (ext.equals(".jar") || ext.equals(".zip"))
+ return new JarClassPath(pathname);
+ }
+
+ return new DirClassPath(pathname);
}
/**
* Obtains the contents of the class file for the class
* specified by <code>classname</code>.
*
- * @param classname a fully-qualified class name
+ * @param classname a fully-qualified class name
*/
byte[] readClassfile(String classname)
- throws NotFoundException, IOException
+ throws NotFoundException, IOException
{
- InputStream fin = openClassfile(classname);
- byte[] b = readStream(fin);
- fin.close();
- return b;
+ InputStream fin = openClassfile(classname);
+ byte[] b = readStream(fin);
+ fin.close();
+ return b;
}
/**
* Opens the class file for the class specified by
* <code>classname</code>.
*
- * @param classname a fully-qualified class name
+ * @param classname a fully-qualified class name
*/
public InputStream openClassfile(String classname)
- throws NotFoundException
+ throws NotFoundException
{
- ClassPathList list = pathList;
- InputStream ins = null;
- NotFoundException error = null;
- while (list != null) {
- try {
- ins = list.path.openClassfile(classname);
- }
- catch (NotFoundException e) {
- if (error == null)
- error = e;
- }
-
- if (ins == null)
- list = list.next;
- else
- return ins;
- }
-
- if (error != null)
- throw error;
- else
- throw new NotFoundException(classname);
+ ClassPathList list = pathList;
+ InputStream ins = null;
+ NotFoundException error = null;
+ while (list != null) {
+ try {
+ ins = list.path.openClassfile(classname);
+ }
+ catch (NotFoundException e) {
+ if (error == null)
+ error = e;
+ }
+
+ if (ins == null)
+ list = list.next;
+ else
+ return ins;
+ }
+
+ if (error != null)
+ throw error;
+ else
+ throw new NotFoundException(classname);
}
/**
* Reads an input stream until it reaches the end.
*
- * @return the contents of that input stream
+ * @return the contents of that input stream
*/
public static byte[] readStream(InputStream fin) throws IOException {
- byte[][] bufs = new byte[8][];
- int bufsize = 4096;
-
- for (int i = 0; i < 8; ++i) {
- bufs[i] = new byte[bufsize];
- int size = 0;
- int len = 0;
- do {
- len = fin.read(bufs[i], size, bufsize - size);
- if (len >= 0)
- size += len;
- else {
- byte[] result = new byte[bufsize - 4096 + size];
- int s = 0;
- for (int j = 0; j < i; ++j) {
- System.arraycopy(bufs[j], 0, result, s, s + 4096);
- s = s + s + 4096;
- }
-
- System.arraycopy(bufs[i], 0, result, s, size);
- return result;
- }
- } while (size < bufsize);
- bufsize *= 2;
- }
-
- throw new IOException("too much data");
+ byte[][] bufs = new byte[8][];
+ int bufsize = 4096;
+
+ for (int i = 0; i < 8; ++i) {
+ bufs[i] = new byte[bufsize];
+ int size = 0;
+ int len = 0;
+ do {
+ len = fin.read(bufs[i], size, bufsize - size);
+ if (len >= 0)
+ size += len;
+ else {
+ byte[] result = new byte[bufsize - 4096 + size];
+ int s = 0;
+ for (int j = 0; j < i; ++j) {
+ System.arraycopy(bufs[j], 0, result, s, s + 4096);
+ s = s + s + 4096;
+ }
+
+ System.arraycopy(bufs[i], 0, result, s, size);
+ return result;
+ }
+ } while (size < bufsize);
+ bufsize *= 2;
+ }
+
+ throw new IOException("too much data");
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
* the exactly same as the type of the instantiated class specified by
* <code>newClass</code>.
*
- * @param newClass the instantiated class.
- * @param calledClass the class in which the static method is
- * declared.
- * @param calledMethod the name of the static method.
+ * @param newClass the instantiated class.
+ * @param calledClass the class in which the static method is
+ * declared.
+ * @param calledMethod the name of the static method.
*/
public void replaceNew(CtClass newClass,
- CtClass calledClass, String calledMethod) {
- transformers = new TransformNew(transformers, newClass.getName(),
- calledClass.getName(), calledMethod);
+ CtClass calledClass, String calledMethod) {
+ transformers = new TransformNew(transformers, newClass.getName(),
+ calledClass.getName(), calledMethod);
}
/**
* the class directly declaring the field. They must not specify
* a subclass of that class.
*
- * @param field the originally accessed field.
- * @param newClass the class declaring the substituted field.
- * @param newFieldname the name of the substituted field.
+ * @param field the originally accessed field.
+ * @param newClass the class declaring the substituted field.
+ * @param newFieldname the name of the substituted field.
*/
public void redirectFieldAccess(CtField field,
- CtClass newClass, String newFieldname) {
- transformers = new TransformFieldAccess(transformers, field,
- newClass.getName(),
- newFieldname);
+ CtClass newClass, String newFieldname) {
+ transformers = new TransformFieldAccess(transformers, field,
+ newClass.getName(),
+ newFieldname);
}
/**
* type of <code>target</code>. The return type must be the same
* as the field type.
*
- * @param field the field.
- * @param calledClass the class in which the static method is
- * declared.
- * @param calledMethod the name of the static method.
+ * @param field the field.
+ * @param calledClass the class in which the static method is
+ * declared.
+ * @param calledMethod the name of the static method.
*/
public void replaceFieldRead(CtField field,
- CtClass calledClass, String calledMethod) {
- transformers = new TransformReadField(transformers, field,
- calledClass.getName(),
- calledMethod);
+ CtClass calledClass, String calledMethod) {
+ transformers = new TransformReadField(transformers, field,
+ calledClass.getName(),
+ calledMethod);
}
/**
* type of <code>target</code>. The type of the second parameter
* is the same as the field type.
*
- * @param field the field.
- * @param calledClass the class in which the static method is
- * declared.
- * @param calledMethod the name of the static method.
+ * @param field the field.
+ * @param calledClass the class in which the static method is
+ * declared.
+ * @param calledMethod the name of the static method.
*/
public void replaceFieldWrite(CtField field,
- CtClass calledClass, String calledMethod) {
- transformers = new TransformWriteField(transformers, field,
- calledClass.getName(),
- calledMethod);
+ CtClass calledClass, String calledMethod) {
+ transformers = new TransformWriteField(transformers, field,
+ calledClass.getName(),
+ calledMethod);
}
/**
* If the original method is a static method, the substituted method
* must be static.
*
- * @param origMethod original method
- * @param substMethod substituted method
+ * @param origMethod original method
+ * @param substMethod substituted method
*/
public void redirectMethodCall(CtMethod origMethod,
- CtMethod substMethod)
- throws CannotCompileException
+ CtMethod substMethod)
+ throws CannotCompileException
{
- String d1 = origMethod.getMethodInfo2().getDescriptor();
- String d2 = substMethod.getMethodInfo2().getDescriptor();
- if (!d1.equals(d2))
- throw new CannotCompileException("signature mismatch");
+ String d1 = origMethod.getMethodInfo2().getDescriptor();
+ String d2 = substMethod.getMethodInfo2().getDescriptor();
+ if (!d1.equals(d2))
+ throw new CannotCompileException("signature mismatch");
- transformers = new TransformCall(transformers, origMethod,
- substMethod);
+ transformers = new TransformCall(transformers, origMethod,
+ substMethod);
}
/**
* Verbose.print(p, tmp1, tmp2);
* Point p2 = p.move(tmp1, tmp2);</pre></ul>
*
- * @param origMethod the method originally invoked.
- * @param beforeMethod the method invoked before
- * <code>origMethod</code>.
+ * @param origMethod the method originally invoked.
+ * @param beforeMethod the method invoked before
+ * <code>origMethod</code>.
*/
public void insertBeforeMethod(CtMethod origMethod,
- CtMethod beforeMethod)
- throws CannotCompileException
+ CtMethod beforeMethod)
+ throws CannotCompileException
{
- try {
- transformers = new TransformBefore(transformers, origMethod,
- beforeMethod);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ try {
+ transformers = new TransformBefore(transformers, origMethod,
+ beforeMethod);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* Point p2 = p.move(tmp1, tmp2);
* Verbose.print(p, tmp1, tmp2);</pre></ul>
*
- * @param origMethod the method originally invoked.
- * @param afterMethod the method invoked after
- * <code>origMethod</code>.
+ * @param origMethod the method originally invoked.
+ * @param afterMethod the method invoked after
+ * <code>origMethod</code>.
*/
public void insertAfterMethod(CtMethod origMethod,
- CtMethod afterMethod)
- throws CannotCompileException
+ CtMethod afterMethod)
+ throws CannotCompileException
{
- try {
- transformers = new TransformAfter(transformers, origMethod,
- afterMethod);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ try {
+ transformers = new TransformAfter(transformers, origMethod,
+ afterMethod);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* Performs code conversion.
*/
void doit(CtClass clazz, MethodInfo minfo, ConstPool cp)
- throws CannotCompileException
+ throws CannotCompileException
{
- Transformer t;
+ Transformer t;
- CodeAttribute codeAttr = minfo.getCodeAttribute();
- if (codeAttr == null || transformers == null)
- return;
+ CodeAttribute codeAttr = minfo.getCodeAttribute();
+ if (codeAttr == null || transformers == null)
+ return;
- for (t = transformers; t != null; t = t.getNext())
- t.initialize(cp, codeAttr);
+ for (t = transformers; t != null; t = t.getNext())
+ t.initialize(cp, codeAttr);
- CodeIterator iterator = codeAttr.iterator();
- while (iterator.hasNext()) {
- try {
- int pos = iterator.next();
- for (t = transformers; t != null; t = t.getNext())
- pos = t.transform(clazz, pos, iterator, cp);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
- }
+ CodeIterator iterator = codeAttr.iterator();
+ while (iterator.hasNext()) {
+ try {
+ int pos = iterator.next();
+ for (t = transformers; t != null; t = t.getNext())
+ pos = t.transform(clazz, pos, iterator, cp);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
+ }
- int locals = 0;
- for (t = transformers; t != null; t = t.getNext()) {
- int s = t.extraLocals();
- if (s > locals)
- locals = s;
- }
+ int locals = 0;
+ for (t = transformers; t != null; t = t.getNext()) {
+ int s = t.extraLocals();
+ if (s > locals)
+ locals = s;
+ }
- for (t = transformers; t != null; t = t.getNext())
- t.clean();
+ for (t = transformers; t != null; t = t.getNext())
+ t.clean();
- codeAttr.setMaxLocals(codeAttr.getMaxLocals() + locals);
+ codeAttr.setMaxLocals(codeAttr.getMaxLocals() + locals);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
/**
// the name of array type ends with "[]".
CtArray(String name, ClassPool cp) {
- super(name);
- pool = cp;
+ super(name);
+ pool = cp;
}
public ClassPool getClassPool() {
- return pool;
+ return pool;
}
public boolean isArray() {
- return true;
+ return true;
}
public boolean subtypeOf(CtClass clazz) throws NotFoundException {
- if (super.subtypeOf(clazz))
- return true;
+ if (super.subtypeOf(clazz))
+ return true;
- String cname = clazz.getName();
- if (cname.equals(javaLangObject)
- || cname.equals("java.lang.Cloneable"))
- return true;
+ String cname = clazz.getName();
+ if (cname.equals(javaLangObject)
+ || cname.equals("java.lang.Cloneable"))
+ return true;
- return clazz.isArray()
- && getComponentType().subtypeOf(clazz.getComponentType());
+ return clazz.isArray()
+ && getComponentType().subtypeOf(clazz.getComponentType());
}
public CtClass getComponentType() throws NotFoundException {
- String name = getName();
- return pool.get(name.substring(0, name.length() - 2));
+ String name = getName();
+ return pool.get(name.substring(0, name.length() - 2));
}
public CtClass getSuperclass() throws NotFoundException {
- return pool.get(javaLangObject);
+ return pool.get(javaLangObject);
}
public CtMethod[] getMethods() {
- try {
- return getSuperclass().getMethods();
- }
- catch (NotFoundException e) {
- return super.getMethods();
- }
+ try {
+ return getSuperclass().getMethods();
+ }
+ catch (NotFoundException e) {
+ return super.getMethods();
+ }
}
public CtMethod getMethod(String name, String desc)
- throws NotFoundException
+ throws NotFoundException
{
- return getSuperclass().getMethod(name, desc);
+ return getSuperclass().getMethod(name, desc);
}
public CtConstructor[] getConstructors() {
- try {
- return getSuperclass().getConstructors();
- }
- catch (NotFoundException e) {
- return super.getConstructors();
- }
+ try {
+ return getSuperclass().getConstructors();
+ }
+ catch (NotFoundException e) {
+ return super.getConstructors();
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
protected MethodInfo methodInfo;
protected CtBehavior(CtClass clazz, MethodInfo minfo) {
- super(clazz);
- methodInfo = minfo;
+ super(clazz);
+ methodInfo = minfo;
}
/**
* class file.
*/
public MethodInfo getMethodInfo() {
- declaringClass.checkModify();
- return methodInfo;
+ declaringClass.checkModify();
+ return methodInfo;
}
/**
/**
* Obtains the modifiers of the member.
*
- * @return modifiers encoded with
- * <code>javassist.Modifier</code>.
+ * @return modifiers encoded with
+ * <code>javassist.Modifier</code>.
* @see Modifier
*/
public int getModifiers() {
- return AccessFlag.toModifier(methodInfo.getAccessFlags());
+ return AccessFlag.toModifier(methodInfo.getAccessFlags());
}
/**
* @see Modifier
*/
public void setModifiers(int mod) {
- declaringClass.checkModify();
- methodInfo.setAccessFlags(AccessFlag.of(mod));
+ declaringClass.checkModify();
+ methodInfo.setAccessFlags(AccessFlag.of(mod));
}
/**
* Obtains parameter types of this member.
*/
public CtClass[] getParameterTypes() throws NotFoundException {
- return Descriptor.getParameterTypes(methodInfo.getDescriptor(),
- declaringClass.getClassPool());
+ return Descriptor.getParameterTypes(methodInfo.getDescriptor(),
+ declaringClass.getClassPool());
}
/**
* Obtains the type of the returned value.
*/
CtClass getReturnType0() throws NotFoundException {
- return Descriptor.getReturnType(methodInfo.getDescriptor(),
- declaringClass.getClassPool());
+ return Descriptor.getReturnType(methodInfo.getDescriptor(),
+ declaringClass.getClassPool());
}
/**
* same string.
*/
public String getSignature() {
- return methodInfo.getDescriptor();
+ return methodInfo.getDescriptor();
}
/**
* Obtains exceptions that this member may throw.
*/
public CtClass[] getExceptionTypes() throws NotFoundException {
- String[] exceptions;
- ExceptionsAttribute ea = methodInfo.getExceptionsAttribute();
- if (ea == null)
- exceptions = null;
- else
- exceptions = ea.getExceptions();
-
- return declaringClass.getClassPool().get(exceptions);
+ String[] exceptions;
+ ExceptionsAttribute ea = methodInfo.getExceptionsAttribute();
+ if (ea == null)
+ exceptions = null;
+ else
+ exceptions = ea.getExceptions();
+
+ return declaringClass.getClassPool().get(exceptions);
}
/**
* Sets exceptions that this member may throw.
*/
public void setExceptionTypes(CtClass[] types) throws NotFoundException {
- declaringClass.checkModify();
- if (types == null) {
- methodInfo.removeExceptionsAttribute();
- return;
- }
-
- String[] names = new String[types.length];
- for (int i = 0; i < types.length; ++i)
- names[i] = types[i].getName();
-
- ExceptionsAttribute ea = methodInfo.getExceptionsAttribute();
- if (ea == null) {
- ea = new ExceptionsAttribute(methodInfo.getConstPool());
- methodInfo.setExceptionsAttribute(ea);
- }
-
- ea.setExceptions(names);
+ declaringClass.checkModify();
+ if (types == null) {
+ methodInfo.removeExceptionsAttribute();
+ return;
+ }
+
+ String[] names = new String[types.length];
+ for (int i = 0; i < types.length; ++i)
+ names[i] = types[i].getName();
+
+ ExceptionsAttribute ea = methodInfo.getExceptionsAttribute();
+ if (ea == null) {
+ ea = new ExceptionsAttribute(methodInfo.getConstPool());
+ methodInfo.setExceptionsAttribute(ea);
+ }
+
+ ea.setExceptions(names);
}
+ /**
+ * Returns true if the body is empty.
+ */
+ public abstract boolean isEmpty();
+
/**
* Sets a member body.
*
- * @param src the source code representing the member body.
- * It must be a single statement or block.
+ * @param src the source code representing the member body.
+ * It must be a single statement or block.
*/
public void setBody(String src) throws CannotCompileException {
- declaringClass.checkModify();
- try {
- Javac jv = new Javac(declaringClass);
- Bytecode b = jv.compileBody(this, src);
- methodInfo.setCodeAttribute(b.toCodeAttribute());
- methodInfo.setAccessFlags(methodInfo.getAccessFlags()
- & ~AccessFlag.ABSTRACT);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
+ declaringClass.checkModify();
+ try {
+ Javac jv = new Javac(declaringClass);
+ Bytecode b = jv.compileBody(this, src);
+ methodInfo.setCodeAttribute(b.toCodeAttribute());
+ methodInfo.setAccessFlags(methodInfo.getAccessFlags()
+ & ~AccessFlag.ABSTRACT);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
}
static void setBody0(CtClass srcClass, MethodInfo srcInfo,
- CtClass destClass, MethodInfo destInfo,
- ClassMap map)
- throws CannotCompileException
+ CtClass destClass, MethodInfo destInfo,
+ ClassMap map)
+ throws CannotCompileException
{
- destClass.checkModify();
-
- if (map == null)
- map = new ClassMap();
-
- map.put(srcClass.getName(), destClass.getName());
- try {
- CodeAttribute cattr = srcInfo.getCodeAttribute();
- if (cattr != null) {
- ConstPool cp = destInfo.getConstPool();
- CodeAttribute ca = (CodeAttribute)cattr.copy(cp, map);
- destInfo.setCodeAttribute(ca);
- }
- }
- catch (CodeAttribute.RuntimeCopyException e) {
- /* the exception may be thrown by copy() in CodeAttribute.
- */
- throw new CannotCompileException(e);
- }
-
- destInfo.setAccessFlags(destInfo.getAccessFlags()
- & ~AccessFlag.ABSTRACT);
+ destClass.checkModify();
+
+ if (map == null)
+ map = new ClassMap();
+
+ map.put(srcClass.getName(), destClass.getName());
+ try {
+ CodeAttribute cattr = srcInfo.getCodeAttribute();
+ if (cattr != null) {
+ ConstPool cp = destInfo.getConstPool();
+ CodeAttribute ca = (CodeAttribute)cattr.copy(cp, map);
+ destInfo.setCodeAttribute(ca);
+ }
+ }
+ catch (CodeAttribute.RuntimeCopyException e) {
+ /* the exception may be thrown by copy() in CodeAttribute.
+ */
+ throw new CannotCompileException(e);
+ }
+
+ destInfo.setAccessFlags(destInfo.getAccessFlags()
+ & ~AccessFlag.ABSTRACT);
}
/**
* If that attribute is not found in the class file, this
* method returns null.
*
- * @param name attribute name
+ * @param name attribute name
*/
public byte[] getAttribute(String name) {
- AttributeInfo ai = methodInfo.getAttribute(name);
- if (ai == null)
- return null;
- else
- return ai.get();
+ AttributeInfo ai = methodInfo.getAttribute(name);
+ if (ai == null)
+ return null;
+ else
+ return ai.get();
}
/**
* Adds an attribute. The attribute is saved in the class file.
*
- * @param name attribute name
- * @param data attribute value
+ * @param name attribute name
+ * @param data attribute value
*/
public void setAttribute(String name, byte[] data) {
- declaringClass.checkModify();
- methodInfo.addAttribute(new AttributeInfo(methodInfo.getConstPool(),
- name, data));
+ declaringClass.checkModify();
+ methodInfo.addAttribute(new AttributeInfo(methodInfo.getConstPool(),
+ name, data));
}
/**
* For example, if the given name is <code>"Point.paint"</code>,
* then the variable is indicated by <code>$cflow(Point.paint)</code>.
*
- * @param name <code>$cflow</code> name. It can include
- * alphabets, numbers, <code>_</code>,
- * <code>$</code>, and <code>.</code> (dot).
+ * @param name <code>$cflow</code> name. It can include
+ * alphabets, numbers, <code>_</code>,
+ * <code>$</code>, and <code>.</code> (dot).
*
* @see javassist.runtime.Cflow
*/
public void useCflow(String name) throws CannotCompileException {
- CtClass cc = declaringClass;
- cc.checkModify();
- ClassPool pool = cc.getClassPool();
- String fname;
- int i = 0;
- while (true) {
- fname = "_cflow$" + i++;
- try {
- cc.getDeclaredField(fname);
- }
- catch(NotFoundException e) {
- break;
- }
- }
-
- pool.recordCflow(name, declaringClass.getName(), fname);
- try {
- CtClass type = pool.get("javassist.runtime.Cflow");
- CtField field = new CtField(type, fname, cc);
- field.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
- cc.addField(field, CtField.Initializer.byNew(type));
- insertBefore(fname + ".enter();");
- String src = fname + ".exit();";
- insertAfter(src, true);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ CtClass cc = declaringClass;
+ cc.checkModify();
+ ClassPool pool = cc.getClassPool();
+ String fname;
+ int i = 0;
+ while (true) {
+ fname = "_cflow$" + i++;
+ try {
+ cc.getDeclaredField(fname);
+ }
+ catch(NotFoundException e) {
+ break;
+ }
+ }
+
+ pool.recordCflow(name, declaringClass.getName(), fname);
+ try {
+ CtClass type = pool.get("javassist.runtime.Cflow");
+ CtField field = new CtField(type, fname, cc);
+ field.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
+ cc.addField(field, CtField.Initializer.byNew(type));
+ insertBefore(fname + ".enter();");
+ String src = fname + ".exit();";
+ insertAfter(src, true);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* Modifies the member body.
*
- * @param converter specifies how to modify.
+ * @param converter specifies how to modify.
*/
public void instrument(CodeConverter converter)
- throws CannotCompileException
+ throws CannotCompileException
{
- declaringClass.checkModify();
- ConstPool cp = methodInfo.getConstPool();
- converter.doit(getDeclaringClass(), methodInfo, cp);
+ declaringClass.checkModify();
+ ConstPool cp = methodInfo.getConstPool();
+ converter.doit(getDeclaringClass(), methodInfo, cp);
}
/**
* Modifies the member body.
*
- * @param editor specifies how to modify.
+ * @param editor specifies how to modify.
*/
public void instrument(ExprEditor editor)
- throws CannotCompileException
+ throws CannotCompileException
{
- // if the class is not frozen,
- // does not trun the modified flag on.
- if (declaringClass.isFrozen())
- declaringClass.checkModify();
+ // if the class is not frozen,
+ // does not trun the modified flag on.
+ if (declaringClass.isFrozen())
+ declaringClass.checkModify();
- if (editor.doit(declaringClass, methodInfo))
- declaringClass.checkModify();
+ if (editor.doit(declaringClass, methodInfo))
+ declaringClass.checkModify();
}
/**
* Inserts bytecode at the beginning of the body.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertBefore(String src) throws CannotCompileException {
- declaringClass.checkModify();
- CodeAttribute ca = methodInfo.getCodeAttribute();
- CodeIterator iterator = ca.iterator();
- Javac jv = new Javac(declaringClass);
- try {
- jv.recordParams(getParameterTypes(),
- Modifier.isStatic(getModifiers()));
- jv.compileStmnt(src);
- Bytecode b = jv.getBytecode();
- int stack = b.getMaxStack();
- int locals = b.getMaxLocals();
-
- if (stack > ca.getMaxStack())
- ca.setMaxStack(stack);
-
- if (locals > ca.getMaxLocals())
- ca.setMaxLocals(locals);
-
- int pos = iterator.insertEx(b.get());
- iterator.insert(b.getExceptionTable(), pos);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
+ declaringClass.checkModify();
+ CodeAttribute ca = methodInfo.getCodeAttribute();
+ if (ca == null)
+ throw new CannotCompileException("no method body");
+
+ CodeIterator iterator = ca.iterator();
+ Javac jv = new Javac(declaringClass);
+ try {
+ jv.recordParams(getParameterTypes(),
+ Modifier.isStatic(getModifiers()));
+ jv.compileStmnt(src);
+ Bytecode b = jv.getBytecode();
+ int stack = b.getMaxStack();
+ int locals = b.getMaxLocals();
+
+ if (stack > ca.getMaxStack())
+ ca.setMaxStack(stack);
+
+ if (locals > ca.getMaxLocals())
+ ca.setMaxLocals(locals);
+
+ int pos = iterator.insertEx(b.get());
+ iterator.insert(b.getExceptionTable(), pos);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* The bytecode is inserted just before every return insturction.
* It is not executed when an exception is thrown.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertAfter(String src)
- throws CannotCompileException
+ throws CannotCompileException
{
- insertAfter(src, false);
+ insertAfter(src, false);
}
/**
* Inserts bytecode at the end of the body.
* The bytecode is inserted just before every return insturction.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
- * @param asFinally true if the inserted bytecode is executed
- * not only when the control normally returns
- * but also when an exception is thrown.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
+ * @param asFinally true if the inserted bytecode is executed
+ * not only when the control normally returns
+ * but also when an exception is thrown.
*/
public void insertAfter(String src, boolean asFinally)
- throws CannotCompileException
+ throws CannotCompileException
{
- declaringClass.checkModify();
- CodeAttribute ca = methodInfo.getCodeAttribute();
- CodeIterator iterator = ca.iterator();
- int retAddr = ca.getMaxLocals();
- Bytecode b = new Bytecode(methodInfo.getConstPool(), 0, retAddr + 1);
- b.setStackDepth(ca.getMaxStack() + 1);
- Javac jv = new Javac(b, declaringClass);
- try {
- jv.recordParams(getParameterTypes(),
- Modifier.isStatic(getModifiers()));
- CtClass rtype = getReturnType0();
- int varNo = jv.recordReturnType(rtype, true);
- boolean isVoid = rtype == CtClass.voidType;
-
- int handlerLen = insertAfterHandler(asFinally, b, rtype);
-
- b.addAstore(retAddr);
- if (isVoid) {
- b.addOpcode(Opcode.ACONST_NULL);
- b.addAstore(varNo);
- jv.compileStmnt(src);
- }
- else {
- b.addStore(varNo, rtype);
- jv.compileStmnt(src);
- b.addLoad(varNo, rtype);
- }
-
- b.addRet(retAddr);
- ca.setMaxStack(b.getMaxStack());
- ca.setMaxLocals(b.getMaxLocals());
-
- int gapPos = iterator.append(b.get());
- iterator.append(b.getExceptionTable(), gapPos);
-
- if (asFinally)
- ca.getExceptionTable().add(0, gapPos, gapPos, 0);
-
- int gapLen = iterator.getCodeLength() - gapPos - handlerLen;
- int subr = iterator.getCodeLength() - gapLen;
-
- while (iterator.hasNext()) {
- int pos = iterator.next();
- if (pos >= subr)
- break;
-
- int c = iterator.byteAt(pos);
- if (c == Opcode.ARETURN || c == Opcode.IRETURN
- || c == Opcode.FRETURN || c == Opcode.LRETURN
- || c == Opcode.DRETURN || c == Opcode.RETURN) {
- if (subr - pos > Short.MAX_VALUE - 5) {
- iterator.insertGap(pos, 5);
- iterator.writeByte(Opcode.JSR_W, pos);
- iterator.write32bit(subr - pos + 5, pos + 1);
- }
- else {
- iterator.insertGap(pos, 3);
- iterator.writeByte(Opcode.JSR, pos);
- iterator.write16bit(subr - pos + 3, pos + 1);
- }
-
- subr = iterator.getCodeLength() - gapLen;
- }
- }
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
+ declaringClass.checkModify();
+ CodeAttribute ca = methodInfo.getCodeAttribute();
+ if (ca == null)
+ throw new CannotCompileException("no method body");
+
+ CodeIterator iterator = ca.iterator();
+ int retAddr = ca.getMaxLocals();
+ Bytecode b = new Bytecode(methodInfo.getConstPool(), 0, retAddr + 1);
+ b.setStackDepth(ca.getMaxStack() + 1);
+ Javac jv = new Javac(b, declaringClass);
+ try {
+ jv.recordParams(getParameterTypes(),
+ Modifier.isStatic(getModifiers()));
+ CtClass rtype = getReturnType0();
+ int varNo = jv.recordReturnType(rtype, true);
+ boolean isVoid = rtype == CtClass.voidType;
+
+ int handlerLen = insertAfterHandler(asFinally, b, rtype);
+
+ b.addAstore(retAddr);
+ if (isVoid) {
+ b.addOpcode(Opcode.ACONST_NULL);
+ b.addAstore(varNo);
+ jv.compileStmnt(src);
+ }
+ else {
+ b.addStore(varNo, rtype);
+ jv.compileStmnt(src);
+ b.addLoad(varNo, rtype);
+ }
+
+ b.addRet(retAddr);
+ ca.setMaxStack(b.getMaxStack());
+ ca.setMaxLocals(b.getMaxLocals());
+
+ int gapPos = iterator.append(b.get());
+ iterator.append(b.getExceptionTable(), gapPos);
+
+ if (asFinally)
+ ca.getExceptionTable().add(0, gapPos, gapPos, 0);
+
+ int gapLen = iterator.getCodeLength() - gapPos - handlerLen;
+ int subr = iterator.getCodeLength() - gapLen;
+
+ while (iterator.hasNext()) {
+ int pos = iterator.next();
+ if (pos >= subr)
+ break;
+
+ int c = iterator.byteAt(pos);
+ if (c == Opcode.ARETURN || c == Opcode.IRETURN
+ || c == Opcode.FRETURN || c == Opcode.LRETURN
+ || c == Opcode.DRETURN || c == Opcode.RETURN) {
+ if (subr - pos > Short.MAX_VALUE - 5) {
+ int s = iterator.insertGap(pos, 5);
+ iterator.writeByte(Opcode.JSR_W, pos);
+ iterator.write32bit(subr - pos + s, pos + 1);
+ }
+ else {
+ int s = iterator.insertGap(pos, 3);
+ iterator.writeByte(Opcode.JSR, pos);
+ iterator.write16bit(subr - pos + s, pos + 1);
+ }
+
+ subr = iterator.getCodeLength() - gapLen;
+ }
+ }
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
}
private int insertAfterHandler(boolean asFinally, Bytecode b,
- CtClass rtype)
+ CtClass rtype)
{
- if (!asFinally)
- return 0;
-
- int var = b.getMaxLocals();
- b.incMaxLocals(1);
- int pc = b.currentPc();
- b.addAstore(var);
- if (rtype.isPrimitive()) {
- char c = ((CtPrimitiveType)rtype).getDescriptor();
- if (c == 'D')
- b.addDconst(0.0);
- else if (c == 'F')
- b.addFconst(0);
- else if (c == 'J')
- b.addLconst(0);
- else if (c != 'V') // int, boolean, char, short, ...
- b.addIconst(0);
- }
- else
- b.addOpcode(Opcode.ACONST_NULL);
-
- b.addOpcode(Opcode.JSR);
- int pc2 = b.currentPc();
- b.addIndex(0); // correct later
- b.addAload(var);
- b.addOpcode(Opcode.ATHROW);
- int pc3 = b.currentPc();
- b.write16bit(pc2, pc3 - pc2 + 1);
- return pc3 - pc;
+ if (!asFinally)
+ return 0;
+
+ int var = b.getMaxLocals();
+ b.incMaxLocals(1);
+ int pc = b.currentPc();
+ b.addAstore(var);
+ if (rtype.isPrimitive()) {
+ char c = ((CtPrimitiveType)rtype).getDescriptor();
+ if (c == 'D')
+ b.addDconst(0.0);
+ else if (c == 'F')
+ b.addFconst(0);
+ else if (c == 'J')
+ b.addLconst(0);
+ else if (c != 'V') // int, boolean, char, short, ...
+ b.addIconst(0);
+ }
+ else
+ b.addOpcode(Opcode.ACONST_NULL);
+
+ b.addOpcode(Opcode.JSR);
+ int pc2 = b.currentPc();
+ b.addIndex(0); // correct later
+ b.addAload(var);
+ b.addOpcode(Opcode.ATHROW);
+ int pc3 = b.currentPc();
+ b.write16bit(pc2, pc3 - pc2 + 1);
+ return pc3 - pc;
}
/* -- OLD version --
public void insertAfter(String src) throws CannotCompileException {
- declaringClass.checkModify();
- CodeAttribute ca = methodInfo.getCodeAttribute();
- CodeIterator iterator = ca.iterator();
- Bytecode b = new Bytecode(methodInfo.getConstPool(),
- ca.getMaxStack(), ca.getMaxLocals());
- b.setStackDepth(ca.getMaxStack());
- Javac jv = new Javac(b, declaringClass);
- try {
- jv.recordParams(getParameterTypes(),
- Modifier.isStatic(getModifiers()));
- CtClass rtype = getReturnType0();
- int varNo = jv.recordReturnType(rtype, true);
- boolean isVoid = rtype == CtClass.voidType;
- if (isVoid) {
- b.addOpcode(Opcode.ACONST_NULL);
- b.addAstore(varNo);
- jv.compileStmnt(src);
- }
- else {
- b.addStore(varNo, rtype);
- jv.compileStmnt(src);
- b.addLoad(varNo, rtype);
- }
-
- byte[] code = b.get();
- ca.setMaxStack(b.getMaxStack());
- ca.setMaxLocals(b.getMaxLocals());
- while (iterator.hasNext()) {
- int pos = iterator.next();
- int c = iterator.byteAt(pos);
- if (c == Opcode.ARETURN || c == Opcode.IRETURN
- || c == Opcode.FRETURN || c == Opcode.LRETURN
- || c == Opcode.DRETURN || c == Opcode.RETURN)
- iterator.insert(pos, code);
- }
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
+ declaringClass.checkModify();
+ CodeAttribute ca = methodInfo.getCodeAttribute();
+ CodeIterator iterator = ca.iterator();
+ Bytecode b = new Bytecode(methodInfo.getConstPool(),
+ ca.getMaxStack(), ca.getMaxLocals());
+ b.setStackDepth(ca.getMaxStack());
+ Javac jv = new Javac(b, declaringClass);
+ try {
+ jv.recordParams(getParameterTypes(),
+ Modifier.isStatic(getModifiers()));
+ CtClass rtype = getReturnType0();
+ int varNo = jv.recordReturnType(rtype, true);
+ boolean isVoid = rtype == CtClass.voidType;
+ if (isVoid) {
+ b.addOpcode(Opcode.ACONST_NULL);
+ b.addAstore(varNo);
+ jv.compileStmnt(src);
+ }
+ else {
+ b.addStore(varNo, rtype);
+ jv.compileStmnt(src);
+ b.addLoad(varNo, rtype);
+ }
+
+ byte[] code = b.get();
+ ca.setMaxStack(b.getMaxStack());
+ ca.setMaxLocals(b.getMaxLocals());
+ while (iterator.hasNext()) {
+ int pos = iterator.next();
+ int c = iterator.byteAt(pos);
+ if (c == Opcode.ARETURN || c == Opcode.IRETURN
+ || c == Opcode.FRETURN || c == Opcode.LRETURN
+ || c == Opcode.DRETURN || c == Opcode.RETURN)
+ iterator.insert(pos, code);
+ }
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
}
*/
* Adds a catch clause that handles an exception thrown in the
* body. The catch clause must end with a return or throw statement.
*
- * @param src the source code representing the catch clause.
- * It must be a single statement or block.
- * @param exceptionType the type of the exception handled by the
- * catch clause.
- * @param exceptionName the name of the variable containing the
- * caught exception.
+ * @param src the source code representing the catch clause.
+ * It must be a single statement or block.
+ * @param exceptionType the type of the exception handled by the
+ * catch clause.
+ */
+ public void addCatch(String src, CtClass exceptionType)
+ throws CannotCompileException
+ {
+ addCatch(src, exceptionType, "$e");
+ }
+
+ /**
+ * Adds a catch clause that handles an exception thrown in the
+ * body. The catch clause must end with a return or throw statement.
+ *
+ * @param src the source code representing the catch clause.
+ * It must be a single statement or block.
+ * @param exceptionType the type of the exception handled by the
+ * catch clause.
+ * @param exceptionName the name of the variable containing the
+ * caught exception, for example,
+ * <code>$e</code>.
*/
public void addCatch(String src, CtClass exceptionType,
- String exceptionName)
- throws CannotCompileException
+ String exceptionName)
+ throws CannotCompileException
{
- declaringClass.checkModify();
- ConstPool cp = methodInfo.getConstPool();
- CodeAttribute ca = methodInfo.getCodeAttribute();
- CodeIterator iterator = ca.iterator();
- Bytecode b = new Bytecode(cp, ca.getMaxStack(), ca.getMaxLocals());
- b.setStackDepth(1);
- Javac jv = new Javac(b, declaringClass);
- try {
- jv.recordParams(getParameterTypes(),
- Modifier.isStatic(getModifiers()));
- int var = jv.recordVariable(exceptionType, exceptionName);
- b.addAstore(var);
- jv.compileStmnt(src);
-
- int stack = b.getMaxStack();
- int locals = b.getMaxLocals();
-
- if (stack > ca.getMaxStack())
- ca.setMaxStack(stack);
-
- if (locals > ca.getMaxLocals())
- ca.setMaxLocals(locals);
-
- int len = iterator.getCodeLength();
- int pos = iterator.append(b.get());
- ca.getExceptionTable().add(0, len, len,
- cp.addClassInfo(exceptionType));
- iterator.append(b.getExceptionTable(), pos);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
+ declaringClass.checkModify();
+ ConstPool cp = methodInfo.getConstPool();
+ CodeAttribute ca = methodInfo.getCodeAttribute();
+ CodeIterator iterator = ca.iterator();
+ Bytecode b = new Bytecode(cp, ca.getMaxStack(), ca.getMaxLocals());
+ b.setStackDepth(1);
+ Javac jv = new Javac(b, declaringClass);
+ try {
+ jv.recordParams(getParameterTypes(),
+ Modifier.isStatic(getModifiers()));
+ int var = jv.recordVariable(exceptionType, exceptionName);
+ b.addAstore(var);
+ jv.compileStmnt(src);
+
+ int stack = b.getMaxStack();
+ int locals = b.getMaxLocals();
+
+ if (stack > ca.getMaxStack())
+ ca.setMaxStack(stack);
+
+ if (locals > ca.getMaxLocals())
+ ca.setMaxLocals(locals);
+
+ int len = iterator.getCodeLength();
+ int pos = iterator.append(b.get());
+ ca.getExceptionTable().add(0, len, len,
+ cp.addClassInfo(exceptionType));
+ iterator.append(b.getExceptionTable(), pos);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.DataOutputStream;
/**
* The version number of this release.
*/
- public static final String version = "2.4";
+ public static final String version = "2.5";
static final String javaLangObject = "java.lang.Object";
static CtClass[] primitiveTypes;
static {
- primitiveTypes = new CtClass[9];
+ primitiveTypes = new CtClass[9];
- booleanType = new CtPrimitiveType("boolean", 'Z', "java.lang.Boolean",
- "booleanValue", "()Z", Opcode.IRETURN,
- Opcode.T_BOOLEAN, 1);
- primitiveTypes[0] = booleanType;
+ booleanType = new CtPrimitiveType("boolean", 'Z', "java.lang.Boolean",
+ "booleanValue", "()Z", Opcode.IRETURN,
+ Opcode.T_BOOLEAN, 1);
+ primitiveTypes[0] = booleanType;
- charType = new CtPrimitiveType("char", 'C', "java.lang.Character",
- "charValue", "()C", Opcode.IRETURN,
- Opcode.T_CHAR, 1);
- primitiveTypes[1] = charType;
+ charType = new CtPrimitiveType("char", 'C', "java.lang.Character",
+ "charValue", "()C", Opcode.IRETURN,
+ Opcode.T_CHAR, 1);
+ primitiveTypes[1] = charType;
- byteType = new CtPrimitiveType("byte", 'B', "java.lang.Byte",
- "byteValue", "()B", Opcode.IRETURN,
- Opcode.T_BYTE, 1);
- primitiveTypes[2] = byteType;
+ byteType = new CtPrimitiveType("byte", 'B', "java.lang.Byte",
+ "byteValue", "()B", Opcode.IRETURN,
+ Opcode.T_BYTE, 1);
+ primitiveTypes[2] = byteType;
- shortType = new CtPrimitiveType("short", 'S', "java.lang.Short",
- "shortValue", "()S", Opcode.IRETURN,
- Opcode.T_SHORT, 1);
- primitiveTypes[3] = shortType;
+ shortType = new CtPrimitiveType("short", 'S', "java.lang.Short",
+ "shortValue", "()S", Opcode.IRETURN,
+ Opcode.T_SHORT, 1);
+ primitiveTypes[3] = shortType;
- intType = new CtPrimitiveType("int", 'I', "java.lang.Integer",
- "intValue", "()I", Opcode.IRETURN,
- Opcode.T_INT, 1);
- primitiveTypes[4] = intType;
+ intType = new CtPrimitiveType("int", 'I', "java.lang.Integer",
+ "intValue", "()I", Opcode.IRETURN,
+ Opcode.T_INT, 1);
+ primitiveTypes[4] = intType;
- longType = new CtPrimitiveType("long", 'J', "java.lang.Long",
- "longValue", "()J", Opcode.LRETURN,
- Opcode.T_LONG, 2);
- primitiveTypes[5] = longType;
+ longType = new CtPrimitiveType("long", 'J', "java.lang.Long",
+ "longValue", "()J", Opcode.LRETURN,
+ Opcode.T_LONG, 2);
+ primitiveTypes[5] = longType;
- floatType = new CtPrimitiveType("float", 'F', "java.lang.Float",
- "floatValue", "()F", Opcode.FRETURN,
- Opcode.T_FLOAT, 1);
- primitiveTypes[6] = floatType;
+ floatType = new CtPrimitiveType("float", 'F', "java.lang.Float",
+ "floatValue", "()F", Opcode.FRETURN,
+ Opcode.T_FLOAT, 1);
+ primitiveTypes[6] = floatType;
- doubleType = new CtPrimitiveType("double", 'D', "java.lang.Double",
- "doubleValue", "()D", Opcode.DRETURN,
- Opcode.T_DOUBLE, 2);
- primitiveTypes[7] = doubleType;
+ doubleType = new CtPrimitiveType("double", 'D', "java.lang.Double",
+ "doubleValue", "()D", Opcode.DRETURN,
+ Opcode.T_DOUBLE, 2);
+ primitiveTypes[7] = doubleType;
- voidType = new CtPrimitiveType("void", 'V', "java.lang.Void",
- null, null, Opcode.RETURN, 0, 0);
- primitiveTypes[8] = voidType;
+ voidType = new CtPrimitiveType("void", 'V', "java.lang.Void",
+ null, null, Opcode.RETURN, 0, 0);
+ primitiveTypes[8] = voidType;
}
protected CtClass(String name) {
- qualifiedName = name;
+ qualifiedName = name;
}
/**
* is true.
*/
public ClassFile getClassFile() {
- checkModify();
- return getClassFile2();
+ checkModify();
+ return getClassFile2();
}
/**
*/
public boolean isFrozen() { return true; }
+ void freeze() {}
+
void checkModify() throws RuntimeException {
- if (isFrozen())
- throw new RuntimeException("the class is frozen");
+ if (isFrozen())
+ throw new RuntimeException("the class is frozen");
- // isModified() must return true after this method is invoked.
+ // isModified() must return true after this method is invoked.
}
/**
* that the class will be reloaded or written out later again.
*/
public void defrost() {
- throw new RuntimeException("cannot defrost " + getName());
+ throw new RuntimeException("cannot defrost " + getName());
}
/**
* Returns <code>true</code> if this object represents an array type.
*/
public boolean isArray() {
- return false;
+ return false;
}
/**
* type of the array. Otherwise, it returns <code>null</code>.
*/
public CtClass getComponentType() throws NotFoundException {
- return null;
+ return null;
}
/**
* this class is the same as <code>clazz<code>.
*/
public boolean subtypeOf(CtClass clazz) throws NotFoundException {
- return this == clazz || getName().equals(clazz.getName());
+ return this == clazz || getName().equals(clazz.getName());
}
/**
* Obtains the not-qualified class name.
*/
public final String getSimpleName() {
- String qname = qualifiedName;
- int index = qname.lastIndexOf('.');
- if (index < 0)
- return qname;
- else
- return qname.substring(index + 1);
+ String qname = qualifiedName;
+ int index = qname.lastIndexOf('.');
+ if (index < 0)
+ return qname;
+ else
+ return qname.substring(index + 1);
}
/**
* Obtains the package name. It may be <code>null</code>.
*/
public final String getPackageName() {
- String qname = qualifiedName;
- int index = qname.lastIndexOf('.');
- if (index < 0)
- return null;
- else
- return qname.substring(0, index);
+ String qname = qualifiedName;
+ int index = qname.lastIndexOf('.');
+ if (index < 0)
+ return null;
+ else
+ return qname.substring(0, index);
}
/**
* Sets the class name
*
- * @param name fully-qualified name
+ * @param name fully-qualified name
*/
public void setName(String name) {
- checkModify();
- if (name != null)
- qualifiedName = name;
+ checkModify();
+ if (name != null)
+ qualifiedName = name;
}
/**
* Substitutes <code>newName</code> for all occurrences of a class
* name <code>oldName</code> in the class file.
*
- * @param oldName replaced class name
- * @param newName substituted class name
+ * @param oldName replaced class name
+ * @param newName substituted class name
*/
public void replaceClassName(String oldname, String newname) {
- checkModify();
+ checkModify();
}
/**
* to this method. After this method finishes, that instance would
* contain all the class names appearing in the class file.
*
- * @param map the hashtable associating replaced class names
- * with substituted names.
+ * @param map the hashtable associating replaced class names
+ * with substituted names.
*/
public void replaceClassName(ClassMap map) {
- checkModify();
+ checkModify();
}
/**
* <p>This method may return <code>null</code>.
*/
public Collection getRefClasses() {
- ClassFile cf = getClassFile2();
- if (cf != null) {
- ClassMap cm = new ClassMap() {
- public void put(String oldname, String newname) {
- put0(oldname, newname);
- }
+ ClassFile cf = getClassFile2();
+ if (cf != null) {
+ ClassMap cm = new ClassMap() {
+ public void put(String oldname, String newname) {
+ put0(oldname, newname);
+ }
- public Object get(Object jvmClassName) {
- String n = toJavaName((String)jvmClassName);
- put0(n, n);
- return null;
- }
+ public Object get(Object jvmClassName) {
+ String n = toJavaName((String)jvmClassName);
+ put0(n, n);
+ return null;
+ }
- public void fix(String name) {}
- };
- cf.renameClass(cm);
- return cm.values();
- }
- else
- return null;
+ public void fix(String name) {}
+ };
+ cf.renameClass(cm);
+ return cm.values();
+ }
+ else
+ return null;
}
/**
* It returns <code>true</code> if this object represents an interface.
*/
public boolean isInterface() {
- return false;
+ return false;
}
/**
* @see Modifier
*/
public int getModifiers() {
- return 0;
+ return 0;
}
/**
* Sets the modifiers.
*
- * @param mod modifiers encoded by
- * <code>javassist.Modifier</code>
+ * @param mod modifiers encoded by
+ * <code>javassist.Modifier</code>
* @see Modifier
*/
public void setModifiers(int mod) {
- checkModify();
+ checkModify();
}
/**
* the class represented by this object.
*/
public boolean subclassOf(CtClass superclass) {
- return false;
+ return false;
}
/**
* It returns null if the class is <code>java.lang.Object</code>.
*/
public CtClass getSuperclass() throws NotFoundException {
- return null;
+ return null;
}
/**
* Changes a super class.
*/
public void setSuperclass(CtClass clazz) throws CannotCompileException {
- checkModify();
+ checkModify();
}
/**
* class.
*/
public CtClass[] getInterfaces() throws NotFoundException {
- return new CtClass[0];
+ return new CtClass[0];
}
/**
* Sets interfaces.
*
- * @param list a list of the <code>CtClass</code> objects
- * representing interfaces, or
- * <code>null</code> if the class implements
- * no interfaces.
+ * @param list a list of the <code>CtClass</code> objects
+ * representing interfaces, or
+ * <code>null</code> if the class implements
+ * no interfaces.
*/
public void setInterfaces(CtClass[] list) {
- checkModify();
+ checkModify();
}
/**
* Adds an interface.
*
- * @param anInterface the added interface.
+ * @param anInterface the added interface.
*/
public void addInterface(CtClass anInterface) {
- checkModify();
+ checkModify();
}
/**
* may be a private field declared in a super class or interface.
*/
public CtField getField(String name) throws NotFoundException {
- throw new NotFoundException(name);
+ throw new NotFoundException(name);
}
/**
* <p>Note: this method does not search the superclasses.
*/
public CtField getDeclaredField(String name) throws NotFoundException {
- throw new NotFoundException(name);
+ throw new NotFoundException(name);
}
/**
* Gets all the constructors and methods declared in the class.
*/
public CtBehavior[] getDeclaredBehaviors() {
- return new CtBehavior[0];
+ return new CtBehavior[0];
}
/**
* representing all the public constructors of the class.
*/
public CtConstructor[] getConstructors() {
- return new CtConstructor[0];
+ return new CtConstructor[0];
}
/**
* For details of the method descriptor, see the JVM specification
* or <code>javassist.bytecode.Descriptor</code>.
*
- * @param name method name
- * @param desc method descriptor
+ * @param name method name
+ * @param desc method descriptor
* @see javassist.bytecode.Descriptor
*/
public CtConstructor getConstructor(String desc)
- throws NotFoundException
+ throws NotFoundException
{
- throw new NotFoundException("no such a constructor");
+ throw new NotFoundException("no such a constructor");
}
/**
* @see javassist.CtConstructor
*/
public CtConstructor[] getDeclaredConstructors() {
- return new CtConstructor[0];
+ return new CtConstructor[0];
}
/**
* Returns a constructor receiving the specified parameters.
*
- * @param params parameter types.
+ * @param params parameter types.
*/
public CtConstructor getDeclaredConstructor(CtClass[] params)
- throws NotFoundException
+ throws NotFoundException
{
- String desc = Descriptor.ofConstructor(params);
- return getConstructor(desc);
+ String desc = Descriptor.ofConstructor(params);
+ return getConstructor(desc);
}
/**
* @see javassist.CtConstructor
*/
public CtConstructor getClassInitializer() {
- return null;
+ return null;
}
/**
* superclasses.
*/
public CtMethod[] getMethods() {
- return new CtMethod[0];
+ return new CtMethod[0];
}
/**
* called method descriptor,
* which is defined in the JVM specification.
*
- * @param name method name
- * @param desc method descriptor
+ * @param name method name
+ * @param desc method descriptor
* @see javassist.bytecode.Descriptor
*/
public CtMethod getMethod(String name, String desc)
- throws NotFoundException
+ throws NotFoundException
{
- throw new NotFoundException(name);
+ throw new NotFoundException(name);
}
/**
* @see javassist.CtMethod
*/
public CtMethod[] getDeclaredMethods() {
- return new CtMethod[0];
+ return new CtMethod[0];
}
/**
*
* <p>Note: this method does not search the superclasses.
*
- * @param name method name
- * @param params parameter types
+ * @param name method name
+ * @param params parameter types
* @see javassist.CtMethod
*/
public CtMethod getDeclaredMethod(String name, CtClass[] params)
- throws NotFoundException
+ throws NotFoundException
{
- throw new NotFoundException(name);
+ throw new NotFoundException(name);
}
/**
* @see javassist.CtMethod
*/
public CtMethod getDeclaredMethod(String name) throws NotFoundException {
- throw new NotFoundException(name);
+ throw new NotFoundException(name);
}
/**
* Adds a constructor.
*/
public void addConstructor(CtConstructor c)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
+ checkModify();
}
/**
* Adds a method.
*/
public void addMethod(CtMethod m) throws CannotCompileException {
- checkModify();
+ checkModify();
}
/**
* @see javassist.CtField#CtField(CtField,CtClass)
*/
public void addField(CtField f) throws CannotCompileException {
- addField(f, (CtField.Initializer)null);
+ addField(f, (CtField.Initializer)null);
}
/**
* <p>Here, the type of variable <code>cc</code> is <code>CtClass</code>.
* The type of <code>f</code> is <code>CtField</code>.
*
- * @param init an expression for the initial value.
+ * @param init an expression for the initial value.
*
* @see javassist.CtField.Initializer#byExpr(String)
* @see javassist.CtField#CtField(CtField,CtClass)
*/
public void addField(CtField f, String init)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
+ checkModify();
}
/**
* <p>This code adds an <code>int</code> field named "i". The
* initial value of this field is 1.
*
- * @param init specifies the initial value of the field.
+ * @param init specifies the initial value of the field.
*
* @see javassist.CtField#CtField(CtField,CtClass)
*/
public void addField(CtField f, CtField.Initializer init)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
+ checkModify();
}
/**
* If that attribute is not found in the class file, this
* method returns null.
*
- * @param name attribute name
+ * @param name attribute name
*/
public byte[] getAttribute(String name) {
- return null;
+ return null;
}
/**
* If there is already an attribute with
* the same name, this method substitutes the new one for it.
*
- * @param name attribute name
- * @param data attribute value
+ * @param name attribute name
+ * @param data attribute value
*/
public void setAttribute(String name, byte[] data) {
- checkModify();
+ checkModify();
}
/**
* on every <code>CtMethod</code> and <code>CtConstructor</code> object
* in the class.
*
- * @param converter specifies how to modify.
+ * @param converter specifies how to modify.
*/
public void instrument(CodeConverter converter)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
+ checkModify();
}
/**
* on every <code>CtMethod</code> and <code>CtConstructor</code> object
* in the class.
*
- * @param editor specifies how to modify.
+ * @param editor specifies how to modify.
*/
public void instrument(ExprEditor editor)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
+ checkModify();
}
/**
* @see javassist.ClassPool#forName(String)
*/
public Class toClass()
- throws NotFoundException, IOException, CannotCompileException
+ throws NotFoundException, IOException, CannotCompileException
{
- return getClassPool2().writeAsClass(getName());
+ return getClassPool2().writeAsClass(getName());
}
/**
* @see javassist.ClassPool#write(String)
*/
public byte[] toBytecode()
- throws NotFoundException, IOException, CannotCompileException
+ throws NotFoundException, IOException, CannotCompileException
{
- return getClassPool2().write(getName());
+ return getClassPool2().write(getName());
}
/**
* @see javassist.ClassPool#writeFile(String)
*/
public void writeFile()
- throws NotFoundException, IOException, CannotCompileException
+ throws NotFoundException, IOException, CannotCompileException
{
- getClassPool2().writeFile(getName());
+ getClassPool2().writeFile(getName());
}
private ClassPool getClassPool2() throws CannotCompileException {
- ClassPool cp = getClassPool();
- if (cp == null)
- throw new CannotCompileException(
- "no ClassPool found. not a class?");
- else
- return cp;
+ ClassPool cp = getClassPool();
+ if (cp == null)
+ throw new CannotCompileException(
+ "no ClassPool found. not a class?");
+ else
+ return cp;
}
/**
*
* <p>This method dose not close the output stream in the end.
*
- * @param out the output stream that a class file is written to.
+ * @param out the output stream that a class file is written to.
*/
void toBytecode(DataOutputStream out)
- throws CannotCompileException, IOException
+ throws CannotCompileException, IOException
{
- throw new CannotCompileException("not a class");
+ throw new CannotCompileException("not a class");
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
import javassist.expr.ExprEditor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
private CtMethod methodsCache;
private FieldInitLink fieldInitializers;
- private Hashtable hiddenMethods; // must be synchronous
+ private Hashtable hiddenMethods; // must be synchronous
private int uniqueNumberSeed;
CtClassType(String name, ClassPool cp) {
- super(name);
- classPool = cp;
- wasChanged = wasFrozen = false;
- classfile = null;
- fieldInitializers = null;
- hiddenMethods = null;
- uniqueNumberSeed = 0;
- eraseCache();
+ super(name);
+ classPool = cp;
+ wasChanged = wasFrozen = false;
+ classfile = null;
+ fieldInitializers = null;
+ hiddenMethods = null;
+ uniqueNumberSeed = 0;
+ eraseCache();
+ }
+
+ CtClassType(InputStream ins, ClassPool cp) throws IOException {
+ this((String)null, cp);
+ classfile = new ClassFile(new DataInputStream(ins));
+ qualifiedName = classfile.getName();
}
protected void eraseCache() {
- fieldsCache = null;
- constructorsCache = null;
- classInitializerCache = null;
- methodsCache = null;
+ fieldsCache = null;
+ constructorsCache = null;
+ classInitializerCache = null;
+ methodsCache = null;
}
public ClassFile getClassFile2() {
- if (classfile != null)
- return classfile;
-
- try {
- byte[] b = classPool.readSource(getName());
- DataInputStream dis
- = new DataInputStream(new ByteArrayInputStream(b));
- return (classfile = new ClassFile(dis));
- }
- catch (NotFoundException e) {
- throw new RuntimeException(e.toString());
- }
- catch (IOException e) {
- throw new RuntimeException(e.toString());
- }
- catch (CannotCompileException e) {
- throw new RuntimeException(e.toString());
- }
+ if (classfile != null)
+ return classfile;
+
+ try {
+ byte[] b = classPool.readSource(getName());
+ DataInputStream dis
+ = new DataInputStream(new ByteArrayInputStream(b));
+ return (classfile = new ClassFile(dis));
+ }
+ catch (NotFoundException e) {
+ throw new RuntimeException(e.toString());
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e.toString());
+ }
+ catch (CannotCompileException e) {
+ throw new RuntimeException(e.toString());
+ }
}
public ClassPool getClassPool() { return classPool; }
public boolean isFrozen() { return wasFrozen; }
+ void freeze() { wasFrozen = true; }
+
void checkModify() throws RuntimeException {
- super.checkModify();
- wasChanged = true;
+ super.checkModify();
+ wasChanged = true;
}
public void defrost() { wasFrozen = false; }
public boolean subtypeOf(CtClass clazz) throws NotFoundException {
- int i;
- String cname = clazz.getName();
- if (this == clazz || getName().equals(cname))
- return true;
+ int i;
+ String cname = clazz.getName();
+ if (this == clazz || getName().equals(cname))
+ return true;
- ClassFile file = getClassFile2();
- String supername = file.getSuperclass();
- if (supername != null && supername.equals(cname))
- return true;
+ ClassFile file = getClassFile2();
+ String supername = file.getSuperclass();
+ if (supername != null && supername.equals(cname))
+ return true;
- String[] ifs = file.getInterfaces();
- int num = ifs.length;
- for (i = 0; i < num; ++i)
- if (ifs[i].equals(cname))
- return true;
+ String[] ifs = file.getInterfaces();
+ int num = ifs.length;
+ for (i = 0; i < num; ++i)
+ if (ifs[i].equals(cname))
+ return true;
- if (supername != null && classPool.get(supername).subtypeOf(clazz))
- return true;
+ if (supername != null && classPool.get(supername).subtypeOf(clazz))
+ return true;
- for (i = 0; i < num; ++i)
- if (classPool.get(ifs[i]).subtypeOf(clazz))
- return true;
+ for (i = 0; i < num; ++i)
+ if (classPool.get(ifs[i]).subtypeOf(clazz))
+ return true;
- return false;
+ return false;
}
public void setName(String name) throws RuntimeException {
- String oldname = getName();
- if (name.equals(oldname))
- return;
+ String oldname = getName();
+ if (name.equals(oldname))
+ return;
- classPool.checkNotFrozen(name,
- "the class with the new name is frozen");
- ClassFile cf = getClassFile2();
- super.setName(name);
- cf.setName(name);
- eraseCache();
- classPool.classNameChanged(oldname, this);
+ classPool.checkNotFrozen(name,
+ "the class with the new name is frozen");
+ ClassFile cf = getClassFile2();
+ super.setName(name);
+ cf.setName(name);
+ eraseCache();
+ classPool.classNameChanged(oldname, this);
}
public void replaceClassName(ClassMap classnames)
- throws RuntimeException
+ throws RuntimeException
{
- String oldClassName = getName();
- String newClassName
- = (String)classnames.get(Descriptor.toJvmName(oldClassName));
- if (newClassName != null) {
- newClassName = Descriptor.toJavaName(newClassName);
- classPool.checkNotFrozen(newClassName,
- "the class " + newClassName + " is frozen");
- }
-
- super.replaceClassName(classnames);
- ClassFile cf = getClassFile2();
- cf.renameClass(classnames);
- eraseCache();
-
- if (newClassName != null) {
- super.setName(newClassName);
- classPool.classNameChanged(oldClassName, this);
- }
+ String oldClassName = getName();
+ String newClassName
+ = (String)classnames.get(Descriptor.toJvmName(oldClassName));
+ if (newClassName != null) {
+ newClassName = Descriptor.toJavaName(newClassName);
+ classPool.checkNotFrozen(newClassName,
+ "the class " + newClassName + " is frozen");
+ }
+
+ super.replaceClassName(classnames);
+ ClassFile cf = getClassFile2();
+ cf.renameClass(classnames);
+ eraseCache();
+
+ if (newClassName != null) {
+ super.setName(newClassName);
+ classPool.classNameChanged(oldClassName, this);
+ }
}
public void replaceClassName(String oldname, String newname)
- throws RuntimeException
+ throws RuntimeException
{
- String thisname = getName();
- if (thisname.equals(oldname))
- setName(newname);
- else {
- super.replaceClassName(oldname, newname);
- getClassFile2().renameClass(oldname, newname);
- eraseCache();
- }
+ String thisname = getName();
+ if (thisname.equals(oldname))
+ setName(newname);
+ else {
+ super.replaceClassName(oldname, newname);
+ getClassFile2().renameClass(oldname, newname);
+ eraseCache();
+ }
}
public boolean isInterface() {
- return Modifier.isInterface(getModifiers());
+ return Modifier.isInterface(getModifiers());
}
public int getModifiers() {
- int acc = getClassFile2().getAccessFlags();
- acc = AccessFlag.clear(acc, AccessFlag.SUPER);
- return AccessFlag.toModifier(acc);
+ int acc = getClassFile2().getAccessFlags();
+ acc = AccessFlag.clear(acc, AccessFlag.SUPER);
+ return AccessFlag.toModifier(acc);
}
public void setModifiers(int mod) {
- checkModify();
- int acc = AccessFlag.of(mod) | AccessFlag.SUPER;
- getClassFile2().setAccessFlags(acc);
+ checkModify();
+ int acc = AccessFlag.of(mod) | AccessFlag.SUPER;
+ getClassFile2().setAccessFlags(acc);
}
public boolean subclassOf(CtClass superclass) {
- CtClass curr = this;
- try {
- while (curr != null) {
- if (curr == superclass)
- return true;
+ if (superclass == null)
+ return false;
+
+ String superName = superclass.getName();
+ CtClass curr = this;
+ try {
+ while (curr != null) {
+ if (curr.getName().equals(superName))
+ return true;
- curr = curr.getSuperclass();
- }
- }
- catch (Exception ignored) {}
- return false;
+ curr = curr.getSuperclass();
+ }
+ }
+ catch (Exception ignored) {}
+ return false;
}
public CtClass getSuperclass() throws NotFoundException {
- String supername = getClassFile2().getSuperclass();
- if (supername == null)
- return null;
- else
- return classPool.get(supername);
+ String supername = getClassFile2().getSuperclass();
+ if (supername == null)
+ return null;
+ else
+ return classPool.get(supername);
}
public void setSuperclass(CtClass clazz) throws CannotCompileException {
- checkModify();
- getClassFile2().setSuperclass(clazz.getName());
+ checkModify();
+ getClassFile2().setSuperclass(clazz.getName());
}
public CtClass[] getInterfaces() throws NotFoundException {
- String[] ifs = getClassFile2().getInterfaces();
- int num = ifs.length;
- CtClass[] ifc = new CtClass[num];
- for (int i = 0; i < num; ++i)
- ifc[i] = classPool.get(ifs[i]);
+ String[] ifs = getClassFile2().getInterfaces();
+ int num = ifs.length;
+ CtClass[] ifc = new CtClass[num];
+ for (int i = 0; i < num; ++i)
+ ifc[i] = classPool.get(ifs[i]);
- return ifc;
+ return ifc;
}
public void setInterfaces(CtClass[] list) {
- checkModify();
- String[] ifs;
- if (list == null)
- ifs = new String[0];
- else {
- int num = list.length;
- ifs = new String[num];
- for (int i = 0; i < num; ++i)
- ifs[i] = list[i].getName();
- }
+ checkModify();
+ String[] ifs;
+ if (list == null)
+ ifs = new String[0];
+ else {
+ int num = list.length;
+ ifs = new String[num];
+ for (int i = 0; i < num; ++i)
+ ifs[i] = list[i].getName();
+ }
- getClassFile2().setInterfaces(ifs);
+ getClassFile2().setInterfaces(ifs);
}
public void addInterface(CtClass anInterface) {
- checkModify();
- if (anInterface != null)
- getClassFile2().addInterface(anInterface.getName());
+ checkModify();
+ if (anInterface != null)
+ getClassFile2().addInterface(anInterface.getName());
}
public CtField[] getFields() {
- ArrayList alist = new ArrayList();
- getFields(alist, this);
- return (CtField[])alist.toArray(new CtField[alist.size()]);
+ ArrayList alist = new ArrayList();
+ getFields(alist, this);
+ return (CtField[])alist.toArray(new CtField[alist.size()]);
}
private static void getFields(ArrayList alist, CtClass cc) {
- int i, num;
- if (cc == null)
- return;
+ int i, num;
+ if (cc == null)
+ return;
- try {
- getFields(alist, cc.getSuperclass());
- }
- catch (NotFoundException e) {}
+ try {
+ getFields(alist, cc.getSuperclass());
+ }
+ catch (NotFoundException e) {}
- try {
- CtClass[] ifs = cc.getInterfaces();
- num = ifs.length;
- for (i = 0; i < num; ++i)
- getFields(alist, ifs[i]);
- }
- catch (NotFoundException e) {}
+ try {
+ CtClass[] ifs = cc.getInterfaces();
+ num = ifs.length;
+ for (i = 0; i < num; ++i)
+ getFields(alist, ifs[i]);
+ }
+ catch (NotFoundException e) {}
- CtField cf = ((CtClassType)cc).getFieldsCache();
- while (cf != null) {
- if (Modifier.isPublic(cf.getModifiers()))
- alist.add(cf);
+ CtField cf = ((CtClassType)cc).getFieldsCache();
+ while (cf != null) {
+ if (Modifier.isPublic(cf.getModifiers()))
+ alist.add(cf);
- cf = cf.next;
- }
+ cf = cf.next;
+ }
}
public CtField getField(String name) throws NotFoundException {
- try {
- return getDeclaredField(name);
- }
- catch (NotFoundException e) {}
-
- try {
- CtClass[] ifs = getInterfaces();
- int num = ifs.length;
- for (int i = 0; i < num; ++i)
- try {
- return ifs[i].getField(name);
- }
- catch (NotFoundException e) {}
- }
- catch (NotFoundException e) {}
-
- try {
- CtClass s = getSuperclass();
- if (s != null)
- return s.getField(name);
- }
- catch (NotFoundException e) {}
-
- throw new NotFoundException(name);
+ try {
+ return getDeclaredField(name);
+ }
+ catch (NotFoundException e) {}
+
+ try {
+ CtClass[] ifs = getInterfaces();
+ int num = ifs.length;
+ for (int i = 0; i < num; ++i)
+ try {
+ return ifs[i].getField(name);
+ }
+ catch (NotFoundException e) {}
+ }
+ catch (NotFoundException e) {}
+
+ try {
+ CtClass s = getSuperclass();
+ if (s != null)
+ return s.getField(name);
+ }
+ catch (NotFoundException e) {}
+
+ throw new NotFoundException(name);
}
public CtField[] getDeclaredFields() {
- CtField cf = getFieldsCache();
- int num = CtField.count(cf);
- CtField[] cfs = new CtField[num];
- int i = 0;
- while (cf != null) {
- cfs[i++] = cf;
- cf = cf.next;
- }
+ CtField cf = getFieldsCache();
+ int num = CtField.count(cf);
+ CtField[] cfs = new CtField[num];
+ int i = 0;
+ while (cf != null) {
+ cfs[i++] = cf;
+ cf = cf.next;
+ }
- return cfs;
+ return cfs;
}
protected CtField getFieldsCache() {
- if (fieldsCache == null) {
- List list = getClassFile2().getFields();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- FieldInfo finfo = (FieldInfo)list.get(i);
- fieldsCache = CtField.append(fieldsCache,
- new CtField(finfo, this));
- }
- }
+ if (fieldsCache == null) {
+ List list = getClassFile2().getFields();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ FieldInfo finfo = (FieldInfo)list.get(i);
+ fieldsCache = CtField.append(fieldsCache,
+ new CtField(finfo, this));
+ }
+ }
- return fieldsCache;
+ return fieldsCache;
}
public CtField getDeclaredField(String name) throws NotFoundException {
- CtField cf = getFieldsCache();
- while (cf != null) {
- if (cf.getName().equals(name))
- return cf;
+ CtField cf = getFieldsCache();
+ while (cf != null) {
+ if (cf.getName().equals(name))
+ return cf;
- cf = cf.next;
- }
+ cf = cf.next;
+ }
- throw new NotFoundException(name);
+ throw new NotFoundException(name);
}
public CtBehavior[] getDeclaredBehaviors() {
- CtConstructor cc = getConstructorsCache();
- CtMethod cm = getMethodsCache();
- int num = CtMethod.count(cm) + CtConstructor.count(cc);
- CtBehavior[] cb = new CtBehavior[num];
- int i = 0;
- while (cc != null) {
- cb[i++] = cc;
- cc = cc.next;
- }
-
- while (cm != null) {
- cb[i++] = cm;
- cm = cm.next;
- }
-
- return cb;
+ CtConstructor cc = getConstructorsCache();
+ CtMethod cm = getMethodsCache();
+ int num = CtMethod.count(cm) + CtConstructor.count(cc);
+ CtBehavior[] cb = new CtBehavior[num];
+ int i = 0;
+ while (cc != null) {
+ cb[i++] = cc;
+ cc = cc.next;
+ }
+
+ while (cm != null) {
+ cb[i++] = cm;
+ cm = cm.next;
+ }
+
+ return cb;
}
public CtConstructor[] getConstructors() {
- CtConstructor[] cons = getDeclaredConstructors();
- if (cons.length == 0)
- return cons;
+ CtConstructor[] cons = getDeclaredConstructors();
+ if (cons.length == 0)
+ return cons;
- int n = 0;
- int i = cons.length;
- while (--i >= 0)
- if (Modifier.isPublic(cons[i].getModifiers()))
- ++n;
+ int n = 0;
+ int i = cons.length;
+ while (--i >= 0)
+ if (Modifier.isPublic(cons[i].getModifiers()))
+ ++n;
- CtConstructor[] result = new CtConstructor[n];
- n = 0;
- i = cons.length;
- while (--i >= 0) {
- CtConstructor c = cons[i];
- if (Modifier.isPublic(c.getModifiers()))
- result[n++] = c;
- }
+ CtConstructor[] result = new CtConstructor[n];
+ n = 0;
+ i = cons.length;
+ while (--i >= 0) {
+ CtConstructor c = cons[i];
+ if (Modifier.isPublic(c.getModifiers()))
+ result[n++] = c;
+ }
- return result;
+ return result;
}
public CtConstructor getConstructor(String desc)
- throws NotFoundException
+ throws NotFoundException
{
- CtConstructor cc = getConstructorsCache();
- while (cc != null) {
- if (cc.getMethodInfo2().getDescriptor().equals(desc))
- return cc;
+ CtConstructor cc = getConstructorsCache();
+ while (cc != null) {
+ if (cc.getMethodInfo2().getDescriptor().equals(desc))
+ return cc;
- cc = cc.next;
- }
+ cc = cc.next;
+ }
- return super.getConstructor(desc);
+ return super.getConstructor(desc);
}
public CtConstructor[] getDeclaredConstructors() {
- CtConstructor cc = getConstructorsCache();
- int num = CtConstructor.count(cc);
- CtConstructor[] ccs = new CtConstructor[num];
- int i = 0;
- while (cc != null) {
- ccs[i++] = cc;
- cc = cc.next;
- }
-
- return ccs;
+ CtConstructor cc = getConstructorsCache();
+ int num = CtConstructor.count(cc);
+ CtConstructor[] ccs = new CtConstructor[num];
+ int i = 0;
+ while (cc != null) {
+ ccs[i++] = cc;
+ cc = cc.next;
+ }
+
+ return ccs;
}
protected CtConstructor getConstructorsCache() {
- if (constructorsCache == null) {
- List list = getClassFile2().getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- if (minfo.isConstructor())
- constructorsCache
- = CtConstructor.append(constructorsCache,
- new CtConstructor(minfo, this));
- }
- }
+ if (constructorsCache == null) {
+ List list = getClassFile2().getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ if (minfo.isConstructor())
+ constructorsCache
+ = CtConstructor.append(constructorsCache,
+ new CtConstructor(minfo, this));
+ }
+ }
- return constructorsCache;
+ return constructorsCache;
}
public CtConstructor getClassInitializer() {
- if (classInitializerCache == null) {
- List list = getClassFile2().getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- if (minfo.isStaticInitializer()) {
- classInitializerCache = new CtConstructor(minfo, this);
- break;
- }
- }
- }
+ if (classInitializerCache == null) {
+ List list = getClassFile2().getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ if (minfo.isStaticInitializer()) {
+ classInitializerCache = new CtConstructor(minfo, this);
+ break;
+ }
+ }
+ }
- return classInitializerCache;
+ return classInitializerCache;
}
public CtMethod[] getMethods() {
- HashMap h = new HashMap();
- getMethods0(h, this);
- return (CtMethod[])h.values().toArray(new CtMethod[0]);
+ HashMap h = new HashMap();
+ getMethods0(h, this);
+ return (CtMethod[])h.values().toArray(new CtMethod[0]);
}
private static void getMethods0(HashMap h, CtClass cc) {
- try {
- CtClass[] ifs = cc.getInterfaces();
- int size = ifs.length;
- for (int i = 0; i < size; ++i)
- getMethods0(h, ifs[i]);
- }
- catch (NotFoundException e) {}
-
- try {
- CtClass s = cc.getSuperclass();
- if (s != null)
- getMethods0(h, s);
- }
- catch (NotFoundException e) {}
-
- if (cc instanceof CtClassType) {
- CtMethod cm = ((CtClassType)cc).getMethodsCache();
- while (cm != null) {
- if (Modifier.isPublic(cm.getModifiers()))
- h.put(cm, cm);
-
- cm = cm.next;
- }
- }
+ try {
+ CtClass[] ifs = cc.getInterfaces();
+ int size = ifs.length;
+ for (int i = 0; i < size; ++i)
+ getMethods0(h, ifs[i]);
+ }
+ catch (NotFoundException e) {}
+
+ try {
+ CtClass s = cc.getSuperclass();
+ if (s != null)
+ getMethods0(h, s);
+ }
+ catch (NotFoundException e) {}
+
+ if (cc instanceof CtClassType) {
+ CtMethod cm = ((CtClassType)cc).getMethodsCache();
+ while (cm != null) {
+ if (Modifier.isPublic(cm.getModifiers()))
+ h.put(cm, cm);
+
+ cm = cm.next;
+ }
+ }
}
public CtMethod getMethod(String name, String desc)
- throws NotFoundException
+ throws NotFoundException
{
- CtMethod m = getMethod0(this, name, desc);
- if (m != null)
- return m;
- else
- throw new NotFoundException(name + "(..) is not found in "
- + getName());
+ CtMethod m = getMethod0(this, name, desc);
+ if (m != null)
+ return m;
+ else
+ throw new NotFoundException(name + "(..) is not found in "
+ + getName());
}
private static CtMethod getMethod0(CtClass cc,
- String name, String desc) {
- if (cc instanceof CtClassType) {
- CtMethod cm = ((CtClassType)cc).getMethodsCache();
- while (cm != null) {
- if (cm.getName().equals(name)
- && cm.getMethodInfo2().getDescriptor().equals(desc))
- return cm;
-
- cm = cm.next;
- }
- }
-
- try {
- CtClass s = cc.getSuperclass();
- if (s != null) {
- CtMethod m = getMethod0(s, name, desc);
- if (m != null)
- return m;
- }
- }
- catch (NotFoundException e) {}
-
- try {
- CtClass[] ifs = cc.getInterfaces();
- int size = ifs.length;
- for (int i = 0; i < size; ++i) {
- CtMethod m = getMethod0(ifs[i], name, desc);
- if (m != null)
- return m;
- }
- }
- catch (NotFoundException e) {}
- return null;
+ String name, String desc) {
+ if (cc instanceof CtClassType) {
+ CtMethod cm = ((CtClassType)cc).getMethodsCache();
+ while (cm != null) {
+ if (cm.getName().equals(name)
+ && cm.getMethodInfo2().getDescriptor().equals(desc))
+ return cm;
+
+ cm = cm.next;
+ }
+ }
+
+ try {
+ CtClass s = cc.getSuperclass();
+ if (s != null) {
+ CtMethod m = getMethod0(s, name, desc);
+ if (m != null)
+ return m;
+ }
+ }
+ catch (NotFoundException e) {}
+
+ try {
+ CtClass[] ifs = cc.getInterfaces();
+ int size = ifs.length;
+ for (int i = 0; i < size; ++i) {
+ CtMethod m = getMethod0(ifs[i], name, desc);
+ if (m != null)
+ return m;
+ }
+ }
+ catch (NotFoundException e) {}
+ return null;
}
public CtMethod[] getDeclaredMethods() {
- CtMethod cm = getMethodsCache();
- int num = CtMethod.count(cm);
- CtMethod[] cms = new CtMethod[num];
- int i = 0;
- while (cm != null) {
- cms[i++] = cm;
- cm = cm.next;
- }
-
- return cms;
+ CtMethod cm = getMethodsCache();
+ int num = CtMethod.count(cm);
+ CtMethod[] cms = new CtMethod[num];
+ int i = 0;
+ while (cm != null) {
+ cms[i++] = cm;
+ cm = cm.next;
+ }
+
+ return cms;
}
public CtMethod getDeclaredMethod(String name) throws NotFoundException {
- CtMethod m = getMethodsCache();
- while (m != null) {
- if (m.getName().equals(name))
- return m;
+ CtMethod m = getMethodsCache();
+ while (m != null) {
+ if (m.getName().equals(name))
+ return m;
- m = m.next;
- }
+ m = m.next;
+ }
- throw new NotFoundException(name + "(..) is not found in "
- + getName());
+ throw new NotFoundException(name + "(..) is not found in "
+ + getName());
}
public CtMethod getDeclaredMethod(String name, CtClass[] params)
- throws NotFoundException
+ throws NotFoundException
{
- String desc = Descriptor.ofParameters(params);
- CtMethod m = getMethodsCache();
- while (m != null) {
- if (m.getName().equals(name)
- && m.getMethodInfo2().getDescriptor().startsWith(desc))
- return m;
+ String desc = Descriptor.ofParameters(params);
+ CtMethod m = getMethodsCache();
+ while (m != null) {
+ if (m.getName().equals(name)
+ && m.getMethodInfo2().getDescriptor().startsWith(desc))
+ return m;
- m = m.next;
- }
+ m = m.next;
+ }
- throw new NotFoundException(name + "(..) is not found in "
- + getName());
+ throw new NotFoundException(name + "(..) is not found in "
+ + getName());
}
protected CtMethod getMethodsCache() {
- if (methodsCache == null) {
- List list = getClassFile2().getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- if (minfo.isMethod())
- methodsCache = CtMethod.append(methodsCache,
- new CtMethod(minfo, this));
- }
- }
+ if (methodsCache == null) {
+ List list = getClassFile2().getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ if (minfo.isMethod())
+ methodsCache = CtMethod.append(methodsCache,
+ new CtMethod(minfo, this));
+ }
+ }
- return methodsCache;
+ return methodsCache;
}
public void addField(CtField f, String init)
- throws CannotCompileException
+ throws CannotCompileException
{
- addField(f, CtField.Initializer.byExpr(init));
+ addField(f, CtField.Initializer.byExpr(init));
}
public void addField(CtField f, CtField.Initializer init)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
- if (f.getDeclaringClass() != this)
- throw new CannotCompileException("cannot add");
+ checkModify();
+ if (f.getDeclaringClass() != this)
+ throw new CannotCompileException("cannot add");
- if (init == null)
- init = f.getInit();
+ if (init == null)
+ init = f.getInit();
- getFieldsCache();
- fieldsCache = CtField.append(fieldsCache, f);
- getClassFile2().addField(f.getFieldInfo2());
+ getFieldsCache();
+ fieldsCache = CtField.append(fieldsCache, f);
+ getClassFile2().addField(f.getFieldInfo2());
- if (init != null) {
- FieldInitLink fil = new FieldInitLink(f, init);
- FieldInitLink link = fieldInitializers;
- if (link == null)
- fieldInitializers = fil;
- else {
- while (link.next != null)
- link = link.next;
+ if (init != null) {
+ FieldInitLink fil = new FieldInitLink(f, init);
+ FieldInitLink link = fieldInitializers;
+ if (link == null)
+ fieldInitializers = fil;
+ else {
+ while (link.next != null)
+ link = link.next;
- link.next = fil;
- }
- }
+ link.next = fil;
+ }
+ }
}
public void addConstructor(CtConstructor c)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
- if (c.getDeclaringClass() != this)
- throw new CannotCompileException("cannot add");
+ checkModify();
+ if (c.getDeclaringClass() != this)
+ throw new CannotCompileException("cannot add");
- getConstructorsCache();
- constructorsCache = CtConstructor.append(constructorsCache, c);
- getClassFile2().addMethod(c.getMethodInfo2());
+ getConstructorsCache();
+ constructorsCache = CtConstructor.append(constructorsCache, c);
+ getClassFile2().addMethod(c.getMethodInfo2());
}
public void addMethod(CtMethod m) throws CannotCompileException {
- checkModify();
- if (m.getDeclaringClass() != this)
- throw new CannotCompileException("cannot add");
+ checkModify();
+ if (m.getDeclaringClass() != this)
+ throw new CannotCompileException("cannot add");
- getMethodsCache();
- methodsCache = CtMethod.append(methodsCache, m);
- getClassFile2().addMethod(m.getMethodInfo2());
- if ((m.getModifiers() & Modifier.ABSTRACT) != 0)
- setModifiers(getModifiers() | Modifier.ABSTRACT);
+ getMethodsCache();
+ methodsCache = CtMethod.append(methodsCache, m);
+ getClassFile2().addMethod(m.getMethodInfo2());
+ if ((m.getModifiers() & Modifier.ABSTRACT) != 0)
+ setModifiers(getModifiers() | Modifier.ABSTRACT);
}
public byte[] getAttribute(String name) {
- AttributeInfo ai = getClassFile2().getAttribute(name);
- if (ai == null)
- return null;
- else
- return ai.get();
+ AttributeInfo ai = getClassFile2().getAttribute(name);
+ if (ai == null)
+ return null;
+ else
+ return ai.get();
}
public void setAttribute(String name, byte[] data) {
- checkModify();
- ClassFile cf = getClassFile2();
- cf.addAttribute(new AttributeInfo(cf.getConstPool(), name, data));
+ checkModify();
+ ClassFile cf = getClassFile2();
+ cf.addAttribute(new AttributeInfo(cf.getConstPool(), name, data));
}
public void instrument(CodeConverter converter)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
- ClassFile cf = getClassFile2();
- ConstPool cp = cf.getConstPool();
- List list = cf.getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- converter.doit(this, minfo, cp);
- }
+ checkModify();
+ ClassFile cf = getClassFile2();
+ ConstPool cp = cf.getConstPool();
+ List list = cf.getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ converter.doit(this, minfo, cp);
+ }
}
public void instrument(ExprEditor editor)
- throws CannotCompileException
+ throws CannotCompileException
{
- checkModify();
- ClassFile cf = getClassFile2();
- List list = cf.getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- editor.doit(this, minfo);
- }
+ checkModify();
+ ClassFile cf = getClassFile2();
+ List list = cf.getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ editor.doit(this, minfo);
+ }
}
void toBytecode(DataOutputStream out)
- throws CannotCompileException, IOException
+ throws CannotCompileException, IOException
{
- ClassFile cf = getClassFile2();
- try {
- modifyClassConstructor(cf);
- modifyConstructors(cf);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
-
- wasFrozen = true;
- try {
- cf.write(out);
- out.flush();
- }
- catch (IOException e) {
- throw new CannotCompileException(e);
- }
+ ClassFile cf = getClassFile2();
+ try {
+ modifyClassConstructor(cf);
+ modifyConstructors(cf);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+
+ wasFrozen = true;
+ try {
+ cf.write(out);
+ out.flush();
+ }
+ catch (IOException e) {
+ throw new CannotCompileException(e);
+ }
}
protected void modifyClassConstructor(ClassFile cf)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- Bytecode code = new Bytecode(cf.getConstPool(), 0, 0);
- Javac jv = new Javac(code, this);
- int stacksize = 0;
- boolean none = true;
- for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) {
- CtField f = fi.field;
- if (Modifier.isStatic(f.getModifiers())) {
- none = false;
- int s = fi.init.compileIfStatic(f.getType(), f.getName(),
- code, jv);
- if (stacksize < s)
- stacksize = s;
- }
- }
-
- if (none)
- return; // no initializer for static fileds.
-
- MethodInfo m = cf.getStaticInitializer();
- if (m == null) {
- code.add(Bytecode.RETURN);
- code.setMaxStack(stacksize);
- m = new MethodInfo(cf.getConstPool(),
- "<clinit>", "()V");
- m.setAccessFlags(AccessFlag.STATIC);
- m.setCodeAttribute(code.toCodeAttribute());
- cf.addMethod(m);
- }
- else {
- CodeAttribute codeAttr = m.getCodeAttribute();
- if (codeAttr == null)
- throw new CannotCompileException("empty <clinit>");
-
- try {
- CodeIterator it = codeAttr.iterator();
- int pos = it.insertEx(code.get());
- it.insert(code.getExceptionTable(), pos);
- int maxstack = codeAttr.getMaxStack();
- if (maxstack < stacksize)
- codeAttr.setMaxStack(stacksize);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
- }
+ Bytecode code = new Bytecode(cf.getConstPool(), 0, 0);
+ Javac jv = new Javac(code, this);
+ int stacksize = 0;
+ boolean none = true;
+ for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) {
+ CtField f = fi.field;
+ if (Modifier.isStatic(f.getModifiers())) {
+ none = false;
+ int s = fi.init.compileIfStatic(f.getType(), f.getName(),
+ code, jv);
+ if (stacksize < s)
+ stacksize = s;
+ }
+ }
+
+ if (none)
+ return; // no initializer for static fileds.
+
+ MethodInfo m = cf.getStaticInitializer();
+ if (m == null) {
+ code.add(Bytecode.RETURN);
+ code.setMaxStack(stacksize);
+ m = new MethodInfo(cf.getConstPool(),
+ "<clinit>", "()V");
+ m.setAccessFlags(AccessFlag.STATIC);
+ m.setCodeAttribute(code.toCodeAttribute());
+ cf.addMethod(m);
+ }
+ else {
+ CodeAttribute codeAttr = m.getCodeAttribute();
+ if (codeAttr == null)
+ throw new CannotCompileException("empty <clinit>");
+
+ try {
+ CodeIterator it = codeAttr.iterator();
+ int pos = it.insertEx(code.get());
+ it.insert(code.getExceptionTable(), pos);
+ int maxstack = codeAttr.getMaxStack();
+ if (maxstack < stacksize)
+ codeAttr.setMaxStack(stacksize);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
+ }
}
protected void modifyConstructors(ClassFile cf)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- if (fieldInitializers == null)
- return;
-
- ConstPool cp = cf.getConstPool();
- List list = cf.getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- if (minfo.isConstructor()) {
- CodeAttribute codeAttr = minfo.getCodeAttribute();
- if (codeAttr != null)
- try {
- Bytecode init = new Bytecode(cp, 0,
- codeAttr.getMaxLocals());
- CtClass[] params
- = Descriptor.getParameterTypes(
- minfo.getDescriptor(),
- classPool);
- int stacksize = makeFieldInitializer(init, params);
- insertAuxInitializer(codeAttr, init, stacksize);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
- }
- }
+ if (fieldInitializers == null)
+ return;
+
+ ConstPool cp = cf.getConstPool();
+ List list = cf.getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ if (minfo.isConstructor()) {
+ CodeAttribute codeAttr = minfo.getCodeAttribute();
+ if (codeAttr != null)
+ try {
+ Bytecode init = new Bytecode(cp, 0,
+ codeAttr.getMaxLocals());
+ CtClass[] params
+ = Descriptor.getParameterTypes(
+ minfo.getDescriptor(),
+ classPool);
+ int stacksize = makeFieldInitializer(init, params);
+ insertAuxInitializer(codeAttr, init, stacksize);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
+ }
+ }
}
private static void insertAuxInitializer(CodeAttribute codeAttr,
- Bytecode initializer,
- int stacksize)
- throws BadBytecode
+ Bytecode initializer,
+ int stacksize)
+ throws BadBytecode
{
- CodeIterator it = codeAttr.iterator();
- int index = it.skipSuperConstructor();
- if (index < 0) {
- index = it.skipThisConstructor();
- if (index >= 0)
- return; // this() is called.
+ CodeIterator it = codeAttr.iterator();
+ int index = it.skipSuperConstructor();
+ if (index < 0) {
+ index = it.skipThisConstructor();
+ if (index >= 0)
+ return; // this() is called.
- // Neither this() or super() is called.
- }
+ // Neither this() or super() is called.
+ }
- int pos = it.insertEx(initializer.get());
- it.insert(initializer.getExceptionTable(), pos);
- int maxstack = codeAttr.getMaxStack();
- if (maxstack < stacksize)
- codeAttr.setMaxStack(stacksize);
+ int pos = it.insertEx(initializer.get());
+ it.insert(initializer.getExceptionTable(), pos);
+ int maxstack = codeAttr.getMaxStack();
+ if (maxstack < stacksize)
+ codeAttr.setMaxStack(stacksize);
}
private int makeFieldInitializer(Bytecode code, CtClass[] parameters)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- int stacksize = 0;
- Javac jv = new Javac(code, this);
- try {
- jv.recordParams(parameters, false);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
-
- for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) {
- CtField f = fi.field;
- if (!Modifier.isStatic(f.getModifiers())) {
- int s = fi.init.compile(f.getType(), f.getName(), code,
- parameters, jv);
- if (stacksize < s)
- stacksize = s;
- }
- }
-
- return stacksize;
+ int stacksize = 0;
+ Javac jv = new Javac(code, this);
+ try {
+ jv.recordParams(parameters, false);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+
+ for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) {
+ CtField f = fi.field;
+ if (!Modifier.isStatic(f.getModifiers())) {
+ int s = fi.init.compile(f.getType(), f.getName(), code,
+ parameters, jv);
+ if (stacksize < s)
+ stacksize = s;
+ }
+ }
+
+ return stacksize;
}
// Methods used by CtNewWrappedMethod
Hashtable getHiddenMethods() {
- if (hiddenMethods == null)
- hiddenMethods = new Hashtable();
+ if (hiddenMethods == null)
+ hiddenMethods = new Hashtable();
- return hiddenMethods;
+ return hiddenMethods;
}
int getUniqueNumber() { return uniqueNumberSeed++; }
CtField.Initializer init;
FieldInitLink(CtField f, CtField.Initializer i) {
- next = null;
- field = f;
- init = i;
+ next = null;
+ field = f;
+ init = i;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
protected CtConstructor next;
protected CtConstructor(MethodInfo minfo, CtClass declaring) {
- super(declaring, minfo);
- next = null;
+ super(declaring, minfo);
+ next = null;
}
/**
* <p>The created constructor does not include a constructor body,
* must be specified with <code>setBody()</code>.
*
- * @param declaring the class to which the created method is added.
- * @param parameters a list of the parameter types
+ * @param declaring the class to which the created method is added.
+ * @param parameters a list of the parameter types
*
* @see CtClass#addConstructor(CtConstructor)
* @see CtConstructor#setBody(String)
* @see CtConstructor#setBody(CtConstructor,ClassMap)
*/
public CtConstructor(CtClass[] parameters, CtClass declaring) {
- this((MethodInfo)null, declaring);
- ConstPool cp = declaring.getClassFile2().getConstPool();
- String desc = Descriptor.ofConstructor(parameters);
- methodInfo = new MethodInfo(cp, "<init>", desc);
- setModifiers(Modifier.PUBLIC);
+ this((MethodInfo)null, declaring);
+ ConstPool cp = declaring.getClassFile2().getConstPool();
+ String desc = Descriptor.ofConstructor(parameters);
+ methodInfo = new MethodInfo(cp, "<init>", desc);
+ setModifiers(Modifier.PUBLIC);
}
/**
* copying it. Otherwise, use <code>Class.forName()</code> in the
* expression.
*
- * @param src the source method.
+ * @param src the source method.
* @param declaring the class to which the created method is added.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*
* @see CtClass#addConstructor(CtConstructor)
* @see ClassMap#fix(String)
*/
public CtConstructor(CtConstructor src, CtClass declaring, ClassMap map)
- throws CannotCompileException
+ throws CannotCompileException
{
- this((MethodInfo)null, declaring);
- MethodInfo srcInfo = src.methodInfo;
- CtClass srcClass = src.getDeclaringClass();
- ConstPool cp = declaring.getClassFile2().getConstPool();
- if (map == null)
- map = new ClassMap();
-
- map.put(srcClass.getName(), declaring.getName());
- try {
- boolean patch = false;
- CtClass srcSuper = srcClass.getSuperclass();
- String destSuperName = declaring.getSuperclass().getName();
- if (srcSuper != null) {
- String srcSuperName = srcSuper.getName();
- if (!srcSuperName.equals(destSuperName))
- if (srcSuperName.equals(CtClass.javaLangObject))
- patch = true;
- else
- map.put(srcSuperName, destSuperName);
- }
-
- methodInfo = new MethodInfo(cp, srcInfo.getName(), srcInfo, map);
- if (patch)
- methodInfo.setSuperclass(destSuperName);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
+ this((MethodInfo)null, declaring);
+ MethodInfo srcInfo = src.methodInfo;
+ CtClass srcClass = src.getDeclaringClass();
+ ConstPool cp = declaring.getClassFile2().getConstPool();
+ if (map == null)
+ map = new ClassMap();
+
+ map.put(srcClass.getName(), declaring.getName());
+ try {
+ boolean patch = false;
+ CtClass srcSuper = srcClass.getSuperclass();
+ String destSuperName = declaring.getSuperclass().getName();
+ if (srcSuper != null) {
+ String srcSuperName = srcSuper.getName();
+ if (!srcSuperName.equals(destSuperName))
+ if (srcSuperName.equals(CtClass.javaLangObject))
+ patch = true;
+ else
+ map.put(srcSuperName, destSuperName);
+ }
+
+ methodInfo = new MethodInfo(cp, srcInfo.getName(), srcInfo, map);
+ if (patch)
+ methodInfo.setSuperclass(destSuperName);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
}
static CtConstructor append(CtConstructor list, CtConstructor tail) {
- tail.next = null;
- if (list == null)
- return tail;
- else {
- CtConstructor lst = list;
- while (lst.next != null)
- lst = lst.next;
-
- lst.next = tail;
- return list;
- }
+ tail.next = null;
+ if (list == null)
+ return tail;
+ else {
+ CtConstructor lst = list;
+ while (lst.next != null)
+ lst = lst.next;
+
+ lst.next = tail;
+ return list;
+ }
}
static int count(CtConstructor m) {
- int n = 0;
- while (m != null) {
- ++n;
- m = m.next;
- }
+ int n = 0;
+ while (m != null) {
+ ++n;
+ m = m.next;
+ }
- return n;
+ return n;
}
/**
* class file.
*/
public MethodInfo getMethodInfo() {
- return super.getMethodInfo();
+ return super.getMethodInfo();
}
/**
* Returns true if this object represents a constructor.
*/
public boolean isConstructor() {
- return methodInfo.isConstructor();
+ return methodInfo.isConstructor();
}
/**
* Returns true if this object represents a static initializer.
*/
public boolean isClassInitializer() {
- return methodInfo.isStaticInitializer();
+ return methodInfo.isStaticInitializer();
}
/**
* Obtains the encoded modifiers of the constructor.
*
- * @return modifiers encoded with
- * <code>javassist.Modifier</code>.
+ * @return modifiers encoded with
+ * <code>javassist.Modifier</code>.
* @see Modifier
*/
public int getModifiers() {
- return super.getModifiers();
+ return super.getModifiers();
}
/**
* @see Modifier
*/
public void setModifiers(int mod) {
- super.setModifiers(mod);
+ super.setModifiers(mod);
}
/**
* then this method returns <code>"<clinit>"</code>.
*/
public String getName() {
- if (methodInfo.isStaticInitializer())
- return MethodInfo.nameClinit;
- else
- return declaringClass.getName();
+ if (methodInfo.isStaticInitializer())
+ return MethodInfo.nameClinit;
+ else
+ return declaringClass.getName();
}
/**
* Returns the class that declares this constructor.
*/
public CtClass getDeclaringClass() {
- return super.getDeclaringClass();
+ return super.getDeclaringClass();
}
/**
* Obtains parameter types of this constructor.
*/
public CtClass[] getParameterTypes() throws NotFoundException {
- return super.getParameterTypes();
+ return super.getParameterTypes();
}
/**
* <code>getSignature()</code> returns the same string.
*/
public String getSignature() {
- return super.getSignature();
+ return super.getSignature();
}
/**
* Obtains exceptions that this constructor may throw.
*/
public CtClass[] getExceptionTypes() throws NotFoundException {
- return super.getExceptionTypes();
+ return super.getExceptionTypes();
}
/**
* Sets exceptions that this constructor may throw.
*/
public void setExceptionTypes(CtClass[] types)
- throws NotFoundException
+ throws NotFoundException
{
- super.setExceptionTypes(types);
+ super.setExceptionTypes(types);
+ }
+
+ /**
+ * Returns true if the constructor is the default one.
+ */
+ public boolean isEmpty() {
+ CodeAttribute ca = getMethodInfo2().getCodeAttribute();
+ if (ca == null)
+ return false; // native or abstract??
+ // they are not allowed, though.
+
+ ConstPool cp = ca.getConstPool();
+ CodeIterator it = ca.iterator();
+ try {
+ int pos, desc;
+ return it.byteAt(it.next()) == Opcode.ALOAD_0
+ && it.byteAt(pos = it.next()) == Opcode.INVOKESPECIAL
+ && (desc = cp.isConstructor(CtClass.javaLangObject,
+ it.u16bitAt(pos + 1))) != 0
+ && cp.getUtf8Info(desc).equals("()V")
+ && it.byteAt(it.next()) == Opcode.RETURN
+ && !it.hasNext();
+ }
+ catch (BadBytecode e) {}
+ return false;
}
/**
* Sets a constructor body.
*
- * @param src the source code representing the constructor body.
- * It must be a single statement or block.
+ * @param src the source code representing the constructor body.
+ * It must be a single statement or block.
*/
public void setBody(String src) throws CannotCompileException {
- super.setBody(src);
+ super.setBody(src);
}
/**
* are replaced with the names specified by
* <code>map</code> if <code>map</code> is not <code>null</code>.
*
- * @param src the method that the body is copied from.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param src the method that the body is copied from.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*/
public void setBody(CtConstructor src, ClassMap map)
- throws CannotCompileException
+ throws CannotCompileException
{
- setBody0(src.declaringClass, src.methodInfo,
- declaringClass, methodInfo, map);
+ setBody0(src.declaringClass, src.methodInfo,
+ declaringClass, methodInfo, map);
}
/**
* If that attribute is not found in the class file, this
* method returns null.
*
- * @param name attribute name
+ * @param name attribute name
*/
public byte[] getAttribute(String name) {
- return super.getAttribute(name);
+ return super.getAttribute(name);
}
/**
* Adds an attribute. The attribute is saved in the class file.
*
- * @param name attribute name
- * @param data attribute value
+ * @param name attribute name
+ * @param data attribute value
*/
public void setAttribute(String name, byte[] data) {
- super.setAttribute(name, data);
+ super.setAttribute(name, data);
}
/**
* For example, if the given name is <code>"Point.paint"</code>,
* then the variable is indicated by <code>$cflow(Point.paint)</code>.
*
- * @param name <code>$cflow</code> name. It can include
- * alphabets, numbers, <code>_</code>,
- * <code>$</code>, and <code>.</code> (dot).
+ * @param name <code>$cflow</code> name. It can include
+ * alphabets, numbers, <code>_</code>,
+ * <code>$</code>, and <code>.</code> (dot).
*
* @see javassist.runtime.Cflow
*/
public void useCflow(String name) throws CannotCompileException {
- super.useCflow(name);
+ super.useCflow(name);
}
/**
* Modifies the constructor body.
*
- * @param converter specifies how to modify.
+ * @param converter specifies how to modify.
*/
public void instrument(CodeConverter converter)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.instrument(converter);
+ super.instrument(converter);
}
/**
* Modifies the constructor body.
*
- * @param editor specifies how to modify.
+ * @param editor specifies how to modify.
*/
public void instrument(ExprEditor editor)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.instrument(editor);
+ super.instrument(editor);
}
/**
* For example, it cannot access instance members although it can access
* static members.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertBefore(String src) throws CannotCompileException {
- super.insertBefore(src);
+ super.insertBefore(src);
}
/**
* Inserts bytecode just after another constructor in the super class
* or this class is called.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertBeforeBody(String src) throws CannotCompileException {
- declaringClass.checkModify();
- CodeAttribute ca = methodInfo.getCodeAttribute();
- CodeIterator iterator = ca.iterator();
- Bytecode b = new Bytecode(methodInfo.getConstPool(),
- ca.getMaxStack(), ca.getMaxLocals());
- b.setStackDepth(ca.getMaxStack());
- Javac jv = new Javac(b, declaringClass);
- try {
- jv.recordParams(getParameterTypes(), false);
- jv.compileStmnt(src);
- ca.setMaxStack(b.getMaxStack());
- ca.setMaxLocals(b.getMaxLocals());
- iterator.skipConstructor();
- int pos = iterator.insertEx(b.get());
- iterator.insert(b.getExceptionTable(), pos);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
+ declaringClass.checkModify();
+ CodeAttribute ca = methodInfo.getCodeAttribute();
+ CodeIterator iterator = ca.iterator();
+ Bytecode b = new Bytecode(methodInfo.getConstPool(),
+ ca.getMaxStack(), ca.getMaxLocals());
+ b.setStackDepth(ca.getMaxStack());
+ Javac jv = new Javac(b, declaringClass);
+ try {
+ jv.recordParams(getParameterTypes(), false);
+ jv.compileStmnt(src);
+ ca.setMaxStack(b.getMaxStack());
+ ca.setMaxLocals(b.getMaxLocals());
+ iterator.skipConstructor();
+ int pos = iterator.insertEx(b.get());
+ iterator.insert(b.getExceptionTable(), pos);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* The bytecode is inserted just before every return insturction.
* It is not executed when an exception is thrown.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertAfter(String src)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.insertAfter(src);
+ super.insertAfter(src);
}
/**
* Inserts bytecode at the end of the constructor body.
* The bytecode is inserted just before every return insturction.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
- * @param asFinally true if the inserted bytecode is executed
- * not only when the transfer normally returns
- * but also when an exception is thrown.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
+ * @param asFinally true if the inserted bytecode is executed
+ * not only when the transfer normally returns
+ * but also when an exception is thrown.
*/
public void insertAfter(String src, boolean asFinally)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.insertAfter(src, asFinally);
+ super.insertAfter(src, asFinally);
}
/**
* constructor body.
* The catch clause must end with a return or throw statement.
*
- * @param src the source code representing the catch clause.
- * It must be a single statement or block.
- * @param exceptionType the type of the exception handled by the
- * catch clause.
- * @param exceptionName the name of the variable containing the
- * caught exception.
+ * @param src the source code representing the catch clause.
+ * It must be a single statement or block.
+ * @param exceptionType the type of the exception handled by the
+ * catch clause.
*/
- public void addCatch(String src, CtClass exceptionType,
- String exceptionName)
- throws CannotCompileException
+ public void addCatch(String src, CtClass exceptionType)
+ throws CannotCompileException
{
- super.addCatch(src, exceptionType, exceptionName);
+ super.addCatch(src, exceptionType);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
* call <code>CtNewMethod.getter()</code> and
* <code>CtNewMethod.setter()</code>.
*
- * @param type field type
- * @param name field name
- * @param declaring the class to which the field will be added.
+ * @param type field type
+ * @param name field name
+ * @param declaring the class to which the field will be added.
*
* @see CtClass#addField(CtField)
* @see CtNewMethod#getter(String,CtField)
* @see CtField.Initializer
*/
public CtField(CtClass type, String name, CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- this(Descriptor.of(type), name, declaring);
+ this(Descriptor.of(type), name, declaring);
}
/**
* call <code>CtNewMethod.getter()</code> and
* <code>CtNewMethod.setter()</code>.
*
- * @param src the original field
- * @param declaring the class to which the field will be added.
+ * @param src the original field
+ * @param declaring the class to which the field will be added.
* @see CtNewMethod#getter(String,CtField)
* @see CtNewMethod#setter(String,CtField)
* @see CtField.Initializer
*/
public CtField(CtField src, CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- this(src.fieldInfo.getDescriptor(), src.fieldInfo.getName(),
- declaring);
+ this(src.fieldInfo.getDescriptor(), src.fieldInfo.getName(),
+ declaring);
}
private CtField(String typeDesc, String name, CtClass clazz)
- throws CannotCompileException
+ throws CannotCompileException
{
- super(clazz);
- next = null;
- ClassFile cf = clazz.getClassFile2();
- if (cf == null)
- throw new CannotCompileException("bad declaring class: "
- + clazz.getName());
-
- fieldInfo = new FieldInfo(cf.getConstPool(), name, typeDesc);
+ super(clazz);
+ next = null;
+ ClassFile cf = clazz.getClassFile2();
+ if (cf == null)
+ throw new CannotCompileException("bad declaring class: "
+ + clazz.getName());
+
+ fieldInfo = new FieldInfo(cf.getConstPool(), name, typeDesc);
}
CtField(FieldInfo fi, CtClass clazz) {
- super(clazz);
- fieldInfo = fi;
- next = null;
+ super(clazz);
+ fieldInfo = fi;
+ next = null;
}
/* Javac.CtFieldWithInit overrides.
/* Called by CtClassType.addField().
*/
Initializer getInit() {
- ASTree tree = getInitAST();
- if (tree == null)
- return null;
- else
- return Initializer.byExpr(tree);
+ ASTree tree = getInitAST();
+ if (tree == null)
+ return null;
+ else
+ return Initializer.byExpr(tree);
}
/**
* <p>Note that the source code ends with <code>';'</code>
* (semicolon).
*
- * @param src the source text.
+ * @param src the source text.
* @param declaring the class to which the created field is added.
*/
public static CtField make(String src, CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- Javac compiler = new Javac(declaring);
- try {
- CtMember obj = compiler.compile(src);
- if (obj instanceof CtField)
- return (CtField)obj; // an instance of Javac.CtFieldWithInit
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
-
- throw new CannotCompileException("not a field");
+ Javac compiler = new Javac(declaring);
+ try {
+ CtMember obj = compiler.compile(src);
+ if (obj instanceof CtField)
+ return (CtField)obj; // an instance of Javac.CtFieldWithInit
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+
+ throw new CannotCompileException("not a field");
}
static CtField append(CtField list, CtField tail) {
- tail.next = null;
- if (list == null)
- return tail;
- else {
- CtField lst = list;
- while (lst.next != null)
- lst = lst.next;
-
- lst.next = tail;
- return list;
- }
+ tail.next = null;
+ if (list == null)
+ return tail;
+ else {
+ CtField lst = list;
+ while (lst.next != null)
+ lst = lst.next;
+
+ lst.next = tail;
+ return list;
+ }
}
static int count(CtField f) {
- int n = 0;
- while (f != null) {
- ++n;
- f = f.next;
- }
+ int n = 0;
+ while (f != null) {
+ ++n;
+ f = f.next;
+ }
- return n;
+ return n;
}
/**
* Returns the FieldInfo representing the field in the class file.
*/
public FieldInfo getFieldInfo() {
- declaringClass.checkModify();
- return fieldInfo;
+ declaringClass.checkModify();
+ return fieldInfo;
}
/**
* Returns the class declaring the field.
*/
public CtClass getDeclaringClass() {
- // this is redundant but for javadoc.
- return super.getDeclaringClass();
+ // this is redundant but for javadoc.
+ return super.getDeclaringClass();
}
/**
* Returns the name of the field.
*/
public String getName() {
- return fieldInfo.getName();
+ return fieldInfo.getName();
}
/**
* Changes the name of the field.
*/
public void setName(String newName) {
- fieldInfo.setName(newName);
+ fieldInfo.setName(newName);
}
/**
* @see Modifier
*/
public int getModifiers() {
- return AccessFlag.toModifier(fieldInfo.getAccessFlags());
+ return AccessFlag.toModifier(fieldInfo.getAccessFlags());
}
/**
* @see Modifier
*/
public void setModifiers(int mod) {
- fieldInfo.setAccessFlags(AccessFlag.of(mod));
+ fieldInfo.setAccessFlags(AccessFlag.of(mod));
}
/**
* Returns the type of the field.
*/
public CtClass getType() throws NotFoundException {
- return Descriptor.toCtClass(fieldInfo.getDescriptor(),
- declaringClass.getClassPool());
+ return Descriptor.toCtClass(fieldInfo.getDescriptor(),
+ declaringClass.getClassPool());
}
/**
* Sets the type of the field.
*/
public void setType(CtClass clazz) {
- declaringClass.checkModify();
- fieldInfo.setDescriptor(Descriptor.of(clazz));
+ declaringClass.checkModify();
+ fieldInfo.setDescriptor(Descriptor.of(clazz));
}
/**
* If that attribute is not found in the class file, this
* method returns null.
*
- * @param name attribute name
+ * @param name attribute name
*/
public byte[] getAttribute(String name) {
- AttributeInfo ai = fieldInfo.getAttribute(name);
- if (ai == null)
- return null;
- else
- return ai.get();
+ AttributeInfo ai = fieldInfo.getAttribute(name);
+ if (ai == null)
+ return null;
+ else
+ return ai.get();
}
/**
* Adds an attribute. The attribute is saved in the class file.
*
- * @param name attribute name
- * @param data attribute value
+ * @param name attribute name
+ * @param data attribute value
*/
public void setAttribute(String name, byte[] data) {
- declaringClass.checkModify();
- fieldInfo.addAttribute(new AttributeInfo(fieldInfo.getConstPool(),
- name, data));
+ declaringClass.checkModify();
+ fieldInfo.addAttribute(new AttributeInfo(fieldInfo.getConstPool(),
+ name, data));
}
// inner classes
* @see CtClass#addField(CtField,CtField.Initializer)
*/
public static abstract class Initializer {
- /**
- * Makes an initializer that assigns a constant integer value.
- * The field must be integer type.
- */
- public static Initializer constant(int i) {
- return new IntInitializer(i);
- }
-
- /**
- * Makes an initializer that assigns a constant long value.
- * The field must be long type.
- */
- public static Initializer constant(long l) {
- return new LongInitializer(l);
- }
-
- /**
- * Makes an initializer that assigns a constant double value.
- * The field must be double type.
- */
- public static Initializer constant(double d) {
- return new DoubleInitializer(d);
- }
-
- /**
- * Makes an initializer that assigns a constant string value.
- * The field must be <code>java.lang.String</code> type.
- */
- public static Initializer constant(String s) {
- return new StringInitializer(s);
- }
-
- /**
- * Makes an initializer using a constructor parameter.
- *
- * <p>The initial value is the
- * N-th parameter given to the constructor of the object including
- * the field. If the constructor takes less than N parameters,
- * the field is not initialized.
- * If the field is static, it is never initialized.
- *
- * @param nth the n-th (>= 0) parameter is used as
- * the initial value.
- * If nth is 0, then the first parameter is
- * used.
- */
- public static Initializer byParameter(int nth) {
- ParamInitializer i = new ParamInitializer();
- i.nthParam = nth;
- return i;
- }
-
- /**
- * Makes an initializer creating a new object.
- *
- * <p>This initializer creates a new object and uses it as the initial
- * value of the field. The constructor of the created object receives
- * the parameter:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * </ul>
- *
- * <p>If the initialized field is static, then the constructor does
- * not receive any parameters.
- *
- * @param objectType the class instantiated for the initial value.
- */
- public static Initializer byNew(CtClass objectType) {
- NewInitializer i = new NewInitializer();
- i.objectType = objectType;
- i.stringParams = null;
- i.withConstructorParams = false;
- return i;
- }
-
- /**
- * Makes an initializer creating a new object.
- *
- * <p>This initializer creates a new object and uses it as the initial
- * value of the field. The constructor of the created object receives
- * the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * <code>String[] strs</code> - the character strings specified
- * by <code>stringParams</code><br>
- * </ul>
- *
- * <p>If the initialized field is static, then the constructor
- * receives only <code>strs</code>.
- *
- * @param objectType the class instantiated for the initial value.
- * @param stringParams the array of strings passed to the
- * constructor.
- */
- public static Initializer byNew(CtClass objectType,
- String[] stringParams) {
- NewInitializer i = new NewInitializer();
- i.objectType = objectType;
- i.stringParams = stringParams;
- i.withConstructorParams = false;
- return i;
- }
-
- /**
- * Makes an initializer creating a new object.
- *
- * <p>This initializer creates a new object and uses it as the initial
- * value of the field. The constructor of the created object receives
- * the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * <code>Object[] args</code> - the parameters passed to the
- * constructor of the object including the
- * filed.
- * </ul>
- *
- * <p>If the initialized field is static, then the constructor does
- * not receive any parameters.
- *
- * @param objectType the class instantiated for the initial value.
- *
- * @see javassist.CtField.Initializer#byNewArray(CtClass,int)
- * @see javassist.CtField.Initializer#byNewArray(CtClass,int[])
- */
- public static Initializer byNewWithParams(CtClass objectType) {
- NewInitializer i = new NewInitializer();
- i.objectType = objectType;
- i.stringParams = null;
- i.withConstructorParams = true;
- return i;
- }
-
- /**
- * Makes an initializer creating a new object.
- *
- * <p>This initializer creates a new object and uses it as the initial
- * value of the field. The constructor of the created object receives
- * the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * <code>String[] strs</code> - the character strings specified
- * by <code>stringParams</code><br>
- * <code>Object[] args</code> - the parameters passed to the
- * constructor of the object including the
- * filed.
- * </ul>
- *
- * <p>If the initialized field is static, then the constructor receives
- * only <code>strs</code>.
- *
- * @param objectType the class instantiated for the initial value.
- * @param stringParams the array of strings passed to the
- * constructor.
- */
- public static Initializer byNewWithParams(CtClass objectType,
- String[] stringParams) {
- NewInitializer i = new NewInitializer();
- i.objectType = objectType;
- i.stringParams = stringParams;
- i.withConstructorParams = true;
- return i;
- }
-
- /**
- * Makes an initializer calling a static method.
- *
- * <p>This initializer calls a static method and uses the returned
- * value as the initial value of the field.
- * The called method receives the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * </ul>
- *
- * <p>If the initialized field is static, then the method does
- * not receive any parameters.
- *
- * <p>The type of the returned value must be the same as the field
- * type.
- *
- * @param methodClass the class that the static method is
- * declared in.
- * @param methodName the name of the satic method.
- */
- public static Initializer byCall(CtClass methodClass,
- String methodName) {
- MethodInitializer i = new MethodInitializer();
- i.objectType = methodClass;
- i.methodName = methodName;
- i.stringParams = null;
- i.withConstructorParams = false;
- return i;
- }
-
- /**
- * Makes an initializer calling a static method.
- *
- * <p>This initializer calls a static method and uses the returned
- * value as the initial value of the field. The called method
- * receives the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * <code>String[] strs</code> - the character strings specified
- * by <code>stringParams</code><br>
- * </ul>
- *
- * <p>If the initialized field is static, then the method
- * receive only <code>strs</code>.
- *
- * <p>The type of the returned value must be the same as the field
- * type.
- *
- * @param methodClass the class that the static method is
- * declared in.
- * @param methodName the name of the satic method.
- * @param stringParams the array of strings passed to the
- * static method.
- */
- public static Initializer byCall(CtClass methodClass,
- String methodName,
- String[] stringParams) {
- MethodInitializer i = new MethodInitializer();
- i.objectType = methodClass;
- i.methodName = methodName;
- i.stringParams = stringParams;
- i.withConstructorParams = false;
- return i;
- }
-
- /**
- * Makes an initializer calling a static method.
- *
- * <p>This initializer calls a static method and uses the returned
- * value as the initial value of the field. The called method
- * receives the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * <code>Object[] args</code> - the parameters passed to the
- * constructor of the object including the
- * filed.
- * </ul>
- *
- * <p>If the initialized field is static, then the method does
- * not receive any parameters.
- *
- * <p>The type of the returned value must be the same as the field
- * type.
- *
- * @param methodClass the class that the static method is
- * declared in.
- * @param methodName the name of the satic method.
- */
- public static Initializer byCallWithParams(CtClass methodClass,
- String methodName) {
- MethodInitializer i = new MethodInitializer();
- i.objectType = methodClass;
- i.methodName = methodName;
- i.stringParams = null;
- i.withConstructorParams = true;
- return i;
- }
-
- /**
- * Makes an initializer calling a static method.
- *
- * <p>This initializer calls a static method and uses the returned
- * value as the initial value of the field. The called method
- * receives the parameters:
- *
- * <ul><code>Object obj</code> - the object including the field.<br>
- * <code>String[] strs</code> - the character strings specified
- * by <code>stringParams</code><br>
- * <code>Object[] args</code> - the parameters passed to the
- * constructor of the object including the
- * filed.
- * </ul>
- *
- * <p>If the initialized field is static, then the method
- * receive only <code>strs</code>.
- *
- * <p>The type of the returned value must be the same as the field
- * type.
- *
- * @param methodClass the class that the static method is
- * declared in.
- * @param methodName the name of the satic method.
- * @param stringParams the array of strings passed to the
- * static method.
- */
- public static Initializer byCallWithParams(CtClass methodClass,
- String methodName, String[] stringParams) {
- MethodInitializer i = new MethodInitializer();
- i.objectType = methodClass;
- i.methodName = methodName;
- i.stringParams = stringParams;
- i.withConstructorParams = true;
- return i;
- }
-
- /**
- * Makes an initializer creating a new array.
- *
- * @param type the type of the array.
- * @param size the size of the array.
- * @throws NotFoundException if the type of the array components
- * is not found.
- */
- public static Initializer byNewArray(CtClass type, int size)
- throws NotFoundException
- {
- return new ArrayInitializer(type.getComponentType(), size);
- }
-
- /**
- * Makes an initializer creating a new multi-dimensional array.
- *
- * @param type the type of the array.
- * @param sizes an <code>int</code> array of the size in every
- * dimension.
- * The first element is the size in the first
- * dimension. The second is in the second, etc.
- */
- public static Initializer byNewArray(CtClass type, int[] sizes) {
- return new MultiArrayInitializer(type, sizes);
- }
-
- /**
- * Makes an initializer.
- *
- * @param source initializer expression.
- */
- public static Initializer byExpr(String source) {
- return new CodeInitializer(source);
- }
-
- static Initializer byExpr(ASTree source) {
- return new PtreeInitializer(source);
- }
-
- // Check whether this initializer is valid for the field type.
- // If it is invaild, this method throws an exception.
- void check(CtClass type) throws CannotCompileException {}
-
- // produce codes for initialization
- abstract int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException;
-
- // produce codes for initialization
- abstract int compileIfStatic(CtClass type, String name,
- Bytecode code, Javac drv) throws CannotCompileException;
+ /**
+ * Makes an initializer that assigns a constant integer value.
+ * The field must be integer type.
+ */
+ public static Initializer constant(int i) {
+ return new IntInitializer(i);
+ }
+
+ /**
+ * Makes an initializer that assigns a constant long value.
+ * The field must be long type.
+ */
+ public static Initializer constant(long l) {
+ return new LongInitializer(l);
+ }
+
+ /**
+ * Makes an initializer that assigns a constant double value.
+ * The field must be double type.
+ */
+ public static Initializer constant(double d) {
+ return new DoubleInitializer(d);
+ }
+
+ /**
+ * Makes an initializer that assigns a constant string value.
+ * The field must be <code>java.lang.String</code> type.
+ */
+ public static Initializer constant(String s) {
+ return new StringInitializer(s);
+ }
+
+ /**
+ * Makes an initializer using a constructor parameter.
+ *
+ * <p>The initial value is the
+ * N-th parameter given to the constructor of the object including
+ * the field. If the constructor takes less than N parameters,
+ * the field is not initialized.
+ * If the field is static, it is never initialized.
+ *
+ * @param nth the n-th (>= 0) parameter is used as
+ * the initial value.
+ * If nth is 0, then the first parameter is
+ * used.
+ */
+ public static Initializer byParameter(int nth) {
+ ParamInitializer i = new ParamInitializer();
+ i.nthParam = nth;
+ return i;
+ }
+
+ /**
+ * Makes an initializer creating a new object.
+ *
+ * <p>This initializer creates a new object and uses it as the initial
+ * value of the field. The constructor of the created object receives
+ * the parameter:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the constructor does
+ * not receive any parameters.
+ *
+ * @param objectType the class instantiated for the initial value.
+ */
+ public static Initializer byNew(CtClass objectType) {
+ NewInitializer i = new NewInitializer();
+ i.objectType = objectType;
+ i.stringParams = null;
+ i.withConstructorParams = false;
+ return i;
+ }
+
+ /**
+ * Makes an initializer creating a new object.
+ *
+ * <p>This initializer creates a new object and uses it as the initial
+ * value of the field. The constructor of the created object receives
+ * the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * <code>String[] strs</code> - the character strings specified
+ * by <code>stringParams</code><br>
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the constructor
+ * receives only <code>strs</code>.
+ *
+ * @param objectType the class instantiated for the initial value.
+ * @param stringParams the array of strings passed to the
+ * constructor.
+ */
+ public static Initializer byNew(CtClass objectType,
+ String[] stringParams) {
+ NewInitializer i = new NewInitializer();
+ i.objectType = objectType;
+ i.stringParams = stringParams;
+ i.withConstructorParams = false;
+ return i;
+ }
+
+ /**
+ * Makes an initializer creating a new object.
+ *
+ * <p>This initializer creates a new object and uses it as the initial
+ * value of the field. The constructor of the created object receives
+ * the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * <code>Object[] args</code> - the parameters passed to the
+ * constructor of the object including the
+ * filed.
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the constructor does
+ * not receive any parameters.
+ *
+ * @param objectType the class instantiated for the initial value.
+ *
+ * @see javassist.CtField.Initializer#byNewArray(CtClass,int)
+ * @see javassist.CtField.Initializer#byNewArray(CtClass,int[])
+ */
+ public static Initializer byNewWithParams(CtClass objectType) {
+ NewInitializer i = new NewInitializer();
+ i.objectType = objectType;
+ i.stringParams = null;
+ i.withConstructorParams = true;
+ return i;
+ }
+
+ /**
+ * Makes an initializer creating a new object.
+ *
+ * <p>This initializer creates a new object and uses it as the initial
+ * value of the field. The constructor of the created object receives
+ * the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * <code>String[] strs</code> - the character strings specified
+ * by <code>stringParams</code><br>
+ * <code>Object[] args</code> - the parameters passed to the
+ * constructor of the object including the
+ * filed.
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the constructor receives
+ * only <code>strs</code>.
+ *
+ * @param objectType the class instantiated for the initial value.
+ * @param stringParams the array of strings passed to the
+ * constructor.
+ */
+ public static Initializer byNewWithParams(CtClass objectType,
+ String[] stringParams) {
+ NewInitializer i = new NewInitializer();
+ i.objectType = objectType;
+ i.stringParams = stringParams;
+ i.withConstructorParams = true;
+ return i;
+ }
+
+ /**
+ * Makes an initializer calling a static method.
+ *
+ * <p>This initializer calls a static method and uses the returned
+ * value as the initial value of the field.
+ * The called method receives the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the method does
+ * not receive any parameters.
+ *
+ * <p>The type of the returned value must be the same as the field
+ * type.
+ *
+ * @param methodClass the class that the static method is
+ * declared in.
+ * @param methodName the name of the satic method.
+ */
+ public static Initializer byCall(CtClass methodClass,
+ String methodName) {
+ MethodInitializer i = new MethodInitializer();
+ i.objectType = methodClass;
+ i.methodName = methodName;
+ i.stringParams = null;
+ i.withConstructorParams = false;
+ return i;
+ }
+
+ /**
+ * Makes an initializer calling a static method.
+ *
+ * <p>This initializer calls a static method and uses the returned
+ * value as the initial value of the field. The called method
+ * receives the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * <code>String[] strs</code> - the character strings specified
+ * by <code>stringParams</code><br>
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the method
+ * receive only <code>strs</code>.
+ *
+ * <p>The type of the returned value must be the same as the field
+ * type.
+ *
+ * @param methodClass the class that the static method is
+ * declared in.
+ * @param methodName the name of the satic method.
+ * @param stringParams the array of strings passed to the
+ * static method.
+ */
+ public static Initializer byCall(CtClass methodClass,
+ String methodName,
+ String[] stringParams) {
+ MethodInitializer i = new MethodInitializer();
+ i.objectType = methodClass;
+ i.methodName = methodName;
+ i.stringParams = stringParams;
+ i.withConstructorParams = false;
+ return i;
+ }
+
+ /**
+ * Makes an initializer calling a static method.
+ *
+ * <p>This initializer calls a static method and uses the returned
+ * value as the initial value of the field. The called method
+ * receives the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * <code>Object[] args</code> - the parameters passed to the
+ * constructor of the object including the
+ * filed.
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the method does
+ * not receive any parameters.
+ *
+ * <p>The type of the returned value must be the same as the field
+ * type.
+ *
+ * @param methodClass the class that the static method is
+ * declared in.
+ * @param methodName the name of the satic method.
+ */
+ public static Initializer byCallWithParams(CtClass methodClass,
+ String methodName) {
+ MethodInitializer i = new MethodInitializer();
+ i.objectType = methodClass;
+ i.methodName = methodName;
+ i.stringParams = null;
+ i.withConstructorParams = true;
+ return i;
+ }
+
+ /**
+ * Makes an initializer calling a static method.
+ *
+ * <p>This initializer calls a static method and uses the returned
+ * value as the initial value of the field. The called method
+ * receives the parameters:
+ *
+ * <ul><code>Object obj</code> - the object including the field.<br>
+ * <code>String[] strs</code> - the character strings specified
+ * by <code>stringParams</code><br>
+ * <code>Object[] args</code> - the parameters passed to the
+ * constructor of the object including the
+ * filed.
+ * </ul>
+ *
+ * <p>If the initialized field is static, then the method
+ * receive only <code>strs</code>.
+ *
+ * <p>The type of the returned value must be the same as the field
+ * type.
+ *
+ * @param methodClass the class that the static method is
+ * declared in.
+ * @param methodName the name of the satic method.
+ * @param stringParams the array of strings passed to the
+ * static method.
+ */
+ public static Initializer byCallWithParams(CtClass methodClass,
+ String methodName, String[] stringParams) {
+ MethodInitializer i = new MethodInitializer();
+ i.objectType = methodClass;
+ i.methodName = methodName;
+ i.stringParams = stringParams;
+ i.withConstructorParams = true;
+ return i;
+ }
+
+ /**
+ * Makes an initializer creating a new array.
+ *
+ * @param type the type of the array.
+ * @param size the size of the array.
+ * @throws NotFoundException if the type of the array components
+ * is not found.
+ */
+ public static Initializer byNewArray(CtClass type, int size)
+ throws NotFoundException
+ {
+ return new ArrayInitializer(type.getComponentType(), size);
+ }
+
+ /**
+ * Makes an initializer creating a new multi-dimensional array.
+ *
+ * @param type the type of the array.
+ * @param sizes an <code>int</code> array of the size in every
+ * dimension.
+ * The first element is the size in the first
+ * dimension. The second is in the second, etc.
+ */
+ public static Initializer byNewArray(CtClass type, int[] sizes) {
+ return new MultiArrayInitializer(type, sizes);
+ }
+
+ /**
+ * Makes an initializer.
+ *
+ * @param source initializer expression.
+ */
+ public static Initializer byExpr(String source) {
+ return new CodeInitializer(source);
+ }
+
+ static Initializer byExpr(ASTree source) {
+ return new PtreeInitializer(source);
+ }
+
+ // Check whether this initializer is valid for the field type.
+ // If it is invaild, this method throws an exception.
+ void check(CtClass type) throws CannotCompileException {}
+
+ // produce codes for initialization
+ abstract int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException;
+
+ // produce codes for initialization
+ abstract int compileIfStatic(CtClass type, String name,
+ Bytecode code, Javac drv) throws CannotCompileException;
}
static abstract class CodeInitializer0 extends Initializer {
- abstract void compileExpr(Javac drv) throws CompileError;
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- try {
- code.addAload(0);
- compileExpr(drv);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return code.getMaxStack();
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- try {
- compileExpr(drv);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return code.getMaxStack();
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
- }
+ abstract void compileExpr(Javac drv) throws CompileError;
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ try {
+ code.addAload(0);
+ compileExpr(drv);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return code.getMaxStack();
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ try {
+ compileExpr(drv);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return code.getMaxStack();
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
+ }
}
static class CodeInitializer extends CodeInitializer0 {
- private String expression;
+ private String expression;
- CodeInitializer(String expr) { expression = expr; }
+ CodeInitializer(String expr) { expression = expr; }
- void compileExpr(Javac drv) throws CompileError {
- drv.compileExpr(expression);
- }
+ void compileExpr(Javac drv) throws CompileError {
+ drv.compileExpr(expression);
+ }
}
static class PtreeInitializer extends CodeInitializer0 {
- private ASTree expression;
+ private ASTree expression;
- PtreeInitializer(ASTree expr) { expression = expr; }
+ PtreeInitializer(ASTree expr) { expression = expr; }
- void compileExpr(Javac drv) throws CompileError {
- drv.compileExpr(expression);
- }
+ void compileExpr(Javac drv) throws CompileError {
+ drv.compileExpr(expression);
+ }
}
/**
* of the class containing that field.
*/
static class ParamInitializer extends Initializer {
- int nthParam;
-
- ParamInitializer() {}
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- if (parameters != null && nthParam < parameters.length) {
- code.addAload(0);
- int nth = nthParamToLocal(nthParam, parameters, false);
- int s = code.addLoad(nth, type) + 1;
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return s; // stack size
- }
- else
- return 0; // do not initialize
- }
-
- /**
- * Computes the index of the local variable that the n-th parameter
- * is assigned to.
- *
- * @param nth n-th parameter
- * @param params list of parameter types
- * @param isStatic true if the method is static.
- */
- static int nthParamToLocal(int nth, CtClass[] params,
- boolean isStatic) {
- CtClass longType = CtClass.longType;
- CtClass doubleType = CtClass.doubleType;
- int k;
- if (isStatic)
- k = 0;
- else
- k = 1; // 0 is THIS.
-
- for (int i = 0; i < nth; ++i) {
- CtClass type = params[i];
- if (type == longType || type == doubleType)
- k += 2;
- else
- ++k;
- }
-
- return k;
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- return 0;
- }
+ int nthParam;
+
+ ParamInitializer() {}
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ if (parameters != null && nthParam < parameters.length) {
+ code.addAload(0);
+ int nth = nthParamToLocal(nthParam, parameters, false);
+ int s = code.addLoad(nth, type) + 1;
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return s; // stack size
+ }
+ else
+ return 0; // do not initialize
+ }
+
+ /**
+ * Computes the index of the local variable that the n-th parameter
+ * is assigned to.
+ *
+ * @param nth n-th parameter
+ * @param params list of parameter types
+ * @param isStatic true if the method is static.
+ */
+ static int nthParamToLocal(int nth, CtClass[] params,
+ boolean isStatic) {
+ CtClass longType = CtClass.longType;
+ CtClass doubleType = CtClass.doubleType;
+ int k;
+ if (isStatic)
+ k = 0;
+ else
+ k = 1; // 0 is THIS.
+
+ for (int i = 0; i < nth; ++i) {
+ CtClass type = params[i];
+ if (type == longType || type == doubleType)
+ k += 2;
+ else
+ ++k;
+ }
+
+ return k;
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ return 0;
+ }
}
/**
* A field initialized with an object created by the new operator.
*/
static class NewInitializer extends Initializer {
- CtClass objectType;
- String[] stringParams;
- boolean withConstructorParams;
-
- NewInitializer() {}
-
- /**
- * Produces codes in which a new object is created and assigned to
- * the field as the initial value.
- */
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- int stacksize;
-
- code.addAload(0);
- code.addNew(objectType);
- code.add(Bytecode.DUP);
- code.addAload(0);
-
- if (stringParams == null)
- stacksize = 4;
- else
- stacksize = compileStringParameter(code) + 4;
-
- if (withConstructorParams)
- stacksize += CtNewWrappedMethod.compileParameterList(code,
- parameters, 1);
-
- code.addInvokespecial(objectType, "<init>", getDescriptor());
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return stacksize;
- }
-
- private String getDescriptor() {
- final String desc3
- = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)V";
-
- if (stringParams == null)
- if (withConstructorParams)
- return "(Ljava/lang/Object;[Ljava/lang/Object;)V";
- else
- return "(Ljava/lang/Object;)V";
- else
- if (withConstructorParams)
- return desc3;
- else
- return "(Ljava/lang/Object;[Ljava/lang/String;)V";
- }
-
- /**
- * Produces codes for a static field.
- */
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- String desc;
-
- code.addNew(objectType);
- code.add(Bytecode.DUP);
-
- int stacksize = 2;
- if (stringParams == null)
- desc = "()V";
- else {
- desc = "([Ljava/lang/String;)V";
- stacksize += compileStringParameter(code);
- }
-
- code.addInvokespecial(objectType, "<init>", desc);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return stacksize;
- }
-
- protected final int compileStringParameter(Bytecode code)
- throws CannotCompileException
- {
- int nparam = stringParams.length;
- code.addIconst(nparam);
- code.addAnewarray("java.lang.String");
- for (int j = 0; j < nparam; ++j) {
- code.add(Bytecode.DUP); // dup
- code.addIconst(j); // iconst_<j>
- code.addLdc(stringParams[j]); // ldc ...
- code.add(Bytecode.AASTORE); // aastore
- }
-
- return 4;
- }
+ CtClass objectType;
+ String[] stringParams;
+ boolean withConstructorParams;
+
+ NewInitializer() {}
+
+ /**
+ * Produces codes in which a new object is created and assigned to
+ * the field as the initial value.
+ */
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ int stacksize;
+
+ code.addAload(0);
+ code.addNew(objectType);
+ code.add(Bytecode.DUP);
+ code.addAload(0);
+
+ if (stringParams == null)
+ stacksize = 4;
+ else
+ stacksize = compileStringParameter(code) + 4;
+
+ if (withConstructorParams)
+ stacksize += CtNewWrappedMethod.compileParameterList(code,
+ parameters, 1);
+
+ code.addInvokespecial(objectType, "<init>", getDescriptor());
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return stacksize;
+ }
+
+ private String getDescriptor() {
+ final String desc3
+ = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)V";
+
+ if (stringParams == null)
+ if (withConstructorParams)
+ return "(Ljava/lang/Object;[Ljava/lang/Object;)V";
+ else
+ return "(Ljava/lang/Object;)V";
+ else
+ if (withConstructorParams)
+ return desc3;
+ else
+ return "(Ljava/lang/Object;[Ljava/lang/String;)V";
+ }
+
+ /**
+ * Produces codes for a static field.
+ */
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ String desc;
+
+ code.addNew(objectType);
+ code.add(Bytecode.DUP);
+
+ int stacksize = 2;
+ if (stringParams == null)
+ desc = "()V";
+ else {
+ desc = "([Ljava/lang/String;)V";
+ stacksize += compileStringParameter(code);
+ }
+
+ code.addInvokespecial(objectType, "<init>", desc);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return stacksize;
+ }
+
+ protected final int compileStringParameter(Bytecode code)
+ throws CannotCompileException
+ {
+ int nparam = stringParams.length;
+ code.addIconst(nparam);
+ code.addAnewarray("java.lang.String");
+ for (int j = 0; j < nparam; ++j) {
+ code.add(Bytecode.DUP); // dup
+ code.addIconst(j); // iconst_<j>
+ code.addLdc(stringParams[j]); // ldc ...
+ code.add(Bytecode.AASTORE); // aastore
+ }
+
+ return 4;
+ }
}
* A field initialized with the result of a static method call.
*/
static class MethodInitializer extends NewInitializer {
- String methodName;
- // the method class is specified by objectType.
-
- MethodInitializer() {}
-
- /**
- * Produces codes in which a new object is created and assigned to
- * the field as the initial value.
- */
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- int stacksize;
-
- code.addAload(0);
- code.addAload(0);
-
- if (stringParams == null)
- stacksize = 2;
- else
- stacksize = compileStringParameter(code) + 2;
-
- if (withConstructorParams)
- stacksize += CtNewWrappedMethod.compileParameterList(code,
- parameters, 1);
-
- String typeDesc = Descriptor.of(type);
- String mDesc = getDescriptor() + typeDesc;
- code.addInvokestatic(objectType, methodName, mDesc);
- code.addPutfield(Bytecode.THIS, name, typeDesc);
- return stacksize;
- }
-
- private String getDescriptor() {
- final String desc3
- = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)";
-
- if (stringParams == null)
- if (withConstructorParams)
- return "(Ljava/lang/Object;[Ljava/lang/Object;)";
- else
- return "(Ljava/lang/Object;)";
- else
- if (withConstructorParams)
- return desc3;
- else
- return "(Ljava/lang/Object;[Ljava/lang/String;)";
- }
-
- /**
- * Produces codes for a static field.
- */
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- String desc;
-
- int stacksize = 1;
- if (stringParams == null)
- desc = "()";
- else {
- desc = "([Ljava/lang/String;)";
- stacksize += compileStringParameter(code);
- }
-
- String typeDesc = Descriptor.of(type);
- code.addInvokestatic(objectType, methodName, desc + typeDesc);
- code.addPutstatic(Bytecode.THIS, name, typeDesc);
- return stacksize;
- }
+ String methodName;
+ // the method class is specified by objectType.
+
+ MethodInitializer() {}
+
+ /**
+ * Produces codes in which a new object is created and assigned to
+ * the field as the initial value.
+ */
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ int stacksize;
+
+ code.addAload(0);
+ code.addAload(0);
+
+ if (stringParams == null)
+ stacksize = 2;
+ else
+ stacksize = compileStringParameter(code) + 2;
+
+ if (withConstructorParams)
+ stacksize += CtNewWrappedMethod.compileParameterList(code,
+ parameters, 1);
+
+ String typeDesc = Descriptor.of(type);
+ String mDesc = getDescriptor() + typeDesc;
+ code.addInvokestatic(objectType, methodName, mDesc);
+ code.addPutfield(Bytecode.THIS, name, typeDesc);
+ return stacksize;
+ }
+
+ private String getDescriptor() {
+ final String desc3
+ = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)";
+
+ if (stringParams == null)
+ if (withConstructorParams)
+ return "(Ljava/lang/Object;[Ljava/lang/Object;)";
+ else
+ return "(Ljava/lang/Object;)";
+ else
+ if (withConstructorParams)
+ return desc3;
+ else
+ return "(Ljava/lang/Object;[Ljava/lang/String;)";
+ }
+
+ /**
+ * Produces codes for a static field.
+ */
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ String desc;
+
+ int stacksize = 1;
+ if (stringParams == null)
+ desc = "()";
+ else {
+ desc = "([Ljava/lang/String;)";
+ stacksize += compileStringParameter(code);
+ }
+
+ String typeDesc = Descriptor.of(type);
+ code.addInvokestatic(objectType, methodName, desc + typeDesc);
+ code.addPutstatic(Bytecode.THIS, name, typeDesc);
+ return stacksize;
+ }
}
static class IntInitializer extends Initializer {
- int value;
-
- IntInitializer(int v) { value = v; }
-
- void check(CtClass type) throws CannotCompileException {
- if (type != CtClass.intType)
- throw new CannotCompileException("type mismatch");
- }
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- code.addAload(0);
- code.addIconst(value);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return 2; // stack size
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- code.addIconst(value);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return 1; // stack size
- }
+ int value;
+
+ IntInitializer(int v) { value = v; }
+
+ void check(CtClass type) throws CannotCompileException {
+ if (type != CtClass.intType)
+ throw new CannotCompileException("type mismatch");
+ }
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ code.addAload(0);
+ code.addIconst(value);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return 2; // stack size
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ code.addIconst(value);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return 1; // stack size
+ }
}
static class LongInitializer extends Initializer {
- long value;
-
- LongInitializer(long v) { value = v; }
-
- void check(CtClass type) throws CannotCompileException {
- if (type != CtClass.longType)
- throw new CannotCompileException("type mismatch");
- }
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- code.addAload(0);
- code.addLdc2w(value);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return 3; // stack size
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- code.addLdc2w(value);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return 2; // stack size
- }
+ long value;
+
+ LongInitializer(long v) { value = v; }
+
+ void check(CtClass type) throws CannotCompileException {
+ if (type != CtClass.longType)
+ throw new CannotCompileException("type mismatch");
+ }
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ code.addAload(0);
+ code.addLdc2w(value);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return 3; // stack size
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ code.addLdc2w(value);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return 2; // stack size
+ }
}
static class DoubleInitializer extends Initializer {
- double value;
-
- DoubleInitializer(double v) { value = v; }
-
- void check(CtClass type) throws CannotCompileException {
- if (type != CtClass.doubleType)
- throw new CannotCompileException("type mismatch");
- }
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- code.addAload(0);
- code.addLdc2w(value);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return 3; // stack size
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- code.addLdc2w(value);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return 2; // stack size
- }
+ double value;
+
+ DoubleInitializer(double v) { value = v; }
+
+ void check(CtClass type) throws CannotCompileException {
+ if (type != CtClass.doubleType)
+ throw new CannotCompileException("type mismatch");
+ }
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ code.addAload(0);
+ code.addLdc2w(value);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return 3; // stack size
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ code.addLdc2w(value);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return 2; // stack size
+ }
}
static class StringInitializer extends Initializer {
- String value;
-
- StringInitializer(String v) { value = v; }
-
- void check(CtClass type) throws CannotCompileException {
- if (!type.getName().equals("java.lang.String"))
- throw new CannotCompileException("type mismatch");
- }
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- code.addAload(0);
- code.addLdc(value);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return 2; // stack size
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- code.addLdc(value);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return 1; // stack size
- }
+ String value;
+
+ StringInitializer(String v) { value = v; }
+
+ void check(CtClass type) throws CannotCompileException {
+ if (!type.getName().equals("java.lang.String"))
+ throw new CannotCompileException("type mismatch");
+ }
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ code.addAload(0);
+ code.addLdc(value);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return 2; // stack size
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ code.addLdc(value);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return 1; // stack size
+ }
}
static class ArrayInitializer extends Initializer {
- CtClass type;
- int size;
-
- ArrayInitializer(CtClass t, int s) { type = t; size = s; }
-
- private void addNewarray(Bytecode code) {
- if (type.isPrimitive())
- code.addNewarray(((CtPrimitiveType)type).getArrayType(),
- size);
- else
- code.addAnewarray(type, size);
- }
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- code.addAload(0);
- addNewarray(code);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return 2; // stack size
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- addNewarray(code);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return 1; // stack size
- }
+ CtClass type;
+ int size;
+
+ ArrayInitializer(CtClass t, int s) { type = t; size = s; }
+
+ private void addNewarray(Bytecode code) {
+ if (type.isPrimitive())
+ code.addNewarray(((CtPrimitiveType)type).getArrayType(),
+ size);
+ else
+ code.addAnewarray(type, size);
+ }
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ code.addAload(0);
+ addNewarray(code);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return 2; // stack size
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ addNewarray(code);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return 1; // stack size
+ }
}
static class MultiArrayInitializer extends Initializer {
- CtClass type;
- int[] dim;
-
- MultiArrayInitializer(CtClass t, int[] d) { type = t; dim = d; }
-
- void check(CtClass type) throws CannotCompileException {
- if (!type.isArray())
- throw new CannotCompileException("type mismatch");
- }
-
- int compile(CtClass type, String name, Bytecode code,
- CtClass[] parameters, Javac drv)
- throws CannotCompileException
- {
- code.addAload(0);
- int s = code.addMultiNewarray(type, dim);
- code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
- return s + 1; // stack size
- }
-
- int compileIfStatic(CtClass type, String name, Bytecode code,
- Javac drv) throws CannotCompileException
- {
- int s = code.addMultiNewarray(type, dim);
- code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
- return s; // stack size
- }
+ CtClass type;
+ int[] dim;
+
+ MultiArrayInitializer(CtClass t, int[] d) { type = t; dim = d; }
+
+ void check(CtClass type) throws CannotCompileException {
+ if (!type.isArray())
+ throw new CannotCompileException("type mismatch");
+ }
+
+ int compile(CtClass type, String name, Bytecode code,
+ CtClass[] parameters, Javac drv)
+ throws CannotCompileException
+ {
+ code.addAload(0);
+ int s = code.addMultiNewarray(type, dim);
+ code.addPutfield(Bytecode.THIS, name, Descriptor.of(type));
+ return s + 1; // stack size
+ }
+
+ int compileIfStatic(CtClass type, String name, Bytecode code,
+ Javac drv) throws CannotCompileException
+ {
+ int s = code.addMultiNewarray(type, dim);
+ code.addPutstatic(Bytecode.THIS, name, Descriptor.of(type));
+ return s; // stack size
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
/**
/**
* Obtains the modifiers of the member.
*
- * @return modifiers encoded with
- * <code>javassist.Modifier</code>.
+ * @return modifiers encoded with
+ * <code>javassist.Modifier</code>.
* @see Modifier
*/
public abstract int getModifiers();
* If that attribute is not found in the class file, this
* method returns null.
*
- * @param name attribute name
+ * @param name attribute name
*/
public abstract byte[] getAttribute(String name);
/**
* Adds an attribute. The attribute is saved in the class file.
*
- * @param name attribute name
- * @param data attribute value
+ * @param name attribute name
+ * @param data attribute value
*/
public abstract void setAttribute(String name, byte[] data);
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
protected int cachedHashCode;
CtMethod(MethodInfo minfo, CtClass declaring) {
- super(declaring, minfo);
- next = null;
- cachedHashCode = 0;
+ super(declaring, minfo);
+ next = null;
+ cachedHashCode = 0;
}
/**
* Creates a public abstract method. The created method must be
* added to a class with <code>CtClass.addMethod()</code>.
*
- * @param declaring the class to which the created method is added.
- * @param returnType the type of the returned value
- * @param mname the method name
- * @param parameters a list of the parameter types
+ * @param declaring the class to which the created method is added.
+ * @param returnType the type of the returned value
+ * @param mname the method name
+ * @param parameters a list of the parameter types
*
* @see CtClass#addMethod(CtMethod)
*/
public CtMethod(CtClass returnType, String mname,
- CtClass[] parameters, CtClass declaring) {
- this(null, declaring);
- ConstPool cp = declaring.getClassFile2().getConstPool();
- String desc = Descriptor.ofMethod(returnType, parameters);
- methodInfo = new MethodInfo(cp, mname, desc);
- setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
+ CtClass[] parameters, CtClass declaring) {
+ this(null, declaring);
+ ConstPool cp = declaring.getClassFile2().getConstPool();
+ String desc = Descriptor.ofMethod(returnType, parameters);
+ methodInfo = new MethodInfo(cp, mname, desc);
+ setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
}
/**
* copying it. Otherwise, use <code>Class.forName()</code> in the
* expression.
*
- * @param src the source method.
+ * @param src the source method.
* @param declaring the class to which the created method is added.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*
* @see CtClass#addMethod(CtMethod)
* @see ClassMap#fix(String)
*/
public CtMethod(CtMethod src, CtClass declaring, ClassMap map)
- throws CannotCompileException
+ throws CannotCompileException
{
- this(null, declaring);
- MethodInfo srcInfo = src.methodInfo;
- CtClass srcClass = src.getDeclaringClass();
- ConstPool cp = declaring.getClassFile2().getConstPool();
- if (map == null)
- map = new ClassMap();
-
- map.put(srcClass.getName(), declaring.getName());
- try {
- CtClass srcSuper = srcClass.getSuperclass();
- if (srcSuper != null) {
- String srcSuperName = srcSuper.getName();
- if (!srcSuperName.equals(CtClass.javaLangObject))
- map.put(srcSuperName,
- declaring.getSuperclass().getName());
- }
-
- methodInfo = new MethodInfo(cp, srcInfo.getName(), srcInfo, map);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
+ this(null, declaring);
+ MethodInfo srcInfo = src.methodInfo;
+ CtClass srcClass = src.getDeclaringClass();
+ ConstPool cp = declaring.getClassFile2().getConstPool();
+ if (map == null)
+ map = new ClassMap();
+
+ map.put(srcClass.getName(), declaring.getName());
+ try {
+ CtClass srcSuper = srcClass.getSuperclass();
+ if (srcSuper != null) {
+ String srcSuperName = srcSuper.getName();
+ if (!srcSuperName.equals(CtClass.javaLangObject))
+ map.put(srcSuperName,
+ declaring.getSuperclass().getName());
+ }
+
+ methodInfo = new MethodInfo(cp, srcInfo.getName(), srcInfo, map);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
}
static CtMethod append(CtMethod list, CtMethod tail) {
- tail.next = null;
- if (list == null)
- return tail;
- else {
- CtMethod lst = list;
- while (lst.next != null)
- lst = lst.next;
+ tail.next = null;
+ if (list == null)
+ return tail;
+ else {
+ CtMethod lst = list;
+ while (lst.next != null)
+ lst = lst.next;
- lst.next = tail;
- return list;
- }
+ lst.next = tail;
+ return list;
+ }
}
static int count(CtMethod m) {
- int n = 0;
- while (m != null) {
- ++n;
- m = m.next;
- }
+ int n = 0;
+ while (m != null) {
+ ++n;
+ m = m.next;
+ }
- return n;
+ return n;
}
/**
* the hash codes for the two methods are equal.
*/
public int hashCode() {
- /* This method is overridden in ExistingMethod for optimization.
- */
- if (cachedHashCode == 0) {
- String signature
- = methodInfo.getName() + ':' + methodInfo.getDescriptor();
+ /* This method is overridden in ExistingMethod for optimization.
+ */
+ if (cachedHashCode == 0) {
+ String signature
+ = methodInfo.getName() + ':' + methodInfo.getDescriptor();
- // System.identityHashCode() returns 0 only for null.
- cachedHashCode = System.identityHashCode(signature.intern());
- }
+ // System.identityHashCode() returns 0 only for null.
+ cachedHashCode = System.identityHashCode(signature.intern());
+ }
- return cachedHashCode;
+ return cachedHashCode;
}
/**
* same signature as this method.
*/
public boolean equals(Object obj) {
- return obj != null && obj instanceof CtMethod
- && obj.hashCode() == hashCode();
+ return obj != null && obj instanceof CtMethod
+ && obj.hashCode() == hashCode();
}
/**
* Returns the MethodInfo representing the method in the class file.
*/
public MethodInfo getMethodInfo() {
- return super.getMethodInfo();
+ return super.getMethodInfo();
}
/**
* Obtains the modifiers of the method.
*
- * @return modifiers encoded with
- * <code>javassist.Modifier</code>.
+ * @return modifiers encoded with
+ * <code>javassist.Modifier</code>.
* @see Modifier
*/
public int getModifiers() {
- return super.getModifiers();
+ return super.getModifiers();
}
/**
* @see Modifier
*/
public void setModifiers(int mod) {
- super.setModifiers(mod);
+ super.setModifiers(mod);
}
/**
* Obtains the name of this method.
*/
public String getName() {
- return methodInfo.getName();
+ return methodInfo.getName();
}
/**
* Changes the name of this method.
*/
public void setName(String newname) {
- declaringClass.checkModify();
- methodInfo.setName(newname);
+ declaringClass.checkModify();
+ methodInfo.setName(newname);
}
/**
* Returns the class that declares this method.
*/
public CtClass getDeclaringClass() {
- return super.getDeclaringClass();
+ return super.getDeclaringClass();
}
/**
* Obtains parameter types of this method.
*/
public CtClass[] getParameterTypes() throws NotFoundException {
- return super.getParameterTypes();
+ return super.getParameterTypes();
}
/**
* Obtains the type of the returned value.
*/
public CtClass getReturnType() throws NotFoundException {
- return getReturnType0();
+ return getReturnType0();
}
/**
* same string.
*/
public String getSignature() {
- return super.getSignature();
+ return super.getSignature();
}
/**
* Obtains exceptions that this method may throw.
*/
public CtClass[] getExceptionTypes() throws NotFoundException {
- return super.getExceptionTypes();
+ return super.getExceptionTypes();
}
/**
* Sets exceptions that this method may throw.
*
- * @param types exception types (or null)
+ * @param types exception types (or null)
*/
public void setExceptionTypes(CtClass[] types) throws NotFoundException {
- super.setExceptionTypes(types);
+ super.setExceptionTypes(types);
+ }
+
+ /**
+ * Returns true if the method body is empty, that is, <code>{}</code>.
+ * It also returns true if the method is an abstract method.
+ */
+ public boolean isEmpty() {
+ CodeAttribute ca = getMethodInfo2().getCodeAttribute();
+ if (ca == null) // abstract or native
+ return (getModifiers() & Modifier.ABSTRACT) != 0;
+
+ CodeIterator it = ca.iterator();
+ try {
+ return it.hasNext() && it.byteAt(it.next()) == Opcode.RETURN
+ && !it.hasNext();
+ }
+ catch (BadBytecode e) {}
+ return false;
}
/**
* Sets a method body.
*
- * @param src the source code representing the method body.
- * It must be a single statement or block.
+ * @param src the source code representing the method body.
+ * It must be a single statement or block.
*/
public void setBody(String src) throws CannotCompileException {
- super.setBody(src);
+ super.setBody(src);
}
/**
* are replaced with the names specified by
* <code>map</code> if <code>map</code> is not <code>null</code>.
*
- * @param src the method that the body is copied from.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param src the method that the body is copied from.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*/
public void setBody(CtMethod src, ClassMap map)
- throws CannotCompileException
+ throws CannotCompileException
{
- setBody0(src.declaringClass, src.methodInfo,
- declaringClass, methodInfo, map);
+ setBody0(src.declaringClass, src.methodInfo,
+ declaringClass, methodInfo, map);
}
/**
* Replace a method body with a new method body wrapping the
* given method.
*
- * @param mbody the wrapped method
- * @param constParam the constant parameter given to
- * the wrapped method
- * (maybe <code>null</code>).
+ * @param mbody the wrapped method
+ * @param constParam the constant parameter given to
+ * the wrapped method
+ * (maybe <code>null</code>).
*
* @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass)
*/
public void setWrappedBody(CtMethod mbody, ConstParameter constParam)
- throws CannotCompileException
+ throws CannotCompileException
{
- declaringClass.checkModify();
-
- CtClass clazz = getDeclaringClass();
- CtClass[] params;
- CtClass retType;
- try {
- params = getParameterTypes();
- retType = getReturnType();
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
-
- Bytecode code = CtNewWrappedMethod.makeBody(clazz,
- clazz.getClassFile2(),
- mbody,
- params, retType,
- constParam);
- CodeAttribute cattr = code.toCodeAttribute();
- methodInfo.setCodeAttribute(cattr);
- methodInfo.setAccessFlags(methodInfo.getAccessFlags()
- & ~AccessFlag.ABSTRACT);
+ declaringClass.checkModify();
+
+ CtClass clazz = getDeclaringClass();
+ CtClass[] params;
+ CtClass retType;
+ try {
+ params = getParameterTypes();
+ retType = getReturnType();
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+
+ Bytecode code = CtNewWrappedMethod.makeBody(clazz,
+ clazz.getClassFile2(),
+ mbody,
+ params, retType,
+ constParam);
+ CodeAttribute cattr = code.toCodeAttribute();
+ methodInfo.setCodeAttribute(cattr);
+ methodInfo.setAccessFlags(methodInfo.getAccessFlags()
+ & ~AccessFlag.ABSTRACT);
}
/**
* If that attribute is not found in the class file, this
* method returns null.
*
- * @param name attribute name
+ * @param name attribute name
*/
public byte[] getAttribute(String name) {
- return super.getAttribute(name);
+ return super.getAttribute(name);
}
/**
* Adds an attribute. The attribute is saved in the class file.
*
- * @param name attribute name
- * @param data attribute value
+ * @param name attribute name
+ * @param data attribute value
*/
public void setAttribute(String name, byte[] data) {
- super.setAttribute(name, data);
+ super.setAttribute(name, data);
}
/**
* For example, if the given name is <code>"Point.paint"</code>,
* then the variable is indicated by <code>$cflow(Point.paint)</code>.
*
- * @param name <code>$cflow</code> name. It can include
- * alphabets, numbers, <code>_</code>,
- * <code>$</code>, and <code>.</code> (dot).
+ * @param name <code>$cflow</code> name. It can include
+ * alphabets, numbers, <code>_</code>,
+ * <code>$</code>, and <code>.</code> (dot).
*
* @see javassist.runtime.Cflow
*/
public void useCflow(String name) throws CannotCompileException {
- super.useCflow(name);
+ super.useCflow(name);
}
/**
* Modifies the method body.
*
- * @param converter specifies how to modify.
+ * @param converter specifies how to modify.
*/
public void instrument(CodeConverter converter)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.instrument(converter);
+ super.instrument(converter);
}
/**
* Modifies the method body.
*
- * @param editor specifies how to modify.
+ * @param editor specifies how to modify.
*/
public void instrument(ExprEditor editor)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.instrument(editor);
+ super.instrument(editor);
}
/**
* Inserts bytecode at the beginning of the method body.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertBefore(String src) throws CannotCompileException {
- super.insertBefore(src);
+ super.insertBefore(src);
}
/**
* The bytecode is inserted just before every return insturction.
* It is not executed when an exception is thrown.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
*/
public void insertAfter(String src)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.insertAfter(src);
+ super.insertAfter(src);
}
/**
* Inserts bytecode at the end of the method body.
* The bytecode is inserted just before every return insturction.
*
- * @param src the source code representing the inserted bytecode.
- * It must be a single statement or block.
- * @param asFinally true if the inserted bytecode is executed
- * not only when the transfer normally returns
- * but also when an exception is thrown.
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
+ * @param asFinally true if the inserted bytecode is executed
+ * not only when the transfer normally returns
+ * but also when an exception is thrown.
*/
public void insertAfter(String src, boolean asFinally)
- throws CannotCompileException
+ throws CannotCompileException
{
- super.insertAfter(src, asFinally);
+ super.insertAfter(src, asFinally);
}
/**
* method body.
* The catch clause must end with a return or throw statement.
*
- * @param src the source code representing the catch clause.
- * It must be a single statement or block.
- * @param exceptionType the type of the exception handled by the
- * catch clause.
- * @param exceptionName the name of the variable containing the
- * caught exception.
+ * @param src the source code representing the catch clause.
+ * It must be a single statement or block.
+ * @param exceptionType the type of the exception handled by the
+ * catch clause.
*/
- public void addCatch(String src, CtClass exceptionType,
- String exceptionName)
- throws CannotCompileException
+ public void addCatch(String src, CtClass exceptionType)
+ throws CannotCompileException
{
- super.addCatch(src, exceptionType, exceptionName);
+ super.addCatch(src, exceptionType);
}
// inner classes
* @see CtNewConstructor#make(CtClass[],CtClass[],int,CtMethod,CtMethod.ConstParameter,CtClass)
*/
public static class ConstParameter {
- /**
- * Makes an integer constant.
- *
- * @param i the constant value.
- */
- public static ConstParameter integer(int i) {
- return new IntConstParameter(i);
- }
-
- /**
- * Makes an <code>String</code> constant.
- *
- * @param s the constant value.
- */
- public static ConstParameter string(String s) {
- return new StringConstParameter(s);
- }
-
- ConstParameter() {}
-
- int compile(Bytecode code) throws CannotCompileException {
- return 0;
- }
-
- String descriptor() {
- return defaultDescriptor();
- }
-
- static String defaultDescriptor() {
- return "([Ljava/lang/Object;)Ljava/lang/Object;";
- }
-
- String constDescriptor() {
- return defaultConstDescriptor();
- }
-
- /**
- * Returns the descriptor for constructors.
- */
- static String defaultConstDescriptor() {
- return "([Ljava/lang/Object;)V";
- }
+ /**
+ * Makes an integer constant.
+ *
+ * @param i the constant value.
+ */
+ public static ConstParameter integer(int i) {
+ return new IntConstParameter(i);
+ }
+
+ /**
+ * Makes a long integer constant.
+ *
+ * @param i the constant value.
+ */
+ public static ConstParameter integer(long i) {
+ return new LongConstParameter(i);
+ }
+
+ /**
+ * Makes an <code>String</code> constant.
+ *
+ * @param s the constant value.
+ */
+ public static ConstParameter string(String s) {
+ return new StringConstParameter(s);
+ }
+
+ ConstParameter() {}
+
+ /**
+ * @return the size of the stack consumption.
+ */
+ int compile(Bytecode code) throws CannotCompileException {
+ return 0;
+ }
+
+ String descriptor() {
+ return defaultDescriptor();
+ }
+
+ /**
+ * @see CtNewWrappedMethod
+ */
+ static String defaultDescriptor() {
+ return "([Ljava/lang/Object;)Ljava/lang/Object;";
+ }
+
+ /**
+ * Returns the descriptor for constructors.
+ *
+ * @see CtNewWrappedConstructor
+ */
+ String constDescriptor() {
+ return defaultConstDescriptor();
+ }
+
+ /**
+ * Returns the default descriptor for constructors.
+ */
+ static String defaultConstDescriptor() {
+ return "([Ljava/lang/Object;)V";
+ }
}
static class IntConstParameter extends ConstParameter {
- int param;
+ int param;
+
+ IntConstParameter(int i) {
+ param = i;
+ }
+
+ int compile(Bytecode code) throws CannotCompileException {
+ code.addIconst(param);
+ return 1;
+ }
+
+ String descriptor() {
+ return "([Ljava/lang/Object;I)Ljava/lang/Object;";
+ }
+
+ String constDescriptor() {
+ return "([Ljava/lang/Object;I)V";
+ }
+ }
+
+ static class LongConstParameter extends ConstParameter {
+ long param;
- IntConstParameter(int i) {
- param = i;
- }
+ LongConstParameter(long l) {
+ param = l;
+ }
- int compile(Bytecode code) throws CannotCompileException {
- code.addIconst(param);
- return 1;
- }
+ int compile(Bytecode code) throws CannotCompileException {
+ code.addLconst(param);
+ return 2;
+ }
- String descriptor() {
- return "([Ljava/lang/Object;I)Ljava/lang/Object;";
- }
+ String descriptor() {
+ return "([Ljava/lang/Object;J)Ljava/lang/Object;";
+ }
- String constDescriptor() {
- return "([Ljava/lang/Object;I)V";
- }
+ String constDescriptor() {
+ return "([Ljava/lang/Object;J)V";
+ }
}
static class StringConstParameter extends ConstParameter {
- String param;
+ String param;
- StringConstParameter(String s) {
- param = s;
- }
+ StringConstParameter(String s) {
+ param = s;
+ }
- int compile(Bytecode code) throws CannotCompileException {
- code.addLdc(param);
- return 1;
- }
+ int compile(Bytecode code) throws CannotCompileException {
+ code.addLdc(param);
+ return 1;
+ }
- String descriptor() {
- return "([Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;";
- }
+ String descriptor() {
+ return "([Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;";
+ }
- String constDescriptor() {
- return "([Ljava/lang/Object;Ljava/lang/String;)V";
- }
+ String constDescriptor() {
+ return "([Ljava/lang/Object;Ljava/lang/String;)V";
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.DataOutputStream;
protected boolean hasConstructor;
CtNewClass(String name, ClassPool cp,
- boolean isInterface, CtClass superclass) {
- super(name, cp);
- wasChanged = true;
- eraseCache();
- String superName;
- if (superclass == null)
- superName = null;
- else
- superName = superclass.getName();
+ boolean isInterface, CtClass superclass) {
+ super(name, cp);
+ wasChanged = true;
+ eraseCache();
+ String superName;
+ if (superclass == null)
+ superName = null;
+ else
+ superName = superclass.getName();
- classfile = new ClassFile(isInterface, name, superName);
+ classfile = new ClassFile(isInterface, name, superName);
- setModifiers(Modifier.setPublic(getModifiers()));
- hasConstructor = isInterface;
+ setModifiers(Modifier.setPublic(getModifiers()));
+ hasConstructor = isInterface;
}
public void addConstructor(CtConstructor c)
- throws CannotCompileException
+ throws CannotCompileException
{
- hasConstructor = true;
- super.addConstructor(c);
+ hasConstructor = true;
+ super.addConstructor(c);
}
void toBytecode(DataOutputStream out)
- throws CannotCompileException, IOException
+ throws CannotCompileException, IOException
{
- if (!hasConstructor)
- try {
- inheritAllConstructors();
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ if (!hasConstructor)
+ try {
+ inheritAllConstructors();
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
- super.toBytecode(out);
+ super.toBytecode(out);
}
/**
* calls the super's constructor with the same signature.
*/
public void inheritAllConstructors()
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- CtClass superclazz;
- CtConstructor[] cs;
+ CtClass superclazz;
+ CtConstructor[] cs;
- superclazz = getSuperclass();
- cs = superclazz.getDeclaredConstructors();
+ superclazz = getSuperclass();
+ cs = superclazz.getDeclaredConstructors();
- int n = 0;
- for (int i = 0; i < cs.length; ++i) {
- CtConstructor c = cs[i];
- if (Modifier.isPublic(c.getModifiers())) {
- CtConstructor cons
- = CtNewConstructor.make(c.getParameterTypes(),
- c.getExceptionTypes(), this);
- addConstructor(cons);
- ++n;
- }
- }
+ int n = 0;
+ for (int i = 0; i < cs.length; ++i) {
+ CtConstructor c = cs[i];
+ if (Modifier.isPublic(c.getModifiers())) {
+ CtConstructor cons
+ = CtNewConstructor.make(c.getParameterTypes(),
+ c.getExceptionTypes(), this);
+ addConstructor(cons);
+ ++n;
+ }
+ }
- if (n < 1)
- throw new CannotCompileException(
- "no public constructor in " + superclazz.getName());
+ if (n < 1)
+ throw new CannotCompileException(
+ "no public constructor in " + superclazz.getName());
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
* Specifies that no parameters are passed to a super-class'
* constructor. That is, the default constructor is invoked.
*/
- public static final int PASS_NONE = 0; // call super()
+ public static final int PASS_NONE = 0; // call super()
/**
* Specifies that parameters are converted into an array of
* <code>Object</code> and passed to a super-class'
* constructor.
*/
- public static final int PASS_ARRAY = 1; // an array of parameters
+ public static final int PASS_ARRAY = 1; // an array of parameters
/**
* Specifies that parameters are passed <i>as is</i>
* The source code must include not only the constructor body
* but the whole declaration.
*
- * @param src the source text.
+ * @param src the source text.
* @param declaring the class to which the created constructor is added.
*/
public static CtConstructor make(String src, CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- Javac compiler = new Javac(declaring);
- try {
- CtMember obj = compiler.compile(src);
- if (obj instanceof CtConstructor)
- return (CtConstructor)obj;
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
+ Javac compiler = new Javac(declaring);
+ try {
+ CtMember obj = compiler.compile(src);
+ if (obj instanceof CtConstructor)
+ return (CtConstructor)obj;
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
- throw new CannotCompileException("not a constructor");
+ throw new CannotCompileException("not a constructor");
}
/**
* Creates a public constructor.
*
- * @param returnType the type of the returned value
- * @param mname the method name
- * @param parameters a list of the parameter types
- * @param exceptions a list of the exception types
- * @param src the source text of the method body.
- * It must be a block surrounded by <code>{}</code>.
+ * @param returnType the type of the returned value
+ * @param mname the method name
+ * @param parameters a list of the parameter types
+ * @param exceptions a list of the exception types
+ * @param src the source text of the method body.
+ * It must be a block surrounded by <code>{}</code>.
* @param declaring the class to which the created method is added.
*/
public static CtConstructor make(CtClass[] parameters,
- CtClass[] exceptions,
- String body, CtClass declaring)
- throws CannotCompileException
+ CtClass[] exceptions,
+ String body, CtClass declaring)
+ throws CannotCompileException
{
- try {
- CtConstructor cc = new CtConstructor(parameters, declaring);
- cc.setExceptionTypes(exceptions);
- cc.setBody(body);
- return cc;
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ try {
+ CtConstructor cc = new CtConstructor(parameters, declaring);
+ cc.setExceptionTypes(exceptions);
+ cc.setBody(body);
+ return cc;
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* Creats a copy of a constructor.
*
- * @param c the copied constructor.
+ * @param c the copied constructor.
* @param declaring the class to which the created method is added.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*
* @see CtConstructor#CtConstructor(CtConstructor,CtClass,ClassMap)
*/
public static CtConstructor copy(CtConstructor c, CtClass declaring,
- ClassMap map) throws CannotCompileException {
- return new CtConstructor(c, declaring, map);
+ ClassMap map) throws CannotCompileException {
+ return new CtConstructor(c, declaring, map);
}
/**
* <code>super()</code>.
*/
public static CtConstructor defaultConstructor(CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- CtConstructor cons = new CtConstructor((CtClass[])null, declaring);
+ CtConstructor cons = new CtConstructor((CtClass[])null, declaring);
- ConstPool cp = declaring.getClassFile2().getConstPool();
- Bytecode code = new Bytecode(cp, 1, 1);
- code.addAload(0);
- try {
- code.addInvokespecial(declaring.getSuperclass(),
- "<init>", "()V");
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ ConstPool cp = declaring.getClassFile2().getConstPool();
+ Bytecode code = new Bytecode(cp, 1, 1);
+ code.addAload(0);
+ try {
+ code.addInvokespecial(declaring.getSuperclass(),
+ "<init>", "()V");
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
- code.add(Bytecode.RETURN);
+ code.add(Bytecode.RETURN);
- cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
- return cons;
+ cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
+ return cons;
}
/**
* objects implicitly insert initialization code in constructor
* bodies.
*
- * @param parameters parameter types
- * @param exceptions exception types
- * @param declaring the class to which the created constructor
- * is added.
+ * @param parameters parameter types
+ * @param exceptions exception types
+ * @param declaring the class to which the created constructor
+ * is added.
* @see CtField.Initializer#byParameter(int)
*/
public static CtConstructor skeleton(CtClass[] parameters,
- CtClass[] exceptions, CtClass declaring)
- throws CannotCompileException
+ CtClass[] exceptions, CtClass declaring)
+ throws CannotCompileException
{
- return make(parameters, exceptions, PASS_NONE,
- null, null, declaring);
+ return make(parameters, exceptions, PASS_NONE,
+ null, null, declaring);
}
/**
* specified by <code>parameters</code> and calls the super's
* constructor with those parameters.
*
- * @param parameters parameter types
- * @param exceptions exception types
- * @param declaring the class to which the created constructor
- * is added.
+ * @param parameters parameter types
+ * @param exceptions exception types
+ * @param declaring the class to which the created constructor
+ * is added.
*/
public static CtConstructor make(CtClass[] parameters,
- CtClass[] exceptions, CtClass declaring)
- throws CannotCompileException
+ CtClass[] exceptions, CtClass declaring)
+ throws CannotCompileException
{
- return make(parameters, exceptions, PASS_PARAMS,
- null, null, declaring);
+ return make(parameters, exceptions, PASS_PARAMS,
+ null, null, declaring);
}
/**
* }
* }</pre></ul>
*
- * @param parameters a list of the parameter types
- * @param exceptions a list of the exceptions
- * @param howto how to pass parameters to the super-class'
- * constructor (<code>PASS_NONE</code>,
- * <code>PASS_ARRAY</code>,
- * or <code>PASS_PARAMS</code>)
- * @param body appended body (may be <code>null</code>).
- * It must be not a constructor but a method.
- * @param cparam constant parameter (may be <code>null</code>.)
- * @param declaring the class to which the created constructor
- * is added.
+ * @param parameters a list of the parameter types
+ * @param exceptions a list of the exceptions
+ * @param howto how to pass parameters to the super-class'
+ * constructor (<code>PASS_NONE</code>,
+ * <code>PASS_ARRAY</code>,
+ * or <code>PASS_PARAMS</code>)
+ * @param body appended body (may be <code>null</code>).
+ * It must be not a constructor but a method.
+ * @param cparam constant parameter (may be <code>null</code>.)
+ * @param declaring the class to which the created constructor
+ * is added.
*
* @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass)
*/
public static CtConstructor make(CtClass[] parameters,
- CtClass[] exceptions, int howto,
- CtMethod body, ConstParameter cparam,
- CtClass declaring)
- throws CannotCompileException
+ CtClass[] exceptions, int howto,
+ CtMethod body, ConstParameter cparam,
+ CtClass declaring)
+ throws CannotCompileException
{
- return CtNewWrappedConstructor.wrapped(parameters, exceptions,
- howto, body, cparam, declaring);
+ return CtNewWrappedConstructor.wrapped(parameters, exceptions,
+ howto, body, cparam, declaring);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
*
* <ul><pre>"public Object id(Object obj) { return obj; }"</pre></ul>
*
- * @param src the source text.
+ * @param src the source text.
* @param declaring the class to which the created method is added.
*/
public static CtMethod make(String src, CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- return make(src, declaring, null, null);
+ return make(src, declaring, null, null);
}
/**
* <p>If the source code includes <code>$proceed()</code>, then
* it is compiled into a method call on the specified object.
*
- * @param src the source text.
+ * @param src the source text.
* @param declaring the class to which the created method is added.
- * @param delegateObj the source text specifying the object
- * that is called on by <code>$proceed()</code>.
- * @param delegateMethod the name of the method
- * that is called by <code>$proceed()</code>.
+ * @param delegateObj the source text specifying the object
+ * that is called on by <code>$proceed()</code>.
+ * @param delegateMethod the name of the method
+ * that is called by <code>$proceed()</code>.
*/
public static CtMethod make(String src, CtClass declaring,
- String delegateObj, String delegateMethod)
- throws CannotCompileException
+ String delegateObj, String delegateMethod)
+ throws CannotCompileException
{
- Javac compiler = new Javac(declaring);
- try {
- if (delegateMethod != null)
- compiler.recordProceed(delegateObj, delegateMethod);
+ Javac compiler = new Javac(declaring);
+ try {
+ if (delegateMethod != null)
+ compiler.recordProceed(delegateObj, delegateMethod);
- CtMember obj = compiler.compile(src);
- if (obj instanceof CtMethod)
- return (CtMethod)obj;
- }
- catch (CompileError e) {
- throw new CannotCompileException(e);
- }
+ CtMember obj = compiler.compile(src);
+ if (obj instanceof CtMethod)
+ return (CtMethod)obj;
+ }
+ catch (CompileError e) {
+ throw new CannotCompileException(e);
+ }
- throw new CannotCompileException("not a method");
+ throw new CannotCompileException("not a method");
}
/**
* Creates a public method.
*
- * @param returnType the type of the returned value
- * @param mname the method name
- * @param parameters a list of the parameter types
- * @param exceptions a list of the exception types
- * @param src the source text of the method body.
- * It must be a block surrounded by <code>{}</code>.
+ * @param returnType the type of the returned value
+ * @param mname the method name
+ * @param parameters a list of the parameter types
+ * @param exceptions a list of the exception types
+ * @param src the source text of the method body.
+ * It must be a block surrounded by <code>{}</code>.
* @param declaring the class to which the created method is added.
*/
public static CtMethod make(CtClass returnType, String mname,
- CtClass[] parameters, CtClass[] exceptions,
- String body, CtClass declaring)
- throws CannotCompileException
+ CtClass[] parameters, CtClass[] exceptions,
+ String body, CtClass declaring)
+ throws CannotCompileException
{
- try {
- CtMethod cm
- = new CtMethod(returnType, mname, parameters, declaring);
- cm.setExceptionTypes(exceptions);
- cm.setBody(body);
- return cm;
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ try {
+ CtMethod cm
+ = new CtMethod(returnType, mname, parameters, declaring);
+ cm.setExceptionTypes(exceptions);
+ cm.setBody(body);
+ return cm;
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
/**
* Creates a copy of a method. This method is provided for creating
* a new method based on an existing method.
*
- * @param src the source method.
+ * @param src the source method.
* @param declaring the class to which the created method is added.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*
* @see CtMethod#CtMethod(CtMethod,CtClass,ClassMap)
*/
public static CtMethod copy(CtMethod src, CtClass declaring,
- ClassMap map) throws CannotCompileException {
- return new CtMethod(src, declaring, map);
+ ClassMap map) throws CannotCompileException {
+ return new CtMethod(src, declaring, map);
}
/**
* This method is provided for creating
* a new method based on an existing method.
*
- * @param src the source method.
- * @param name the name of the created method.
+ * @param src the source method.
+ * @param name the name of the created method.
* @param declaring the class to which the created method is added.
- * @param map the hashtable associating original class names
- * with substituted names.
- * It can be <code>null</code>.
+ * @param map the hashtable associating original class names
+ * with substituted names.
+ * It can be <code>null</code>.
*
* @see CtMethod#CtMethod(CtMethod,CtClass,ClassMap)
*/
public static CtMethod copy(CtMethod src, String name, CtClass declaring,
- ClassMap map) throws CannotCompileException {
- CtMethod cm = new CtMethod(src, declaring, map);
- cm.setName(name);
- return cm;
+ ClassMap map) throws CannotCompileException {
+ CtMethod cm = new CtMethod(src, declaring, map);
+ cm.setName(name);
+ return cm;
}
/**
* Creates a public abstract method.
*
- * @param returnType the type of the returned value
- * @param mname the method name
- * @param parameters a list of the parameter types
- * @param exceptions a list of the exception types
+ * @param returnType the type of the returned value
+ * @param mname the method name
+ * @param parameters a list of the parameter types
+ * @param exceptions a list of the exception types
* @param declaring the class to which the created method is added.
*
* @see CtMethod#CtMethod(CtClass,String,CtClass[],CtClass)
*/
public static CtMethod abstractMethod(CtClass returnType,
- String mname,
- CtClass[] parameters,
- CtClass[] exceptions,
- CtClass declaring)
- throws NotFoundException
+ String mname,
+ CtClass[] parameters,
+ CtClass[] exceptions,
+ CtClass declaring)
+ throws NotFoundException
{
- CtMethod cm = new CtMethod(returnType, mname, parameters, declaring);
- cm.setExceptionTypes(exceptions);
- return cm;
+ CtMethod cm = new CtMethod(returnType, mname, parameters, declaring);
+ cm.setExceptionTypes(exceptions);
+ return cm;
}
/**
* The created method is initially not static even if the field is
* static. Change the modifiers if the method should be static.
*
- * @param methodName the name of the getter
- * @param field the field accessed.
+ * @param methodName the name of the getter
+ * @param field the field accessed.
*/
public static CtMethod getter(String methodName, CtField field)
- throws CannotCompileException
+ throws CannotCompileException
{
- FieldInfo finfo = field.getFieldInfo2();
- String fieldType = finfo.getDescriptor();
- String desc = "()" + fieldType;
- ConstPool cp = finfo.getConstPool();
- MethodInfo minfo = new MethodInfo(cp, methodName, desc);
- minfo.setAccessFlags(AccessFlag.PUBLIC);
+ FieldInfo finfo = field.getFieldInfo2();
+ String fieldType = finfo.getDescriptor();
+ String desc = "()" + fieldType;
+ ConstPool cp = finfo.getConstPool();
+ MethodInfo minfo = new MethodInfo(cp, methodName, desc);
+ minfo.setAccessFlags(AccessFlag.PUBLIC);
- Bytecode code = new Bytecode(cp, 2, 1);
- try {
- String fieldName = finfo.getName();
- if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0) {
- code.addAload(0);
- code.addGetfield(Bytecode.THIS, fieldName, fieldType);
- }
- else
- code.addGetstatic(Bytecode.THIS, fieldName, fieldType);
+ Bytecode code = new Bytecode(cp, 2, 1);
+ try {
+ String fieldName = finfo.getName();
+ if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0) {
+ code.addAload(0);
+ code.addGetfield(Bytecode.THIS, fieldName, fieldType);
+ }
+ else
+ code.addGetstatic(Bytecode.THIS, fieldName, fieldType);
- code.addReturn(field.getType());
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ code.addReturn(field.getType());
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
- minfo.setCodeAttribute(code.toCodeAttribute());
- return new CtMethod(minfo, field.getDeclaringClass());
+ minfo.setCodeAttribute(code.toCodeAttribute());
+ return new CtMethod(minfo, field.getDeclaringClass());
}
/**
* The created method is initially not static even if the field is
* static. Change the modifiers if the method should be static.
*
- * @param methodName the name of the setter
- * @param field the field accessed.
+ * @param methodName the name of the setter
+ * @param field the field accessed.
*/
public static CtMethod setter(String methodName, CtField field)
- throws CannotCompileException
+ throws CannotCompileException
{
- FieldInfo finfo = field.getFieldInfo2();
- String fieldType = finfo.getDescriptor();
- String desc = "(" + fieldType + ")V";
- ConstPool cp = finfo.getConstPool();
- MethodInfo minfo = new MethodInfo(cp, methodName, desc);
- minfo.setAccessFlags(AccessFlag.PUBLIC);
+ FieldInfo finfo = field.getFieldInfo2();
+ String fieldType = finfo.getDescriptor();
+ String desc = "(" + fieldType + ")V";
+ ConstPool cp = finfo.getConstPool();
+ MethodInfo minfo = new MethodInfo(cp, methodName, desc);
+ minfo.setAccessFlags(AccessFlag.PUBLIC);
- Bytecode code = new Bytecode(cp, 3, 3);
- try {
- String fieldName = finfo.getName();
- if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0) {
- code.addAload(0);
- code.addLoad(1, field.getType());
- code.addPutfield(Bytecode.THIS, fieldName, fieldType);
- }
- else {
- code.addLoad(0, field.getType());
- code.addPutstatic(Bytecode.THIS, fieldName, fieldType);
- }
+ Bytecode code = new Bytecode(cp, 3, 3);
+ try {
+ String fieldName = finfo.getName();
+ if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0) {
+ code.addAload(0);
+ code.addLoad(1, field.getType());
+ code.addPutfield(Bytecode.THIS, fieldName, fieldType);
+ }
+ else {
+ code.addLoad(0, field.getType());
+ code.addPutstatic(Bytecode.THIS, fieldName, fieldType);
+ }
- code.addReturn(null);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ code.addReturn(null);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
- minfo.setCodeAttribute(code.toCodeAttribute());
- return new CtMethod(minfo, field.getDeclaringClass());
+ minfo.setCodeAttribute(code.toCodeAttribute());
+ return new CtMethod(minfo, field.getDeclaringClass());
}
/**
* <p>The name of the created method can be changed by
* <code>setName()</code>.
*
- * @param delegate the method that the created method forwards to.
- * @param declaring the class to which the created method is
- * added.
+ * @param delegate the method that the created method forwards to.
+ * @param declaring the class to which the created method is
+ * added.
*/
public static CtMethod delegator(CtMethod delegate, CtClass declaring)
- throws CannotCompileException
+ throws CannotCompileException
{
- try {
- return delegator0(delegate, declaring);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ try {
+ return delegator0(delegate, declaring);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
private static CtMethod delegator0(CtMethod delegate, CtClass declaring)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- MethodInfo deleInfo = delegate.getMethodInfo2();
- String methodName = deleInfo.getName();
- String desc = deleInfo.getDescriptor();
- ConstPool cp = declaring.getClassFile2().getConstPool();
- MethodInfo minfo = new MethodInfo(cp, methodName, desc);
- minfo.setAccessFlags(deleInfo.getAccessFlags());
+ MethodInfo deleInfo = delegate.getMethodInfo2();
+ String methodName = deleInfo.getName();
+ String desc = deleInfo.getDescriptor();
+ ConstPool cp = declaring.getClassFile2().getConstPool();
+ MethodInfo minfo = new MethodInfo(cp, methodName, desc);
+ minfo.setAccessFlags(deleInfo.getAccessFlags());
- ExceptionsAttribute eattr = deleInfo.getExceptionsAttribute();
- if (eattr != null)
- minfo.setExceptionsAttribute(
- (ExceptionsAttribute)eattr.copy(cp, null));
+ ExceptionsAttribute eattr = deleInfo.getExceptionsAttribute();
+ if (eattr != null)
+ minfo.setExceptionsAttribute(
+ (ExceptionsAttribute)eattr.copy(cp, null));
- Bytecode code = new Bytecode(cp, 0, 0);
- boolean isStatic = Modifier.isStatic(delegate.getModifiers());
- CtClass deleClass = delegate.getDeclaringClass();
- CtClass[] params = delegate.getParameterTypes();
- int s;
- if (isStatic) {
- s = code.addLoadParameters(params);
- code.addInvokestatic(deleClass, methodName, desc);
- }
- else {
- code.addLoad(0, deleClass);
- s = code.addLoadParameters(params);
- code.addInvokespecial(deleClass, methodName, desc);
- }
+ Bytecode code = new Bytecode(cp, 0, 0);
+ boolean isStatic = Modifier.isStatic(delegate.getModifiers());
+ CtClass deleClass = delegate.getDeclaringClass();
+ CtClass[] params = delegate.getParameterTypes();
+ int s;
+ if (isStatic) {
+ s = code.addLoadParameters(params);
+ code.addInvokestatic(deleClass, methodName, desc);
+ }
+ else {
+ code.addLoad(0, deleClass);
+ s = code.addLoadParameters(params);
+ code.addInvokespecial(deleClass, methodName, desc);
+ }
- code.addReturn(delegate.getReturnType());
- code.setMaxLocals(++s);
- code.setMaxStack(s < 2 ? 2 : s); // for a 2-word return value
- minfo.setCodeAttribute(code.toCodeAttribute());
- return new CtMethod(minfo, declaring);
+ code.addReturn(delegate.getReturnType());
+ code.setMaxLocals(++s);
+ code.setMaxStack(s < 2 ? 2 : s); // for a 2-word return value
+ minfo.setCodeAttribute(code.toCodeAttribute());
+ return new CtMethod(minfo, declaring);
}
/**
* <code>StringVector</code> class, which is a vector containing
* only <code>String</code> objects, and other vector classes.
*
- * @param returnType the type of the returned value.
- * @param mname the method name.
- * @param parameters a list of the parameter types.
- * @param exceptions a list of the exception types.
- * @param body the method body
- * @param constParam the constant parameter
- * (maybe <code>null</code>).
- * @param declaring the class to which the created method is
- * added.
+ * @param returnType the type of the returned value.
+ * @param mname the method name.
+ * @param parameters a list of the parameter types.
+ * @param exceptions a list of the exception types.
+ * @param body the method body
+ * @param constParam the constant parameter
+ * (maybe <code>null</code>).
+ * @param declaring the class to which the created method is
+ * added.
*/
public static CtMethod wrapped(CtClass returnType,
- String mname,
- CtClass[] parameterTypes,
- CtClass[] exceptionTypes,
- CtMethod body, ConstParameter constParam,
- CtClass declaring)
- throws CannotCompileException
+ String mname,
+ CtClass[] parameterTypes,
+ CtClass[] exceptionTypes,
+ CtMethod body, ConstParameter constParam,
+ CtClass declaring)
+ throws CannotCompileException
{
- return CtNewWrappedMethod.wrapped(returnType, mname, parameterTypes,
- exceptionTypes, body, constParam, declaring);
+ return CtNewWrappedMethod.wrapped(returnType, mname, parameterTypes,
+ exceptionTypes, body, constParam, declaring);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
private static final int PASS_PARAMS = CtNewConstructor.PASS_PARAMS;
public static CtConstructor wrapped(CtClass[] parameterTypes,
- CtClass[] exceptionTypes,
- int howToCallSuper,
- CtMethod body,
- ConstParameter constParam,
- CtClass declaring)
- throws CannotCompileException
+ CtClass[] exceptionTypes,
+ int howToCallSuper,
+ CtMethod body,
+ ConstParameter constParam,
+ CtClass declaring)
+ throws CannotCompileException
{
- try {
- CtConstructor cons = new CtConstructor(parameterTypes, declaring);
- cons.setExceptionTypes(exceptionTypes);
- Bytecode code = makeBody(declaring, declaring.getClassFile2(),
- howToCallSuper, body,
- parameterTypes, constParam);
- cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
- return cons;
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
+ try {
+ CtConstructor cons = new CtConstructor(parameterTypes, declaring);
+ cons.setExceptionTypes(exceptionTypes);
+ Bytecode code = makeBody(declaring, declaring.getClassFile2(),
+ howToCallSuper, body,
+ parameterTypes, constParam);
+ cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
+ return cons;
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
}
protected static Bytecode makeBody(CtClass declaring, ClassFile classfile,
- int howToCallSuper,
- CtMethod wrappedBody,
- CtClass[] parameters,
- ConstParameter cparam)
- throws CannotCompileException
+ int howToCallSuper,
+ CtMethod wrappedBody,
+ CtClass[] parameters,
+ ConstParameter cparam)
+ throws CannotCompileException
{
- int stacksize, stacksize2;
+ int stacksize, stacksize2;
- int superclazz = classfile.getSuperclassId();
- Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0);
- code.setMaxLocals(false, parameters, 0);
- code.addAload(0);
- if (howToCallSuper == PASS_NONE) {
- stacksize = 1;
- code.addInvokespecial(superclazz, "<init>", "()V");
- }
- else if (howToCallSuper == PASS_PARAMS) {
- stacksize = code.addLoadParameters(parameters) + 1;
- code.addInvokespecial(superclazz, "<init>",
- Descriptor.ofConstructor(parameters));
- }
- else {
- stacksize = compileParameterList(code, parameters, 1);
- String desc;
- if (cparam == null) {
- stacksize2 = 2;
- desc = ConstParameter.defaultConstDescriptor();
- }
- else {
- stacksize2 = cparam.compile(code) + 2;
- desc = cparam.constDescriptor();
- }
+ int superclazz = classfile.getSuperclassId();
+ Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0);
+ code.setMaxLocals(false, parameters, 0);
+ code.addAload(0);
+ if (howToCallSuper == PASS_NONE) {
+ stacksize = 1;
+ code.addInvokespecial(superclazz, "<init>", "()V");
+ }
+ else if (howToCallSuper == PASS_PARAMS) {
+ stacksize = code.addLoadParameters(parameters) + 1;
+ code.addInvokespecial(superclazz, "<init>",
+ Descriptor.ofConstructor(parameters));
+ }
+ else {
+ stacksize = compileParameterList(code, parameters, 1);
+ String desc;
+ if (cparam == null) {
+ stacksize2 = 2;
+ desc = ConstParameter.defaultConstDescriptor();
+ }
+ else {
+ stacksize2 = cparam.compile(code) + 2;
+ desc = cparam.constDescriptor();
+ }
- if (stacksize < stacksize2)
- stacksize = stacksize2;
+ if (stacksize < stacksize2)
+ stacksize = stacksize2;
- code.addInvokespecial(superclazz, "<init>", desc);
- }
+ code.addInvokespecial(superclazz, "<init>", desc);
+ }
- if (wrappedBody == null)
- code.add(Bytecode.RETURN);
- else {
- stacksize2 = makeBody0(declaring, classfile, wrappedBody,
- false, parameters, CtClass.voidType,
- cparam, code);
- if (stacksize < stacksize2)
- stacksize = stacksize2;
- }
+ if (wrappedBody == null)
+ code.add(Bytecode.RETURN);
+ else {
+ stacksize2 = makeBody0(declaring, classfile, wrappedBody,
+ false, parameters, CtClass.voidType,
+ cparam, code);
+ if (stacksize < stacksize2)
+ stacksize = stacksize2;
+ }
- code.setMaxStack(stacksize);
- return code;
+ code.setMaxStack(stacksize);
+ return code;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.*;
private static final String addedWrappedMethod = "_added_m$";
public static CtMethod wrapped(CtClass returnType, String mname,
- CtClass[] parameterTypes,
- CtClass[] exceptionTypes,
- CtMethod body, ConstParameter constParam,
- CtClass declaring)
- throws CannotCompileException
+ CtClass[] parameterTypes,
+ CtClass[] exceptionTypes,
+ CtMethod body, ConstParameter constParam,
+ CtClass declaring)
+ throws CannotCompileException
{
- CtMethod mt = new CtMethod(returnType, mname, parameterTypes,
- declaring);
- mt.setModifiers(body.getModifiers());
- try {
- mt.setExceptionTypes(exceptionTypes);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
-
- Bytecode code = makeBody(declaring, declaring.getClassFile2(), body,
- parameterTypes, returnType, constParam);
- mt.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
- return mt;
+ CtMethod mt = new CtMethod(returnType, mname, parameterTypes,
+ declaring);
+ mt.setModifiers(body.getModifiers());
+ try {
+ mt.setExceptionTypes(exceptionTypes);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+
+ Bytecode code = makeBody(declaring, declaring.getClassFile2(), body,
+ parameterTypes, returnType, constParam);
+ mt.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
+ return mt;
}
static Bytecode makeBody(CtClass clazz, ClassFile classfile,
- CtMethod wrappedBody,
- CtClass[] parameters,
- CtClass returnType,
- ConstParameter cparam)
- throws CannotCompileException
+ CtMethod wrappedBody,
+ CtClass[] parameters,
+ CtClass returnType,
+ ConstParameter cparam)
+ throws CannotCompileException
{
- boolean isStatic = Modifier.isStatic(wrappedBody.getModifiers());
- Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0);
- int stacksize = makeBody0(clazz, classfile, wrappedBody, isStatic,
- parameters, returnType, cparam, code);
- code.setMaxStack(stacksize);
- code.setMaxLocals(isStatic, parameters, 0);
- return code;
+ boolean isStatic = Modifier.isStatic(wrappedBody.getModifiers());
+ Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0);
+ int stacksize = makeBody0(clazz, classfile, wrappedBody, isStatic,
+ parameters, returnType, cparam, code);
+ code.setMaxStack(stacksize);
+ code.setMaxLocals(isStatic, parameters, 0);
+ return code;
}
protected static int makeBody0(CtClass clazz, ClassFile classfile,
- CtMethod wrappedBody,
- boolean isStatic, CtClass[] parameters,
- CtClass returnType, ConstParameter cparam,
- Bytecode code)
- throws CannotCompileException
+ CtMethod wrappedBody,
+ boolean isStatic, CtClass[] parameters,
+ CtClass returnType, ConstParameter cparam,
+ Bytecode code)
+ throws CannotCompileException
{
- if (!(clazz instanceof CtClassType))
- throw new CannotCompileException("bad declaring class"
- + clazz.getName());
-
- if (!isStatic)
- code.addAload(0);
-
- int stacksize = compileParameterList(code, parameters,
- (isStatic ? 0 : 1));
- int stacksize2;
- String desc;
- if (cparam == null) {
- stacksize2 = 0;
- desc = ConstParameter.defaultDescriptor();
- }
- else {
- stacksize2 = cparam.compile(code);
- desc = cparam.descriptor();
- }
-
- checkSignature(wrappedBody, desc);
-
- String bodyname;
- try {
- bodyname = addBodyMethod((CtClassType)clazz, classfile,
- wrappedBody);
- /* if an exception is thrown below, the method added above
- * should be removed. (future work :<)
- */
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
-
- if (isStatic)
- code.addInvokestatic(Bytecode.THIS, bodyname, desc);
- else
- code.addInvokespecial(Bytecode.THIS, bodyname, desc);
-
- compileReturn(code, returnType); // consumes 2 stack entries
-
- if (stacksize < stacksize2 + 2)
- stacksize = stacksize2 + 2;
-
- return stacksize;
+ if (!(clazz instanceof CtClassType))
+ throw new CannotCompileException("bad declaring class"
+ + clazz.getName());
+
+ if (!isStatic)
+ code.addAload(0);
+
+ int stacksize = compileParameterList(code, parameters,
+ (isStatic ? 0 : 1));
+ int stacksize2;
+ String desc;
+ if (cparam == null) {
+ stacksize2 = 0;
+ desc = ConstParameter.defaultDescriptor();
+ }
+ else {
+ stacksize2 = cparam.compile(code);
+ desc = cparam.descriptor();
+ }
+
+ checkSignature(wrappedBody, desc);
+
+ String bodyname;
+ try {
+ bodyname = addBodyMethod((CtClassType)clazz, classfile,
+ wrappedBody);
+ /* if an exception is thrown below, the method added above
+ * should be removed. (future work :<)
+ */
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
+
+ if (isStatic)
+ code.addInvokestatic(Bytecode.THIS, bodyname, desc);
+ else
+ code.addInvokespecial(Bytecode.THIS, bodyname, desc);
+
+ compileReturn(code, returnType); // consumes 2 stack entries
+
+ if (stacksize < stacksize2 + 2)
+ stacksize = stacksize2 + 2;
+
+ return stacksize;
}
private static void checkSignature(CtMethod wrappedBody,
- String descriptor)
- throws CannotCompileException
+ String descriptor)
+ throws CannotCompileException
{
- if (!descriptor.equals(wrappedBody.getMethodInfo2().getDescriptor()))
- throw new CannotCompileException(
- "wrapped method with a bad signature: "
- + wrappedBody.getDeclaringClass().getName()
- + '.' + wrappedBody.getName());
+ if (!descriptor.equals(wrappedBody.getMethodInfo2().getDescriptor()))
+ throw new CannotCompileException(
+ "wrapped method with a bad signature: "
+ + wrappedBody.getDeclaringClass().getName()
+ + '.' + wrappedBody.getName());
}
private static String addBodyMethod(CtClassType clazz,
- ClassFile classfile,
- CtMethod src)
- throws BadBytecode
+ ClassFile classfile,
+ CtMethod src)
+ throws BadBytecode
{
- Hashtable bodies = clazz.getHiddenMethods();
- String bodyname = (String)bodies.get(src);
- if (bodyname == null) {
- do {
- bodyname = addedWrappedMethod + clazz.getUniqueNumber();
- } while (classfile.getMethod(bodyname) != null);
-
- ClassMap map = new ClassMap();
- map.put(src.getDeclaringClass().getName(), clazz.getName());
- MethodInfo body = new MethodInfo(classfile.getConstPool(),
- bodyname, src.getMethodInfo2(),
- map);
- int acc = body.getAccessFlags();
- body.setAccessFlags(AccessFlag.setPrivate(acc));
- classfile.addMethod(body);
- bodies.put(src, bodyname);
- }
-
- return bodyname;
+ Hashtable bodies = clazz.getHiddenMethods();
+ String bodyname = (String)bodies.get(src);
+ if (bodyname == null) {
+ do {
+ bodyname = addedWrappedMethod + clazz.getUniqueNumber();
+ } while (classfile.getMethod(bodyname) != null);
+
+ ClassMap map = new ClassMap();
+ map.put(src.getDeclaringClass().getName(), clazz.getName());
+ MethodInfo body = new MethodInfo(classfile.getConstPool(),
+ bodyname, src.getMethodInfo2(),
+ map);
+ int acc = body.getAccessFlags();
+ body.setAccessFlags(AccessFlag.setPrivate(acc));
+ classfile.addMethod(body);
+ bodies.put(src, bodyname);
+ }
+
+ return bodyname;
}
/* compileParameterList() returns the stack size used
* by the produced code.
*
- * @param regno the index of the local variable in which
- * the first argument is received.
- * (0: static method, 1: regular method.)
+ * @param regno the index of the local variable in which
+ * the first argument is received.
+ * (0: static method, 1: regular method.)
*/
static int compileParameterList(Bytecode code,
- CtClass[] params, int regno) {
- return JvstCodeGen.compileParameterList(code, params, regno);
+ CtClass[] params, int regno) {
+ return JvstCodeGen.compileParameterList(code, params, regno);
}
/*
* The produced codes cosume 1 or 2 stack entries.
*/
private static void compileReturn(Bytecode code, CtClass type) {
- if (type.isPrimitive()) {
- CtPrimitiveType pt = (CtPrimitiveType)type;
- if (pt != CtClass.voidType) {
- String wrapper = pt.getWrapperName();
- code.addCheckcast(wrapper);
- code.addInvokevirtual(wrapper, pt.getGetMethodName(),
- pt.getGetMethodDescriptor());
- }
-
- code.addOpcode(pt.getReturnOp());
- }
- else {
- code.addCheckcast(type);
- code.addOpcode(Bytecode.ARETURN);
- }
+ if (type.isPrimitive()) {
+ CtPrimitiveType pt = (CtPrimitiveType)type;
+ if (pt != CtClass.voidType) {
+ String wrapper = pt.getWrapperName();
+ code.addCheckcast(wrapper);
+ code.addInvokevirtual(wrapper, pt.getGetMethodName(),
+ pt.getGetMethodDescriptor());
+ }
+
+ code.addOpcode(pt.getReturnOp());
+ }
+ else {
+ code.addCheckcast(type);
+ code.addOpcode(Bytecode.ARETURN);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
/**
private int dataSize;
CtPrimitiveType(String name, char desc, String wrapper,
- String methodName, String mDesc, int opcode, int atype,
- int size) {
- super(name);
- descriptor = desc;
- wrapperName = wrapper;
- getMethodName = methodName;
- mDescriptor = mDesc;
- returnOp = opcode;
- arrayType = atype;
- dataSize = size;
+ String methodName, String mDesc, int opcode, int atype,
+ int size) {
+ super(name);
+ descriptor = desc;
+ wrapperName = wrapper;
+ getMethodName = methodName;
+ mDescriptor = mDesc;
+ returnOp = opcode;
+ arrayType = atype;
+ dataSize = size;
}
/**
/*
- * This file is part of the Javassist toolkit.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
/**
* Main method.
*
- * @param args[0] class file name.
+ * @param args[0] class file name.
*/
public static void main(String[] args) throws Exception {
- if (args.length != 1) {
- System.err.println("Usage: java Dump <class file name>");
- return;
- }
+ if (args.length != 1) {
+ System.err.println("Usage: java Dump <class file name>");
+ return;
+ }
- DataInputStream in = new DataInputStream(
- new FileInputStream(args[0]));
- ClassFile w = new ClassFile(in);
- PrintWriter out = new PrintWriter(System.out, true);
- out.println("*** constant pool ***");
- w.getConstPool().print(out);
- out.println();
- out.println("*** members ***");
- ClassFileWriter.print(w, out);
+ DataInputStream in = new DataInputStream(
+ new FileInputStream(args[0]));
+ ClassFile w = new ClassFile(in);
+ PrintWriter out = new PrintWriter(System.out, true);
+ out.println("*** constant pool ***");
+ w.getConstPool().print(out);
+ out.println();
+ out.println("*** members ***");
+ ClassFileWriter.print(w, out);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
* @see javassist.Translator
*/
public class Loader extends ClassLoader {
- private Hashtable notDefinedHere; // must be atomic.
- private Vector notDefinedPackages; // must be atomic.
+ private Hashtable notDefinedHere; // must be atomic.
+ private Vector notDefinedPackages; // must be atomic.
private ClassPool source;
/**
* Creates a new class loader.
*/
public Loader() {
- this(null);
+ this(null);
}
/**
* Creates a new class loader.
*
- * @param cp the source of class files.
+ * @param cp the source of class files.
*/
public Loader(ClassPool cp) {
- notDefinedHere = new Hashtable();
- notDefinedPackages = new Vector();
- source = cp;
- delegateLoadingOf("javassist.Loader");
+ init(cp);
+ }
+
+ /**
+ * Creates a new class loader
+ * using the specified parent class loader for delegation.
+ *
+ * @param parent the parent class loader.
+ * @param cp the source of class files.
+ */
+ public Loader(ClassLoader parent, ClassPool cp) {
+ super(parent);
+ init(cp);
+ }
+
+ private void init(ClassPool cp) {
+ notDefinedHere = new Hashtable();
+ notDefinedPackages = new Vector();
+ source = cp;
+ delegateLoadingOf("javassist.Loader");
}
/**
* in that package and the sub packages are delegated.
*/
public void delegateLoadingOf(String classname) {
- if (classname.endsWith("."))
- notDefinedPackages.addElement(classname);
- else
- notDefinedHere.put(classname, this);
+ if (classname.endsWith("."))
+ notDefinedPackages.addElement(classname);
+ else
+ notDefinedHere.put(classname, this);
}
/**
* Sets the soruce <code>ClassPool</code>.
*/
public void setClassPool(ClassPool cp) {
- source = cp;
+ source = cp;
}
/**
*
* <p>This method calls <code>run()</code>.
*
- * @param args[0] class name to be loaded.
- * @param args[1-n] parameters passed to <code>main()</code>.
+ * @param args[0] class name to be loaded.
+ * @param args[1-n] parameters passed to <code>main()</code>.
*
* @see javassist.Loader#run(String[])
*/
public static void main(String[] args) throws Throwable {
- Loader cl = new Loader();
- cl.run(args);
+ Loader cl = new Loader();
+ cl.run(args);
}
/**
* Loads a class and calls <code>main()</code> in that class.
*
- * @param args[0] the name of the loaded class.
- * @param args[1-n] parameters passed to <code>main()</code>.
+ * @param args[0] the name of the loaded class.
+ * @param args[1-n] parameters passed to <code>main()</code>.
*/
public void run(String[] args) throws Throwable {
- int n = args.length - 1;
- if (n >= 0) {
- String[] args2 = new String[n];
- for (int i = 0; i < n; ++i)
- args2[i] = args[i + 1];
+ int n = args.length - 1;
+ if (n >= 0) {
+ String[] args2 = new String[n];
+ for (int i = 0; i < n; ++i)
+ args2[i] = args[i + 1];
- run(args[0], args2);
- }
+ run(args[0], args2);
+ }
}
/**
* Loads a class and calls <code>main()</code> in that class.
*
- * @param classname the loaded class.
- * @param args parameters passed to <code>main()</code>.
+ * @param classname the loaded class.
+ * @param args parameters passed to <code>main()</code>.
*/
public void run(String classname, String[] args) throws Throwable {
- Class c = loadClass(classname);
- try {
- c.getDeclaredMethod("main", new Class[] { String[].class })
- .invoke(null, new Object[] { args });
- }
- catch (java.lang.reflect.InvocationTargetException e) {
- throw e.getTargetException();
- }
+ Class c = loadClass(classname);
+ try {
+ c.getDeclaredMethod("main", new Class[] { String[].class })
+ .invoke(null, new Object[] { args });
+ }
+ catch (java.lang.reflect.InvocationTargetException e) {
+ throw e.getTargetException();
+ }
}
/**
* Requests the class loader to load a class.
*/
protected Class loadClass(String name, boolean resolve)
- throws ClassFormatError, ClassNotFoundException
+ throws ClassFormatError, ClassNotFoundException
{
- Class c = findLoadedClass(name);
- if (c == null)
- c = loadClassByDelegation(name);
+ Class c = findLoadedClass(name);
+ if (c == null)
+ c = loadClassByDelegation(name);
- if (c == null)
- c = findClass(name);
+ if (c == null)
+ c = findClass(name);
- if (c == null)
- c = delegateToParent(name);
+ if (c == null)
+ c = delegateToParent(name);
- if (resolve)
- resolveClass(c);
+ if (resolve)
+ resolveClass(c);
- return c;
+ return c;
}
/**
* <code>Loader</code>.
*/
protected Class findClass(String name) {
- byte[] classfile;
- try {
- if (source != null)
- classfile = source.write(name);
- else {
- String jarname = "/" + name.replace('.', '/') + ".class";
- InputStream in = this.getClass().getResourceAsStream(jarname);
+ byte[] classfile;
+ try {
+ if (source != null)
+ classfile = source.write(name);
+ else {
+ String jarname = "/" + name.replace('.', '/') + ".class";
+ InputStream in = this.getClass().getResourceAsStream(jarname);
- classfile = ClassPoolTail.readStream(in);
- }
- }
- catch (Exception e) {
- return null;
- }
+ classfile = ClassPoolTail.readStream(in);
+ }
+ }
+ catch (Exception e) {
+ return null;
+ }
- return defineClass(name, classfile, 0, classfile.length);
+ return defineClass(name, classfile, 0, classfile.length);
}
private Class loadClassByDelegation(String name)
- throws ClassNotFoundException
+ throws ClassNotFoundException
{
- /* The swing components must be loaded by a system
- * class loader.
- * javax.swing.UIManager loads a (concrete) subclass
- * of LookAndFeel by a system class loader and cast
- * an instance of the class to LookAndFeel for
- * (maybe) a security reason. To avoid failure of
- * type conversion, LookAndFeel must not be loaded
- * by this class loader.
- */
+ /* The swing components must be loaded by a system
+ * class loader.
+ * javax.swing.UIManager loads a (concrete) subclass
+ * of LookAndFeel by a system class loader and cast
+ * an instance of the class to LookAndFeel for
+ * (maybe) a security reason. To avoid failure of
+ * type conversion, LookAndFeel must not be loaded
+ * by this class loader.
+ */
- Class c = null;
- if (doDelegation)
- if (name.startsWith("java.") || name.startsWith("javax.")
- || name.startsWith("sun.") || name.startsWith("com.sun.")
- || notDelegated(name))
- c = delegateToParent(name);
+ Class c = null;
+ if (doDelegation)
+ if (name.startsWith("java.") || name.startsWith("javax.")
+ || name.startsWith("sun.") || name.startsWith("com.sun.")
+ || notDelegated(name))
+ c = delegateToParent(name);
- return c;
+ return c;
}
private boolean notDelegated(String name) {
- if (notDefinedHere.get(name) != null)
- return true;
+ if (notDefinedHere.get(name) != null)
+ return true;
- int n = notDefinedPackages.size();
- for (int i = 0; i < n; ++i)
- if (name.startsWith((String)notDefinedPackages.elementAt(i)))
- return true;
+ int n = notDefinedPackages.size();
+ for (int i = 0; i < n; ++i)
+ if (name.startsWith((String)notDefinedPackages.elementAt(i)))
+ return true;
- return false;
+ return false;
}
private Class delegateToParent(String classname)
- throws ClassNotFoundException
+ throws ClassNotFoundException
{
- ClassLoader cl = getParent();
- if (cl != null)
- return cl.loadClass(classname);
- else
- return findSystemClass(classname);
+ ClassLoader cl = getParent();
+ if (cl != null)
+ return cl.loadClass(classname);
+ else
+ return findSystemClass(classname);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import javassist.bytecode.AccessFlag;
* modifier.
*/
public static boolean isPublic(int mod) {
- return (mod & PUBLIC) != 0;
+ return (mod & PUBLIC) != 0;
}
/**
* modifier.
*/
public static boolean isPrivate(int mod) {
- return (mod & PRIVATE) != 0;
+ return (mod & PRIVATE) != 0;
}
/**
* modifier.
*/
public static boolean isProtected(int mod) {
- return (mod & PROTECTED) != 0;
+ return (mod & PROTECTED) != 0;
}
/**
* modifier.
*/
public static boolean isStatic(int mod) {
- return (mod & STATIC) != 0;
+ return (mod & STATIC) != 0;
}
/**
* modifier.
*/
public static boolean isFinal(int mod) {
- return (mod & FINAL) != 0;
+ return (mod & FINAL) != 0;
}
/**
* modifier.
*/
public static boolean isSynchronized(int mod) {
- return (mod & SYNCHRONIZED) != 0;
+ return (mod & SYNCHRONIZED) != 0;
}
/**
* modifier.
*/
public static boolean isVolatile(int mod) {
- return (mod & VOLATILE) != 0;
+ return (mod & VOLATILE) != 0;
}
/**
* modifier.
*/
public static boolean isTransient(int mod) {
- return (mod & TRANSIENT) != 0;
+ return (mod & TRANSIENT) != 0;
}
/**
* modifier.
*/
public static boolean isNative(int mod) {
- return (mod & NATIVE) != 0;
+ return (mod & NATIVE) != 0;
}
/**
* modifier.
*/
public static boolean isInterface(int mod) {
- return (mod & INTERFACE) != 0;
+ return (mod & INTERFACE) != 0;
}
/**
* modifier.
*/
public static boolean isAbstract(int mod) {
- return (mod & ABSTRACT) != 0;
+ return (mod & ABSTRACT) != 0;
}
/**
* modifier.
*/
public static boolean isStrict(int mod) {
- return (mod & STRICT) != 0;
+ return (mod & STRICT) != 0;
}
/**
* cleared.
*/
public static int setPublic(int mod) {
- return (mod & ~(PRIVATE | PROTECTED)) | PUBLIC;
+ return (mod & ~(PRIVATE | PROTECTED)) | PUBLIC;
}
/**
* cleared.
*/
public static int setProtected(int mod) {
- return (mod & ~(PRIVATE | PUBLIC)) | PROTECTED;
+ return (mod & ~(PRIVATE | PUBLIC)) | PROTECTED;
}
/**
* cleared.
*/
public static int setPrivate(int mod) {
- return (mod & ~(PROTECTED | PUBLIC)) | PRIVATE;
+ return (mod & ~(PROTECTED | PUBLIC)) | PRIVATE;
}
/**
* Clears the public, protected, and private bits.
*/
public static int setPackage(int mod) {
- return (mod & ~(PROTECTED | PUBLIC | PRIVATE));
+ return (mod & ~(PROTECTED | PUBLIC | PRIVATE));
}
/**
* Clears a specified bit in <code>mod</code>.
*/
public static int clear(int mod, int clearBit) {
- return mod & ~clearBit;
+ return mod & ~clearBit;
}
public static String toString(int mod) {
- return java.lang.reflect.Modifier.toString(mod);
+ return java.lang.reflect.Modifier.toString(mod);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
/**
*/
public class NotFoundException extends Exception {
public NotFoundException(String msg) {
- super(msg);
+ super(msg);
}
public NotFoundException(String msg, Exception e) {
- super(msg + " because of " + e.toString());
+ super(msg + " because of " + e.toString());
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
* modifying a class to maintain serialization compatability.
*/
public static void setSerialVersionUID(CtClass clazz)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- // check for pre-existing field.
- try {
- clazz.getDeclaredField("serialVersionUID");
- return;
- }
- catch (NotFoundException e) {}
-
- // check if the class is serializable.
- if (!isSerializable(clazz))
- return;
+ // check for pre-existing field.
+ try {
+ clazz.getDeclaredField("serialVersionUID");
+ return;
+ }
+ catch (NotFoundException e) {}
+
+ // check if the class is serializable.
+ if (!isSerializable(clazz))
+ return;
- // add field with default value.
- CtField field = new CtField(CtClass.longType, "serialVersionUID",
- clazz);
- field.setModifiers(Modifier.PRIVATE | Modifier.STATIC |
- Modifier.FINAL);
- clazz.addField(field, calculateDefault(clazz) + "L");
+ // add field with default value.
+ CtField field = new CtField(CtClass.longType, "serialVersionUID",
+ clazz);
+ field.setModifiers(Modifier.PRIVATE | Modifier.STATIC |
+ Modifier.FINAL);
+ clazz.addField(field, calculateDefault(clazz) + "L");
}
/**
* Does the class implement Serializable?
*/
private static boolean isSerializable(CtClass clazz)
- throws NotFoundException
+ throws NotFoundException
{
ClassPool pool = clazz.getClassPool();
- return clazz.subtypeOf(pool.get("java.io.Serializable"));
+ return clazz.subtypeOf(pool.get("java.io.Serializable"));
}
/**
* Unique Identifiers.
*/
static long calculateDefault(CtClass clazz)
- throws CannotCompileException
+ throws CannotCompileException
{
- try {
+ try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bout);
ClassFile classFile = clazz.getClassFile();
CtConstructor[] constructors = clazz.getDeclaredConstructors();
Arrays.sort(constructors, new Comparator() {
public int compare(Object o1, Object o2) {
- CtConstructor c1 = (CtConstructor)o1;
- CtConstructor c2 = (CtConstructor)o2;
- return c1.getMethodInfo2().getDescriptor().compareTo(
- c2.getMethodInfo2().getDescriptor());
- }
- });
+ CtConstructor c1 = (CtConstructor)o1;
+ CtConstructor c2 = (CtConstructor)o2;
+ return c1.getMethodInfo2().getDescriptor().compareTo(
+ c2.getMethodInfo2().getDescriptor());
+ }
+ });
for (int i = 0; i < constructors.length; i++) {
CtConstructor constructor = constructors[i];
out.writeUTF("<init>");
out.writeInt(mods);
out.writeUTF(constructor.getMethodInfo2()
- .getDescriptor().replace('/', '.'));
+ .getDescriptor().replace('/', '.'));
}
}
CtMethod[] methods = clazz.getDeclaredMethods();
Arrays.sort(methods, new Comparator() {
public int compare(Object o1, Object o2) {
- CtMethod m1 = (CtMethod)o1;
- CtMethod m2 = (CtMethod)o2;
- int value = m1.getName().compareTo(m2.getName());
- if (value == 0)
- value = m1.getMethodInfo2().getDescriptor()
- .compareTo(m2.getMethodInfo2().getDescriptor());
-
- return value;
- }
+ CtMethod m1 = (CtMethod)o1;
+ CtMethod m2 = (CtMethod)o2;
+ int value = m1.getName().compareTo(m2.getName());
+ if (value == 0)
+ value = m1.getMethodInfo2().getDescriptor()
+ .compareTo(m2.getMethodInfo2().getDescriptor());
+
+ return value;
+ }
});
for (int i = 0; i < methods.length; i++) {
out.writeUTF(method.getName());
out.writeInt(mods);
out.writeUTF(method.getMethodInfo2()
- .getDescriptor().replace('/', '.'));
+ .getDescriptor().replace('/', '.'));
}
}
hash = (hash << 8) | (digested[i] & 0xFF);
return hash;
- }
- catch (IOException e) {
- throw new CannotCompileException(e);
- }
- catch (NoSuchAlgorithmException e) {
- throw new CannotCompileException(e);
- }
+ }
+ catch (IOException e) {
+ throw new CannotCompileException(e);
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CannotCompileException(e);
+ }
}
private static String javaName(CtClass clazz) {
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
/**
* Is invoked by a <code>ClassPool</code> for initialization
* when the object is attached to a <code>ClassPool</code> object.
*
- * @param pool the <code>ClassPool</code> that this translator
- * is attached to.
+ * @param pool the <code>ClassPool</code> that this translator
+ * is attached to.
*
* @see ClassPool#ClassPool(ClassPool,Translator)
* @see ClassPool#getDefault(Translator)
*/
void start(ClassPool pool)
- throws NotFoundException, CannotCompileException;
+ throws NotFoundException, CannotCompileException;
/**
* Is invoked by a <code>ClassPool</code> for notifying that
* <p>If CtClass.frozen() is true, that is, if the class has been
* already modified and written, then onWrite() is not invoked.
*
- * @param pool the <code>ClassPool</code> that this translator
- * is attached to.
- * @param classname a fully-qualified class name
+ * @param pool the <code>ClassPool</code> that this translator
+ * is attached to.
+ * @param classname a fully-qualified class name
*
* @see ClassPool#writeFile(String)
* @see ClassPool#writeFile(String, String)
* @see ClassPool#write(String,DataOutputStream)
*/
void onWrite(ClassPool pool, String classname)
- throws NotFoundException, CannotCompileException;
+ throws NotFoundException, CannotCompileException;
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist;
import java.io.*;
protected String directory;
protected String packageName;
- /*
+ /**
* Creates a search path specified with URL (http).
*
* <p>This search path is used only if a requested
* If <code>packageName</code> is <code>null</code>, the URL is used
* for loading any class.
*
- * @param host host name
- * @param port port number
- * @param directory directory name ending with "/".
- * It can be "/" (root directory).
- * @param packageName package name.
+ * @param host host name
+ * @param port port number
+ * @param directory directory name ending with "/".
+ * It can be "/" (root directory).
+ * @param packageName package name.
*/
public URLClassPath(String host, int port,
- String directory, String packageName) {
- hostname = host;
- this.port = port;
- this.directory = directory;
- this.packageName = packageName;
+ String directory, String packageName) {
+ hostname = host;
+ this.port = port;
+ this.directory = directory;
+ this.packageName = packageName;
}
public String toString() {
- return hostname + ":" + port + directory;
+ return hostname + ":" + port + directory;
}
/**
* Opens a class file with http.
*/
public InputStream openClassfile(String classname) {
- try {
- if (packageName == null || classname.startsWith(packageName)) {
- String jarname
- = directory + classname.replace('.', '/') + ".class";
- URLConnection con = fetchClass0(hostname, port, jarname);
- return con.getInputStream();
- }
- }
- catch (IOException e) {}
- return null; // not found
+ try {
+ if (packageName == null || classname.startsWith(packageName)) {
+ String jarname
+ = directory + classname.replace('.', '/') + ".class";
+ URLConnection con = fetchClass0(hostname, port, jarname);
+ return con.getInputStream();
+ }
+ }
+ catch (IOException e) {}
+ return null; // not found
}
+ /**
+ * Closes this class path.
+ */
+ public void close() {}
+
/**
* Reads a class file on an http server.
*
- * @param host host name
- * @param port port number
- * @param directory directory name ending with "/".
- * It can be "/" (root directory).
- * @param classname fully-qualified class name
+ * @param host host name
+ * @param port port number
+ * @param directory directory name ending with "/".
+ * It can be "/" (root directory).
+ * @param classname fully-qualified class name
*/
public static byte[] fetchClass(String host, int port,
- String directory, String classname)
- throws IOException
+ String directory, String classname)
+ throws IOException
{
- byte[] b;
- URLConnection con = fetchClass0(host, port,
- directory + classname.replace('.', '/') + ".class");
- int size = con.getContentLength();
- InputStream s = con.getInputStream();
- if (size <= 0)
- b = ClassPoolTail.readStream(s);
- else {
- b = new byte[size];
- int len = 0;
- do {
- int n = s.read(b, len, size - len);
- if (n < 0) {
- s.close();
- throw new IOException("the stream was closed: "
- + classname);
- }
- len += n;
- } while (len < size);
- }
+ byte[] b;
+ URLConnection con = fetchClass0(host, port,
+ directory + classname.replace('.', '/') + ".class");
+ int size = con.getContentLength();
+ InputStream s = con.getInputStream();
+ if (size <= 0)
+ b = ClassPoolTail.readStream(s);
+ else {
+ b = new byte[size];
+ int len = 0;
+ do {
+ int n = s.read(b, len, size - len);
+ if (n < 0) {
+ s.close();
+ throw new IOException("the stream was closed: "
+ + classname);
+ }
+ len += n;
+ } while (len < size);
+ }
- s.close();
- return b;
+ s.close();
+ return b;
}
private static URLConnection fetchClass0(String host, int port,
- String filename)
- throws IOException
+ String filename)
+ throws IOException
{
- URL url;
- try {
- url = new URL("http", host, port, filename);
- }
- catch (MalformedURLException e) {
- // should never reache here.
- throw new IOException("invalid URL?");
- }
+ URL url;
+ try {
+ url = new URL("http", host, port, filename);
+ }
+ catch (MalformedURLException e) {
+ // should never reache here.
+ throw new IOException("invalid URL?");
+ }
- URLConnection con = url.openConnection();
- con.connect();
- return con;
+ URLConnection con = url.openConnection();
+ con.connect();
+ return con;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
/**
* cleared.
*/
public static int setPublic(int accflags) {
- return (accflags & ~(PRIVATE | PROTECTED)) | PUBLIC;
+ return (accflags & ~(PRIVATE | PROTECTED)) | PUBLIC;
}
/**
* cleared.
*/
public static int setProtected(int accflags) {
- return (accflags & ~(PRIVATE | PUBLIC)) | PROTECTED;
+ return (accflags & ~(PRIVATE | PUBLIC)) | PROTECTED;
}
/**
* cleared.
*/
public static int setPrivate(int accflags) {
- return (accflags & ~(PROTECTED | PUBLIC)) | PRIVATE;
+ return (accflags & ~(PROTECTED | PUBLIC)) | PRIVATE;
}
/**
* Clears the public, protected, and private bits.
*/
public static int setPackage(int accflags) {
- return (accflags & ~(PROTECTED | PUBLIC | PRIVATE));
+ return (accflags & ~(PROTECTED | PUBLIC | PRIVATE));
}
/**
* Clears a specified bit in <code>accflags</code>.
*/
public static int clear(int accflags, int clearBit) {
- return accflags & ~clearBit;
+ return accflags & ~clearBit;
}
/**
* Converts a javassist.Modifier into
* a javassist.bytecode.AccessFlag.
*
- * @param modifier javassist.Modifier
+ * @param modifier javassist.Modifier
*/
public static int of(int modifier) {
- return modifier;
+ return modifier;
}
/**
* Converts a javassist.bytecode.AccessFlag
* into a javassist.Modifier.
*
- * @param accflags javassist.bytecode.Accessflag
+ * @param accflags javassist.bytecode.Accessflag
*/
public static int toModifier(int accflags) {
- return accflags;
+ return accflags;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
import java.util.ListIterator;
// Note: if you define a new subclass of AttributeInfo, then
-// update AttributeInfo.read().
+// update AttributeInfo.read().
/**
* <code>attribute_info</code> structure.
byte[] info;
protected AttributeInfo(ConstPool cp, int attrname, byte[] attrinfo) {
- constPool = cp;
- name = attrname;
- info = attrinfo;
+ constPool = cp;
+ name = attrname;
+ info = attrinfo;
}
protected AttributeInfo(ConstPool cp, String attrname) {
- this(cp, attrname, (byte[])null);
+ this(cp, attrname, (byte[])null);
}
/**
* Constructs an <code>attribute_info</code> structure.
*
- * @param cp constant pool table
- * @param attrname attribute name
- * @param attrinfo <code>info</code> field
- * of <code>attribute_info</code> structure.
+ * @param cp constant pool table
+ * @param attrname attribute name
+ * @param attrinfo <code>info</code> field
+ * of <code>attribute_info</code> structure.
*/
public AttributeInfo(ConstPool cp, String attrname, byte[] attrinfo) {
- this(cp, cp.addUtf8Info(attrname), attrinfo);
+ this(cp, cp.addUtf8Info(attrname), attrinfo);
}
protected AttributeInfo(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- constPool = cp;
- name = n;
- int len = in.readInt();
- info = new byte[len];
- if (len > 0)
- in.readFully(info);
+ constPool = cp;
+ name = n;
+ int len = in.readInt();
+ info = new byte[len];
+ if (len > 0)
+ in.readFully(info);
}
static AttributeInfo read(ConstPool cp, DataInputStream in)
- throws IOException
+ throws IOException
{
- int name = in.readUnsignedShort();
- String nameStr = cp.getUtf8Info(name);
- if (nameStr.equals(CodeAttribute.tag))
- return new CodeAttribute(cp, name, in);
- else if (nameStr.equals(ExceptionsAttribute.tag))
- return new ExceptionsAttribute(cp, name, in);
- else if (nameStr.equals(ConstantAttribute.tag))
- return new ConstantAttribute(cp, name, in);
- else if (nameStr.equals(SourceFileAttribute.tag))
- return new SourceFileAttribute(cp, name, in);
- else if (nameStr.equals(LineNumberAttribute.tag))
- return new LineNumberAttribute(cp, name, in);
- else if (nameStr.equals(SyntheticAttribute.tag))
- return new SyntheticAttribute(cp, name, in);
- else if (nameStr.equals(InnerClassesAttribute.tag))
- return new InnerClassesAttribute(cp, name, in);
- else
- return new AttributeInfo(cp, name, in);
+ int name = in.readUnsignedShort();
+ String nameStr = cp.getUtf8Info(name);
+ if (nameStr.equals(CodeAttribute.tag))
+ return new CodeAttribute(cp, name, in);
+ else if (nameStr.equals(ExceptionsAttribute.tag))
+ return new ExceptionsAttribute(cp, name, in);
+ else if (nameStr.equals(ConstantAttribute.tag))
+ return new ConstantAttribute(cp, name, in);
+ else if (nameStr.equals(SourceFileAttribute.tag))
+ return new SourceFileAttribute(cp, name, in);
+ else if (nameStr.equals(LineNumberAttribute.tag))
+ return new LineNumberAttribute(cp, name, in);
+ else if (nameStr.equals(SyntheticAttribute.tag))
+ return new SyntheticAttribute(cp, name, in);
+ else if (nameStr.equals(InnerClassesAttribute.tag))
+ return new InnerClassesAttribute(cp, name, in);
+ else
+ return new AttributeInfo(cp, name, in);
}
/**
* Returns an attribute name.
*/
public String getName() {
- return constPool.getUtf8Info(name);
+ return constPool.getUtf8Info(name);
}
/**
* The returned value is <code>attribute_length + 6</code>.
*/
public int length() {
- return info.length + 6;
+ return info.length + 6;
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- int s = info.length;
- byte[] newInfo = new byte[s];
- for (int i = 0; i < s; ++i)
- newInfo[i] = info[i];
+ int s = info.length;
+ byte[] newInfo = new byte[s];
+ for (int i = 0; i < s; ++i)
+ newInfo[i] = info[i];
- return new AttributeInfo(newCp, getName(), newInfo);
+ return new AttributeInfo(newCp, getName(), newInfo);
}
void write(DataOutputStream out) throws IOException {
- out.writeShort(name);
- out.writeInt(info.length);
- if (info.length > 0)
- out.write(info);
+ out.writeShort(name);
+ out.writeInt(info.length);
+ if (info.length > 0)
+ out.write(info);
}
static int getLength(LinkedList list) {
- int size = 0;
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- AttributeInfo attr = (AttributeInfo)list.get(i);
- size += attr.length();
- }
-
- return size;
+ int size = 0;
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ AttributeInfo attr = (AttributeInfo)list.get(i);
+ size += attr.length();
+ }
+
+ return size;
}
static AttributeInfo lookup(LinkedList list, String name) {
- if (list == null)
- return null;
+ if (list == null)
+ return null;
- ListIterator iterator = list.listIterator();
- while (iterator.hasNext()) {
- AttributeInfo ai = (AttributeInfo)iterator.next();
- if (ai.getName().equals(name))
- return ai;
- }
+ ListIterator iterator = list.listIterator();
+ while (iterator.hasNext()) {
+ AttributeInfo ai = (AttributeInfo)iterator.next();
+ if (ai.getName().equals(name))
+ return ai;
+ }
- return null; // no such attribute
+ return null; // no such attribute
}
static AttributeInfo lookup(LinkedList list, Class type) {
- if (list == null)
- return null;
+ if (list == null)
+ return null;
- ListIterator iterator = list.listIterator();
- while (iterator.hasNext()) {
- Object obj = iterator.next();
- if (type.isInstance(obj))
- return (AttributeInfo)obj;
- }
+ ListIterator iterator = list.listIterator();
+ while (iterator.hasNext()) {
+ Object obj = iterator.next();
+ if (type.isInstance(obj))
+ return (AttributeInfo)obj;
+ }
- return null; // no such attribute
+ return null; // no such attribute
}
static synchronized void remove(LinkedList list, String name) {
- if (list == null)
- return;
-
- ListIterator iterator = list.listIterator();
- while (iterator.hasNext()) {
- AttributeInfo ai = (AttributeInfo)iterator.next();
- if (ai.getName().equals(name))
- iterator.remove();
- }
+ if (list == null)
+ return;
+
+ ListIterator iterator = list.listIterator();
+ while (iterator.hasNext()) {
+ AttributeInfo ai = (AttributeInfo)iterator.next();
+ if (ai.getName().equals(name))
+ iterator.remove();
+ }
}
static synchronized void remove(LinkedList list, Class type) {
- if (list == null)
- return;
-
- ListIterator iterator = list.listIterator();
- while (iterator.hasNext()) {
- Object obj = iterator.next();
- if (type.isInstance(obj))
- iterator.remove();
- }
+ if (list == null)
+ return;
+
+ ListIterator iterator = list.listIterator();
+ while (iterator.hasNext()) {
+ Object obj = iterator.next();
+ if (type.isInstance(obj))
+ iterator.remove();
+ }
}
static void writeAll(LinkedList list, DataOutputStream out)
- throws IOException
+ throws IOException
{
- if (list == null)
- return;
-
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- AttributeInfo attr = (AttributeInfo)list.get(i);
- attr.write(out);
- }
+ if (list == null)
+ return;
+
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ AttributeInfo attr = (AttributeInfo)list.get(i);
+ attr.write(out);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
/**
*/
public class BadBytecode extends Exception {
public BadBytecode(int opcode) {
- super("bytecode " + opcode);
+ super("bytecode " + opcode);
}
public BadBytecode(String msg) {
- super(msg);
+ super(msg);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
/**
* Reads an unsigned 16bit integer at the index.
*/
public static int readU16bit(byte[] code, int index) {
- return ((code[index] & 0xff) << 8) | (code[index + 1] & 0xff);
+ return ((code[index] & 0xff) << 8) | (code[index + 1] & 0xff);
}
/**
* Reads a signed 16bit integer at the index.
*/
public static int readS16bit(byte[] code, int index) {
- return (code[index] << 8) | (code[index + 1] & 0xff);
+ return (code[index] << 8) | (code[index + 1] & 0xff);
}
/**
* Writes a 16bit integer at the index.
*/
public static void write16bit(int value, byte[] code, int index) {
- code[index] = (byte)(value >>> 8);
- code[index + 1] = (byte)value;
+ code[index] = (byte)(value >>> 8);
+ code[index + 1] = (byte)value;
}
/**
* Reads a 32bit integer at the index.
*/
public static int read32bit(byte[] code, int index) {
- return (code[index] << 24) | ((code[index + 1] & 0xff) << 16)
- | ((code[index + 2] & 0xff) << 8) | (code[index + 3] & 0xff);
+ return (code[index] << 24) | ((code[index + 1] & 0xff) << 16)
+ | ((code[index + 2] & 0xff) << 8) | (code[index + 3] & 0xff);
}
/**
* Writes a 32bit integer at the index.
*/
public static void write32bit(int value, byte[] code, int index) {
- code[index] = (byte)(value >>> 24);
- code[index + 1] = (byte)(value >>> 16);
- code[index + 2] = (byte)(value >>> 8);
- code[index + 3] = (byte)value;
+ code[index] = (byte)(value >>> 24);
+ code[index + 1] = (byte)(value >>> 16);
+ code[index + 2] = (byte)(value >>> 8);
+ code[index + 3] = (byte)value;
}
/**
* Copies a 32bit integer.
*
- * @param src the source byte array.
- * @param isrc the index into the source byte array.
- * @param dest the destination byte array.
- * @param idest the index into the destination byte array.
+ * @param src the source byte array.
+ * @param isrc the index into the source byte array.
+ * @param dest the destination byte array.
+ * @param idest the index into the destination byte array.
*/
static void copy32bit(byte[] src, int isrc, byte[] dest, int idest) {
- dest[idest] = src[isrc];
- dest[idest + 1] = src[isrc + 1];
- dest[idest + 2] = src[isrc + 2];
- dest[idest + 3] = src[isrc + 3];
+ dest[idest] = src[isrc];
+ dest[idest + 1] = src[isrc + 1];
+ dest[idest + 2] = src[isrc + 2];
+ dest[idest + 3] = src[isrc + 3];
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataOutputStream;
* of <code>max_stack</code> and <code>max_locals</code>.
* They can be changed later.
*
- * @param cp constant pool table.
- * @param stacksize <code>max_stack</code>.
- * @param localvars <code>max_locals</code>.
+ * @param cp constant pool table.
+ * @param stacksize <code>max_stack</code>.
+ * @param localvars <code>max_locals</code>.
*/
public Bytecode(ConstPool cp, int stacksize, int localvars) {
- this();
- constPool = cp;
- maxStack = stacksize;
- maxLocals = localvars;
- tryblocks = new ExceptionTable(cp);
- stackDepth = 0;
+ this();
+ constPool = cp;
+ maxStack = stacksize;
+ maxLocals = localvars;
+ tryblocks = new ExceptionTable(cp);
+ stackDepth = 0;
}
/* used in add().
*/
private Bytecode() {
- buffer = new byte[bufsize];
- num = 0;
- next = null;
+ buffer = new byte[bufsize];
+ num = 0;
+ next = null;
}
/**
* Converts to a <code>CodeAttribute</code>.
*/
public CodeAttribute toCodeAttribute() {
- return new CodeAttribute(constPool, maxStack, maxLocals,
- get(), tryblocks);
+ return new CodeAttribute(constPool, maxStack, maxLocals,
+ get(), tryblocks);
}
/**
* Returns the length of the bytecode sequence.
*/
public int length() {
- int len = 0;
- Bytecode b = this;
- while (b != null) {
- len += b.num;
- b = b.next;
- }
+ int len = 0;
+ Bytecode b = this;
+ while (b != null) {
+ len += b.num;
+ b = b.next;
+ }
- return len;
+ return len;
}
private void copy(byte[] dest, int index) {
- Bytecode b = this;
- while (b != null) {
- System.arraycopy(b.buffer, 0, dest, index, b.num);
- index += b.num;
- b = b.next;
- }
+ Bytecode b = this;
+ while (b != null) {
+ System.arraycopy(b.buffer, 0, dest, index, b.num);
+ index += b.num;
+ b = b.next;
+ }
}
/**
* Returns the produced bytecode sequence.
*/
public byte[] get() {
- byte[] b = new byte[length()];
- copy(b, 0);
- return b;
+ byte[] b = new byte[length()];
+ copy(b, 0);
+ return b;
}
/**
* @see #addOpcode(int)
*/
public void setMaxStack(int size) {
- maxStack = size;
+ maxStack = size;
}
/**
* Sets <code>max_locals</code>.
*/
public void setMaxLocals(int size) {
- maxLocals = size;
+ maxLocals = size;
}
/**
* used to pass method parameters and sets <code>max_locals</code>
* to that number plus <code>locals</code>.
*
- * @param isStatic true if <code>params</code> must be
- * interpreted as parameters to a static method.
- * @param params parameter types.
- * @param locals the number of local variables excluding
- * ones used to pass parameters.
+ * @param isStatic true if <code>params</code> must be
+ * interpreted as parameters to a static method.
+ * @param params parameter types.
+ * @param locals the number of local variables excluding
+ * ones used to pass parameters.
*/
public void setMaxLocals(boolean isStatic, CtClass[] params,
- int locals) {
- if (!isStatic)
- ++locals;
+ int locals) {
+ if (!isStatic)
+ ++locals;
- if (params != null) {
- CtClass doubleType = CtClass.doubleType;
- CtClass longType = CtClass.longType;
- int n = params.length;
- for (int i = 0; i < n; ++i) {
- CtClass type = params[i];
- if (type == doubleType || type == longType)
- locals += 2;
- else
- ++locals;
- }
- }
+ if (params != null) {
+ CtClass doubleType = CtClass.doubleType;
+ CtClass longType = CtClass.longType;
+ int n = params.length;
+ for (int i = 0; i < n; ++i) {
+ CtClass type = params[i];
+ if (type == doubleType || type == longType)
+ locals += 2;
+ else
+ ++locals;
+ }
+ }
- maxLocals = locals;
+ maxLocals = locals;
}
/**
* Increments <code>max_locals</code>.
*/
public void incMaxLocals(int diff) {
- maxLocals += diff;
+ maxLocals += diff;
}
/**
* Adds a new entry of <code>exception_table</code>.
*/
public void addExceptionHandler(int start, int end,
- int handler, CtClass type) {
- addExceptionHandler(start, end, handler,
- constPool.addClassInfo(type));
+ int handler, CtClass type) {
+ addExceptionHandler(start, end, handler,
+ constPool.addClassInfo(type));
}
/**
* Adds a new entry of <code>exception_table</code>.
*/
public void addExceptionHandler(int start, int end,
- int handler, int type) {
- tryblocks.add(start, end, handler, type);
+ int handler, int type) {
+ tryblocks.add(start, end, handler, type);
}
/**
* that have been added so far.
*/
public int currentPc() {
- int n = 0;
- Bytecode b = this;
- while (b != null) {
- n += b.num;
- b = b.next;
- }
+ int n = 0;
+ Bytecode b = this;
+ while (b != null) {
+ n += b.num;
+ b = b.next;
+ }
- return n;
+ return n;
}
/**
* Reads a signed 8bit value at the offset from the beginning of the
* bytecode sequence.
*
- * @throws ArrayIndexOutOfBoundsException if offset is invalid.
+ * @throws ArrayIndexOutOfBoundsException if offset is invalid.
*/
public int read(int offset) {
- if (offset < 0)
- return Opcode.NOP;
- else if (offset < num)
- return buffer[offset];
- else
- try {
- return next.read(offset - num);
- }
- catch (NullPointerException e) {
- throw new ArrayIndexOutOfBoundsException(offset);
- }
+ if (offset < 0)
+ return Opcode.NOP;
+ else if (offset < num)
+ return buffer[offset];
+ else
+ try {
+ return next.read(offset - num);
+ }
+ catch (NullPointerException e) {
+ throw new ArrayIndexOutOfBoundsException(offset);
+ }
}
/**
* bytecode sequence.
*/
public int read16bit(int offset) {
- int v1 = read(offset);
- int v2 = read(offset + 1);
- return (v1 << 8) + (v2 & 0xff);
+ int v1 = read(offset);
+ int v2 = read(offset + 1);
+ return (v1 << 8) + (v2 & 0xff);
}
/**
* Writes an 8bit value at the offset from the beginning of the
* bytecode sequence.
*
- * @throws ArrayIndexOutOfBoundsException if offset is invalid.
+ * @throws ArrayIndexOutOfBoundsException if offset is invalid.
*/
public void write(int offset, int value) {
- if (offset < num)
- buffer[offset] = (byte)value;
- else
- try {
- next.write(offset - num, value);
- }
- catch (NullPointerException e) {
- throw new ArrayIndexOutOfBoundsException(offset);
- }
+ if (offset < num)
+ buffer[offset] = (byte)value;
+ else
+ try {
+ next.write(offset - num, value);
+ }
+ catch (NullPointerException e) {
+ throw new ArrayIndexOutOfBoundsException(offset);
+ }
}
/**
* bytecode sequence.
*/
public void write16bit(int offset, int value) {
- write(offset, value >>> 8);
- write(offset + 1, value);
+ write(offset, value >>> 8);
+ write(offset + 1, value);
}
/**
* Appends an 8bit value to the end of the bytecode sequence.
*/
public void add(int code) {
- if (num < bufsize)
- buffer[num++] = (byte)code;
- else {
- if (next == null)
- next = new Bytecode();
+ if (num < bufsize)
+ buffer[num++] = (byte)code;
+ else {
+ if (next == null)
+ next = new Bytecode();
- next.add(code);
- }
+ next.add(code);
+ }
}
/**
* <code>growStack()</code> must be explicitly called.
*/
public void addOpcode(int code) {
- add(code);
- growStack(STACK_GROW[code]);
+ add(code);
+ growStack(STACK_GROW[code]);
}
/**
* It also updates <code>max_stack</code> if the current stack depth
* is the deepest so far.
*
- * @param diff the number added to the current stack depth.
+ * @param diff the number added to the current stack depth.
*/
public void growStack(int diff) {
- setStackDepth(stackDepth + diff);
+ setStackDepth(stackDepth + diff);
}
/**
* It also updates <code>max_stack</code> if the current stack depth
* is the deepest so far.
*
- * @param depth new value.
+ * @param depth new value.
*/
public void setStackDepth(int depth) {
- stackDepth = depth;
- if (stackDepth > maxStack)
- maxStack = stackDepth;
+ stackDepth = depth;
+ if (stackDepth > maxStack)
+ maxStack = stackDepth;
}
/**
* It never changes the current stack depth.
*/
public void addIndex(int index) {
- add(index >> 8);
- add(index);
+ add(index >> 8);
+ add(index);
}
/**
* Appends ALOAD or (WIDE) ALOAD_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addAload(int n) {
- if (n < 4)
- addOpcode(42 + n); // aload_<n>
- else if (n < 0x100) {
- addOpcode(ALOAD); // aload
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(ALOAD);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(42 + n); // aload_<n>
+ else if (n < 0x100) {
+ addOpcode(ALOAD); // aload
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(ALOAD);
+ addIndex(n);
+ }
}
/**
* Appends ASTORE or (WIDE) ASTORE_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addAstore(int n) {
- if (n < 4)
- addOpcode(75 + n); // astore_<n>
- else if (n < 0x100) {
- addOpcode(ASTORE); // astore
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(ASTORE);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(75 + n); // astore_<n>
+ else if (n < 0x100) {
+ addOpcode(ASTORE); // astore
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(ASTORE);
+ addIndex(n);
+ }
}
/**
* Appends ICONST or ICONST_<n>
*
- * @param n the pushed integer constant.
+ * @param n the pushed integer constant.
*/
public void addIconst(int n) {
- if (n < 6 && -2 < n)
- addOpcode(3 + n); // iconst_<i> -1..5
- else if (n <= 127 && -128 <= n) {
- addOpcode(16); // bipush
- add(n);
- }
- else if (n <= 32767 && -32768 <= n) {
- addOpcode(17); // sipush
- add(n >> 8);
- add(n);
- }
- else
- addLdc(constPool.addIntegerInfo(n));
+ if (n < 6 && -2 < n)
+ addOpcode(3 + n); // iconst_<i> -1..5
+ else if (n <= 127 && -128 <= n) {
+ addOpcode(16); // bipush
+ add(n);
+ }
+ else if (n <= 32767 && -32768 <= n) {
+ addOpcode(17); // sipush
+ add(n >> 8);
+ add(n);
+ }
+ else
+ addLdc(constPool.addIntegerInfo(n));
}
/**
* Appends ILOAD or (WIDE) ILOAD_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addIload(int n) {
- if (n < 4)
- addOpcode(26 + n); // iload_<n>
- else if (n < 0x100) {
- addOpcode(ILOAD); // iload
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(ILOAD);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(26 + n); // iload_<n>
+ else if (n < 0x100) {
+ addOpcode(ILOAD); // iload
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(ILOAD);
+ addIndex(n);
+ }
}
/**
* Appends ISTORE or (WIDE) ISTORE_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addIstore(int n) {
- if (n < 4)
- addOpcode(59 + n); // istore_<n>
- else if (n < 0x100) {
- addOpcode(ISTORE); // istore
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(ISTORE);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(59 + n); // istore_<n>
+ else if (n < 0x100) {
+ addOpcode(ISTORE); // istore
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(ISTORE);
+ addIndex(n);
+ }
}
/**
* Appends LCONST or LCONST_<n>
*
- * @param n the pushed long integer constant.
+ * @param n the pushed long integer constant.
*/
public void addLconst(long n) {
- if (n == 0 || n == 1)
- addOpcode(9 + (int)n); // lconst_<n>
- else
- addLdc2w(n);
+ if (n == 0 || n == 1)
+ addOpcode(9 + (int)n); // lconst_<n>
+ else
+ addLdc2w(n);
}
/**
* Appends LLOAD or (WIDE) LLOAD_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addLload(int n) {
- if (n < 4)
- addOpcode(30 + n); // lload_<n>
- else if (n < 0x100) {
- addOpcode(LLOAD); // lload
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(LLOAD);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(30 + n); // lload_<n>
+ else if (n < 0x100) {
+ addOpcode(LLOAD); // lload
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(LLOAD);
+ addIndex(n);
+ }
}
/**
* Appends LSTORE or LSTORE_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addLstore(int n) {
- if (n < 4)
- addOpcode(63 + n); // lstore_<n>
- else if (n < 0x100) {
- addOpcode(LSTORE); // lstore
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(LSTORE);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(63 + n); // lstore_<n>
+ else if (n < 0x100) {
+ addOpcode(LSTORE); // lstore
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(LSTORE);
+ addIndex(n);
+ }
}
/**
* Appends DCONST or DCONST_<n>
*
- * @param d the pushed double constant.
+ * @param d the pushed double constant.
*/
public void addDconst(double d) {
- if (d == 0.0 || d == 1.0)
- addOpcode(14 + (int)d); // dconst_<n>
- else
- addLdc2w(d);
+ if (d == 0.0 || d == 1.0)
+ addOpcode(14 + (int)d); // dconst_<n>
+ else
+ addLdc2w(d);
}
/**
* Appends DLOAD or (WIDE) DLOAD_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addDload(int n) {
- if (n < 4)
- addOpcode(38 + n); // dload_<n>
- else if (n < 0x100) {
- addOpcode(DLOAD); // dload
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(DLOAD);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(38 + n); // dload_<n>
+ else if (n < 0x100) {
+ addOpcode(DLOAD); // dload
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(DLOAD);
+ addIndex(n);
+ }
}
/**
* Appends DSTORE or (WIDE) DSTORE_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addDstore(int n) {
- if (n < 4)
- addOpcode(71 + n); // dstore_<n>
- else if (n < 0x100) {
- addOpcode(DSTORE); // dstore
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(DSTORE);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(71 + n); // dstore_<n>
+ else if (n < 0x100) {
+ addOpcode(DSTORE); // dstore
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(DSTORE);
+ addIndex(n);
+ }
}
/**
* Appends FCONST or FCONST_<n>
*
- * @param f the pushed float constant.
+ * @param f the pushed float constant.
*/
public void addFconst(float f) {
- if (f == 0.0f || f == 1.0f || f == 2.0f)
- addOpcode(11 + (int)f); // fconst_<n>
- else
- addLdc(constPool.addFloatInfo(f));
+ if (f == 0.0f || f == 1.0f || f == 2.0f)
+ addOpcode(11 + (int)f); // fconst_<n>
+ else
+ addLdc(constPool.addFloatInfo(f));
}
/**
* Appends FLOAD or (WIDE) FLOAD_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addFload(int n) {
- if (n < 4)
- addOpcode(34 + n); // fload_<n>
- else if (n < 0x100) {
- addOpcode(FLOAD); // fload
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(FLOAD);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(34 + n); // fload_<n>
+ else if (n < 0x100) {
+ addOpcode(FLOAD); // fload
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(FLOAD);
+ addIndex(n);
+ }
}
/**
* Appends FSTORE or FSTORE_<n>
*
- * @param n an index into the local variable array.
+ * @param n an index into the local variable array.
*/
public void addFstore(int n) {
- if (n < 4)
- addOpcode(67 + n); // fstore_<n>
- else if (n < 0x100) {
- addOpcode(FSTORE); // fstore
- add(n);
- }
- else {
- addOpcode(WIDE);
- addOpcode(FSTORE);
- addIndex(n);
- }
+ if (n < 4)
+ addOpcode(67 + n); // fstore_<n>
+ else if (n < 0x100) {
+ addOpcode(FSTORE); // fstore
+ add(n);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(FSTORE);
+ addIndex(n);
+ }
}
/**
* Appends an instruction for loading a value from the
* local variable at the index <code>n</code>.
*
- * @param n the index.
- * @param type the type of the loaded value.
- * @return the size of the value (1 or 2 word).
+ * @param n the index.
+ * @param type the type of the loaded value.
+ * @return the size of the value (1 or 2 word).
*/
public int addLoad(int n, CtClass type) {
- if (type.isPrimitive()) {
- if (type == CtClass.booleanType || type == CtClass.charType
- || type == CtClass.byteType || type == CtClass.shortType
- || type == CtClass.intType)
- addIload(n);
- else if (type == CtClass.longType) {
- addLload(n);
- return 2;
- }
- else if(type == CtClass.floatType)
- addFload(n);
- else if(type == CtClass.doubleType) {
- addDload(n);
- return 2;
- }
- else
- throw new RuntimeException("void type?");
- }
- else
- addAload(n);
-
- return 1;
+ if (type.isPrimitive()) {
+ if (type == CtClass.booleanType || type == CtClass.charType
+ || type == CtClass.byteType || type == CtClass.shortType
+ || type == CtClass.intType)
+ addIload(n);
+ else if (type == CtClass.longType) {
+ addLload(n);
+ return 2;
+ }
+ else if(type == CtClass.floatType)
+ addFload(n);
+ else if(type == CtClass.doubleType) {
+ addDload(n);
+ return 2;
+ }
+ else
+ throw new RuntimeException("void type?");
+ }
+ else
+ addAload(n);
+
+ return 1;
}
/**
* Appends an instruction for storing a value into the
* local variable at the index <code>n</code>.
*
- * @param n the index.
- * @param type the type of the stored value.
- * @return 2 if the type is long or double. Otherwise 1.
+ * @param n the index.
+ * @param type the type of the stored value.
+ * @return 2 if the type is long or double. Otherwise 1.
*/
public int addStore(int n, CtClass type) {
- if (type.isPrimitive()) {
- if (type == CtClass.booleanType || type == CtClass.charType
- || type == CtClass.byteType || type == CtClass.shortType
- || type == CtClass.intType)
- addIstore(n);
- else if (type == CtClass.longType) {
- addLstore(n);
- return 2;
- }
- else if(type == CtClass.floatType)
- addFstore(n);
- else if(type == CtClass.doubleType) {
- addDstore(n);
- return 2;
- }
- else
- throw new RuntimeException("void type?");
- }
- else
- addAstore(n);
-
- return 1;
+ if (type.isPrimitive()) {
+ if (type == CtClass.booleanType || type == CtClass.charType
+ || type == CtClass.byteType || type == CtClass.shortType
+ || type == CtClass.intType)
+ addIstore(n);
+ else if (type == CtClass.longType) {
+ addLstore(n);
+ return 2;
+ }
+ else if(type == CtClass.floatType)
+ addFstore(n);
+ else if(type == CtClass.doubleType) {
+ addDstore(n);
+ return 2;
+ }
+ else
+ throw new RuntimeException("void type?");
+ }
+ else
+ addAstore(n);
+
+ return 1;
}
/**
* operand stack.
*/
public int addLoadParameters(CtClass[] params) {
- int stacksize = 0;
- if (params != null) {
- int n = params.length;
- for (int i = 0; i < n; ++i)
- stacksize += addLoad(stacksize + 1, params[i]);
- }
+ int stacksize = 0;
+ if (params != null) {
+ int n = params.length;
+ for (int i = 0; i < n; ++i)
+ stacksize += addLoad(stacksize + 1, params[i]);
+ }
- return stacksize;
+ return stacksize;
}
/**
* Appends CHECKCAST.
*
- * @param c the type.
+ * @param c the type.
*/
public void addCheckcast(CtClass c) {
- addOpcode(CHECKCAST);
- addIndex(constPool.addClassInfo(c));
+ addOpcode(CHECKCAST);
+ addIndex(constPool.addClassInfo(c));
}
/**
* Appends CHECKCAST.
*
- * @param classname a fully-qualified class name.
+ * @param classname a fully-qualified class name.
*/
public void addCheckcast(String classname) {
- addOpcode(CHECKCAST);
- addIndex(constPool.addClassInfo(classname));
+ addOpcode(CHECKCAST);
+ addIndex(constPool.addClassInfo(classname));
}
/**
* Appends INSTANCEOF.
*
- * @param classname the class name.
+ * @param classname the class name.
*/
public void addInstanceof(String classname) {
- addOpcode(INSTANCEOF);
- addIndex(constPool.addClassInfo(classname));
+ addOpcode(INSTANCEOF);
+ addIndex(constPool.addClassInfo(classname));
}
/**
* Appends GETFIELD.
*
- * @param c the class
- * @param name the field name
- * @param type the descriptor of the field type.
+ * @param c the class
+ * @param name the field name
+ * @param type the descriptor of the field type.
*
* @see Descriptor#of(CtClass)
*/
public void addGetfield(CtClass c, String name, String type) {
- add(GETFIELD);
- int ci = constPool.addClassInfo(c);
- addIndex(constPool.addFieldrefInfo(ci, name, type));
- growStack(Descriptor.dataSize(type) - 1);
+ add(GETFIELD);
+ int ci = constPool.addClassInfo(c);
+ addIndex(constPool.addFieldrefInfo(ci, name, type));
+ growStack(Descriptor.dataSize(type) - 1);
}
/**
* Appends GETSTATIC.
*
- * @param c the class
- * @param name the field name
- * @param type the descriptor of the field type.
+ * @param c the class
+ * @param name the field name
+ * @param type the descriptor of the field type.
*
* @see Descriptor#of(CtClass)
*/
public void addGetstatic(CtClass c, String name, String type) {
- add(GETSTATIC);
- int ci = constPool.addClassInfo(c);
- addIndex(constPool.addFieldrefInfo(ci, name, type));
- growStack(Descriptor.dataSize(type));
+ add(GETSTATIC);
+ int ci = constPool.addClassInfo(c);
+ addIndex(constPool.addFieldrefInfo(ci, name, type));
+ growStack(Descriptor.dataSize(type));
}
/**
* Appends GETSTATIC.
*
- * @param c the fully-qualified class name
- * @param name the field name
- * @param type the descriptor of the field type.
+ * @param c the fully-qualified class name
+ * @param name the field name
+ * @param type the descriptor of the field type.
*
* @see Descriptor#of(CtClass)
*/
public void addGetstatic(String c, String name, String type) {
- add(GETSTATIC);
- int ci = constPool.addClassInfo(c);
- addIndex(constPool.addFieldrefInfo(ci, name, type));
- growStack(Descriptor.dataSize(type));
+ add(GETSTATIC);
+ int ci = constPool.addClassInfo(c);
+ addIndex(constPool.addFieldrefInfo(ci, name, type));
+ growStack(Descriptor.dataSize(type));
}
/**
* Appends INVOKESPECIAL.
*
- * @param clazz the target class.
- * @param name the method name.
- * @param returnType the return type.
- * @param paramTypes the parameter types.
+ * @param clazz the target class.
+ * @param name the method name.
+ * @param returnType the return type.
+ * @param paramTypes the parameter types.
*/
public void addInvokespecial(CtClass clazz, String name,
- CtClass returnType, CtClass[] paramTypes) {
- String desc = Descriptor.ofMethod(returnType, paramTypes);
- addInvokespecial(clazz, name, desc);
+ CtClass returnType, CtClass[] paramTypes) {
+ String desc = Descriptor.ofMethod(returnType, paramTypes);
+ addInvokespecial(clazz, name, desc);
}
/**
* Appends INVOKESPECIAL.
*
- * @param clazz the target class.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
* @see Descriptor#ofConstructor(CtClass[])
*/
public void addInvokespecial(CtClass clazz, String name, String desc) {
- addInvokespecial(constPool.addClassInfo(clazz), name, desc);
+ addInvokespecial(constPool.addClassInfo(clazz), name, desc);
}
/**
* Appends INVOKESPECIAL.
*
- * @param clazz the fully-qualified class name.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the fully-qualified class name.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
* @see Descriptor#ofConstructor(CtClass[])
*/
public void addInvokespecial(String clazz, String name, String desc) {
- addInvokespecial(constPool.addClassInfo(clazz), name, desc);
+ addInvokespecial(constPool.addClassInfo(clazz), name, desc);
}
/**
* Appends INVOKESPECIAL.
*
- * @param clazz the index of <code>CONSTANT_Class_info</code>
- * structure.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the index of <code>CONSTANT_Class_info</code>
+ * structure.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
* @see Descriptor#ofConstructor(CtClass[])
*/
public void addInvokespecial(int clazz, String name, String desc) {
- add(INVOKESPECIAL);
- addIndex(constPool.addMethodrefInfo(clazz, name, desc));
- growStack(Descriptor.dataSize(desc) - 1);
+ add(INVOKESPECIAL);
+ addIndex(constPool.addMethodrefInfo(clazz, name, desc));
+ growStack(Descriptor.dataSize(desc) - 1);
}
/**
* Appends INVOKESTATIC.
*
- * @param clazz the target class.
- * @param name the method name
- * @param returnType the return type.
- * @param paramTypes the parameter types.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param returnType the return type.
+ * @param paramTypes the parameter types.
*/
public void addInvokestatic(CtClass clazz, String name,
- CtClass returnType, CtClass[] paramTypes) {
- String desc = Descriptor.ofMethod(returnType, paramTypes);
- addInvokestatic(clazz, name, desc);
+ CtClass returnType, CtClass[] paramTypes) {
+ String desc = Descriptor.ofMethod(returnType, paramTypes);
+ addInvokestatic(clazz, name, desc);
}
/**
* Appends INVOKESTATIC.
*
- * @param clazz the target class.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokestatic(CtClass clazz, String name, String desc) {
- addInvokestatic(constPool.addClassInfo(clazz), name, desc);
+ addInvokestatic(constPool.addClassInfo(clazz), name, desc);
}
/**
* Appends INVOKESTATIC.
*
- * @param classname the fully-qualified class name.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param classname the fully-qualified class name.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokestatic(String classname, String name, String desc) {
- addInvokestatic(constPool.addClassInfo(classname), name, desc);
+ addInvokestatic(constPool.addClassInfo(classname), name, desc);
}
/**
* Appends INVOKESTATIC.
*
- * @param clazz the index of <code>CONSTANT_Class_info</code>
- * structure.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the index of <code>CONSTANT_Class_info</code>
+ * structure.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokestatic(int clazz, String name, String desc) {
- add(INVOKESTATIC);
- addIndex(constPool.addMethodrefInfo(clazz, name, desc));
- growStack(Descriptor.dataSize(desc));
+ add(INVOKESTATIC);
+ addIndex(constPool.addMethodrefInfo(clazz, name, desc));
+ growStack(Descriptor.dataSize(desc));
}
/**
* It must be directly declared in the class specified
* in <code>clazz</code>.
*
- * @param clazz the target class.
- * @param name the method name
- * @param returnType the return type.
- * @param paramTypes the parameter types.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param returnType the return type.
+ * @param paramTypes the parameter types.
*/
public void addInvokevirtual(CtClass clazz, String name,
- CtClass returnType, CtClass[] paramTypes) {
- String desc = Descriptor.ofMethod(returnType, paramTypes);
- addInvokevirtual(clazz, name, desc);
+ CtClass returnType, CtClass[] paramTypes) {
+ String desc = Descriptor.ofMethod(returnType, paramTypes);
+ addInvokevirtual(clazz, name, desc);
}
/**
* It must be directly declared in the class specified
* in <code>clazz</code>.
*
- * @param clazz the target class.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokevirtual(CtClass clazz, String name, String desc) {
- addInvokevirtual(constPool.addClassInfo(clazz), name, desc);
+ addInvokevirtual(constPool.addClassInfo(clazz), name, desc);
}
/**
* It must be directly declared in the class specified
* in <code>classname</code>.
*
- * @param classname the fully-qualified class name.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param classname the fully-qualified class name.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokevirtual(String classname, String name, String desc) {
- addInvokevirtual(constPool.addClassInfo(classname), name, desc);
+ addInvokevirtual(constPool.addClassInfo(classname), name, desc);
}
/**
* It must be directly declared in the class specified
* by <code>clazz</code>.
*
- * @param clazz the index of <code>CONSTANT_Class_info</code>
- * structure.
- * @param name the method name
- * @param desc the descriptor of the method signature.
+ * @param clazz the index of <code>CONSTANT_Class_info</code>
+ * structure.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokevirtual(int clazz, String name, String desc) {
- add(INVOKEVIRTUAL);
- addIndex(constPool.addMethodrefInfo(clazz, name, desc));
- growStack(Descriptor.dataSize(desc) - 1);
+ add(INVOKEVIRTUAL);
+ addIndex(constPool.addMethodrefInfo(clazz, name, desc));
+ growStack(Descriptor.dataSize(desc) - 1);
}
/**
* Appends INVOKEINTERFACE.
*
- * @param clazz the target class.
- * @param name the method name
- * @param returnType the return type.
- * @param paramTypes the parameter types.
- * @param count the count operand of the instruction.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param returnType the return type.
+ * @param paramTypes the parameter types.
+ * @param count the count operand of the instruction.
*/
public void addInvokeinterface(CtClass clazz, String name,
- CtClass returnType, CtClass[] paramTypes,
- int count) {
- String desc = Descriptor.ofMethod(returnType, paramTypes);
- addInvokeinterface(clazz, name, desc, count);
+ CtClass returnType, CtClass[] paramTypes,
+ int count) {
+ String desc = Descriptor.ofMethod(returnType, paramTypes);
+ addInvokeinterface(clazz, name, desc, count);
}
/**
* Appends INVOKEINTERFACE.
*
- * @param clazz the target class.
- * @param name the method name
- * @param desc the descriptor of the method signature.
- * @param count the count operand of the instruction.
+ * @param clazz the target class.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
+ * @param count the count operand of the instruction.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokeinterface(CtClass clazz, String name,
- String desc, int count) {
- addInvokeinterface(constPool.addClassInfo(clazz), name, desc,
- count);
+ String desc, int count) {
+ addInvokeinterface(constPool.addClassInfo(clazz), name, desc,
+ count);
}
/**
* Appends INVOKEINTERFACE.
*
- * @param classname the fully-qualified class name.
- * @param name the method name
- * @param desc the descriptor of the method signature.
- * @param count the count operand of the instruction.
+ * @param classname the fully-qualified class name.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
+ * @param count the count operand of the instruction.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokeinterface(String classname, String name,
- String desc, int count) {
- addInvokeinterface(constPool.addClassInfo(classname), name, desc,
- count);
+ String desc, int count) {
+ addInvokeinterface(constPool.addClassInfo(classname), name, desc,
+ count);
}
/**
* Appends INVOKEINTERFACE.
*
- * @param clazz the index of <code>CONSTANT_Class_info</code>
- * structure.
- * @param name the method name
- * @param desc the descriptor of the method signature.
- * @param count the count operand of the instruction.
+ * @param clazz the index of <code>CONSTANT_Class_info</code>
+ * structure.
+ * @param name the method name
+ * @param desc the descriptor of the method signature.
+ * @param count the count operand of the instruction.
*
* @see Descriptor#ofMethod(CtClass,CtClass[])
*/
public void addInvokeinterface(int clazz, String name,
- String desc, int count) {
- add(INVOKEINTERFACE);
- addIndex(constPool.addInterfaceMethodrefInfo(clazz, name, desc));
- add(count);
- add(0);
- growStack(Descriptor.dataSize(desc) - 1);
+ String desc, int count) {
+ add(INVOKEINTERFACE);
+ addIndex(constPool.addInterfaceMethodrefInfo(clazz, name, desc));
+ add(count);
+ add(0);
+ growStack(Descriptor.dataSize(desc) - 1);
}
/**
* Appends LDC or LDC_W. The pushed item is a <code>String</code>
* object.
*
- * @param s the character string pushed by LDC or LDC_W.
+ * @param s the character string pushed by LDC or LDC_W.
*/
public void addLdc(String s) {
- addLdc(constPool.addStringInfo(s));
+ addLdc(constPool.addStringInfo(s));
}
/**
* Appends LDC or LDC_W.
*
- * @param i index into the constant pool.
+ * @param i index into the constant pool.
*/
public void addLdc(int i) {
- if (i > 0xFF) {
- addOpcode(LDC_W);
- addIndex(i);
- }
- else {
- addOpcode(LDC);
- add(i);
- }
+ if (i > 0xFF) {
+ addOpcode(LDC_W);
+ addIndex(i);
+ }
+ else {
+ addOpcode(LDC);
+ add(i);
+ }
}
/**
* Appends LDC2_W. The pushed item is a long value.
*/
public void addLdc2w(long l) {
- addOpcode(LDC2_W);
- addIndex(constPool.addLongInfo(l));
+ addOpcode(LDC2_W);
+ addIndex(constPool.addLongInfo(l));
}
/**
* Appends LDC2_W. The pushed item is a double value.
*/
public void addLdc2w(double d) {
- addOpcode(LDC2_W);
- addIndex(constPool.addDoubleInfo(d));
+ addOpcode(LDC2_W);
+ addIndex(constPool.addDoubleInfo(d));
}
/**
* Appends NEW.
*
- * @param clazz the class of the created instance.
+ * @param clazz the class of the created instance.
*/
public void addNew(CtClass clazz) {
- addOpcode(NEW);
- addIndex(constPool.addClassInfo(clazz));
+ addOpcode(NEW);
+ addIndex(constPool.addClassInfo(clazz));
}
/**
* Appends NEW.
*
- * @param classname the fully-qualified class name.
+ * @param classname the fully-qualified class name.
*/
public void addNew(String classname) {
- addOpcode(NEW);
- addIndex(constPool.addClassInfo(classname));
+ addOpcode(NEW);
+ addIndex(constPool.addClassInfo(classname));
}
/**
* Appends ANEWARRAY.
*
- * @param classname the qualified class name of the element type.
+ * @param classname the qualified class name of the element type.
*/
public void addAnewarray(String classname) {
- addOpcode(ANEWARRAY);
- addIndex(constPool.addClassInfo(classname));
+ addOpcode(ANEWARRAY);
+ addIndex(constPool.addClassInfo(classname));
}
/**
* Appends ICONST and ANEWARRAY.
*
- * @param clazz the elememnt type.
- * @param length the array length.
+ * @param clazz the elememnt type.
+ * @param length the array length.
*/
public void addAnewarray(CtClass clazz, int length) {
- addIconst(length);
- addOpcode(ANEWARRAY);
- addIndex(constPool.addClassInfo(clazz));
+ addIconst(length);
+ addOpcode(ANEWARRAY);
+ addIndex(constPool.addClassInfo(clazz));
}
/**
* Appends NEWARRAY for primitive types.
*
- * @param atype <code>T_BOOLEAN</code>, <code>T_CHAR</code>, ...
+ * @param atype <code>T_BOOLEAN</code>, <code>T_CHAR</code>, ...
* @see Opcode
*/
public void addNewarray(int atype, int length) {
- addIconst(length);
- addOpcode(NEWARRAY);
- add(atype);
+ addIconst(length);
+ addOpcode(NEWARRAY);
+ add(atype);
}
/**
* Appends MULTINEWARRAY.
*
- * @param clazz the array type.
- * @param dimensions the sizes of all dimensions.
- * @return the length of <code>dimensions</code>.
+ * @param clazz the array type.
+ * @param dimensions the sizes of all dimensions.
+ * @return the length of <code>dimensions</code>.
*/
public int addMultiNewarray(CtClass clazz, int[] dimensions) {
- int len = dimensions.length;
- for (int i = 0; i < len; ++i)
- addIconst(dimensions[i]);
+ int len = dimensions.length;
+ for (int i = 0; i < len; ++i)
+ addIconst(dimensions[i]);
- growStack(len);
- return addMultiNewarray(clazz, len);
+ growStack(len);
+ return addMultiNewarray(clazz, len);
}
/**
* Appends MULTINEWARRAY. The size of every dimension must have been
* already pushed on the stack.
*
- * @param clazz the array type.
- * @param dim the number of the dimensions.
- * @return the value of <code>dim</code>.
+ * @param clazz the array type.
+ * @param dim the number of the dimensions.
+ * @return the value of <code>dim</code>.
*/
public int addMultiNewarray(CtClass clazz, int dim) {
- add(MULTIANEWARRAY);
- addIndex(constPool.addClassInfo(clazz));
- add(dim);
- growStack(1 - dim);
- return dim;
+ add(MULTIANEWARRAY);
+ addIndex(constPool.addClassInfo(clazz));
+ add(dim);
+ growStack(1 - dim);
+ return dim;
}
/**
* Appends MULTINEWARRAY.
*
- * @param desc the type descriptor of the created array.
- * @param dim dimensions.
- * @return the value of <code>dim</code>.
+ * @param desc the type descriptor of the created array.
+ * @param dim dimensions.
+ * @return the value of <code>dim</code>.
*/
public int addMultiNewarray(String desc, int dim) {
- add(MULTIANEWARRAY);
- addIndex(constPool.addClassInfo(desc));
- add(dim);
- growStack(1 - dim);
- return dim;
+ add(MULTIANEWARRAY);
+ addIndex(constPool.addClassInfo(desc));
+ add(dim);
+ growStack(1 - dim);
+ return dim;
}
/**
* Appends PUTFIELD.
*
- * @param c the target class.
- * @param name the field name.
- * @param desc the descriptor of the field type.
+ * @param c the target class.
+ * @param name the field name.
+ * @param desc the descriptor of the field type.
*/
public void addPutfield(CtClass c, String name, String desc) {
- add(PUTFIELD);
- int ci = constPool.addClassInfo(c);
- addIndex(constPool.addFieldrefInfo(ci, name, desc));
- growStack(-1 - Descriptor.dataSize(desc));
+ add(PUTFIELD);
+ int ci = constPool.addClassInfo(c);
+ addIndex(constPool.addFieldrefInfo(ci, name, desc));
+ growStack(-1 - Descriptor.dataSize(desc));
}
/**
* Appends PUTSTATIC.
*
- * @param c the target class.
- * @param name the field name.
- * @param desc the descriptor of the field type.
+ * @param c the target class.
+ * @param name the field name.
+ * @param desc the descriptor of the field type.
*/
public void addPutstatic(CtClass c, String name, String desc) {
- add(PUTSTATIC);
- int ci = constPool.addClassInfo(c);
- addIndex(constPool.addFieldrefInfo(ci, name, desc));
- growStack(-Descriptor.dataSize(desc));
+ add(PUTSTATIC);
+ int ci = constPool.addClassInfo(c);
+ addIndex(constPool.addFieldrefInfo(ci, name, desc));
+ growStack(-Descriptor.dataSize(desc));
}
/**
* Appends ARETURN, IRETURN, .., or RETURN.
*
- * @param type the return type.
+ * @param type the return type.
*/
public void addReturn(CtClass type) {
- if (type == null)
- addOpcode(RETURN);
- else if (type.isPrimitive()) {
- CtPrimitiveType ptype = (CtPrimitiveType)type;
- addOpcode(ptype.getReturnOp());
- }
- else
- addOpcode(ARETURN);
+ if (type == null)
+ addOpcode(RETURN);
+ else if (type.isPrimitive()) {
+ CtPrimitiveType ptype = (CtPrimitiveType)type;
+ addOpcode(ptype.getReturnOp());
+ }
+ else
+ addOpcode(ARETURN);
}
/**
* Appends RET.
*
- * @param var local variable
+ * @param var local variable
*/
public void addRet(int var) {
- if (var < 0x100) {
- addOpcode(RET);
- add(var);
- }
- else {
- addOpcode(WIDE);
- addOpcode(RET);
- addIndex(var);
- }
+ if (var < 0x100) {
+ addOpcode(RET);
+ add(var);
+ }
+ else {
+ addOpcode(WIDE);
+ addOpcode(RET);
+ addIndex(var);
+ }
}
/**
* Appends instructions for executing
* <code>java.lang.System.println(<i>message</i>)</code>.
*
- * @param message printed message.
+ * @param message printed message.
*/
public void addPrintln(String message) {
- addGetstatic("java.lang.System", "err", "Ljava/io/PrintStream;");
- addLdc(message);
- addInvokevirtual("java.io.PrintStream",
- "println", "(Ljava/lang/String;)V");
+ addGetstatic("java.lang.System", "err", "Ljava/io/PrintStream;");
+ addLdc(message);
+ addInvokevirtual("java.io.PrintStream",
+ "println", "(Ljava/lang/String;)V");
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
LinkedList methods;
LinkedList attributes;
- String thisclassname; // not JVM-internal name
+ String thisclassname; // not JVM-internal name
/**
* Constructs a class file from a byte stream.
*/
public ClassFile(DataInputStream in) throws IOException {
- read(in);
+ read(in);
}
/**
* Constructs a class file including no members.
*
- * @param isInterface true if this is an interface.
- * false if this is a class.
- * @param classname a fully-qualified class name
- * @param superclass a fully-qualified super class name
+ * @param isInterface true if this is an interface.
+ * false if this is a class.
+ * @param classname a fully-qualified class name
+ * @param superclass a fully-qualified super class name
*/
public ClassFile(boolean isInterface,
- String classname, String superclass) {
- constPool = new ConstPool(classname);
- thisClass = constPool.getThisClassInfo();
- if (isInterface)
- accessFlags = AccessFlag.SUPER | AccessFlag.INTERFACE
- | AccessFlag.ABSTRACT;
- else
- accessFlags = AccessFlag.SUPER;
-
- initSuperclass(superclass);
- interfaces = null;
- fields = new LinkedList();
- methods = new LinkedList();
- thisclassname = classname;
-
- attributes = new LinkedList();
- attributes.add(new SourceFileAttribute(constPool,
- getSourcefileName(thisclassname)));
+ String classname, String superclass) {
+ constPool = new ConstPool(classname);
+ thisClass = constPool.getThisClassInfo();
+ if (isInterface)
+ accessFlags = AccessFlag.SUPER | AccessFlag.INTERFACE
+ | AccessFlag.ABSTRACT;
+ else
+ accessFlags = AccessFlag.SUPER;
+
+ initSuperclass(superclass);
+ interfaces = null;
+ fields = new LinkedList();
+ methods = new LinkedList();
+ thisclassname = classname;
+
+ attributes = new LinkedList();
+ attributes.add(new SourceFileAttribute(constPool,
+ getSourcefileName(thisclassname)));
}
private void initSuperclass(String superclass) {
- if (superclass != null)
- superClass = constPool.addClassInfo(superclass);
- else
- superClass = constPool.addClassInfo("java.lang.Object");
+ if (superclass != null)
+ superClass = constPool.addClassInfo(superclass);
+ else
+ superClass = constPool.addClassInfo("java.lang.Object");
}
private static String getSourcefileName(String qname) {
- int index = qname.lastIndexOf('.');
- if (index >= 0)
- qname = qname.substring(index + 1);
+ int index = qname.lastIndexOf('.');
+ if (index >= 0)
+ qname = qname.substring(index + 1);
- return qname + ".java";
+ return qname + ".java";
}
/**
* Returns a constant pool table.
*/
public ConstPool getConstPool() {
- return constPool;
+ return constPool;
}
/**
* Returns true if this is an interface.
*/
public boolean isInterface() {
- return (accessFlags & AccessFlag.INTERFACE) != 0;
+ return (accessFlags & AccessFlag.INTERFACE) != 0;
}
/**
* Returns true if this is a final class or interface.
*/
public boolean isFinal() {
- return (accessFlags & AccessFlag.FINAL) != 0;
+ return (accessFlags & AccessFlag.FINAL) != 0;
}
/**
* Returns true if this is an abstract class or an interface.
*/
public boolean isAbstract() {
- return (accessFlags & AccessFlag.ABSTRACT) != 0;
+ return (accessFlags & AccessFlag.ABSTRACT) != 0;
}
/**
* @see javassist.bytecode.AccessFlag
*/
public int getAccessFlags() {
- return accessFlags;
+ return accessFlags;
}
/**
* @see javassist.bytecode.AccessFlag
*/
public void setAccessFlags(int acc) {
- accessFlags = acc | AccessFlag.SUPER;
+ accessFlags = acc | AccessFlag.SUPER;
}
/**
* Returns the class name.
*/
public String getName() {
- return thisclassname;
+ return thisclassname;
}
/**
* for all occurrences of the old class name in the class file.
*/
public void setName(String name) {
- renameClass(thisclassname, name);
+ renameClass(thisclassname, name);
}
/**
* Returns the super class name.
*/
public String getSuperclass() {
- return constPool.getClassInfo(superClass);
+ return constPool.getClassInfo(superClass);
}
/**
* the super class.
*/
public int getSuperclassId() {
- return superClass;
+ return superClass;
}
/**
* only the calls to a super constructor are modified.
*/
public void setSuperclass(String superclass)
- throws CannotCompileException
+ throws CannotCompileException
{
- if (constPool.getClassInfo(superClass).equals("java.lang.Object")) {
- if (superclass != null)
- try {
- superClass = constPool.addClassInfo(superclass);
- setSuperclass2(superclass);
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
- }
- else {
- if (superclass == null)
- superclass = "java.lang.Object";
-
- renameClass(constPool.getClassInfo(superClass), superclass);
- }
+ if (constPool.getClassInfo(superClass).equals("java.lang.Object")) {
+ if (superclass != null)
+ try {
+ superClass = constPool.addClassInfo(superclass);
+ setSuperclass2(superclass);
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
+ }
+ else {
+ if (superclass == null)
+ superclass = "java.lang.Object";
+
+ renameClass(constPool.getClassInfo(superClass), superclass);
+ }
}
/* If the original super class is java.lang.Object, a special
* where X is the new super class.
*/
private void setSuperclass2(String superclass) throws BadBytecode {
- LinkedList list = methods;
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- minfo.setSuperclass(superclass);
- }
+ LinkedList list = methods;
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ minfo.setSuperclass(superclass);
+ }
}
/**
* If this fact is not guaranteed, the bytecode verifier may cause
* an error.
*
- * @param oldname the replaced class name
- * @param newname the substituted class name
+ * @param oldname the replaced class name
+ * @param newname the substituted class name
*/
public final void renameClass(String oldname, String newname) {
- LinkedList list;
- int n;
-
- if (oldname.equals(newname))
- return;
-
- if (oldname.equals(thisclassname))
- thisclassname = newname;
-
- oldname = Descriptor.toJvmName(oldname);
- newname = Descriptor.toJvmName(newname);
- constPool.renameClass(oldname, newname);
-
- list = methods;
- n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- String desc = minfo.getDescriptor();
- minfo.setDescriptor(Descriptor.rename(desc, oldname, newname));
- }
-
- list = fields;
- n = list.size();
- for (int i = 0; i < n; ++i) {
- FieldInfo finfo = (FieldInfo)list.get(i);
- String desc = finfo.getDescriptor();
- finfo.setDescriptor(Descriptor.rename(desc, oldname, newname));
- }
+ LinkedList list;
+ int n;
+
+ if (oldname.equals(newname))
+ return;
+
+ if (oldname.equals(thisclassname))
+ thisclassname = newname;
+
+ oldname = Descriptor.toJvmName(oldname);
+ newname = Descriptor.toJvmName(newname);
+ constPool.renameClass(oldname, newname);
+
+ list = methods;
+ n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ String desc = minfo.getDescriptor();
+ minfo.setDescriptor(Descriptor.rename(desc, oldname, newname));
+ }
+
+ list = fields;
+ n = list.size();
+ for (int i = 0; i < n; ++i) {
+ FieldInfo finfo = (FieldInfo)list.get(i);
+ String desc = finfo.getDescriptor();
+ finfo.setDescriptor(Descriptor.rename(desc, oldname, newname));
+ }
}
/**
* Replaces all occurrences of several class names in the class file.
*
- * @param classnames specifies which class name is replaced
- * with which new name. Class names must
- * be described with the JVM-internal
- * representation like
- * <code>java/lang/Object</code>.
+ * @param classnames specifies which class name is replaced
+ * with which new name. Class names must
+ * be described with the JVM-internal
+ * representation like
+ * <code>java/lang/Object</code>.
*
* @see #renameClass(String,String)
*/
public final void renameClass(Map classnames) {
- String jvmNewThisName
- = (String)classnames.get(Descriptor.toJvmName(thisclassname));
- if (jvmNewThisName != null)
- thisclassname = Descriptor.toJavaName(jvmNewThisName);
-
- constPool.renameClass(classnames);
-
- LinkedList list = methods;
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- String desc = minfo.getDescriptor();
- minfo.setDescriptor(Descriptor.rename(desc, classnames));
- }
-
- list = fields;
- n = list.size();
- for (int i = 0; i < n; ++i) {
- FieldInfo finfo = (FieldInfo)list.get(i);
- String desc = finfo.getDescriptor();
- finfo.setDescriptor(Descriptor.rename(desc, classnames));
- }
+ String jvmNewThisName
+ = (String)classnames.get(Descriptor.toJvmName(thisclassname));
+ if (jvmNewThisName != null)
+ thisclassname = Descriptor.toJavaName(jvmNewThisName);
+
+ constPool.renameClass(classnames);
+
+ LinkedList list = methods;
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ String desc = minfo.getDescriptor();
+ minfo.setDescriptor(Descriptor.rename(desc, classnames));
+ }
+
+ list = fields;
+ n = list.size();
+ for (int i = 0; i < n; ++i) {
+ FieldInfo finfo = (FieldInfo)list.get(i);
+ String desc = finfo.getDescriptor();
+ finfo.setDescriptor(Descriptor.rename(desc, classnames));
+ }
}
/**
* Returns the names of the interfaces implemented by the class.
*/
public String[] getInterfaces() {
- if (interfaces == null)
- return new String[0];
- else {
- int n = interfaces.length;
- String[] list = new String[n];
- for (int i = 0; i < n; ++i)
- list[i] = constPool.getClassInfo(interfaces[i]);
-
- return list;
- }
+ if (interfaces == null)
+ return new String[0];
+ else {
+ int n = interfaces.length;
+ String[] list = new String[n];
+ for (int i = 0; i < n; ++i)
+ list[i] = constPool.getClassInfo(interfaces[i]);
+
+ return list;
+ }
}
/**
* Sets the interfaces.
*
- * @param nameList the names of the interfaces.
+ * @param nameList the names of the interfaces.
*/
public void setInterfaces(String[] nameList) {
- if (nameList != null) {
- int n = nameList.length;
- interfaces = new int[n];
- for (int i = 0; i < n; ++i)
- interfaces[i] = constPool.addClassInfo(nameList[i]);
- }
+ if (nameList != null) {
+ int n = nameList.length;
+ interfaces = new int[n];
+ for (int i = 0; i < n; ++i)
+ interfaces[i] = constPool.addClassInfo(nameList[i]);
+ }
}
/**
* interfaces implemented by the class.
*/
public void addInterface(String name) {
- int info = constPool.addClassInfo(name);
- if (interfaces == null) {
- interfaces = new int[1];
- interfaces[0] = info;
- }
- else {
- int n = interfaces.length;
- int[] newarray = new int[n + 1];
- System.arraycopy(interfaces, 0, newarray, 0, n);
- newarray[n] = info;
- interfaces = newarray;
- }
+ int info = constPool.addClassInfo(name);
+ if (interfaces == null) {
+ interfaces = new int[1];
+ interfaces[0] = info;
+ }
+ else {
+ int n = interfaces.length;
+ int[] newarray = new int[n + 1];
+ System.arraycopy(interfaces, 0, newarray, 0, n);
+ newarray[n] = info;
+ interfaces = newarray;
+ }
}
/**
* Appends a field to the class.
*/
public void addField(FieldInfo finfo) {
- fields.add(finfo);
+ fields.add(finfo);
}
/**
* Returns the method with the specified name. If there are multiple
* methods with that name, this method returns one of them.
*
- * @return null if no such a method is found.
+ * @return null if no such a method is found.
*/
public MethodInfo getMethod(String name) {
- LinkedList list = methods;
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- if (minfo.getName().equals(name))
- return minfo;
- }
-
- return null;
+ LinkedList list = methods;
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ if (minfo.getName().equals(name))
+ return minfo;
+ }
+
+ return null;
}
/**
* it does not exist.
*/
public MethodInfo getStaticInitializer() {
- return getMethod(MethodInfo.nameClinit);
+ return getMethod(MethodInfo.nameClinit);
}
/**
* Appends a method to the class.
*/
public void addMethod(MethodInfo minfo) {
- methods.add(minfo);
+ methods.add(minfo);
}
/**
/**
* Returns the attribute with the specified name.
*
- * @param name attribute name
+ * @param name attribute name
*/
public AttributeInfo getAttribute(String name) {
- LinkedList list = attributes;
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- AttributeInfo ai = (AttributeInfo)list.get(i);
- if (ai.getName().equals(name))
- return ai;
- }
-
- return null;
+ LinkedList list = attributes;
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ AttributeInfo ai = (AttributeInfo)list.get(i);
+ if (ai.getName().equals(name))
+ return ai;
+ }
+
+ return null;
}
/**
* the same name, the new one substitutes for it.
*/
public void addAttribute(AttributeInfo info) {
- AttributeInfo.remove(attributes, info.getName());
- attributes.add(info);
+ AttributeInfo.remove(attributes, info.getName());
+ attributes.add(info);
}
/**
* Returns the source file containing this class.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getSourceFile() {
- SourceFileAttribute sf
- = (SourceFileAttribute)getAttribute(SourceFileAttribute.tag);
- if (sf == null)
- return null;
- else
- return sf.getFileName();
+ SourceFileAttribute sf
+ = (SourceFileAttribute)getAttribute(SourceFileAttribute.tag);
+ if (sf == null)
+ return null;
+ else
+ return sf.getFileName();
}
private void read(DataInputStream in) throws IOException {
- int i, n;
- int magic = in.readInt();
- if (magic != 0xCAFEBABE)
- throw new IOException("non class file");
-
- int major = in.readUnsignedShort();
- int minor = in.readUnsignedShort();
- constPool = new ConstPool(in);
- accessFlags = in.readUnsignedShort();
- thisClass = in.readUnsignedShort();
- constPool.setThisClassInfo(thisClass);
- superClass = in.readUnsignedShort();
- n = in.readUnsignedShort();
- if (n == 0)
- interfaces = null;
- else {
- interfaces = new int[n];
- for (i = 0; i < n; ++i)
- interfaces[i] = in.readUnsignedShort();
- }
-
- ConstPool cp = constPool;
- n = in.readUnsignedShort();
- fields = new LinkedList();
- for (i = 0; i < n; ++i)
- addField(new FieldInfo(cp, in));
-
- n = in.readUnsignedShort();
- methods = new LinkedList();
- for (i = 0; i < n; ++i)
- addMethod(new MethodInfo(cp, in));
-
- attributes = new LinkedList();
- n = in.readUnsignedShort();
- for (i = 0; i < n; ++i)
- addAttribute(AttributeInfo.read(cp, in));
-
- thisclassname = constPool.getClassInfo(thisClass);
+ int i, n;
+ int magic = in.readInt();
+ if (magic != 0xCAFEBABE)
+ throw new IOException("non class file");
+
+ int major = in.readUnsignedShort();
+ int minor = in.readUnsignedShort();
+ constPool = new ConstPool(in);
+ accessFlags = in.readUnsignedShort();
+ thisClass = in.readUnsignedShort();
+ constPool.setThisClassInfo(thisClass);
+ superClass = in.readUnsignedShort();
+ n = in.readUnsignedShort();
+ if (n == 0)
+ interfaces = null;
+ else {
+ interfaces = new int[n];
+ for (i = 0; i < n; ++i)
+ interfaces[i] = in.readUnsignedShort();
+ }
+
+ ConstPool cp = constPool;
+ n = in.readUnsignedShort();
+ fields = new LinkedList();
+ for (i = 0; i < n; ++i)
+ addField(new FieldInfo(cp, in));
+
+ n = in.readUnsignedShort();
+ methods = new LinkedList();
+ for (i = 0; i < n; ++i)
+ addMethod(new MethodInfo(cp, in));
+
+ attributes = new LinkedList();
+ n = in.readUnsignedShort();
+ for (i = 0; i < n; ++i)
+ addAttribute(AttributeInfo.read(cp, in));
+
+ thisclassname = constPool.getClassInfo(thisClass);
}
/**
* into an output stream.
*/
public void write(DataOutputStream out) throws IOException {
- int i, n;
-
- out.writeInt(0xCAFEBABE); // magic
- out.writeShort(3); // major version
- out.writeShort(45); // minor version
- constPool.write(out); // constant pool
- out.writeShort(accessFlags);
- out.writeShort(thisClass);
- out.writeShort(superClass);
-
- if (interfaces == null)
- n = 0;
- else
- n = interfaces.length;
-
- out.writeShort(n);
- for (i = 0; i < n; ++i)
- out.writeShort(interfaces[i]);
-
- LinkedList list = fields;
- n = list.size();
- out.writeShort(n);
- for (i = 0; i < n; ++i) {
- FieldInfo finfo = (FieldInfo)list.get(i);
- finfo.write(out);
- }
-
- list = methods;
- n = list.size();
- out.writeShort(n);
- for (i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- minfo.write(out);
- }
-
- out.writeShort(attributes.size());
- AttributeInfo.writeAll(attributes, out);
+ int i, n;
+
+ out.writeInt(0xCAFEBABE); // magic
+ out.writeShort(3); // major version
+ out.writeShort(45); // minor version
+ constPool.write(out); // constant pool
+ out.writeShort(accessFlags);
+ out.writeShort(thisClass);
+ out.writeShort(superClass);
+
+ if (interfaces == null)
+ n = 0;
+ else
+ n = interfaces.length;
+
+ out.writeShort(n);
+ for (i = 0; i < n; ++i)
+ out.writeShort(interfaces[i]);
+
+ LinkedList list = fields;
+ n = list.size();
+ out.writeShort(n);
+ for (i = 0; i < n; ++i) {
+ FieldInfo finfo = (FieldInfo)list.get(i);
+ finfo.write(out);
+ }
+
+ list = methods;
+ n = list.size();
+ out.writeShort(n);
+ for (i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ minfo.write(out);
+ }
+
+ out.writeShort(attributes.size());
+ AttributeInfo.writeAll(attributes, out);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.PrintWriter;
* Prints the contents of a class file to the standard output stream.
*/
public static void print(ClassFile cf) {
- print(cf, new PrintWriter(System.out, true));
+ print(cf, new PrintWriter(System.out, true));
}
/**
* Prints the contents of a class file.
*/
public static void print(ClassFile cf, PrintWriter out) {
- List list;
- int n;
+ List list;
+ int n;
- /* 0x0020 (SYNCHRONIZED) means ACC_SUPER if the modifiers
- * are of a class.
- */
- int mod
- = AccessFlag.toModifier(cf.getAccessFlags()
- & ~AccessFlag.SYNCHRONIZED);
- out.println(Modifier.toString(mod) + " class "
- + cf.getName() + " extends " + cf.getSuperclass());
- out.println();
+ /* 0x0020 (SYNCHRONIZED) means ACC_SUPER if the modifiers
+ * are of a class.
+ */
+ int mod
+ = AccessFlag.toModifier(cf.getAccessFlags()
+ & ~AccessFlag.SYNCHRONIZED);
+ out.println(Modifier.toString(mod) + " class "
+ + cf.getName() + " extends " + cf.getSuperclass());
+ out.println();
- ConstPool cp = cf.getConstPool();
- list = cf.getFields();
- n = list.size();
- for (int i = 0; i < n; ++i) {
- FieldInfo finfo = (FieldInfo)list.get(i);
- int acc = finfo.getAccessFlags();
- out.println(Modifier.toString(AccessFlag.toModifier(acc))
- + " " + finfo.getName() + "\t"
- + finfo.getDescriptor());
- printAttributes(finfo.getAttributes(), out);
- }
+ ConstPool cp = cf.getConstPool();
+ list = cf.getFields();
+ n = list.size();
+ for (int i = 0; i < n; ++i) {
+ FieldInfo finfo = (FieldInfo)list.get(i);
+ int acc = finfo.getAccessFlags();
+ out.println(Modifier.toString(AccessFlag.toModifier(acc))
+ + " " + finfo.getName() + "\t"
+ + finfo.getDescriptor());
+ printAttributes(finfo.getAttributes(), out);
+ }
- out.println();
- list = cf.getMethods();
- n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- int acc = minfo.getAccessFlags();
- out.println(Modifier.toString(AccessFlag.toModifier(acc))
- + " " + minfo.getName() + "\t"
- + minfo.getDescriptor());
- printAttributes(minfo.getAttributes(), out);
- out.println();
- }
+ out.println();
+ list = cf.getMethods();
+ n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ int acc = minfo.getAccessFlags();
+ out.println(Modifier.toString(AccessFlag.toModifier(acc))
+ + " " + minfo.getName() + "\t"
+ + minfo.getDescriptor());
+ printAttributes(minfo.getAttributes(), out);
+ out.println();
+ }
- out.println();
- printAttributes(cf.getAttributes(), out);
+ out.println();
+ printAttributes(cf.getAttributes(), out);
}
static void printAttributes(List list, PrintWriter out) {
- if (list == null)
- return;
+ if (list == null)
+ return;
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- AttributeInfo ai = (AttributeInfo)list.get(i);
- if (ai instanceof CodeAttribute) {
- CodeAttribute ca = (CodeAttribute)ai;
- out.println("attribute: " + ai.getName() + ": "
- + ai.getClass().getName());
- out.println("max stack " + ca.getMaxStack()
- + ", max locals " + ca.getMaxLocals()
- + ", " + ca.getExceptionTable().size()
- + " catch blocks");
- out.println("<code attribute begin>");
- printAttributes(ca.getAttributes(), out);
- out.println("<code attribute end>");
- }
- else
- out.println("attribute: " + ai.getName()
- + " (" + ai.get().length + " byte): "
- + ai.getClass().getName());
- }
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ AttributeInfo ai = (AttributeInfo)list.get(i);
+ if (ai instanceof CodeAttribute) {
+ CodeAttribute ca = (CodeAttribute)ai;
+ out.println("attribute: " + ai.getName() + ": "
+ + ai.getClass().getName());
+ out.println("max stack " + ca.getMaxStack()
+ + ", max locals " + ca.getMaxLocals()
+ + ", " + ca.getExceptionTable().size()
+ + " catch blocks");
+ out.println("<code attribute begin>");
+ printAttributes(ca.getAttributes(), out);
+ out.println("<code attribute end>");
+ }
+ else
+ out.println("attribute: " + ai.getName()
+ + " (" + ai.get().length + " byte): "
+ + ai.getClass().getName());
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
/**
* Constructs a <code>Code_attribute</code>.
*
- * @param cp constant pool table
- * @param stack <code>max_stack</code>
- * @param locals <code>max_locals</code>
- * @param code <code>code[]</code>
- * @param etable <code>exception_table[]</code>
+ * @param cp constant pool table
+ * @param stack <code>max_stack</code>
+ * @param locals <code>max_locals</code>
+ * @param code <code>code[]</code>
+ * @param etable <code>exception_table[]</code>
*/
public CodeAttribute(ConstPool cp, int stack, int locals, byte[] code,
- ExceptionTable etable)
+ ExceptionTable etable)
{
- super(cp, tag);
- maxStack = stack;
- maxLocals = locals;
- info = code;
- exceptions = etable;
- attributes = new LinkedList();
+ super(cp, tag);
+ maxStack = stack;
+ maxLocals = locals;
+ info = code;
+ exceptions = etable;
+ attributes = new LinkedList();
}
/**
* Constructs a copy of <code>Code_attribute</code>.
* Specified class names are replaced during the copy.
*
- * @param cp constant pool table.
- * @param src source Code attribute.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param cp constant pool table.
+ * @param src source Code attribute.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
private CodeAttribute(ConstPool cp, CodeAttribute src, Map classnames)
- throws BadBytecode
+ throws BadBytecode
{
- super(cp, tag);
-
- maxStack = src.getMaxStack();
- maxLocals = src.getMaxLocals();
- exceptions = src.getExceptionTable().copy(cp, classnames);
- info = src.copyCode(cp, classnames, exceptions);
- attributes = new LinkedList();
-
- /* Since an index into the source constant pool table may not
- be translated, we don't copy the attributes.
- */
- /*
- List src_attr = src.getAttributes();
- int num = src_attr.size();
- for (int i = 0; i < num; ++i) {
- AttributeInfo ai = (AttributeInfo)src_attr.get(i);
- attributes.add(ai.copy(cp, classnames));
- }
- */
+ super(cp, tag);
+
+ maxStack = src.getMaxStack();
+ maxLocals = src.getMaxLocals();
+ exceptions = src.getExceptionTable().copy(cp, classnames);
+ info = src.copyCode(cp, classnames, exceptions);
+ attributes = new LinkedList();
+
+ /* Since an index into the source constant pool table may not
+ be translated, we don't copy the attributes.
+ */
+ /*
+ List src_attr = src.getAttributes();
+ int num = src_attr.size();
+ for (int i = 0; i < num; ++i) {
+ AttributeInfo ai = (AttributeInfo)src_attr.get(i);
+ attributes.add(ai.copy(cp, classnames));
+ }
+ */
}
CodeAttribute(ConstPool cp, int name_id, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, name_id, (byte[])null);
- int attr_len = in.readInt();
+ super(cp, name_id, (byte[])null);
+ int attr_len = in.readInt();
- maxStack = in.readUnsignedShort();
- maxLocals = in.readUnsignedShort();
+ maxStack = in.readUnsignedShort();
+ maxLocals = in.readUnsignedShort();
- int code_len = in.readInt();
- info = new byte[code_len];
- in.readFully(info);
+ int code_len = in.readInt();
+ info = new byte[code_len];
+ in.readFully(info);
- exceptions = new ExceptionTable(cp, in);
+ exceptions = new ExceptionTable(cp, in);
- attributes = new LinkedList();
- int num = in.readUnsignedShort();
- for (int i = 0; i < num; ++i)
- attributes.add(AttributeInfo.read(cp, in));
+ attributes = new LinkedList();
+ int num = in.readUnsignedShort();
+ for (int i = 0; i < num; ++i)
+ attributes.add(AttributeInfo.read(cp, in));
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
- * @exception RuntimeCopyException if a <code>BadBytecode</code>
- * exception is thrown, it is
- * converted into
- * <code>RuntimeCopyException</code>.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
+ * @exception RuntimeCopyException if a <code>BadBytecode</code>
+ * exception is thrown, it is
+ * converted into
+ * <code>RuntimeCopyException</code>.
*
* @return <code>CodeAttribute</code> object.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames)
- throws RuntimeCopyException
+ throws RuntimeCopyException
{
- try {
- return new CodeAttribute(newCp, this, classnames);
- }
- catch (BadBytecode e) {
- throw new RuntimeCopyException("bad bytecode. fatal?");
- }
+ try {
+ return new CodeAttribute(newCp, this, classnames);
+ }
+ catch (BadBytecode e) {
+ throw new RuntimeCopyException("bad bytecode. fatal?");
+ }
}
/**
* in <code>CodeAttribute</code>.
*/
public static class RuntimeCopyException extends RuntimeException {
- /**
- * Constructs an exception.
- */
- public RuntimeCopyException(String s) {
- super(s);
- }
+ /**
+ * Constructs an exception.
+ */
+ public RuntimeCopyException(String s) {
+ super(s);
+ }
}
/**
* The returned value is <code>attribute_length + 6</code>.
*/
public int length() {
- return 18 + info.length + exceptions.size() * 8
- + AttributeInfo.getLength(attributes);
+ return 18 + info.length + exceptions.size() * 8
+ + AttributeInfo.getLength(attributes);
}
void write(DataOutputStream out) throws IOException {
- out.writeShort(name); // attribute_name_index
- out.writeInt(length() - 6); // attribute_length
- out.writeShort(maxStack); // max_stack
- out.writeShort(maxLocals); // max_locals
- out.writeInt(info.length); // code_length
- out.write(info); // code
- exceptions.write(out);
- out.writeShort(attributes.size()); // attributes_count
- AttributeInfo.writeAll(attributes, out); // attributes
+ out.writeShort(name); // attribute_name_index
+ out.writeInt(length() - 6); // attribute_length
+ out.writeShort(maxStack); // max_stack
+ out.writeShort(maxLocals); // max_locals
+ out.writeInt(info.length); // code_length
+ out.write(info); // code
+ exceptions.write(out);
+ out.writeShort(attributes.size()); // attributes_count
+ AttributeInfo.writeAll(attributes, out); // attributes
}
/**
* This method is not available.
*
- * @throws java.lang.UnsupportedOperationException always thrown.
+ * @throws java.lang.UnsupportedOperationException always thrown.
*/
public byte[] get() {
- throw new UnsupportedOperationException("CodeAttribute.get()");
+ throw new UnsupportedOperationException("CodeAttribute.get()");
}
/**
* This method is not available.
*
- * @throws java.lang.UnsupportedOperationException always thrown.
+ * @throws java.lang.UnsupportedOperationException always thrown.
*/
public void set(byte[] newinfo) {
- throw new UnsupportedOperationException("CodeAttribute.set()");
+ throw new UnsupportedOperationException("CodeAttribute.set()");
}
/**
* this code attribute.
*/
public String getDeclaringClass() {
- ConstPool cp = getConstPool();
- return cp.getClassName();
+ ConstPool cp = getConstPool();
+ return cp.getClassName();
}
/**
* Returns <code>max_stack</code>.
*/
public int getMaxStack() {
- return maxStack;
+ return maxStack;
}
/**
* Sets <code>max_stack</code>.
*/
public void setMaxStack(int value) {
- maxStack = value;
+ maxStack = value;
}
/**
* Returns <code>max_locals</code>.
*/
public int getMaxLocals() {
- return maxLocals;
+ return maxLocals;
}
/**
* Sets <code>max_locals</code>.
*/
public void setMaxLocals(int value) {
- maxLocals = value;
+ maxLocals = value;
}
/**
* Returns <code>code_length</code>.
*/
public int getCodeLength() {
- return info.length;
+ return info.length;
}
/**
* Returns <code>code[]</code>.
*/
public byte[] getCode() {
- return info;
+ return info;
}
/**
* Makes a new iterator for reading this code attribute.
*/
public CodeIterator iterator() {
- return new CodeIterator(this);
+ return new CodeIterator(this);
}
/**
* Returns the attribute with the specified name.
* If it is not found, this method returns null.
*
- * @param name attribute name
- * @return an <code>AttributeInfo</code> object or null.
+ * @param name attribute name
+ * @return an <code>AttributeInfo</code> object or null.
*/
public AttributeInfo getAttribute(String name) {
- return AttributeInfo.lookup(attributes, name);
+ return AttributeInfo.lookup(attributes, name);
}
/**
* Copies code.
*/
private byte[] copyCode(ConstPool destCp, Map classnames,
- ExceptionTable etable)
- throws BadBytecode
+ ExceptionTable etable)
+ throws BadBytecode
{
- int len = getCodeLength();
- byte[] newCode = new byte[len];
+ int len = getCodeLength();
+ byte[] newCode = new byte[len];
- LdcEntry ldc = copyCode(this.info, 0, len, this.getConstPool(),
- newCode, destCp, classnames);
- return LdcEntry.doit(newCode, ldc, etable);
+ LdcEntry ldc = copyCode(this.info, 0, len, this.getConstPool(),
+ newCode, destCp, classnames);
+ return LdcEntry.doit(newCode, ldc, etable);
}
private static LdcEntry copyCode(byte[] code, int beginPos, int endPos,
- ConstPool srcCp, byte[] newcode,
- ConstPool destCp, Map classnameMap)
- throws BadBytecode
+ ConstPool srcCp, byte[] newcode,
+ ConstPool destCp, Map classnameMap)
+ throws BadBytecode
{
- int i2, index;
- LdcEntry ldcEntry = null;
-
- for (int i = beginPos; i < endPos; i = i2) {
- i2 = CodeIterator.nextOpcode(code, i);
- byte c = code[i];
- newcode[i] = c;
- switch (c & 0xff) {
- case LDC_W :
- case LDC2_W :
- case GETSTATIC :
- case PUTSTATIC :
- case GETFIELD :
- case PUTFIELD :
- case INVOKEVIRTUAL :
- case INVOKESPECIAL :
- case INVOKESTATIC :
- case NEW :
- case ANEWARRAY :
- case CHECKCAST :
- case INSTANCEOF :
- copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp,
- classnameMap);
- break;
- case LDC :
- index = code[i + 1] & 0xff;
- index = srcCp.copy(index, destCp, classnameMap);
- if (index < 0x100)
- newcode[i + 1] = (byte)index;
- else {
- LdcEntry ldc = new LdcEntry();
- ldc.where = i;
- ldc.index = index;
- ldc.next = ldcEntry;
- ldcEntry = ldc;
- }
- break;
- case INVOKEINTERFACE :
- copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp,
- classnameMap);
- newcode[i + 3] = code[i + 3];
- newcode[i + 4] = code[i + 4];
- break;
- case MULTIANEWARRAY :
- copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp,
- classnameMap);
- newcode[i + 3] = code[i + 3];
- break;
- default :
- while (++i < i2)
- newcode[i] = code[i];
-
- break;
- }
- }
-
- return ldcEntry;
+ int i2, index;
+ LdcEntry ldcEntry = null;
+
+ for (int i = beginPos; i < endPos; i = i2) {
+ i2 = CodeIterator.nextOpcode(code, i);
+ byte c = code[i];
+ newcode[i] = c;
+ switch (c & 0xff) {
+ case LDC_W :
+ case LDC2_W :
+ case GETSTATIC :
+ case PUTSTATIC :
+ case GETFIELD :
+ case PUTFIELD :
+ case INVOKEVIRTUAL :
+ case INVOKESPECIAL :
+ case INVOKESTATIC :
+ case NEW :
+ case ANEWARRAY :
+ case CHECKCAST :
+ case INSTANCEOF :
+ copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp,
+ classnameMap);
+ break;
+ case LDC :
+ index = code[i + 1] & 0xff;
+ index = srcCp.copy(index, destCp, classnameMap);
+ if (index < 0x100)
+ newcode[i + 1] = (byte)index;
+ else {
+ LdcEntry ldc = new LdcEntry();
+ ldc.where = i;
+ ldc.index = index;
+ ldc.next = ldcEntry;
+ ldcEntry = ldc;
+ }
+ break;
+ case INVOKEINTERFACE :
+ copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp,
+ classnameMap);
+ newcode[i + 3] = code[i + 3];
+ newcode[i + 4] = code[i + 4];
+ break;
+ case MULTIANEWARRAY :
+ copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp,
+ classnameMap);
+ newcode[i + 3] = code[i + 3];
+ break;
+ default :
+ while (++i < i2)
+ newcode[i] = code[i];
+
+ break;
+ }
+ }
+
+ return ldcEntry;
}
private static void copyConstPoolInfo(int i, byte[] code, ConstPool srcCp,
- byte[] newcode, ConstPool destCp,
- Map classnameMap) {
- int index = ((code[i] & 0xff) << 8) | (code[i + 1] & 0xff);
- index = srcCp.copy(index, destCp, classnameMap);
- newcode[i] = (byte)(index >> 8);
- newcode[i + 1] = (byte)index;
+ byte[] newcode, ConstPool destCp,
+ Map classnameMap) {
+ int index = ((code[i] & 0xff) << 8) | (code[i + 1] & 0xff);
+ index = srcCp.copy(index, destCp, classnameMap);
+ newcode[i] = (byte)(index >> 8);
+ newcode[i + 1] = (byte)index;
}
}
int index;
static byte[] doit(byte[] code, LdcEntry ldc, ExceptionTable etable)
- throws BadBytecode
+ throws BadBytecode
{
- while (ldc != null) {
- int where = ldc.where;
- code = CodeIterator.insertGap(code, where, 1, false, etable);
- code[where] = (byte)Opcode.LDC_W;
- ByteArray.write16bit(ldc.index, code, where + 1);
- ldc = ldc.next;
- }
-
- return code;
+ while (ldc != null) {
+ int where = ldc.where;
+ code = CodeIterator.insertGap(code, where, 1, false, etable);
+ code[where] = (byte)Opcode.LDC_W;
+ ByteArray.write16bit(ldc.index, code, where + 1);
+ ldc = ldc.next;
+ }
+
+ return code;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
/**
protected int currentPos;
CodeIterator(CodeAttribute ca) {
- codeAttr = ca;
- bytecode = ca.getCode();
- begin();
+ codeAttr = ca;
+ bytecode = ca.getCode();
+ begin();
}
/**
* Moves to the first instruction.
*/
public void begin() {
- currentPos = 0;
- endPos = getCodeLength();
+ currentPos = 0;
+ endPos = getCodeLength();
}
/**
* @see CodeAttribute#getCode()
*/
public void move(int index) {
- currentPos = index;
+ currentPos = index;
}
/**
* Returns a Code attribute read with this iterator.
*/
public CodeAttribute get() {
- return codeAttr;
+ return codeAttr;
}
/**
* Returns <code>code_length</code> of <code>Code_attribute</code>.
*/
public int getCodeLength() {
- return bytecode.length;
+ return bytecode.length;
}
/**
* Writes an 8bit value at the given index.
*/
public void writeByte(int value, int index) {
- bytecode[index] = (byte)value;
+ bytecode[index] = (byte)value;
}
/**
* Returns the unsigned 16bit value at the given index.
*/
public int u16bitAt(int index) {
- return ByteArray.readU16bit(bytecode, index);
+ return ByteArray.readU16bit(bytecode, index);
}
/**
* Returns the signed 16bit value at the given index.
*/
public int s16bitAt(int index) {
- return ByteArray.readS16bit(bytecode, index);
+ return ByteArray.readS16bit(bytecode, index);
}
/**
* Writes a 16 bit integer at the index.
*/
public void write16bit(int value, int index) {
- ByteArray.write16bit(value, bytecode, index);
+ ByteArray.write16bit(value, bytecode, index);
}
/**
* Returns the signed 32bit value at the given index.
*/
public int s32bitAt(int index) {
- return ByteArray.read32bit(bytecode, index);
+ return ByteArray.read32bit(bytecode, index);
}
/**
* Writes a 32bit integer at the index.
*/
public void write32bit(int value, int index) {
- ByteArray.write32bit(value, bytecode, index);
+ ByteArray.write32bit(value, bytecode, index);
}
/**
* Writes a byte array at the index.
*/
public void write(byte[] code, int index) {
- int len = code.length;
- for (int j = 0; j < len; ++j)
- bytecode[index++] = code[j];
+ int len = code.length;
+ for (int j = 0; j < len; ++j)
+ bytecode[index++] = code[j];
}
/**
* @see CodeIterator#byteAt(int)
*/
public int next() throws BadBytecode {
- int pos = currentPos;
- currentPos = nextOpcode(bytecode, pos);
- return pos;
+ int pos = currentPos;
+ currentPos = nextOpcode(bytecode, pos);
+ return pos;
}
/**
*
* <p>This method works only for a constructor.
*
- * @return the index of the INVOKESPECIAL instruction, or -1
- * if a constructor invocation is not found.
+ * @return the index of the INVOKESPECIAL instruction, or -1
+ * if a constructor invocation is not found.
*/
public int skipConstructor() throws BadBytecode {
- return skipSuperConstructor0(-1);
+ return skipSuperConstructor0(-1);
}
/**
*
* <p>This method works only for a constructor.
*
- * @return the index of the INVOKESPECIAL instruction, or -1
- * if a super constructor invocation is not found
- * but <code>this()</code> is found.
+ * @return the index of the INVOKESPECIAL instruction, or -1
+ * if a super constructor invocation is not found
+ * but <code>this()</code> is found.
*/
public int skipSuperConstructor() throws BadBytecode {
- return skipSuperConstructor0(0);
+ return skipSuperConstructor0(0);
}
/**
*
* <p>This method works only for a constructor.
*
- * @return the index of the INVOKESPECIAL instruction, or -1
- * if a explicit constructor invocation is not found
- * but <code>super()</code> is found.
+ * @return the index of the INVOKESPECIAL instruction, or -1
+ * if a explicit constructor invocation is not found
+ * but <code>super()</code> is found.
*/
public int skipThisConstructor() throws BadBytecode {
- return skipSuperConstructor0(1);
+ return skipSuperConstructor0(1);
}
- /* skipSuper 1: this(), 0: super(), -1: both.
+ /* skipSuper 1: this(), 0: super(), -1: both.
*/
private int skipSuperConstructor0(int skipThis) throws BadBytecode {
- begin();
- ConstPool cp = codeAttr.getConstPool();
- String thisClassName = codeAttr.getDeclaringClass();
- int nested = 0;
- while (hasNext()) {
- int index = next();
- int c = byteAt(index);
- if (c == NEW)
- ++nested;
- else if (c == INVOKESPECIAL) {
- int mref = ByteArray.readU16bit(bytecode, index + 1);
- if (cp.getMethodrefName(mref).equals(MethodInfo.nameInit))
- if (--nested < 0) {
- if (skipThis < 0)
- return index;
-
- String cname = cp.getMethodrefClassName(mref);
- if (cname.equals(thisClassName) == (skipThis > 0))
- return index;
- else
- break;
- }
- }
- }
-
- begin();
- return -1;
+ begin();
+ ConstPool cp = codeAttr.getConstPool();
+ String thisClassName = codeAttr.getDeclaringClass();
+ int nested = 0;
+ while (hasNext()) {
+ int index = next();
+ int c = byteAt(index);
+ if (c == NEW)
+ ++nested;
+ else if (c == INVOKESPECIAL) {
+ int mref = ByteArray.readU16bit(bytecode, index + 1);
+ if (cp.getMethodrefName(mref).equals(MethodInfo.nameInit))
+ if (--nested < 0) {
+ if (skipThis < 0)
+ return index;
+
+ String cname = cp.getMethodrefClassName(mref);
+ if (cname.equals(thisClassName) == (skipThis > 0))
+ return index;
+ else
+ break;
+ }
+ }
+ }
+
+ begin();
+ return -1;
}
/**
* bytecode sequence for adjusting alignment if the code attribute
* includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.
*
- * @param code inserted bytecode sequence.
- * @return the index indicating the first byte of the
- * inserted byte sequence.
+ * @param code inserted bytecode sequence.
+ * @return the index indicating the first byte of the
+ * inserted byte sequence.
*/
public int insert(byte[] code)
- throws BadBytecode
+ throws BadBytecode
{
- int pos = currentPos;
- insert0(currentPos, code, false);
- return pos;
+ int pos = currentPos;
+ insert0(currentPos, code, false);
+ return pos;
}
/**
* bytecode sequence for adjusting alignment if the code attribute
* includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.
*
- * @param pos the index at which a byte sequence is inserted.
- * @param code inserted bytecode sequence.
+ * @param pos the index at which a byte sequence is inserted.
+ * @param code inserted bytecode sequence.
*/
public void insert(int pos, byte[] code) throws BadBytecode {
- insert0(pos, code, false);
+ insert0(pos, code, false);
}
/**
* bytecode sequence for adjusting alignment if the code attribute
* includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.
*
- * @param code inserted bytecode sequence.
- * @return the index indicating the first byte of the
- * inserted byte sequence.
+ * @param code inserted bytecode sequence.
+ * @return the index indicating the first byte of the
+ * inserted byte sequence.
*/
public int insertEx(byte[] code)
- throws BadBytecode
+ throws BadBytecode
{
- int pos = currentPos;
- insert0(currentPos, code, true);
- return pos;
+ int pos = currentPos;
+ insert0(currentPos, code, true);
+ return pos;
}
/**
* bytecode sequence for adjusting alignment if the code attribute
* includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.
*
- * @param pos the index at which a byte sequence is inserted.
- * @param code inserted bytecode sequence.
+ * @param pos the index at which a byte sequence is inserted.
+ * @param code inserted bytecode sequence.
*/
public void insertEx(int pos, byte[] code) throws BadBytecode {
- insert0(pos, code, true);
+ insert0(pos, code, true);
}
private void insert0(int pos, byte[] code, boolean exclusive)
- throws BadBytecode
+ throws BadBytecode
{
- int len = code.length;
- if (len <= 0)
- return;
+ int len = code.length;
+ if (len <= 0)
+ return;
- insertGapCore(pos, len, exclusive); // currentPos will change.
- for (int j = 0; j < len; ++j)
- bytecode[pos++] = code[j];
+ insertGapCore(pos, len, exclusive); // currentPos will change.
+ for (int j = 0; j < len; ++j)
+ bytecode[pos++] = code[j];
}
/**
* <p>If the next instruction is at the beginning of a block statement,
* then the gap is inserted within that block.
*
- * @param length gap length
- * @return the index indicating the first byte of the inserted gap.
+ * @param length gap length
+ * @return the index indicating the first byte of the inserted gap.
*/
public int insertGap(int length) throws BadBytecode {
- int pos = currentPos;
- insertGapCore(currentPos, length, false);
- return pos;
+ int pos = currentPos;
+ insertGapCore(currentPos, length, false);
+ return pos;
}
/**
* of a block statement,
* then the gap is inserted within that block.
*
- * @param pos the index at which a gap is inserted.
- * @param length gap length.
+ * @param pos the index at which a gap is inserted.
+ * @param length gap length.
+ * @return the length of the inserted gap.
+ * It might be bigger than <code>length</code>.
*/
- public void insertGap(int pos, int length) throws BadBytecode {
- insertGapCore(pos, length, false);
+ public int insertGap(int pos, int length) throws BadBytecode {
+ return insertGapCore(pos, length, false);
}
/**
* <p>If the next instruction is at the beginning of a block statement,
* then the gap is excluded from that block.
*
- * @param length gap length
- * @return the index indicating the first byte of the inserted gap.
+ * @param length gap length
+ * @return the index indicating the first byte of the inserted gap.
*/
public int insertExGap(int length) throws BadBytecode {
- int pos = currentPos;
- insertGapCore(currentPos, length, true);
- return pos;
+ int pos = currentPos;
+ insertGapCore(currentPos, length, true);
+ return pos;
}
/**
* of a block statement,
* then the gap is excluded from that block.
*
- * @param pos the index at which a gap is inserted.
- * @param length gap length.
+ * @param pos the index at which a gap is inserted.
+ * @param length gap length.
+ * @return the length of the inserted gap.
+ * It might be bigger than <code>length</code>.
*/
- public void insertExGap(int pos, int length) throws BadBytecode {
- insertGapCore(pos, length, true);
+ public int insertExGap(int pos, int length) throws BadBytecode {
+ return insertGapCore(pos, length, true);
}
- private void insertGapCore(int pos, int length, boolean exclusive)
- throws BadBytecode
+ /**
+ * @return the length of the really inserted gap.
+ */
+ private int insertGapCore(int pos, int length, boolean exclusive)
+ throws BadBytecode
{
- if (length <= 0)
- return;
+ if (length <= 0)
+ return 0;
- int cur = currentPos;
- byte[] c = insertGap(bytecode, pos, length, exclusive,
- get().getExceptionTable());
- if (cur >= pos)
- currentPos = cur + (c.length - bytecode.length);
+ int cur = currentPos;
+ byte[] c = insertGap(bytecode, pos, length, exclusive,
+ get().getExceptionTable());
+ int length2 = c.length - bytecode.length;
+ if (cur >= pos)
+ currentPos = cur + length2;
- codeAttr.setCode(c);
- bytecode = c;
- endPos = getCodeLength();
+ codeAttr.setCode(c);
+ bytecode = c;
+ endPos = getCodeLength();
+ return length2;
}
/**
* at the beginning of the exception table in the code attribute
* edited by this object.
*
- * @param offset the value added to the code positions included
- * in the entries.
+ * @param offset the value added to the code positions included
+ * in the entries.
*/
public void insert(ExceptionTable et, int offset) {
- codeAttr.getExceptionTable().add(0, et, offset);
+ codeAttr.getExceptionTable().add(0, et, offset);
}
/**
* Appends the given bytecode sequence at the end.
*
- * @param code the bytecode appended.
- * @return the position of the first byte of the appended bytecode.
+ * @param code the bytecode appended.
+ * @return the position of the first byte of the appended bytecode.
*/
public int append(byte[] code) {
- int size = getCodeLength();
- int len = code.length;
- if (len <= 0)
- return size;
+ int size = getCodeLength();
+ int len = code.length;
+ if (len <= 0)
+ return size;
- appendGap(len);
- byte[] dest = bytecode;
- for (int i = 0; i < len; ++i)
- dest[i + size] = code[i];
+ appendGap(len);
+ byte[] dest = bytecode;
+ for (int i = 0; i < len; ++i)
+ dest[i + size] = code[i];
- return size;
+ return size;
}
/**
* Appends a gap at the end of the bytecode sequence.
*
- * @param length gap length
+ * @param length gap length
*/
public void appendGap(int gapLength) {
- byte[] code = bytecode;
- int codeLength = code.length;
- byte[] newcode = new byte[codeLength + gapLength];
+ byte[] code = bytecode;
+ int codeLength = code.length;
+ byte[] newcode = new byte[codeLength + gapLength];
- int i;
- for (i = 0; i < codeLength; ++i)
- newcode[i] = code[i];
+ int i;
+ for (i = 0; i < codeLength; ++i)
+ newcode[i] = code[i];
- for (i = codeLength; i < codeLength + gapLength; ++i)
- newcode[i] = NOP;
+ for (i = codeLength; i < codeLength + gapLength; ++i)
+ newcode[i] = NOP;
- codeAttr.setCode(newcode);
- bytecode = newcode;
- endPos = getCodeLength();
+ codeAttr.setCode(newcode);
+ bytecode = newcode;
+ endPos = getCodeLength();
}
/**
* at the end of the exception table in the code attribute
* edited by this object.
*
- * @param offset the value added to the code positions included
- * in the entries.
+ * @param offset the value added to the code positions included
+ * in the entries.
*/
public void append(ExceptionTable et, int offset) {
- ExceptionTable table = codeAttr.getExceptionTable();
- table.add(table.size(), et, offset);
+ ExceptionTable table = codeAttr.getExceptionTable();
+ table.add(table.size(), et, offset);
}
/* opcodeLegth is used for implementing nextOpcode().
*/
private static final int opcodeLength[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 3,
- 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3,
- 3, 3, 3, 3, 3, 5, 0, 3, 2, 3, 1, 1, 3, 3, 1, 1, 0, 4, 3, 3,
- 5, 5
+ 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3,
+ 3, 3, 3, 3, 3, 5, 0, 3, 2, 3, 1, 1, 3, 3, 1, 1, 0, 4, 3, 3,
+ 5, 5
};
// 0 .. UNUSED (186), LOOKUPSWITCH, TABLESWITCH, WIDE
* Calculates the index of the next opcode.
*/
static int nextOpcode(byte[] code, int index)
- throws BadBytecode
+ throws BadBytecode
{
- int opcode;
- try {
- opcode = code[index] & 0xff;
- }
- catch (IndexOutOfBoundsException e) {
- throw new BadBytecode("invalid opcode address");
- }
-
- try {
- int len = opcodeLength[opcode];
- if (len > 0)
- return index + len;
- else if (opcode == WIDE)
- if (code[index + 1] == (byte)IINC) // WIDE IINC
- return index + 6;
- else
- return index + 4; // WIDE ...
- else {
- int index2 = (index & ~3) + 8;
- if (opcode == LOOKUPSWITCH) {
- int npairs = ByteArray.read32bit(code, index2);
- return index2 + npairs * 8 + 4;
- }
- else if (opcode == TABLESWITCH) {
- int low = ByteArray.read32bit(code, index2);
- int high = ByteArray.read32bit(code, index2 + 4);
- return index2 + (high - low + 1) * 4 + 8;
- }
- // else
- // throw new BadBytecode(opcode);
- }
- }
- catch (IndexOutOfBoundsException e) {
- }
-
- // opcode is UNUSED or an IndexOutOfBoundsException was thrown.
- throw new BadBytecode(opcode);
+ int opcode;
+ try {
+ opcode = code[index] & 0xff;
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new BadBytecode("invalid opcode address");
+ }
+
+ try {
+ int len = opcodeLength[opcode];
+ if (len > 0)
+ return index + len;
+ else if (opcode == WIDE)
+ if (code[index + 1] == (byte)IINC) // WIDE IINC
+ return index + 6;
+ else
+ return index + 4; // WIDE ...
+ else {
+ int index2 = (index & ~3) + 8;
+ if (opcode == LOOKUPSWITCH) {
+ int npairs = ByteArray.read32bit(code, index2);
+ return index2 + npairs * 8 + 4;
+ }
+ else if (opcode == TABLESWITCH) {
+ int low = ByteArray.read32bit(code, index2);
+ int high = ByteArray.read32bit(code, index2 + 4);
+ return index2 + (high - low + 1) * 4 + 8;
+ }
+ // else
+ // throw new BadBytecode(opcode);
+ }
+ }
+ catch (IndexOutOfBoundsException e) {
+ }
+
+ // opcode is UNUSED or an IndexOutOfBoundsException was thrown.
+ throw new BadBytecode(opcode);
}
// methods for implementing insertGap().
* a multiple of 4.
*/
static byte[] insertGap(byte[] code, int where, int gapLength,
- boolean exclusive, ExceptionTable etable)
- throws BadBytecode
+ boolean exclusive, ExceptionTable etable)
+ throws BadBytecode
{
- if (gapLength <= 0)
- return code;
-
- try {
- return insertGap0(code, where, gapLength, exclusive, etable);
- }
- catch (AlignmentException e) {
- try {
- return insertGap0(code, where, (gapLength + 3) & ~3,
- exclusive, etable);
- }
- catch (AlignmentException e2) {
- throw new RuntimeException("fatal error?");
- }
- }
+ if (gapLength <= 0)
+ return code;
+
+ try {
+ return insertGap0(code, where, gapLength, exclusive, etable);
+ }
+ catch (AlignmentException e) {
+ try {
+ return insertGap0(code, where, (gapLength + 3) & ~3,
+ exclusive, etable);
+ }
+ catch (AlignmentException e2) {
+ throw new RuntimeException("fatal error?");
+ }
+ }
}
private static byte[] insertGap0(byte[] code, int where, int gapLength,
- boolean exclusive, ExceptionTable etable)
- throws BadBytecode, AlignmentException
+ boolean exclusive, ExceptionTable etable)
+ throws BadBytecode, AlignmentException
{
- int codeLength = code.length;
- byte[] newcode = new byte[codeLength + gapLength];
- insertGap2(code, where, gapLength, codeLength, newcode, exclusive);
- etable.shiftPc(where, gapLength, exclusive);
- return newcode;
+ int codeLength = code.length;
+ byte[] newcode = new byte[codeLength + gapLength];
+ insertGap2(code, where, gapLength, codeLength, newcode, exclusive);
+ etable.shiftPc(where, gapLength, exclusive);
+ return newcode;
}
private static void insertGap2(byte[] code, int where, int gapLength,
- int endPos, byte[] newcode, boolean exclusive)
- throws BadBytecode, AlignmentException
+ int endPos, byte[] newcode, boolean exclusive)
+ throws BadBytecode, AlignmentException
{
- int nextPos;
- int i = 0;
- int j = 0;
- for (; i < endPos; i = nextPos) {
- if (i == where) {
- int j2 = j + gapLength;
- while (j < j2)
- newcode[j++] = NOP;
- }
-
- nextPos = nextOpcode(code, i);
- int inst = code[i] & 0xff;
- // if<cond>, if_icmp<cond>, if_acmp<cond>, goto, jsr
- if ((153 <= inst && inst <= 168)
- || inst == IFNULL || inst == IFNONNULL) {
- /* 2bytes *signed* offset */
- int offset = (code[i + 1] << 8) | (code[i + 2] & 0xff);
- offset = newOffset(i, offset, where, gapLength, exclusive);
- newcode[j] = code[i];
- ByteArray.write16bit(offset, newcode, j + 1);
- j += 3;
- }
- else if (inst == GOTO_W || inst == JSR_W) {
- /* 4bytes offset */
- int offset = ByteArray.read32bit(code, i + 1);
- offset = newOffset(i, offset, where, gapLength, exclusive);
- newcode[j++] = code[i];
- ByteArray.write32bit(offset, newcode, j);
- j += 4;
- }
- else if (inst == TABLESWITCH) {
- if ((gapLength & 3) != 0)
- throw new AlignmentException();
-
- int i0 = i;
- int i2 = (i & ~3) + 4; // 0-3 byte padding
- while (i0 < i2)
- newcode[j++] = code[i0++];
-
- int defaultbyte = newOffset(i, ByteArray.read32bit(code, i2),
- where, gapLength, exclusive);
- ByteArray.write32bit(defaultbyte, newcode, j);
- int lowbyte = ByteArray.read32bit(code, i2 + 4);
- ByteArray.write32bit(lowbyte, newcode, j + 4);
- int highbyte = ByteArray.read32bit(code, i2 + 8);
- ByteArray.write32bit(highbyte, newcode, j + 8);
- j += 12;
- i0 = i2 + 12;
- i2 = i0 + (highbyte - lowbyte + 1) * 4;
- while (i0 < i2) {
- int offset = newOffset(i, ByteArray.read32bit(code, i0),
- where, gapLength, exclusive);
- ByteArray.write32bit(offset, newcode, j);
- j += 4;
- i0 += 4;
- }
- }
- else if (inst == LOOKUPSWITCH) {
- if ((gapLength & 3) != 0)
- throw new AlignmentException();
-
- int i0 = i;
- int i2 = (i & ~3) + 4; // 0-3 byte padding
- while (i0 < i2)
- newcode[j++] = code[i0++];
-
- int defaultbyte = newOffset(i, ByteArray.read32bit(code, i2),
- where, gapLength, exclusive);
- ByteArray.write32bit(defaultbyte, newcode, j);
- int npairs = ByteArray.read32bit(code, i2 + 4);
- ByteArray.write32bit(npairs, newcode, j + 4);
- j += 8;
- i0 = i2 + 8;
- i2 = i0 + npairs * 8;
- while (i0 < i2) {
- ByteArray.copy32bit(code, i0, newcode, j);
- int offset = newOffset(i,
- ByteArray.read32bit(code, i0 + 4),
- where, gapLength, exclusive);
- ByteArray.write32bit(offset, newcode, j + 4);
- j += 8;
- i0 += 8;
- }
- }
- else
- while (i < nextPos)
- newcode[j++] = code[i++];
- }
+ int nextPos;
+ int i = 0;
+ int j = 0;
+ for (; i < endPos; i = nextPos) {
+ if (i == where) {
+ int j2 = j + gapLength;
+ while (j < j2)
+ newcode[j++] = NOP;
+ }
+
+ nextPos = nextOpcode(code, i);
+ int inst = code[i] & 0xff;
+ // if<cond>, if_icmp<cond>, if_acmp<cond>, goto, jsr
+ if ((153 <= inst && inst <= 168)
+ || inst == IFNULL || inst == IFNONNULL) {
+ /* 2bytes *signed* offset */
+ int offset = (code[i + 1] << 8) | (code[i + 2] & 0xff);
+ offset = newOffset(i, offset, where, gapLength, exclusive);
+ newcode[j] = code[i];
+ ByteArray.write16bit(offset, newcode, j + 1);
+ j += 3;
+ }
+ else if (inst == GOTO_W || inst == JSR_W) {
+ /* 4bytes offset */
+ int offset = ByteArray.read32bit(code, i + 1);
+ offset = newOffset(i, offset, where, gapLength, exclusive);
+ newcode[j++] = code[i];
+ ByteArray.write32bit(offset, newcode, j);
+ j += 4;
+ }
+ else if (inst == TABLESWITCH) {
+ if (i != j && (gapLength & 3) != 0)
+ throw new AlignmentException();
+
+ int i0 = i;
+ int i2 = (i & ~3) + 4; // 0-3 byte padding
+ while (i0 < i2)
+ newcode[j++] = code[i0++];
+
+ int defaultbyte = newOffset(i, ByteArray.read32bit(code, i2),
+ where, gapLength, exclusive);
+ ByteArray.write32bit(defaultbyte, newcode, j);
+ int lowbyte = ByteArray.read32bit(code, i2 + 4);
+ ByteArray.write32bit(lowbyte, newcode, j + 4);
+ int highbyte = ByteArray.read32bit(code, i2 + 8);
+ ByteArray.write32bit(highbyte, newcode, j + 8);
+ j += 12;
+ i0 = i2 + 12;
+ i2 = i0 + (highbyte - lowbyte + 1) * 4;
+ while (i0 < i2) {
+ int offset = newOffset(i, ByteArray.read32bit(code, i0),
+ where, gapLength, exclusive);
+ ByteArray.write32bit(offset, newcode, j);
+ j += 4;
+ i0 += 4;
+ }
+ }
+ else if (inst == LOOKUPSWITCH) {
+ if (i != j && (gapLength & 3) != 0)
+ throw new AlignmentException();
+
+ int i0 = i;
+ int i2 = (i & ~3) + 4; // 0-3 byte padding
+ while (i0 < i2)
+ newcode[j++] = code[i0++];
+
+ int defaultbyte = newOffset(i, ByteArray.read32bit(code, i2),
+ where, gapLength, exclusive);
+ ByteArray.write32bit(defaultbyte, newcode, j);
+ int npairs = ByteArray.read32bit(code, i2 + 4);
+ ByteArray.write32bit(npairs, newcode, j + 4);
+ j += 8;
+ i0 = i2 + 8;
+ i2 = i0 + npairs * 8;
+ while (i0 < i2) {
+ ByteArray.copy32bit(code, i0, newcode, j);
+ int offset = newOffset(i,
+ ByteArray.read32bit(code, i0 + 4),
+ where, gapLength, exclusive);
+ ByteArray.write32bit(offset, newcode, j + 4);
+ j += 8;
+ i0 += 8;
+ }
+ }
+ else
+ while (i < nextPos)
+ newcode[j++] = code[i++];
+ }
}
private static int newOffset(int i, int offset, int where,
- int gapLength, boolean exclusive) {
- int target = i + offset;
- if (i < where) {
- if (where < target || (exclusive && where == target))
- offset += gapLength;
- }
- else
- if (target < where || (!exclusive && where == target))
- offset -= gapLength;
-
- return offset;
+ int gapLength, boolean exclusive) {
+ int target = i + offset;
+ if (i < where) {
+ if (where < target || (exclusive && where == target))
+ offset += gapLength;
+ }
+ else
+ if (target < where || (!exclusive && where == target))
+ offset -= gapLength;
+
+ return offset;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
*/
public final class ConstPool {
LongVector items;
- int numOfItems;
+ int numOfItems;
Hashtable classes;
Hashtable strings;
- int thisClassInfo;
+ int thisClassInfo;
private static final int SIZE = 128;
/**
* <code>CONSTANT_InterfaceMethodref</code>
*/
public static final int CONST_InterfaceMethodref
- = InterfaceMethodrefInfo.tag;
+ = InterfaceMethodrefInfo.tag;
/**
* <code>CONSTANT_String</code>
/**
* Constructs a constant pool table.
*
- * @param thisclass the name of the class using this constant
- * pool table
+ * @param thisclass the name of the class using this constant
+ * pool table
*/
public ConstPool(String thisclass) {
- this();
- thisClassInfo = addClassInfo(thisclass);
+ this();
+ thisClassInfo = addClassInfo(thisclass);
}
/**
* Constructs a constant pool table from the given byte stream.
*
- * @param in byte stream.
+ * @param in byte stream.
*/
public ConstPool(DataInputStream in) throws IOException {
- this();
- read(in);
+ this();
+ read(in);
}
private ConstPool() {
- items = new LongVector(SIZE);
- numOfItems = 0;
- addItem(null); // index 0 is reserved by the JVM.
- classes = new Hashtable();
- strings = new Hashtable();
- thisClassInfo = 0;
+ items = new LongVector(SIZE);
+ numOfItems = 0;
+ addItem(null); // index 0 is reserved by the JVM.
+ classes = new Hashtable();
+ strings = new Hashtable();
+ thisClassInfo = 0;
}
/**
* Returns the name of the class using this constant pool table.
*/
public String getClassName() {
- return getClassInfo(thisClassInfo);
+ return getClassInfo(thisClassInfo);
}
/**
* specifying the class using this constant pool table.
*/
public int getThisClassInfo() {
- return thisClassInfo;
+ return thisClassInfo;
}
void setThisClassInfo(int i) {
- thisClassInfo = i;
+ thisClassInfo = i;
}
ConstInfo getItem(int n) {
- return (ConstInfo)items.elementAt(n);
+ return (ConstInfo)items.elementAt(n);
}
/**
* entry at the given index.
*/
public int getTag(int index) {
- return getItem(index).getTag();
+ return getItem(index).getTag();
}
/**
* Reads <code>CONSTANT_Class_info</code> structure
* at the given index.
*
- * @return a fully-qualified class or interface name specified
- * by <code>name_index</code>.
+ * @return a fully-qualified class or interface name specified
+ * by <code>name_index</code>.
*/
public String getClassInfo(int index) {
- ClassInfo c = (ClassInfo)getItem(index);
- if (c == null)
- return null;
- else
- return Descriptor.toJavaName(getUtf8Info(c.name));
+ ClassInfo c = (ClassInfo)getItem(index);
+ if (c == null)
+ return null;
+ else
+ return Descriptor.toJavaName(getUtf8Info(c.name));
}
/**
* at the given index.
*/
public int getNameAndTypeName(int index) {
- NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
- return ntinfo.memberName;
+ NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
+ return ntinfo.memberName;
}
/**
* at the given index.
*/
public int getNameAndTypeDescriptor(int index) {
- NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
- return ntinfo.typeDescriptor;
+ NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
+ return ntinfo.typeDescriptor;
}
/**
* at the given index.
*/
public int getFieldrefClass(int index) {
- FieldrefInfo finfo = (FieldrefInfo)getItem(index);
- return finfo.classIndex;
+ FieldrefInfo finfo = (FieldrefInfo)getItem(index);
+ return finfo.classIndex;
}
/**
* @return the name of the class at that <code>class_index</code>.
*/
public String getFieldrefClassName(int index) {
- FieldrefInfo f = (FieldrefInfo)getItem(index);
- if (f == null)
- return null;
- else
- return getClassInfo(f.classIndex);
+ FieldrefInfo f = (FieldrefInfo)getItem(index);
+ if (f == null)
+ return null;
+ else
+ return getClassInfo(f.classIndex);
}
/**
* at the given index.
*/
public int getFieldrefNameAndType(int index) {
- FieldrefInfo finfo = (FieldrefInfo)getItem(index);
- return finfo.nameAndTypeIndex;
+ FieldrefInfo finfo = (FieldrefInfo)getItem(index);
+ return finfo.nameAndTypeIndex;
}
/**
* <code>CONSTANT_NameAndType_info</code> structure
* indirectly specified by the given index.
*
- * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
- * @return the name of the field.
+ * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
+ * @return the name of the field.
*/
public String getFieldrefName(int index) {
- FieldrefInfo f = (FieldrefInfo)getItem(index);
- if (f == null)
- return null;
- else {
- NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex);
- if(n == null)
- return null;
- else
- return getUtf8Info(n.memberName);
- }
+ FieldrefInfo f = (FieldrefInfo)getItem(index);
+ if (f == null)
+ return null;
+ else {
+ NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex);
+ if(n == null)
+ return null;
+ else
+ return getUtf8Info(n.memberName);
+ }
}
/**
* <code>CONSTANT_NameAndType_info</code> structure
* indirectly specified by the given index.
*
- * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
- * @return the type descriptor of the field.
+ * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
+ * @return the type descriptor of the field.
*/
public String getFieldrefType(int index) {
- FieldrefInfo f = (FieldrefInfo)getItem(index);
- if (f == null)
- return null;
- else {
- NameAndTypeInfo n = (NameAndTypeInfo) getItem(f.nameAndTypeIndex);
- if(n == null)
- return null;
- else
- return getUtf8Info(n.typeDescriptor);
- }
+ FieldrefInfo f = (FieldrefInfo)getItem(index);
+ if (f == null)
+ return null;
+ else {
+ NameAndTypeInfo n = (NameAndTypeInfo) getItem(f.nameAndTypeIndex);
+ if(n == null)
+ return null;
+ else
+ return getUtf8Info(n.typeDescriptor);
+ }
}
/**
* at the given index.
*/
public int getMethodrefClass(int index) {
- MethodrefInfo minfo = (MethodrefInfo)getItem(index);
- return minfo.classIndex;
+ MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+ return minfo.classIndex;
}
/**
* @return the name of the class at that <code>class_index</code>.
*/
public String getMethodrefClassName(int index) {
- MethodrefInfo minfo = (MethodrefInfo)getItem(index);
- if (minfo == null)
- return null;
- else
- return getClassInfo(minfo.classIndex);
+ MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+ if (minfo == null)
+ return null;
+ else
+ return getClassInfo(minfo.classIndex);
}
/**
* at the given index.
*/
public int getMethodrefNameAndType(int index) {
- MethodrefInfo minfo = (MethodrefInfo)getItem(index);
- return minfo.nameAndTypeIndex;
+ MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+ return minfo.nameAndTypeIndex;
}
/**
* <code>CONSTANT_NameAndType_info</code> structure
* indirectly specified by the given index.
*
- * @param index an index to a <code>CONSTANT_Methodref_info</code>.
- * @return the name of the method.
+ * @param index an index to a <code>CONSTANT_Methodref_info</code>.
+ * @return the name of the method.
*/
public String getMethodrefName(int index) {
- MethodrefInfo minfo = (MethodrefInfo)getItem(index);
- if (minfo == null)
- return null;
- else {
- NameAndTypeInfo n
- = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
- if(n == null)
- return null;
- else
- return getUtf8Info(n.memberName);
- }
+ MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+ if (minfo == null)
+ return null;
+ else {
+ NameAndTypeInfo n
+ = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
+ if(n == null)
+ return null;
+ else
+ return getUtf8Info(n.memberName);
+ }
}
/**
* <code>CONSTANT_NameAndType_info</code> structure
* indirectly specified by the given index.
*
- * @param index an index to a <code>CONSTANT_Methodref_info</code>.
- * @return the descriptor of the method.
+ * @param index an index to a <code>CONSTANT_Methodref_info</code>.
+ * @return the descriptor of the method.
*/
public String getMethodrefType(int index) {
- MethodrefInfo minfo = (MethodrefInfo)getItem(index);
- if (minfo == null)
- return null;
- else {
- NameAndTypeInfo n
- = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
- if(n == null)
- return null;
- else
- return getUtf8Info(n.typeDescriptor);
- }
+ MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+ if (minfo == null)
+ return null;
+ else {
+ NameAndTypeInfo n
+ = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
+ if(n == null)
+ return null;
+ else
+ return getUtf8Info(n.typeDescriptor);
+ }
}
/**
* at the given index.
*/
public int getInterfaceMethodrefClass(int index) {
- InterfaceMethodrefInfo minfo
- = (InterfaceMethodrefInfo)getItem(index);
- return minfo.classIndex;
+ InterfaceMethodrefInfo minfo
+ = (InterfaceMethodrefInfo)getItem(index);
+ return minfo.classIndex;
}
/**
* @return the name of the class at that <code>class_index</code>.
*/
public String getInterfaceMethodrefClassName(int index) {
- InterfaceMethodrefInfo minfo
- = (InterfaceMethodrefInfo)getItem(index);
- return getClassInfo(minfo.classIndex);
+ InterfaceMethodrefInfo minfo
+ = (InterfaceMethodrefInfo)getItem(index);
+ return getClassInfo(minfo.classIndex);
}
/**
* at the given index.
*/
public int getInterfaceMethodrefNameAndType(int index) {
- InterfaceMethodrefInfo minfo
- = (InterfaceMethodrefInfo)getItem(index);
- return minfo.nameAndTypeIndex;
+ InterfaceMethodrefInfo minfo
+ = (InterfaceMethodrefInfo)getItem(index);
+ return minfo.nameAndTypeIndex;
}
/**
* <code>CONSTANT_NameAndType_info</code> structure
* indirectly specified by the given index.
*
- * @param index an index to
- * a <code>CONSTANT_InterfaceMethodref_info</code>.
- * @return the name of the method.
+ * @param index an index to
+ * a <code>CONSTANT_InterfaceMethodref_info</code>.
+ * @return the name of the method.
*/
public String getInterfaceMethodrefName(int index) {
- InterfaceMethodrefInfo minfo
- = (InterfaceMethodrefInfo)getItem(index);
- if (minfo == null)
- return null;
- else {
- NameAndTypeInfo n
- = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
- if(n == null)
- return null;
- else
- return getUtf8Info(n.memberName);
- }
+ InterfaceMethodrefInfo minfo
+ = (InterfaceMethodrefInfo)getItem(index);
+ if (minfo == null)
+ return null;
+ else {
+ NameAndTypeInfo n
+ = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
+ if(n == null)
+ return null;
+ else
+ return getUtf8Info(n.memberName);
+ }
}
/**
* <code>CONSTANT_NameAndType_info</code> structure
* indirectly specified by the given index.
*
- * @param index an index to
- * a <code>CONSTANT_InterfaceMethodref_info</code>.
- * @return the descriptor of the method.
+ * @param index an index to
+ * a <code>CONSTANT_InterfaceMethodref_info</code>.
+ * @return the descriptor of the method.
*/
public String getInterfaceMethodrefType(int index) {
- InterfaceMethodrefInfo minfo
- = (InterfaceMethodrefInfo)getItem(index);
- if (minfo == null)
- return null;
- else {
- NameAndTypeInfo n
- = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
- if(n == null)
- return null;
- else
- return getUtf8Info(n.typeDescriptor);
- }
+ InterfaceMethodrefInfo minfo
+ = (InterfaceMethodrefInfo)getItem(index);
+ if (minfo == null)
+ return null;
+ else {
+ NameAndTypeInfo n
+ = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
+ if(n == null)
+ return null;
+ else
+ return getUtf8Info(n.typeDescriptor);
+ }
}
/**
* Reads <code>CONSTANT_Integer_info</code>, <code>_Float_info</code>,
* value.
*/
public Object getLdcValue(int index) {
- ConstInfo constInfo = this.getItem(index);
- Object value = null;
- if (constInfo instanceof StringInfo)
- value = this.getStringInfo(index);
- else if (constInfo instanceof FloatInfo)
- value = new Float(getFloatInfo(index));
- else if (constInfo instanceof IntegerInfo)
- value = new Integer(getIntegerInfo(index));
- else if (constInfo instanceof LongInfo)
- value = new Long(getLongInfo(index));
- else if (constInfo instanceof DoubleInfo)
- value = new Double(getDoubleInfo(index));
- else
- value = null;
+ ConstInfo constInfo = this.getItem(index);
+ Object value = null;
+ if (constInfo instanceof StringInfo)
+ value = this.getStringInfo(index);
+ else if (constInfo instanceof FloatInfo)
+ value = new Float(getFloatInfo(index));
+ else if (constInfo instanceof IntegerInfo)
+ value = new Integer(getIntegerInfo(index));
+ else if (constInfo instanceof LongInfo)
+ value = new Long(getLongInfo(index));
+ else if (constInfo instanceof DoubleInfo)
+ value = new Double(getDoubleInfo(index));
+ else
+ value = null;
- return value;
+ return value;
}
/**
* @return the value specified by this entry.
*/
public int getIntegerInfo(int index) {
- IntegerInfo i = (IntegerInfo)getItem(index);
- return i.value;
+ IntegerInfo i = (IntegerInfo)getItem(index);
+ return i.value;
}
/**
* @return the value specified by this entry.
*/
public float getFloatInfo(int index) {
- FloatInfo i = (FloatInfo)getItem(index);
- return i.value;
+ FloatInfo i = (FloatInfo)getItem(index);
+ return i.value;
}
/**
* @return the value specified by this entry.
*/
public long getLongInfo(int index) {
- LongInfo i = (LongInfo)getItem(index);
- return i.value;
+ LongInfo i = (LongInfo)getItem(index);
+ return i.value;
}
/**
* @return the value specified by this entry.
*/
public double getDoubleInfo(int index) {
- DoubleInfo i = (DoubleInfo)getItem(index);
- return i.value;
+ DoubleInfo i = (DoubleInfo)getItem(index);
+ return i.value;
}
/**
* @return the string specified by <code>string_index</code>.
*/
public String getStringInfo(int index) {
- StringInfo si = (StringInfo)getItem(index);
- return getUtf8Info(si.string);
+ StringInfo si = (StringInfo)getItem(index);
+ return getUtf8Info(si.string);
}
/**
* @return the string specified by this entry.
*/
public String getUtf8Info(int index) {
- Utf8Info utf = (Utf8Info)getItem(index);
- return utf.string;
+ Utf8Info utf = (Utf8Info)getItem(index);
+ return utf.string;
}
/**
* structure at the given index represents the constructor
* of the given class.
*
- * @return the <code>descriptor_index</code> specifying
- * the type descriptor of the that constructor.
- * If it is not that constructor,
- * <code>isConstructor()</code> returns 0.
+ * @return the <code>descriptor_index</code> specifying
+ * the type descriptor of the that constructor.
+ * If it is not that constructor,
+ * <code>isConstructor()</code> returns 0.
*/
public int isConstructor(String classname, int index) {
- return isMember(classname, MethodInfo.nameInit, index);
+ return isMember(classname, MethodInfo.nameInit, index);
}
/**
* at the given index represents the member with the specified
* name and declaring class.
*
- * @param classname the class declaring the member
- * @param membername the member name
- * @param index the index into the constant pool table
+ * @param classname the class declaring the member
+ * @param membername the member name
+ * @param index the index into the constant pool table
*
- * @return the <code>descriptor_index</code> specifying
- * the type descriptor of that member.
- * If it is not that member,
- * <code>isMember()</code> returns 0.
+ * @return the <code>descriptor_index</code> specifying
+ * the type descriptor of that member.
+ * If it is not that member,
+ * <code>isMember()</code> returns 0.
*/
public int isMember(String classname, String membername, int index) {
- MemberrefInfo minfo = (MemberrefInfo)getItem(index);
- if (getClassInfo(minfo.classIndex).equals(classname)) {
- NameAndTypeInfo ntinfo
- = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
- if (getUtf8Info(ntinfo.memberName).equals(membername))
- return ntinfo.typeDescriptor;
- }
+ MemberrefInfo minfo = (MemberrefInfo)getItem(index);
+ if (getClassInfo(minfo.classIndex).equals(classname)) {
+ NameAndTypeInfo ntinfo
+ = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
+ if (getUtf8Info(ntinfo.memberName).equals(membername))
+ return ntinfo.typeDescriptor;
+ }
- return 0; // false
+ return 0; // false
}
private int addItem(ConstInfo info) {
- items.addElement(info);
- return numOfItems++;
+ items.addElement(info);
+ return numOfItems++;
}
/**
* The class names that the item refers to are renamed according
* to the given map.
*
- * @param n the <i>n</i>-th item
- * @param dest destination constant pool table
- * @param classnames the map or null.
+ * @param n the <i>n</i>-th item
+ * @param dest destination constant pool table
+ * @param classnames the map or null.
*/
public int copy(int n, ConstPool dest, Map classnames) {
- if (n == 0)
- return 0;
+ if (n == 0)
+ return 0;
- ConstInfo info = getItem(n);
- return info.copy(this, dest, classnames);
+ ConstInfo info = getItem(n);
+ return info.copy(this, dest, classnames);
}
int addConstInfoPadding() {
- return addItem(new ConstInfoPadding());
+ return addItem(new ConstInfoPadding());
}
/**
* <p>This also adds a <code>CONSTANT_Utf8_info</code> structure
* for storing the class name.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addClassInfo(CtClass c) {
- if (c == THIS)
- return thisClassInfo;
- else if (!c.isArray())
- return addClassInfo(c.getName());
- else {
- // an array type is recorded in the hashtable with
- // the key "[L<classname>;" instead of "<classname>".
- //
- // note: toJvmName(toJvmName(c)) is equal to toJvmName(c).
+ if (c == THIS)
+ return thisClassInfo;
+ else if (!c.isArray())
+ return addClassInfo(c.getName());
+ else {
+ // an array type is recorded in the hashtable with
+ // the key "[L<classname>;" instead of "<classname>".
+ //
+ // note: toJvmName(toJvmName(c)) is equal to toJvmName(c).
- return addClassInfo(Descriptor.toJvmName(c));
- }
+ return addClassInfo(Descriptor.toJvmName(c));
+ }
}
/**
* <p>This also adds a <code>CONSTANT_Utf8_info</code> structure
* for storing the class name.
*
- * @param qname a fully-qualified class name
- * (or the JVM-internal representation of that name).
- * @return the index of the added entry.
+ * @param qname a fully-qualified class name
+ * (or the JVM-internal representation of that name).
+ * @return the index of the added entry.
*/
public int addClassInfo(String qname) {
- ClassInfo info = (ClassInfo)classes.get(qname);
- if (info != null)
- return info.index;
- else {
- int utf8 = addUtf8Info(Descriptor.toJvmName(qname));
- info = new ClassInfo(utf8, numOfItems);
- classes.put(qname, info);
- return addItem(info);
- }
+ ClassInfo info = (ClassInfo)classes.get(qname);
+ if (info != null)
+ return info.index;
+ else {
+ int utf8 = addUtf8Info(Descriptor.toJvmName(qname));
+ info = new ClassInfo(utf8, numOfItems);
+ classes.put(qname, info);
+ return addItem(info);
+ }
}
/**
*
* <p>This also adds <code>CONSTANT_Utf8_info</code> structures.
*
- * @param name <code>name_index</code>
- * @param type <code>descriptor_index</code>
- * @return the index of the added entry.
+ * @param name <code>name_index</code>
+ * @param type <code>descriptor_index</code>
+ * @return the index of the added entry.
*/
public int addNameAndTypeInfo(String name, String type) {
- return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type));
+ return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type));
}
/**
* Adds a new <code>CONSTANT_NameAndType_info</code> structure.
*
- * @param name <code>name_index</code>
- * @param type <code>descriptor_index</code>
- * @return the index of the added entry.
+ * @param name <code>name_index</code>
+ * @param type <code>descriptor_index</code>
+ * @return the index of the added entry.
*/
public int addNameAndTypeInfo(int name, int type) {
- return addItem(new NameAndTypeInfo(name, type));
+ return addItem(new NameAndTypeInfo(name, type));
}
/**
* <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
* structure.
*
- * @param classInfo <code>class_index</code>
- * @param name <code>name_index</code>
- * of <code>CONSTANT_NameAndType_info</code>.
- * @param type <code>descriptor_index</code>
- * of <code>CONSTANT_NameAndType_info</code>.
- * @return the index of the added entry.
+ * @param classInfo <code>class_index</code>
+ * @param name <code>name_index</code>
+ * of <code>CONSTANT_NameAndType_info</code>.
+ * @param type <code>descriptor_index</code>
+ * of <code>CONSTANT_NameAndType_info</code>.
+ * @return the index of the added entry.
*/
public int addFieldrefInfo(int classInfo, String name, String type) {
- int nt = addNameAndTypeInfo(name, type);
- return addFieldrefInfo(classInfo, nt);
+ int nt = addNameAndTypeInfo(name, type);
+ return addFieldrefInfo(classInfo, nt);
}
/**
* Adds a new <code>CONSTANT_Fieldref_info</code> structure.
*
- * @param classInfo <code>class_index</code>
- * @param nameandtypeinfo <code>name_and_type_index</code>.
- * @return the index of the added entry.
+ * @param classInfo <code>class_index</code>
+ * @param nameandtypeinfo <code>name_and_type_index</code>.
+ * @return the index of the added entry.
*/
public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) {
- return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo));
+ return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo));
}
/**
* <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
* structure.
*
- * @param classInfo <code>class_index</code>
- * @param name <code>name_index</code>
- * of <code>CONSTANT_NameAndType_info</code>.
- * @param type <code>descriptor_index</code>
- * of <code>CONSTANT_NameAndType_info</code>.
- * @return the index of the added entry.
+ * @param classInfo <code>class_index</code>
+ * @param name <code>name_index</code>
+ * of <code>CONSTANT_NameAndType_info</code>.
+ * @param type <code>descriptor_index</code>
+ * of <code>CONSTANT_NameAndType_info</code>.
+ * @return the index of the added entry.
*/
public int addMethodrefInfo(int classInfo, String name, String type) {
- int nt = addNameAndTypeInfo(name, type);
- return addMethodrefInfo(classInfo, nt);
+ int nt = addNameAndTypeInfo(name, type);
+ return addMethodrefInfo(classInfo, nt);
}
/**
* Adds a new <code>CONSTANT_Methodref_info</code> structure.
*
- * @param classInfo <code>class_index</code>
- * @param nameandtypeinfo <code>name_and_type_index</code>.
- * @return the index of the added entry.
+ * @param classInfo <code>class_index</code>
+ * @param nameandtypeinfo <code>name_and_type_index</code>.
+ * @return the index of the added entry.
*/
public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) {
- return addItem(new MethodrefInfo(classInfo, nameAndTypeInfo));
+ return addItem(new MethodrefInfo(classInfo, nameAndTypeInfo));
}
/**
* <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
* structure.
*
- * @param classInfo <code>class_index</code>
- * @param name <code>name_index</code>
- * of <code>CONSTANT_NameAndType_info</code>.
- * @param type <code>descriptor_index</code>
- * of <code>CONSTANT_NameAndType_info</code>.
- * @return the index of the added entry.
+ * @param classInfo <code>class_index</code>
+ * @param name <code>name_index</code>
+ * of <code>CONSTANT_NameAndType_info</code>.
+ * @param type <code>descriptor_index</code>
+ * of <code>CONSTANT_NameAndType_info</code>.
+ * @return the index of the added entry.
*/
public int addInterfaceMethodrefInfo(int classInfo, String name,
- String type) {
- int nt = addNameAndTypeInfo(name, type);
- return addInterfaceMethodrefInfo(classInfo, nt);
+ String type) {
+ int nt = addNameAndTypeInfo(name, type);
+ return addInterfaceMethodrefInfo(classInfo, nt);
}
/**
* Adds a new <code>CONSTANT_InterfaceMethodref_info</code>
* structure.
*
- * @param classInfo <code>class_index</code>
- * @param nameandtypeinfo <code>name_and_type_index</code>.
- * @return the index of the added entry.
+ * @param classInfo <code>class_index</code>
+ * @param nameandtypeinfo <code>name_and_type_index</code>.
+ * @return the index of the added entry.
*/
public int addInterfaceMethodrefInfo(int classInfo,
- int nameAndTypeInfo) {
- return addItem(new InterfaceMethodrefInfo(classInfo,
- nameAndTypeInfo));
+ int nameAndTypeInfo) {
+ return addItem(new InterfaceMethodrefInfo(classInfo,
+ nameAndTypeInfo));
}
/**
* <p>This also adds a new <code>CONSTANT_Utf8_info</code>
* structure.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addStringInfo(String str) {
- return addItem(new StringInfo(addUtf8Info(str)));
+ return addItem(new StringInfo(addUtf8Info(str)));
}
/**
* Adds a new <code>CONSTANT_Integer_info</code>
* structure.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addIntegerInfo(int i) {
- return addItem(new IntegerInfo(i));
+ return addItem(new IntegerInfo(i));
}
/**
* Adds a new <code>CONSTANT_Float_info</code>
* structure.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addFloatInfo(float f) {
- return addItem(new FloatInfo(f));
+ return addItem(new FloatInfo(f));
}
/**
* Adds a new <code>CONSTANT_Long_info</code>
* structure.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addLongInfo(long l) {
- int i = addItem(new LongInfo(l));
- addItem(new ConstInfoPadding());
- return i;
+ int i = addItem(new LongInfo(l));
+ addItem(new ConstInfoPadding());
+ return i;
}
/**
* Adds a new <code>CONSTANT_Double_info</code>
* structure.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addDoubleInfo(double d) {
- int i = addItem(new DoubleInfo(d));
- addItem(new ConstInfoPadding());
- return i;
+ int i = addItem(new DoubleInfo(d));
+ addItem(new ConstInfoPadding());
+ return i;
}
/**
* a duplicated entry.
* Instead, it returns the index of the entry already recorded.
*
- * @return the index of the added entry.
+ * @return the index of the added entry.
*/
public int addUtf8Info(String utf8) {
- Utf8Info info = (Utf8Info)strings.get(utf8);
- if (info != null)
- return info.index;
- else {
- info = new Utf8Info(utf8, numOfItems);
- strings.put(utf8, info);
- return addItem(info);
- }
+ Utf8Info info = (Utf8Info)strings.get(utf8);
+ if (info != null)
+ return info.index;
+ else {
+ info = new Utf8Info(utf8, numOfItems);
+ strings.put(utf8, info);
+ return addItem(info);
+ }
}
/**
* Replaces all occurrences of a class name.
*
- * @param oldName the replaced name
- * @param newName the substituted name.
+ * @param oldName the replaced name
+ * @param newName the substituted name.
*/
public void renameClass(String oldName, String newName) {
- LongVector v = items;
- int size = numOfItems;
- for (int i = 1; i < size; ++i)
- ((ConstInfo)v.elementAt(i)).renameClass(this, oldName, newName);
+ LongVector v = items;
+ int size = numOfItems;
+ for (int i = 1; i < size; ++i)
+ ((ConstInfo)v.elementAt(i)).renameClass(this, oldName, newName);
}
/**
* Replaces all occurrences of class names.
*
- * @param classnames specifies pairs of replaced and substituted
- * name.
+ * @param classnames specifies pairs of replaced and substituted
+ * name.
*/
public void renameClass(Map classnames) {
- LongVector v = items;
- int size = numOfItems;
- for (int i = 1; i < size; ++i)
- ((ConstInfo)v.elementAt(i)).renameClass(this, classnames);
+ LongVector v = items;
+ int size = numOfItems;
+ for (int i = 1; i < size; ++i)
+ ((ConstInfo)v.elementAt(i)).renameClass(this, classnames);
}
private void read(DataInputStream in) throws IOException {
- int n = in.readUnsignedShort();
- while (--n > 0) { // index 0 is reserved by JVM
- int tag = readOne(in);
- if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) {
- addItem(new ConstInfoPadding());
- --n;
- }
- }
+ int n = in.readUnsignedShort();
+ while (--n > 0) { // index 0 is reserved by JVM
+ int tag = readOne(in);
+ if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) {
+ addItem(new ConstInfoPadding());
+ --n;
+ }
+ }
}
private int readOne(DataInputStream in) throws IOException {
- ConstInfo info;
- int tag = in.readUnsignedByte();
- switch (tag) {
- case Utf8Info.tag : // 1
- info = new Utf8Info(in, numOfItems);
- strings.put(((Utf8Info)info).string, info);
- break;
- case IntegerInfo.tag : // 3
- info = new IntegerInfo(in);
- break;
- case FloatInfo.tag : // 4
- info = new FloatInfo(in);
- break;
- case LongInfo.tag : // 5
- info = new LongInfo(in);
- break;
- case DoubleInfo.tag : // 6
- info = new DoubleInfo(in);
- break;
- case ClassInfo.tag : // 7
- info = new ClassInfo(in, numOfItems);
- // classes.put(<classname>, info);
- break;
- case StringInfo.tag : // 8
- info = new StringInfo(in);
- break;
- case FieldrefInfo.tag : // 9
- info = new FieldrefInfo(in);
- break;
- case MethodrefInfo.tag : // 10
- info = new MethodrefInfo(in);
- break;
- case InterfaceMethodrefInfo.tag : // 11
- info = new InterfaceMethodrefInfo(in);
- break;
- case NameAndTypeInfo.tag : // 12
- info = new NameAndTypeInfo(in);
- break;
- default :
- throw new IOException("invalid constant type: " + tag);
- }
-
- addItem(info);
- return tag;
+ ConstInfo info;
+ int tag = in.readUnsignedByte();
+ switch (tag) {
+ case Utf8Info.tag : // 1
+ info = new Utf8Info(in, numOfItems);
+ strings.put(((Utf8Info)info).string, info);
+ break;
+ case IntegerInfo.tag : // 3
+ info = new IntegerInfo(in);
+ break;
+ case FloatInfo.tag : // 4
+ info = new FloatInfo(in);
+ break;
+ case LongInfo.tag : // 5
+ info = new LongInfo(in);
+ break;
+ case DoubleInfo.tag : // 6
+ info = new DoubleInfo(in);
+ break;
+ case ClassInfo.tag : // 7
+ info = new ClassInfo(in, numOfItems);
+ // classes.put(<classname>, info);
+ break;
+ case StringInfo.tag : // 8
+ info = new StringInfo(in);
+ break;
+ case FieldrefInfo.tag : // 9
+ info = new FieldrefInfo(in);
+ break;
+ case MethodrefInfo.tag : // 10
+ info = new MethodrefInfo(in);
+ break;
+ case InterfaceMethodrefInfo.tag : // 11
+ info = new InterfaceMethodrefInfo(in);
+ break;
+ case NameAndTypeInfo.tag : // 12
+ info = new NameAndTypeInfo(in);
+ break;
+ default :
+ throw new IOException("invalid constant type: " + tag);
+ }
+
+ addItem(info);
+ return tag;
}
/**
* Writes the contents of the constant pool table.
*/
public void write(DataOutputStream out) throws IOException {
- out.writeShort(numOfItems);
- LongVector v = items;
- int size = numOfItems;
- for (int i = 1; i < size; ++i)
- ((ConstInfo)v.elementAt(i)).write(out);
+ out.writeShort(numOfItems);
+ LongVector v = items;
+ int size = numOfItems;
+ for (int i = 1; i < size; ++i)
+ ((ConstInfo)v.elementAt(i)).write(out);
}
/**
* Prints the contents of the constant pool table.
*/
public void print() {
- print(new PrintWriter(System.out, true));
+ print(new PrintWriter(System.out, true));
}
/**
* Prints the contents of the constant pool table.
*/
public void print(PrintWriter out) {
- int size = numOfItems;
- for (int i = 1; i < size; ++i) {
- out.print(i);
- out.print(" ");
- ((ConstInfo)items.elementAt(i)).print(out);
- }
+ int size = numOfItems;
+ for (int i = 1; i < size; ++i) {
+ out.print(i);
+ out.print(" ");
+ ((ConstInfo)items.elementAt(i)).print(out);
+ }
}
}
public void renameClass(ConstPool cp, String oldName, String newName) {}
public void renameClass(ConstPool cp, Map classnames) {}
public abstract int copy(ConstPool src, ConstPool dest, Map classnames);
- // ** classnames is a mapping between JVM names.
+ // ** classnames is a mapping between JVM names.
public abstract void write(DataOutputStream out) throws IOException;
public abstract void print(PrintWriter out);
public String toString() {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- PrintWriter out = new PrintWriter(bout);
- print(out);
- return bout.toString();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ PrintWriter out = new PrintWriter(bout);
+ print(out);
+ return bout.toString();
}
}
public int getTag() { return 0; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addConstInfoPadding();
+ return dest.addConstInfoPadding();
}
public void write(DataOutputStream out) throws IOException {}
public void print(PrintWriter out) {
- out.println("padding");
+ out.println("padding");
}
}
int index;
public ClassInfo(int className, int i) {
- name = className;
- index = i;
+ name = className;
+ index = i;
}
public ClassInfo(DataInputStream in, int i) throws IOException {
- name = in.readUnsignedShort();
- index = i;
+ name = in.readUnsignedShort();
+ index = i;
}
public int getTag() { return tag; }
public void renameClass(ConstPool cp, String oldName, String newName) {
- if (cp.getUtf8Info(name).equals(oldName))
- name = cp.addUtf8Info(newName);
+ if (cp.getUtf8Info(name).equals(oldName))
+ name = cp.addUtf8Info(newName);
}
public void renameClass(ConstPool cp, Map map) {
- String oldName = cp.getUtf8Info(name);
- String newName = (String)map.get(oldName);
- if (newName != null && !newName.equals(oldName))
- name = cp.addUtf8Info(newName);
+ String oldName = cp.getUtf8Info(name);
+ String newName = (String)map.get(oldName);
+ if (newName != null && !newName.equals(oldName))
+ name = cp.addUtf8Info(newName);
}
public int copy(ConstPool src, ConstPool dest, Map map) {
- String classname = src.getUtf8Info(name);
- if (map != null) {
- String newname = (String)map.get(classname);
- if (newname != null)
- classname = newname;
- }
+ String classname = src.getUtf8Info(name);
+ if (map != null) {
+ String newname = (String)map.get(classname);
+ if (newname != null)
+ classname = newname;
+ }
- return dest.addClassInfo(classname);
+ return dest.addClassInfo(classname);
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeShort(name);
+ out.writeByte(tag);
+ out.writeShort(name);
}
public void print(PrintWriter out) {
- out.print("Class #");
- out.println(name);
+ out.print("Class #");
+ out.println(name);
}
}
int typeDescriptor;
public NameAndTypeInfo(int name, int type) {
- memberName = name;
- typeDescriptor = type;
+ memberName = name;
+ typeDescriptor = type;
}
public NameAndTypeInfo(DataInputStream in) throws IOException {
- memberName = in.readUnsignedShort();
- typeDescriptor = in.readUnsignedShort();
+ memberName = in.readUnsignedShort();
+ typeDescriptor = in.readUnsignedShort();
}
public int getTag() { return tag; }
public void renameClass(ConstPool cp, String oldName, String newName) {
- String type = cp.getUtf8Info(typeDescriptor);
- String type2 = Descriptor.rename(type, oldName, newName);
- if (type != type2)
- typeDescriptor = cp.addUtf8Info(type2);
+ String type = cp.getUtf8Info(typeDescriptor);
+ String type2 = Descriptor.rename(type, oldName, newName);
+ if (type != type2)
+ typeDescriptor = cp.addUtf8Info(type2);
}
public void renameClass(ConstPool cp, Map map) {
- String type = cp.getUtf8Info(typeDescriptor);
- String type2 = Descriptor.rename(type, map);
- if (type != type2)
- typeDescriptor = cp.addUtf8Info(type2);
+ String type = cp.getUtf8Info(typeDescriptor);
+ String type2 = Descriptor.rename(type, map);
+ if (type != type2)
+ typeDescriptor = cp.addUtf8Info(type2);
}
public int copy(ConstPool src, ConstPool dest, Map map) {
- String mname = src.getUtf8Info(memberName);
- String tdesc = src.getUtf8Info(typeDescriptor);
- tdesc = Descriptor.rename(tdesc, map);
- return dest.addNameAndTypeInfo(dest.addUtf8Info(mname),
- dest.addUtf8Info(tdesc));
+ String mname = src.getUtf8Info(memberName);
+ String tdesc = src.getUtf8Info(typeDescriptor);
+ tdesc = Descriptor.rename(tdesc, map);
+ return dest.addNameAndTypeInfo(dest.addUtf8Info(mname),
+ dest.addUtf8Info(tdesc));
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeShort(memberName);
- out.writeShort(typeDescriptor);
+ out.writeByte(tag);
+ out.writeShort(memberName);
+ out.writeShort(typeDescriptor);
}
public void print(PrintWriter out) {
- out.print("NameAndType #");
- out.print(memberName);
- out.print(", type #");
- out.println(typeDescriptor);
+ out.print("NameAndType #");
+ out.print(memberName);
+ out.print(", type #");
+ out.println(typeDescriptor);
}
}
int nameAndTypeIndex;
public MemberrefInfo(int cindex, int ntindex) {
- classIndex = cindex;
- nameAndTypeIndex = ntindex;
+ classIndex = cindex;
+ nameAndTypeIndex = ntindex;
}
public MemberrefInfo(DataInputStream in) throws IOException {
- classIndex = in.readUnsignedShort();
- nameAndTypeIndex = in.readUnsignedShort();
+ classIndex = in.readUnsignedShort();
+ nameAndTypeIndex = in.readUnsignedShort();
}
public int copy(ConstPool src, ConstPool dest, Map map) {
- int classIndex2 = src.getItem(classIndex).copy(src, dest, map);
- int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map);
- return copy2(dest, classIndex2, ntIndex2);
+ int classIndex2 = src.getItem(classIndex).copy(src, dest, map);
+ int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map);
+ return copy2(dest, classIndex2, ntIndex2);
}
abstract protected int copy2(ConstPool dest, int cindex, int ntindex);
public void write(DataOutputStream out) throws IOException {
- out.writeByte(getTag());
- out.writeShort(classIndex);
- out.writeShort(nameAndTypeIndex);
+ out.writeByte(getTag());
+ out.writeShort(classIndex);
+ out.writeShort(nameAndTypeIndex);
}
public void print(PrintWriter out) {
- out.print(getTagName() + " #");
- out.print(classIndex);
- out.print(", name&type #");
- out.println(nameAndTypeIndex);
+ out.print(getTagName() + " #");
+ out.print(classIndex);
+ out.print(", name&type #");
+ out.println(nameAndTypeIndex);
}
public abstract String getTagName();
static final int tag = 9;
public FieldrefInfo(int cindex, int ntindex) {
- super(cindex, ntindex);
+ super(cindex, ntindex);
}
public FieldrefInfo(DataInputStream in) throws IOException {
- super(in);
+ super(in);
}
public int getTag() { return tag; }
public String getTagName() { return "Field"; }
protected int copy2(ConstPool dest, int cindex, int ntindex) {
- return dest.addFieldrefInfo(cindex, ntindex);
+ return dest.addFieldrefInfo(cindex, ntindex);
}
}
static final int tag = 10;
public MethodrefInfo(int cindex, int ntindex) {
- super(cindex, ntindex);
+ super(cindex, ntindex);
}
public MethodrefInfo(DataInputStream in) throws IOException {
- super(in);
+ super(in);
}
public int getTag() { return tag; }
public String getTagName() { return "Method"; }
protected int copy2(ConstPool dest, int cindex, int ntindex) {
- return dest.addMethodrefInfo(cindex, ntindex);
+ return dest.addMethodrefInfo(cindex, ntindex);
}
}
static final int tag = 11;
public InterfaceMethodrefInfo(int cindex, int ntindex) {
- super(cindex, ntindex);
+ super(cindex, ntindex);
}
public InterfaceMethodrefInfo(DataInputStream in) throws IOException {
- super(in);
+ super(in);
}
public int getTag() { return tag; }
public String getTagName() { return "Interface"; }
protected int copy2(ConstPool dest, int cindex, int ntindex) {
- return dest.addInterfaceMethodrefInfo(cindex, ntindex);
+ return dest.addInterfaceMethodrefInfo(cindex, ntindex);
}
}
int string;
public StringInfo(int str) {
- string = str;
+ string = str;
}
public StringInfo(DataInputStream in) throws IOException {
- string = in.readUnsignedShort();
+ string = in.readUnsignedShort();
}
public int getTag() { return tag; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addStringInfo(src.getUtf8Info(string));
+ return dest.addStringInfo(src.getUtf8Info(string));
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeShort(string);
+ out.writeByte(tag);
+ out.writeShort(string);
}
public void print(PrintWriter out) {
- out.print("String #");
- out.println(string);
+ out.print("String #");
+ out.println(string);
}
}
int value;
public IntegerInfo(int i) {
- value = i;
+ value = i;
}
public IntegerInfo(DataInputStream in) throws IOException {
- value = in.readInt();
+ value = in.readInt();
}
public int getTag() { return tag; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addIntegerInfo(value);
+ return dest.addIntegerInfo(value);
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeInt(value);
+ out.writeByte(tag);
+ out.writeInt(value);
}
public void print(PrintWriter out) {
- out.print("Integer ");
- out.println(value);
+ out.print("Integer ");
+ out.println(value);
}
}
float value;
public FloatInfo(float f) {
- value = f;
+ value = f;
}
public FloatInfo(DataInputStream in) throws IOException {
- value = in.readFloat();
+ value = in.readFloat();
}
public int getTag() { return tag; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addFloatInfo(value);
+ return dest.addFloatInfo(value);
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeFloat(value);
+ out.writeByte(tag);
+ out.writeFloat(value);
}
public void print(PrintWriter out) {
- out.print("Float ");
- out.println(value);
+ out.print("Float ");
+ out.println(value);
}
}
long value;
public LongInfo(long l) {
- value = l;
+ value = l;
}
public LongInfo(DataInputStream in) throws IOException {
- value = in.readLong();
+ value = in.readLong();
}
public int getTag() { return tag; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addLongInfo(value);
+ return dest.addLongInfo(value);
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeLong(value);
+ out.writeByte(tag);
+ out.writeLong(value);
}
public void print(PrintWriter out) {
- out.print("Long ");
- out.println(value);
+ out.print("Long ");
+ out.println(value);
}
}
double value;
public DoubleInfo(double d) {
- value = d;
+ value = d;
}
public DoubleInfo(DataInputStream in) throws IOException {
- value = in.readDouble();
+ value = in.readDouble();
}
public int getTag() { return tag; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addDoubleInfo(value);
+ return dest.addDoubleInfo(value);
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeDouble(value);
+ out.writeByte(tag);
+ out.writeDouble(value);
}
public void print(PrintWriter out) {
- out.print("Double ");
- out.println(value);
+ out.print("Double ");
+ out.println(value);
}
}
int index;
public Utf8Info(String utf8, int i) {
- string = utf8;
- index = i;
+ string = utf8;
+ index = i;
}
public Utf8Info(DataInputStream in, int i) throws IOException {
- string = in.readUTF();
- index = i;
+ string = in.readUTF();
+ index = i;
}
public int getTag() { return tag; }
public int copy(ConstPool src, ConstPool dest, Map map) {
- return dest.addUtf8Info(string);
+ return dest.addUtf8Info(string);
}
public void write(DataOutputStream out) throws IOException {
- out.writeByte(tag);
- out.writeUTF(string);
+ out.writeByte(tag);
+ out.writeUTF(string);
}
public void print(PrintWriter out) {
- out.print("UTF8 \"");
- out.print(string);
- out.println("\"");
+ out.print("UTF8 \"");
+ out.print(string);
+ out.println("\"");
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
public static final String tag = "ConstantValue";
ConstantAttribute(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, n, in);
+ super(cp, n, in);
}
/**
* Constructs a ConstantValue attribute.
*
- * @param cp a constant pool table.
- * @param index <code>constantvalue_index</code>
- * of <code>ConstantValue_attribute</code>.
+ * @param cp a constant pool table.
+ * @param index <code>constantvalue_index</code>
+ * of <code>ConstantValue_attribute</code>.
*/
public ConstantAttribute(ConstPool cp, int index) {
- super(cp, tag);
- byte[] bvalue = new byte[2];
- bvalue[0] = (byte)(index >>> 8);
- bvalue[1] = (byte)index;
- set(bvalue);
+ super(cp, tag);
+ byte[] bvalue = new byte[2];
+ bvalue[0] = (byte)(index >>> 8);
+ bvalue[1] = (byte)index;
+ set(bvalue);
}
/**
* Returns <code>constantvalue_index</code>.
*/
public int getConstantValue() {
- return ByteArray.readU16bit(get(), 0);
+ return ByteArray.readU16bit(get(), 0);
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- int index = getConstPool().copy(getConstantValue(), newCp,
- classnames);
- return new ConstantAttribute(newCp, index);
+ int index = getConstPool().copy(getConstantValue(), newCp,
+ classnames);
+ return new ConstantAttribute(newCp, index);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.util.Map;
* to <code>toJvmName(s)</code>.
*/
public static String toJvmName(String classname) {
- return classname.replace('.', '/');
+ return classname.replace('.', '/');
}
/**
* the JVM to the normal one used in Java.
*/
public static String toJavaName(String classname) {
- return classname.replace('/', '.');
+ return classname.replace('/', '.');
}
/**
* JVM.
*/
public static String toJvmName(CtClass clazz) {
- if (clazz.isArray())
- return of(clazz);
- else
- return toJvmName(clazz.getName());
+ if (clazz.isArray())
+ return of(clazz);
+ else
+ return toJvmName(clazz.getName());
}
/**
* Substitutes a class name
* in the given descriptor string.
*
- * @param desc descriptor string
- * @param oldname replaced JVM class name
- * @param newname substituted JVM class name
+ * @param desc descriptor string
+ * @param oldname replaced JVM class name
+ * @param newname substituted JVM class name
*
* @see Descriptor#toJvmName(String)
*/
public static String rename(String desc,
- String oldname, String newname) {
- if (desc.indexOf(oldname) < 0)
- return desc;
-
- StringBuffer newdesc = new StringBuffer();
- int head = 0;
- int i = 0;
- for (;;) {
- int j = desc.indexOf('L', i);
- if (j < 0)
- break;
- else if (desc.startsWith(oldname, j + 1)
- && desc.charAt(j + oldname.length() + 1) == ';') {
- newdesc.append(desc.substring(head, j));
- newdesc.append('L');
- newdesc.append(newname);
- newdesc.append(';');
- head = i = j + oldname.length() + 2;
- }
- else {
- i = desc.indexOf(';', j) + 1;
- if (i < 1)
- break; // ';' was not found.
- }
- }
-
- if (head == 0)
- return desc;
- else {
- int len = desc.length();
- if (head < len)
- newdesc.append(desc.substring(head, len));
-
- return newdesc.toString();
- }
+ String oldname, String newname) {
+ if (desc.indexOf(oldname) < 0)
+ return desc;
+
+ StringBuffer newdesc = new StringBuffer();
+ int head = 0;
+ int i = 0;
+ for (;;) {
+ int j = desc.indexOf('L', i);
+ if (j < 0)
+ break;
+ else if (desc.startsWith(oldname, j + 1)
+ && desc.charAt(j + oldname.length() + 1) == ';') {
+ newdesc.append(desc.substring(head, j));
+ newdesc.append('L');
+ newdesc.append(newname);
+ newdesc.append(';');
+ head = i = j + oldname.length() + 2;
+ }
+ else {
+ i = desc.indexOf(';', j) + 1;
+ if (i < 1)
+ break; // ';' was not found.
+ }
+ }
+
+ if (head == 0)
+ return desc;
+ else {
+ int len = desc.length();
+ if (head < len)
+ newdesc.append(desc.substring(head, len));
+
+ return newdesc.toString();
+ }
}
/**
* Substitutes class names in the given descriptor string
* according to the given <code>map</code>.
*
- * @param map a map between replaced and substituted
- * JVM class names.
+ * @param map a map between replaced and substituted
+ * JVM class names.
*
* @see Descriptor#toJvmName(String)
*/
public static String rename(String desc, Map map) {
- if (map == null)
- return desc;
-
- StringBuffer newdesc = new StringBuffer();
- int head = 0;
- int i = 0;
- for (;;) {
- int j = desc.indexOf('L', i);
- if (j < 0)
- break;
-
- int k = desc.indexOf(';', j);
- if (k < 0)
- break;
-
- i = k + 1;
- String name = desc.substring(j + 1, k);
- String name2 = (String)map.get(name);
- if (name2 != null) {
- newdesc.append(desc.substring(head, j));
- newdesc.append('L');
- newdesc.append(name2);
- newdesc.append(';');
- head = i;
- }
- }
-
- if (head == 0)
- return desc;
- else {
- int len = desc.length();
- if (head < len)
- newdesc.append(desc.substring(head, len));
-
- return newdesc.toString();
- }
+ if (map == null)
+ return desc;
+
+ StringBuffer newdesc = new StringBuffer();
+ int head = 0;
+ int i = 0;
+ for (;;) {
+ int j = desc.indexOf('L', i);
+ if (j < 0)
+ break;
+
+ int k = desc.indexOf(';', j);
+ if (k < 0)
+ break;
+
+ i = k + 1;
+ String name = desc.substring(j + 1, k);
+ String name2 = (String)map.get(name);
+ if (name2 != null) {
+ newdesc.append(desc.substring(head, j));
+ newdesc.append('L');
+ newdesc.append(name2);
+ newdesc.append(';');
+ head = i;
+ }
+ }
+
+ if (head == 0)
+ return desc;
+ else {
+ int len = desc.length();
+ if (head < len)
+ newdesc.append(desc.substring(head, len));
+
+ return newdesc.toString();
+ }
}
/**
* Returns the descriptor representing the given type.
*/
public static String of(CtClass type) {
- StringBuffer sbuf = new StringBuffer();
- toDescriptor(sbuf, type);
- return sbuf.toString();
+ StringBuffer sbuf = new StringBuffer();
+ toDescriptor(sbuf, type);
+ return sbuf.toString();
}
private static void toDescriptor(StringBuffer desc, CtClass type) {
- if (type.isArray()) {
- desc.append('[');
- try {
- toDescriptor(desc, type.getComponentType());
- }
- catch (NotFoundException e) {
- desc.append('L');
- String name = type.getName();
- desc.append(toJvmName(name.substring(0, name.length() - 2)));
- desc.append(';');
- }
- }
- else if (type.isPrimitive()) {
- CtPrimitiveType pt = (CtPrimitiveType)type;
- desc.append(pt.getDescriptor());
- }
- else { // class type
- desc.append('L');
- desc.append(type.getName().replace('.', '/'));
- desc.append(';');
- }
+ if (type.isArray()) {
+ desc.append('[');
+ try {
+ toDescriptor(desc, type.getComponentType());
+ }
+ catch (NotFoundException e) {
+ desc.append('L');
+ String name = type.getName();
+ desc.append(toJvmName(name.substring(0, name.length() - 2)));
+ desc.append(';');
+ }
+ }
+ else if (type.isPrimitive()) {
+ CtPrimitiveType pt = (CtPrimitiveType)type;
+ desc.append(pt.getDescriptor());
+ }
+ else { // class type
+ desc.append('L');
+ desc.append(type.getName().replace('.', '/'));
+ desc.append(';');
+ }
}
/**
* Returns the descriptor representing a constructor receiving
* the given parameter types.
*
- * @param paramTypes parameter types
+ * @param paramTypes parameter types
*/
public static String ofConstructor(CtClass[] paramTypes) {
- return ofMethod(CtClass.voidType, paramTypes);
+ return ofMethod(CtClass.voidType, paramTypes);
}
/**
* Returns the descriptor representing a method that receives
* the given parameter types and returns the given type.
*
- * @param returnType return type
- * @param paramTypes parameter types
+ * @param returnType return type
+ * @param paramTypes parameter types
*/
public static String ofMethod(CtClass returnType, CtClass[] paramTypes) {
- StringBuffer desc = new StringBuffer();
- desc.append('(');
- if (paramTypes != null) {
- int n = paramTypes.length;
- for (int i = 0; i < n; ++i)
- toDescriptor(desc, paramTypes[i]);
- }
-
- desc.append(')');
- if (returnType != null)
- toDescriptor(desc, returnType);
-
- return desc.toString();
+ StringBuffer desc = new StringBuffer();
+ desc.append('(');
+ if (paramTypes != null) {
+ int n = paramTypes.length;
+ for (int i = 0; i < n; ++i)
+ toDescriptor(desc, paramTypes[i]);
+ }
+
+ desc.append(')');
+ if (returnType != null)
+ toDescriptor(desc, returnType);
+
+ return desc.toString();
}
/**
* For example, if the given parameter types are two <code>int</code>,
* then this method returns <code>"(II)"</code>.
*
- * @param paramTypes parameter types
+ * @param paramTypes parameter types
*/
public static String ofParameters(CtClass[] paramTypes) {
- return ofMethod(null, paramTypes);
+ return ofMethod(null, paramTypes);
}
/**
*
* <p><code>classname</code> must not be an array type.
*
- * @param classname parameter type (not primitive type)
- * @param desc descriptor
+ * @param classname parameter type (not primitive type)
+ * @param desc descriptor
*/
public static String appendParameter(String classname,
- String desc) {
- int i = desc.indexOf(')');
- if (i < 0)
- return desc;
- else {
- StringBuffer newdesc = new StringBuffer();
- newdesc.append(desc.substring(0, i));
- newdesc.append('L');
- newdesc.append(classname.replace('.', '/'));
- newdesc.append(';');
- newdesc.append(desc.substring(i));
- return newdesc.toString();
- }
+ String desc) {
+ int i = desc.indexOf(')');
+ if (i < 0)
+ return desc;
+ else {
+ StringBuffer newdesc = new StringBuffer();
+ newdesc.append(desc.substring(0, i));
+ newdesc.append('L');
+ newdesc.append(classname.replace('.', '/'));
+ newdesc.append(';');
+ newdesc.append(desc.substring(i));
+ return newdesc.toString();
+ }
}
/**
*
* <p><code>classname</code> must not be an array type.
*
- * @param classname parameter type (not primitive type)
- * @param desc descriptor
+ * @param classname parameter type (not primitive type)
+ * @param desc descriptor
*/
public static String insertParameter(String classname,
- String desc) {
- if (desc.charAt(0) != '(')
- return desc;
- else
- return "(L" + classname.replace('.', '/') + ';'
- + desc.substring(1);
+ String desc) {
+ if (desc.charAt(0) != '(')
+ return desc;
+ else
+ return "(L" + classname.replace('.', '/') + ';'
+ + desc.substring(1);
}
/**
*
* <p><code>classname</code> must not be an array type.
*
- * @param classname return type
- * @param desc descriptor
+ * @param classname return type
+ * @param desc descriptor
*/
public static String changeReturnType(String classname, String desc) {
- int i = desc.indexOf(')');
- if (i < 0)
- return desc;
- else {
- StringBuffer newdesc = new StringBuffer();
- newdesc.append(desc.substring(0, i + 1));
- newdesc.append('L');
- newdesc.append(classname.replace('.', '/'));
- newdesc.append(';');
- return newdesc.toString();
- }
+ int i = desc.indexOf(')');
+ if (i < 0)
+ return desc;
+ else {
+ StringBuffer newdesc = new StringBuffer();
+ newdesc.append(desc.substring(0, i + 1));
+ newdesc.append('L');
+ newdesc.append(classname.replace('.', '/'));
+ newdesc.append(';');
+ return newdesc.toString();
+ }
}
/**
* Returns the <code>CtClass</code> objects representing the parameter
* types specified by the given descriptor.
*
- * @param desc descriptor
- * @param cp the class pool used for obtaining
- * a <code>CtClass</code> object.
+ * @param desc descriptor
+ * @param cp the class pool used for obtaining
+ * a <code>CtClass</code> object.
*/
public static CtClass[] getParameterTypes(String desc, ClassPool cp)
- throws NotFoundException
+ throws NotFoundException
{
- if (desc.charAt(0) != '(')
- return null;
- else {
- int num = numOfParameters(desc);
- CtClass[] args = new CtClass[num];
- int n = 0;
- int i = 1;
- do {
- i = toCtClass(cp, desc, i, args, n++);
- } while(i > 0);
- return args;
- }
+ if (desc.charAt(0) != '(')
+ return null;
+ else {
+ int num = numOfParameters(desc);
+ CtClass[] args = new CtClass[num];
+ int n = 0;
+ int i = 1;
+ do {
+ i = toCtClass(cp, desc, i, args, n++);
+ } while(i > 0);
+ return args;
+ }
}
/**
* Returns the <code>CtClass</code> object representing the return
* type specified by the given descriptor.
*
- * @param desc descriptor
- * @param cp the class pool used for obtaining
- * a <code>CtClass</code> object.
+ * @param desc descriptor
+ * @param cp the class pool used for obtaining
+ * a <code>CtClass</code> object.
*/
public static CtClass getReturnType(String desc, ClassPool cp)
- throws NotFoundException
+ throws NotFoundException
{
- int i = desc.indexOf(')');
- if (i < 0)
- return null;
- else {
- CtClass[] type = new CtClass[1];
- toCtClass(cp, desc, i + 1, type, 0);
- return type[0];
- }
+ int i = desc.indexOf(')');
+ if (i < 0)
+ return null;
+ else {
+ CtClass[] type = new CtClass[1];
+ toCtClass(cp, desc, i + 1, type, 0);
+ return type[0];
+ }
}
/**
* Returns the number of the prameters included in the given
* descriptor.
*
- * @param desc descriptor
+ * @param desc descriptor
*/
public static int numOfParameters(String desc) {
- int n = 0;
- int i = 1;
- for (;;) {
- char c = desc.charAt(i);
- if (c == ')')
- break;
-
- while (c == '[')
- c = desc.charAt(++i);
-
- if (c == 'L') {
- i = desc.indexOf(';', i) + 1;
- if (i <= 0)
- throw new IndexOutOfBoundsException("bad descriptor");
- }
- else
- ++i;
-
- ++n;
- }
-
- return n;
+ int n = 0;
+ int i = 1;
+ for (;;) {
+ char c = desc.charAt(i);
+ if (c == ')')
+ break;
+
+ while (c == '[')
+ c = desc.charAt(++i);
+
+ if (c == 'L') {
+ i = desc.indexOf(';', i) + 1;
+ if (i <= 0)
+ throw new IndexOutOfBoundsException("bad descriptor");
+ }
+ else
+ ++i;
+
+ ++n;
+ }
+
+ return n;
}
/**
* it accepts <code>Ljava.lang.Object;</code>
* as well as <code>Ljava/lang/Object;</code>.
*
- * @param desc descriptor
- * @param cp the class pool used for obtaining
- * a <code>CtClass</code> object.
+ * @param desc descriptor
+ * @param cp the class pool used for obtaining
+ * a <code>CtClass</code> object.
*/
public static CtClass toCtClass(String desc, ClassPool cp)
- throws NotFoundException
+ throws NotFoundException
{
- CtClass[] clazz = new CtClass[1];
- int res = toCtClass(cp, desc, 0, clazz, 0);
- if (res >= 0)
- return clazz[0];
- else {
- // maybe, you forgot to surround the class name with
- // L and ;. It violates the protocol, but I'm tolerant...
- return cp.get(desc.replace('/', '.'));
- }
+ CtClass[] clazz = new CtClass[1];
+ int res = toCtClass(cp, desc, 0, clazz, 0);
+ if (res >= 0)
+ return clazz[0];
+ else {
+ // maybe, you forgot to surround the class name with
+ // L and ;. It violates the protocol, but I'm tolerant...
+ return cp.get(desc.replace('/', '.'));
+ }
}
private static int toCtClass(ClassPool cp, String desc, int i,
- CtClass[] args, int n)
- throws NotFoundException
+ CtClass[] args, int n)
+ throws NotFoundException
{
- int i2;
- String name;
-
- int arrayDim = 0;
- char c = desc.charAt(i);
- while (c == '[') {
- ++arrayDim;
- c = desc.charAt(++i);
- }
-
- if (c == 'L') {
- i2 = desc.indexOf(';', ++i);
- name = desc.substring(i, i2++).replace('/', '.');
- }
- else {
- CtClass type = toPrimitiveClass(c);
- if (type == null)
- return -1; // error
-
- i2 = i + 1;
- if (arrayDim == 0) {
- args[n] = type;
- return i2; // neither an array type or a class type
- }
- else
- name = type.getName();
- }
-
- if (arrayDim > 0) {
- StringBuffer sbuf = new StringBuffer(name);
- while (arrayDim-- > 0)
- sbuf.append("[]");
-
- name = sbuf.toString();
- }
-
- args[n] = cp.get(name);
- return i2;
+ int i2;
+ String name;
+
+ int arrayDim = 0;
+ char c = desc.charAt(i);
+ while (c == '[') {
+ ++arrayDim;
+ c = desc.charAt(++i);
+ }
+
+ if (c == 'L') {
+ i2 = desc.indexOf(';', ++i);
+ name = desc.substring(i, i2++).replace('/', '.');
+ }
+ else {
+ CtClass type = toPrimitiveClass(c);
+ if (type == null)
+ return -1; // error
+
+ i2 = i + 1;
+ if (arrayDim == 0) {
+ args[n] = type;
+ return i2; // neither an array type or a class type
+ }
+ else
+ name = type.getName();
+ }
+
+ if (arrayDim > 0) {
+ StringBuffer sbuf = new StringBuffer(name);
+ while (arrayDim-- > 0)
+ sbuf.append("[]");
+
+ name = sbuf.toString();
+ }
+
+ args[n] = cp.get(name);
+ return i2;
}
private static CtClass toPrimitiveClass(char c) {
- CtClass type = null;
- switch (c) {
- case 'Z' :
- type = CtClass.booleanType;
- break;
- case 'C' :
- type = CtClass.charType;
- break;
- case 'B' :
- type = CtClass.byteType;
- break;
- case 'S' :
- type = CtClass.shortType;
- break;
- case 'I' :
- type = CtClass.intType;
- break;
- case 'J' :
- type = CtClass.longType;
- break;
- case 'F' :
- type = CtClass.floatType;
- break;
- case 'D' :
- type = CtClass.doubleType;
- break;
- case 'V' :
- type = CtClass.voidType;
- break;
- }
-
- return type;
+ CtClass type = null;
+ switch (c) {
+ case 'Z' :
+ type = CtClass.booleanType;
+ break;
+ case 'C' :
+ type = CtClass.charType;
+ break;
+ case 'B' :
+ type = CtClass.byteType;
+ break;
+ case 'S' :
+ type = CtClass.shortType;
+ break;
+ case 'I' :
+ type = CtClass.intType;
+ break;
+ case 'J' :
+ type = CtClass.longType;
+ break;
+ case 'F' :
+ type = CtClass.floatType;
+ break;
+ case 'D' :
+ type = CtClass.doubleType;
+ break;
+ case 'V' :
+ type = CtClass.voidType;
+ break;
+ }
+
+ return type;
}
/**
* of all the parameters). For example, if the descriptor is
* "(I)D", then this method returns 1 (= 2 - 1).
*
- * @param desc descriptor
+ * @param desc descriptor
*/
public static int dataSize(String desc) {
- int n = 0;
- char c = desc.charAt(0);
- if (c == '(') {
- int i = 1;
- for (;;) {
- c = desc.charAt(i);
- if (c == ')') {
- c = desc.charAt(i + 1);
- break;
- }
-
- boolean array = false;
- while (c == '[') {
- array = true;
- c = desc.charAt(++i);
- }
-
- if (c == 'L') {
- i = desc.indexOf(';', i) + 1;
- if (i <= 0)
- throw new IndexOutOfBoundsException("bad descriptor");
- }
- else
- ++i;
-
- if (!array && (c == 'J' || c == 'D'))
- n -= 2;
- else
- --n;
- }
- }
-
- if (c == 'J' || c == 'D')
- n += 2;
- else if (c != 'V')
- ++n;
-
- return n;
+ int n = 0;
+ char c = desc.charAt(0);
+ if (c == '(') {
+ int i = 1;
+ for (;;) {
+ c = desc.charAt(i);
+ if (c == ')') {
+ c = desc.charAt(i + 1);
+ break;
+ }
+
+ boolean array = false;
+ while (c == '[') {
+ array = true;
+ c = desc.charAt(++i);
+ }
+
+ if (c == 'L') {
+ i = desc.indexOf(';', i) + 1;
+ if (i <= 0)
+ throw new IndexOutOfBoundsException("bad descriptor");
+ }
+ else
+ ++i;
+
+ if (!array && (c == 'J' || c == 'D'))
+ n -= 2;
+ else
+ --n;
+ }
+ }
+
+ if (c == 'J' || c == 'D')
+ n += 2;
+ else if (c != 'V')
+ ++n;
+
+ return n;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
int catchType;
ExceptionTableEntry(int start, int end, int handle, int type) {
- startPc = start;
- endPc = end;
- handlerPc = handle;
- catchType = type;
+ startPc = start;
+ endPc = end;
+ handlerPc = handle;
+ catchType = type;
}
}
/**
* Constructs an <code>exception_table[]</code>.
*
- * @param cp constant pool table.
+ * @param cp constant pool table.
*/
public ExceptionTable(ConstPool cp) {
- constPool = cp;
- entries = new ArrayList();
+ constPool = cp;
+ entries = new ArrayList();
}
ExceptionTable(ConstPool cp, DataInputStream in) throws IOException {
- constPool = cp;
- int length = in.readUnsignedShort();
- ArrayList list = new ArrayList(length);
- for (int i = 0; i < length; ++i) {
- int start = in.readUnsignedShort();
- int end = in.readUnsignedShort();
- int handle = in.readUnsignedShort();
- int type = in.readUnsignedShort();
- list.add(new ExceptionTableEntry(start, end, handle, type));
- }
+ constPool = cp;
+ int length = in.readUnsignedShort();
+ ArrayList list = new ArrayList(length);
+ for (int i = 0; i < length; ++i) {
+ int start = in.readUnsignedShort();
+ int end = in.readUnsignedShort();
+ int handle = in.readUnsignedShort();
+ int type = in.readUnsignedShort();
+ list.add(new ExceptionTableEntry(start, end, handle, type));
+ }
- entries = list;
+ entries = list;
}
/**
* of entries in the <code>exception_table[]</code>.
*/
public int size() {
- return entries.size();
+ return entries.size();
}
/**
* Returns <code>startPc</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
+ * @param nth the <i>n</i>-th (>= 0).
*/
public int startPc(int nth) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- return e.startPc;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ return e.startPc;
}
/**
* Sets <code>startPc</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
- * @param value new value.
+ * @param nth the <i>n</i>-th (>= 0).
+ * @param value new value.
*/
public void setStartPc(int nth, int value) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- e.startPc = value;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ e.startPc = value;
}
/**
* Returns <code>endPc</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
+ * @param nth the <i>n</i>-th (>= 0).
*/
public int endPc(int nth) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- return e.endPc;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ return e.endPc;
}
/**
* Sets <code>endPc</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
- * @param value new value.
+ * @param nth the <i>n</i>-th (>= 0).
+ * @param value new value.
*/
public void setEndPc(int nth, int value) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- e.endPc = value;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ e.endPc = value;
}
/**
* Returns <code>handlerPc</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
+ * @param nth the <i>n</i>-th (>= 0).
*/
public int handlerPc(int nth) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- return e.handlerPc;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ return e.handlerPc;
}
/**
* Sets <code>handlerPc</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
- * @param value new value.
+ * @param nth the <i>n</i>-th (>= 0).
+ * @param value new value.
*/
public void setHandlerPc(int nth, int value) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- e.handlerPc = value;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ e.handlerPc = value;
}
/**
* Returns <code>catchType</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
+ * @param nth the <i>n</i>-th (>= 0).
*/
public int catchType(int nth) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- return e.catchType;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ return e.catchType;
}
/**
* Sets <code>catchType</code> of the <i>n</i>-th entry.
*
- * @param nth the <i>n</i>-th (>= 0).
- * @param value new value.
+ * @param nth the <i>n</i>-th (>= 0).
+ * @param value new value.
*/
public void setCatchType(int nth, int value) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
- e.catchType = value;
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
+ e.catchType = value;
}
/**
* Copies the given exception table at the specified position
* in the table.
*
- * @param index index (>= 0) at which the entry is to be inserted.
- * @param offset the offset added to the code position.
+ * @param index index (>= 0) at which the entry is to be inserted.
+ * @param offset the offset added to the code position.
*/
public void add(int index, ExceptionTable table, int offset) {
- int len = table.size();
- while (--len >= 0) {
- ExceptionTableEntry e
- = (ExceptionTableEntry)table.entries.get(len);
- add(index, e.startPc + offset, e.endPc + offset,
- e.handlerPc + offset, e.catchType);
- }
+ int len = table.size();
+ while (--len >= 0) {
+ ExceptionTableEntry e
+ = (ExceptionTableEntry)table.entries.get(len);
+ add(index, e.startPc + offset, e.endPc + offset,
+ e.handlerPc + offset, e.catchType);
+ }
}
/**
* Adds a new entry at the specified position in the table.
*
- * @param index index (>= 0) at which the entry is to be inserted.
- * @param start <code>startPc</code>
- * @param end <code>endPc</code>
- * @param handler <code>handlerPc</code>
- * @param type <code>catchType</code>
+ * @param index index (>= 0) at which the entry is to be inserted.
+ * @param start <code>startPc</code>
+ * @param end <code>endPc</code>
+ * @param handler <code>handlerPc</code>
+ * @param type <code>catchType</code>
*/
public void add(int index, int start, int end, int handler, int type) {
- entries.add(index,
- new ExceptionTableEntry(start, end, handler, type));
+ entries.add(index,
+ new ExceptionTableEntry(start, end, handler, type));
}
/**
* Appends a new entry at the end of the table.
*
- * @param start <code>startPc</code>
- * @param end <code>endPc</code>
- * @param handler <code>handlerPc</code>
- * @param type <code>catchType</code>
+ * @param start <code>startPc</code>
+ * @param end <code>endPc</code>
+ * @param handler <code>handlerPc</code>
+ * @param type <code>catchType</code>
*/
public void add(int start, int end, int handler, int type) {
- entries.add(new ExceptionTableEntry(start, end, handler, type));
+ entries.add(new ExceptionTableEntry(start, end, handler, type));
}
/**
* Removes the entry at the specified position in the table.
*
- * @param index the index of the removed entry.
+ * @param index the index of the removed entry.
*/
public void remove(int index) {
- entries.remove(index);
+ entries.remove(index);
}
/**
* Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
public ExceptionTable copy(ConstPool newCp, Map classnames) {
- ExceptionTable et = new ExceptionTable(newCp);
- ConstPool srcCp = constPool;
- int len = size();
- for (int i = 0; i < len; ++i) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
- int type = srcCp.copy(e.catchType, newCp, classnames);
- et.add(e.startPc, e.endPc, e.handlerPc, type);
- }
+ ExceptionTable et = new ExceptionTable(newCp);
+ ConstPool srcCp = constPool;
+ int len = size();
+ for (int i = 0; i < len; ++i) {
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
+ int type = srcCp.copy(e.catchType, newCp, classnames);
+ et.add(e.startPc, e.endPc, e.handlerPc, type);
+ }
- return et;
+ return et;
}
void shiftPc(int where, int gapLength, boolean exclusive) {
- int len = size();
- for (int i = 0; i < len; ++i) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
- e.startPc = shiftPc(e.startPc, where, gapLength, exclusive);
- e.endPc = shiftPc(e.endPc, where, gapLength, exclusive);
- e.handlerPc = shiftPc(e.handlerPc, where, gapLength, exclusive);
- }
+ int len = size();
+ for (int i = 0; i < len; ++i) {
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
+ e.startPc = shiftPc(e.startPc, where, gapLength, exclusive);
+ e.endPc = shiftPc(e.endPc, where, gapLength, exclusive);
+ e.handlerPc = shiftPc(e.handlerPc, where, gapLength, exclusive);
+ }
}
private static int shiftPc(int pc, int where, int gapLength,
- boolean exclusive) {
- if (pc > where || (exclusive && pc == where))
- pc += gapLength;
+ boolean exclusive) {
+ if (pc > where || (exclusive && pc == where))
+ pc += gapLength;
- return pc;
+ return pc;
}
void write(DataOutputStream out) throws IOException {
- int len = size();
- out.writeShort(len); // exception_table_length
- for (int i = 0; i < len; ++i) {
- ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
- out.writeShort(e.startPc);
- out.writeShort(e.endPc);
- out.writeShort(e.handlerPc);
- out.writeShort(e.catchType);
- }
+ int len = size();
+ out.writeShort(len); // exception_table_length
+ for (int i = 0; i < len; ++i) {
+ ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
+ out.writeShort(e.startPc);
+ out.writeShort(e.endPc);
+ out.writeShort(e.handlerPc);
+ out.writeShort(e.catchType);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
public static final String tag = "Exceptions";
ExceptionsAttribute(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, n, in);
+ super(cp, n, in);
}
/**
* Constructs a copy of an exceptions attribute.
*
- * @param cp constant pool table.
- * @param src source attribute.
+ * @param cp constant pool table.
+ * @param src source attribute.
*/
private ExceptionsAttribute(ConstPool cp, ExceptionsAttribute src,
- Map classnames) {
- super(cp, tag);
- copyFrom(src, classnames);
+ Map classnames) {
+ super(cp, tag);
+ copyFrom(src, classnames);
}
/**
* Constructs a new exceptions attribute.
*
- * @param cp constant pool table.
+ * @param cp constant pool table.
*/
public ExceptionsAttribute(ConstPool cp) {
- super(cp, tag);
- byte[] data = new byte[2];
- data[0] = data[1] = 0; // empty
- this.info = data;
+ super(cp, tag);
+ byte[] data = new byte[2];
+ data[0] = data[1] = 0; // empty
+ this.info = data;
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- return new ExceptionsAttribute(newCp, this, classnames);
+ return new ExceptionsAttribute(newCp, this, classnames);
}
/**
* Copies the contents from a source attribute.
* Specified class names are replaced during the copy.
*
- * @param srcAttr source Exceptions attribute
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param srcAttr source Exceptions attribute
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
private void copyFrom(ExceptionsAttribute srcAttr, Map classnames) {
- ConstPool srcCp = srcAttr.constPool;
- ConstPool destCp = this.constPool;
- byte[] src = srcAttr.info;
- int num = src.length;
- byte[] dest = new byte[num];
- dest[0] = src[0];
- dest[1] = src[1]; // the number of elements.
- for (int i = 2; i < num; i += 2) {
- int index = ByteArray.readU16bit(src, i);
- ByteArray.write16bit(srcCp.copy(index, destCp, classnames),
- dest, i);
- }
-
- this.info = dest;
+ ConstPool srcCp = srcAttr.constPool;
+ ConstPool destCp = this.constPool;
+ byte[] src = srcAttr.info;
+ int num = src.length;
+ byte[] dest = new byte[num];
+ dest[0] = src[0];
+ dest[1] = src[1]; // the number of elements.
+ for (int i = 2; i < num; i += 2) {
+ int index = ByteArray.readU16bit(src, i);
+ ByteArray.write16bit(srcCp.copy(index, destCp, classnames),
+ dest, i);
+ }
+
+ this.info = dest;
}
/**
* Returns <code>exception_index_table[]</code>.
*/
public int[] getExceptionIndexes() {
- byte[] blist = info;
- int n = blist.length;
- if (n <= 2)
- return null;
+ byte[] blist = info;
+ int n = blist.length;
+ if (n <= 2)
+ return null;
- int[] elist = new int[n / 2 - 1];
- int k = 0;
- for (int j = 2; j < n; j += 2)
- elist[k++] = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff);
+ int[] elist = new int[n / 2 - 1];
+ int k = 0;
+ for (int j = 2; j < n; j += 2)
+ elist[k++] = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff);
- return elist;
+ return elist;
}
/**
* Returns the names of exceptions that the method may throw.
*/
public String[] getExceptions() {
- byte[] blist = info;
- int n = blist.length;
- if (n <= 2)
- return null;
-
- String[] elist = new String[n / 2 - 1];
- int k = 0;
- for (int j = 2; j < n; j += 2) {
- int index = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff);
- elist[k++] = constPool.getClassInfo(index);
- }
-
- return elist;
+ byte[] blist = info;
+ int n = blist.length;
+ if (n <= 2)
+ return null;
+
+ String[] elist = new String[n / 2 - 1];
+ int k = 0;
+ for (int j = 2; j < n; j += 2) {
+ int index = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff);
+ elist[k++] = constPool.getClassInfo(index);
+ }
+
+ return elist;
}
/**
* Sets <code>exception_index_table[]</code>.
*/
public void setExceptionIndexes(int[] elist) {
- int n = elist.length;
- byte[] blist = new byte[n * 2 + 2];
- ByteArray.write16bit(n, blist, 0);
- for (int i = 0; i < n; ++i)
- ByteArray.write16bit(elist[i], blist, i * 2 + 2);
+ int n = elist.length;
+ byte[] blist = new byte[n * 2 + 2];
+ ByteArray.write16bit(n, blist, 0);
+ for (int i = 0; i < n; ++i)
+ ByteArray.write16bit(elist[i], blist, i * 2 + 2);
- info = blist;
+ info = blist;
}
/**
* Sets the names of exceptions that the method may throw.
*/
public void setExceptions(String[] elist) {
- int n = elist.length;
- byte[] blist = new byte[n * 2 + 2];
- ByteArray.write16bit(n, blist, 0);
- for (int i = 0; i < n; ++i)
- ByteArray.write16bit(constPool.addClassInfo(elist[i]),
- blist, i * 2 + 2);
-
- info = blist;
+ int n = elist.length;
+ byte[] blist = new byte[n * 2 + 2];
+ ByteArray.write16bit(n, blist, 0);
+ for (int i = 0; i < n; ++i)
+ ByteArray.write16bit(constPool.addClassInfo(elist[i]),
+ blist, i * 2 + 2);
+
+ info = blist;
}
/**
* Returns the value of <code>exception_index_table[nth]</code>.
*/
public int getException(int nth) {
- int index = nth * 2 + 2; // nth >= 0
- return ((info[index] & 0xff) << 8) | (info[index + 1] & 0xff);
+ int index = nth * 2 + 2; // nth >= 0
+ return ((info[index] & 0xff) << 8) | (info[index + 1] & 0xff);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
int accessFlags;
int name;
int descriptor;
- LinkedList attribute; // may be null.
+ LinkedList attribute; // may be null.
private FieldInfo(ConstPool cp) {
- constPool = cp;
- accessFlags = 0;
- attribute = null;
+ constPool = cp;
+ accessFlags = 0;
+ attribute = null;
}
/**
* Constructs a <code>field_info</code> structure.
*
- * @param cp a constant pool table
- * @param fieldName field name
- * @param desc field descriptor
+ * @param cp a constant pool table
+ * @param fieldName field name
+ * @param desc field descriptor
*
* @see Descriptor
*/
public FieldInfo(ConstPool cp, String fieldName, String desc) {
- this(cp);
- name = cp.addUtf8Info(fieldName);
- descriptor = cp.addUtf8Info(desc);
+ this(cp);
+ name = cp.addUtf8Info(fieldName);
+ descriptor = cp.addUtf8Info(desc);
}
FieldInfo(ConstPool cp, DataInputStream in) throws IOException {
- this(cp);
- read(in);
+ this(cp);
+ read(in);
}
/**
* Returns the field name.
*/
public String getName() {
- return constPool.getUtf8Info(name);
+ return constPool.getUtf8Info(name);
}
/**
* Sets the field name.
*/
public void setName(String newName) {
- name = constPool.addUtf8Info(newName);
+ name = constPool.addUtf8Info(newName);
}
/**
* @see AccessFlag
*/
public int getAccessFlags() {
- return accessFlags;
+ return accessFlags;
}
/**
* @see AccessFlag
*/
public void setAccessFlags(int acc) {
- accessFlags = acc;
+ accessFlags = acc;
}
/**
* @see Descriptor
*/
public String getDescriptor() {
- return constPool.getUtf8Info(descriptor);
+ return constPool.getUtf8Info(descriptor);
}
/**
* @see Descriptor
*/
public void setDescriptor(String desc) {
- if (!desc.equals(getDescriptor()))
- descriptor = constPool.addUtf8Info(desc);
+ if (!desc.equals(getDescriptor()))
+ descriptor = constPool.addUtf8Info(desc);
}
/**
* @see AttributeInfo
*/
public List getAttributes() {
- if (attribute == null)
- attribute = new LinkedList();
+ if (attribute == null)
+ attribute = new LinkedList();
- return attribute;
+ return attribute;
}
/**
* Returns the attribute with the specified name.
*
- * @param name attribute name
+ * @param name attribute name
*/
public AttributeInfo getAttribute(String name) {
- return AttributeInfo.lookup(attribute, name);
+ return AttributeInfo.lookup(attribute, name);
}
/**
* the same name, the new one substitutes for it.
*/
public void addAttribute(AttributeInfo info) {
- if (attribute == null)
- attribute = new LinkedList();
+ if (attribute == null)
+ attribute = new LinkedList();
- AttributeInfo.remove(attribute, info.getName());
- attribute.add(info);
+ AttributeInfo.remove(attribute, info.getName());
+ attribute.add(info);
}
private void read(DataInputStream in) throws IOException {
- accessFlags = in.readUnsignedShort();
- name = in.readUnsignedShort();
- descriptor = in.readUnsignedShort();
- int n = in.readUnsignedShort();
- attribute = new LinkedList();
- for (int i = 0; i < n; ++i)
- attribute.add(AttributeInfo.read(constPool, in));
+ accessFlags = in.readUnsignedShort();
+ name = in.readUnsignedShort();
+ descriptor = in.readUnsignedShort();
+ int n = in.readUnsignedShort();
+ attribute = new LinkedList();
+ for (int i = 0; i < n; ++i)
+ attribute.add(AttributeInfo.read(constPool, in));
}
void write(DataOutputStream out) throws IOException {
- out.writeShort(accessFlags);
- out.writeShort(name);
- out.writeShort(descriptor);
- if (attribute == null)
- out.writeShort(0);
- else {
- out.writeShort(attribute.size());
- AttributeInfo.writeAll(attribute, out);
- }
+ out.writeShort(accessFlags);
+ out.writeShort(name);
+ out.writeShort(descriptor);
+ if (attribute == null)
+ out.writeShort(0);
+ else {
+ out.writeShort(attribute.size());
+ AttributeInfo.writeAll(attribute, out);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
public static final String tag = "InnerClasses";
InnerClassesAttribute(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, n, in);
+ super(cp, n, in);
}
private InnerClassesAttribute(ConstPool cp, byte[] info) {
- super(cp, tag, info);
+ super(cp, tag, info);
}
/**
* Returns <code>classes[nth].inner_class_info_index</code>.
*/
public int innerClass(int nth) {
- return ByteArray.readU16bit(get(), nth * 8 + 2);
+ return ByteArray.readU16bit(get(), nth * 8 + 2);
}
/**
* Returns <code>classes[nth].outer_class_info_index</code>.
*/
public int outerClass(int nth) {
- return ByteArray.readU16bit(get(), nth * 8 + 4);
+ return ByteArray.readU16bit(get(), nth * 8 + 4);
}
/**
* Returns <code>classes[nth].inner_name_index</code>.
*/
public int innerName(int nth) {
- return ByteArray.readU16bit(get(), nth * 8 + 6);
+ return ByteArray.readU16bit(get(), nth * 8 + 6);
}
/**
* Returns <code>classes[nth].inner_class_access_flags</code>.
*/
public int accessFlags(int nth) {
- return ByteArray.readU16bit(get(), nth * 8 + 8);
+ return ByteArray.readU16bit(get(), nth * 8 + 8);
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- byte[] src = get();
- byte[] dest = new byte[src.length];
- ConstPool cp = getConstPool();
- InnerClassesAttribute attr = new InnerClassesAttribute(newCp, dest);
- int n = ByteArray.readU16bit(src, 0);
- ByteArray.write16bit(n, dest, 0);
- int j = 2;
- for (int i = 0; i < n; ++i) {
- int innerClass = ByteArray.readU16bit(src, j);
- int outerClass = ByteArray.readU16bit(src, j + 2);
- int innerName = ByteArray.readU16bit(src, j + 4);
- int innerAccess = ByteArray.readU16bit(src, j + 6);
-
- if (innerClass != 0)
- innerClass = cp.copy(innerClass, newCp, classnames);
-
- ByteArray.write16bit(innerClass, dest, j);
-
- if (outerClass != 0)
- outerClass = cp.copy(outerClass, newCp, classnames);
-
- ByteArray.write16bit(outerClass, dest, j + 2);
-
- if (innerName != 0)
- innerName = cp.copy(innerName, newCp, classnames);
-
- ByteArray.write16bit(innerName, dest, j + 4);
- ByteArray.write16bit(innerAccess, dest, j + 6);
- j += 8;
- }
-
- return attr;
+ byte[] src = get();
+ byte[] dest = new byte[src.length];
+ ConstPool cp = getConstPool();
+ InnerClassesAttribute attr = new InnerClassesAttribute(newCp, dest);
+ int n = ByteArray.readU16bit(src, 0);
+ ByteArray.write16bit(n, dest, 0);
+ int j = 2;
+ for (int i = 0; i < n; ++i) {
+ int innerClass = ByteArray.readU16bit(src, j);
+ int outerClass = ByteArray.readU16bit(src, j + 2);
+ int innerName = ByteArray.readU16bit(src, j + 4);
+ int innerAccess = ByteArray.readU16bit(src, j + 6);
+
+ if (innerClass != 0)
+ innerClass = cp.copy(innerClass, newCp, classnames);
+
+ ByteArray.write16bit(innerClass, dest, j);
+
+ if (outerClass != 0)
+ outerClass = cp.copy(outerClass, newCp, classnames);
+
+ ByteArray.write16bit(outerClass, dest, j + 2);
+
+ if (innerName != 0)
+ innerName = cp.copy(innerName, newCp, classnames);
+
+ ByteArray.write16bit(innerName, dest, j + 4);
+ ByteArray.write16bit(innerAccess, dest, j + 6);
+ j += 8;
+ }
+
+ return attr;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
public static final String tag = "LineNumberTable";
LineNumberAttribute(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, n, in);
+ super(cp, n, in);
}
private LineNumberAttribute(ConstPool cp, byte[] i) {
- super(cp, tag, i);
+ super(cp, tag, i);
}
/**
* This represents the number of entries in the table.
*/
public int tableLength() {
- return ByteArray.readU16bit(info, 0);
+ return ByteArray.readU16bit(info, 0);
}
/**
* This represents the index into the code array at which the code
* for a new line in the original source file begins.
*
- * @param i the i-th entry.
+ * @param i the i-th entry.
*/
public int startPc(int i) {
- return ByteArray.readU16bit(info, i * 4 + 2);
+ return ByteArray.readU16bit(info, i * 4 + 2);
}
/**
* This represents the corresponding line number in the original
* source file.
*
- * @param i the i-th entry.
+ * @param i the i-th entry.
*/
public int lineNumber(int i) {
- return ByteArray.readU16bit(info, i * 4 + 4);
+ return ByteArray.readU16bit(info, i * 4 + 4);
}
/**
* Returns the line number corresponding to the specified bytecode.
*
- * @param pc the index into the code array.
+ * @param pc the index into the code array.
*/
public int toLineNumber(int pc) {
- int n = tableLength();
- int i = 0;
- for (; i < n; ++i)
- if (pc < startPc(i))
- if (i == 0)
- return lineNumber(0);
- else
- break;
+ int n = tableLength();
+ int i = 0;
+ for (; i < n; ++i)
+ if (pc < startPc(i))
+ if (i == 0)
+ return lineNumber(0);
+ else
+ break;
- return lineNumber(i - 1);
+ return lineNumber(i - 1);
}
/**
* Returns the index into the code array at which the code for
* the specified line begins.
*
- * @param line the line number.
- * @return -1 if the specified line is not found.
+ * @param line the line number.
+ * @return -1 if the specified line is not found.
*/
public int toStartPc(int line) {
- int n = tableLength();
- for (int i = 0; i < n; ++i)
- if (line == lineNumber(i))
- return startPc(i);
+ int n = tableLength();
+ for (int i = 0; i < n; ++i)
+ if (line == lineNumber(i))
+ return startPc(i);
- return -1;
+ return -1;
}
/**
* Makes a copy.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames should be null.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames should be null.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- byte[] src = info;
- int num = src.length;
- byte[] dest = new byte[num];
- for (int i = 0; i < num; ++i)
- dest[i] = src[i];
+ byte[] src = info;
+ int num = src.length;
+ byte[] dest = new byte[num];
+ for (int i = 0; i < num; ++i)
+ dest[i] = src[i];
- LineNumberAttribute attr = new LineNumberAttribute(newCp, dest);
- return attr;
+ LineNumberAttribute attr = new LineNumberAttribute(newCp, dest);
+ return attr;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
final class LongVector {
private LongVector next;
public LongVector(int initialSize) {
- num = 0;
- objects = new Object[initialSize];
- next = null;
+ num = 0;
+ objects = new Object[initialSize];
+ next = null;
}
public void addElement(Object obj) {
- LongVector p = this;
- while (p.next != null)
- p = p.next;
+ LongVector p = this;
+ while (p.next != null)
+ p = p.next;
- if (p.num < p.objects.length)
- p.objects[p.num++] = obj;
- else {
- LongVector q = p.next = new LongVector(p.objects.length);
- q.objects[q.num++] = obj;
- }
+ if (p.num < p.objects.length)
+ p.objects[p.num++] = obj;
+ else {
+ LongVector q = p.next = new LongVector(p.objects.length);
+ q.objects[q.num++] = obj;
+ }
}
public int size() {
- LongVector p = this;
- int s = 0;
- while (p != null) {
- s += p.num;
- p = p.next;
- }
+ LongVector p = this;
+ int s = 0;
+ while (p != null) {
+ s += p.num;
+ p = p.next;
+ }
- return s;
+ return s;
}
public Object elementAt(int i) {
- LongVector p = this;
- while (p != null)
- if (i < p.num)
- return p.objects[i];
- else {
- i -= p.num;
- p = p.next;
- }
+ LongVector p = this;
+ while (p != null)
+ if (i < p.num)
+ return p.objects[i];
+ else {
+ i -= p.num;
+ p = p.next;
+ }
- return null;
+ return null;
}
/*
public static void main(String [] args) {
- LongVector v = new LongVector(4);
- int i;
- for (i = 0; i < 128; ++i)
- v.addElement(new Integer(i));
+ LongVector v = new LongVector(4);
+ int i;
+ for (i = 0; i < 128; ++i)
+ v.addElement(new Integer(i));
- System.out.println(v.size());
- for (i = 0; i < v.size(); ++i) {
- System.out.print(v.elementAt(i));
- System.out.print(", ");
- }
+ System.out.println(v.size());
+ for (i = 0; i < v.size(); ++i) {
+ System.out.print(v.elementAt(i));
+ System.out.print(", ");
+ }
}
*/
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
int accessFlags;
int name;
int descriptor;
- LinkedList attribute; // may be null
+ LinkedList attribute; // may be null
/**
* The name of constructors: <code><init></code>.
public static final String nameClinit = "<clinit>";
private MethodInfo(ConstPool cp) {
- constPool = cp;
- attribute = null;
+ constPool = cp;
+ attribute = null;
}
/**
* Constructs a <code>method_info</code> structure.
*
- * @param cp a constant pool table
- * @param methodname method name
- * @param desc method descriptor
+ * @param cp a constant pool table
+ * @param methodname method name
+ * @param desc method descriptor
*
* @see Descriptor
*/
public MethodInfo(ConstPool cp, String methodname, String desc) {
- this(cp);
- accessFlags = 0;
- name = cp.addUtf8Info(methodname);
- descriptor = constPool.addUtf8Info(desc);
+ this(cp);
+ accessFlags = 0;
+ name = cp.addUtf8Info(methodname);
+ descriptor = constPool.addUtf8Info(desc);
}
MethodInfo(ConstPool cp, DataInputStream in) throws IOException {
- this(cp);
- read(in);
+ this(cp);
+ read(in);
}
/**
* attributes are copied from the source. The other attributes
* are ignored.
*
- * @param cp a constant pool table
- * @param methodname a method name
- * @param src a source <code>method_info</code>
- * @param classnameMap specifies pairs of replaced and substituted
- * name.
+ * @param cp a constant pool table
+ * @param methodname a method name
+ * @param src a source <code>method_info</code>
+ * @param classnameMap specifies pairs of replaced and substituted
+ * name.
* @see Descriptor
*/
public MethodInfo(ConstPool cp, String methodname, MethodInfo src,
- Map classnameMap) throws BadBytecode
+ Map classnameMap) throws BadBytecode
{
- this(cp);
- read(src, methodname, classnameMap);
+ this(cp);
+ read(src, methodname, classnameMap);
}
/**
* Returns a method name.
*/
public String getName() {
- return constPool.getUtf8Info(name);
+ return constPool.getUtf8Info(name);
}
/**
* Sets a method name.
*/
public void setName(String newName) {
- name = constPool.addUtf8Info(newName);
+ name = constPool.addUtf8Info(newName);
}
/**
* (static initializer).
*/
public boolean isMethod() {
- String n = getName();
- return !n.equals(nameInit) && !n.equals(nameClinit);
+ String n = getName();
+ return !n.equals(nameInit) && !n.equals(nameClinit);
}
/**
* Returns true if this is a class initializer (static initializer).
*/
public boolean isStaticInitializer() {
- return getName().equals(nameClinit);
+ return getName().equals(nameClinit);
}
/**
* @see AccessFlag
*/
public int getAccessFlags() {
- return accessFlags;
+ return accessFlags;
}
/**
* @see AccessFlag
*/
public void setAccessFlags(int acc) {
- accessFlags = acc;
+ accessFlags = acc;
}
/**
* @see Descriptor
*/
public String getDescriptor() {
- return constPool.getUtf8Info(descriptor);
+ return constPool.getUtf8Info(descriptor);
}
/**
* @see Descriptor
*/
public void setDescriptor(String desc) {
- if (!desc.equals(getDescriptor()))
- descriptor = constPool.addUtf8Info(desc);
+ if (!desc.equals(getDescriptor()))
+ descriptor = constPool.addUtf8Info(desc);
}
/**
* @see AttributeInfo
*/
public List getAttributes() {
- if (attribute == null)
- attribute = new LinkedList();
+ if (attribute == null)
+ attribute = new LinkedList();
- return attribute;
+ return attribute;
}
/**
* Returns the attribute with the specified name.
* If it is not found, this method returns null.
*
- * @param name attribute name
- * @return an <code>AttributeInfo</code> object or null.
+ * @param name attribute name
+ * @return an <code>AttributeInfo</code> object or null.
*/
public AttributeInfo getAttribute(String name) {
- return AttributeInfo.lookup(attribute, name);
+ return AttributeInfo.lookup(attribute, name);
}
/**
* the same name, the new one substitutes for it.
*/
public void addAttribute(AttributeInfo info) {
- if (attribute == null)
- attribute = new LinkedList();
+ if (attribute == null)
+ attribute = new LinkedList();
- AttributeInfo.remove(attribute, info.getName());
- attribute.add(info);
+ AttributeInfo.remove(attribute, info.getName());
+ attribute.add(info);
}
/**
* Returns an Exceptions attribute.
*
- * @return an Exceptions attribute
- * or null if it is not specified.
+ * @return an Exceptions attribute
+ * or null if it is not specified.
*/
public ExceptionsAttribute getExceptionsAttribute() {
- AttributeInfo info
- = AttributeInfo.lookup(attribute, ExceptionsAttribute.class);
- return (ExceptionsAttribute)info;
+ AttributeInfo info
+ = AttributeInfo.lookup(attribute, ExceptionsAttribute.class);
+ return (ExceptionsAttribute)info;
}
/**
* Returns a Code attribute.
*
- * @return a Code attribute
- * or null if it is not specified.
+ * @return a Code attribute
+ * or null if it is not specified.
*/
public CodeAttribute getCodeAttribute() {
- AttributeInfo info
- = AttributeInfo.lookup(attribute, CodeAttribute.class);
- return (CodeAttribute)info;
+ AttributeInfo info
+ = AttributeInfo.lookup(attribute, CodeAttribute.class);
+ return (CodeAttribute)info;
}
/**
* Removes an Exception attribute.
*/
public void removeExceptionsAttribute() {
- AttributeInfo.remove(attribute, ExceptionsAttribute.class);
+ AttributeInfo.remove(attribute, ExceptionsAttribute.class);
}
/**
* as this <code>method_info</code> structure.
*/
public void setExceptionsAttribute(ExceptionsAttribute cattr) {
- removeExceptionsAttribute();
- if (attribute == null)
- attribute = new LinkedList();
+ removeExceptionsAttribute();
+ if (attribute == null)
+ attribute = new LinkedList();
- attribute.add(cattr);
+ attribute.add(cattr);
}
/**
* Removes a Code attribute.
*/
public void removeCodeAttribute() {
- AttributeInfo.remove(attribute, CodeAttribute.class);
+ AttributeInfo.remove(attribute, CodeAttribute.class);
}
/**
* as this <code>method_info</code> structure.
*/
public void setCodeAttribute(CodeAttribute cattr) {
- removeCodeAttribute();
- if (attribute == null)
- attribute = new LinkedList();
+ removeCodeAttribute();
+ if (attribute == null)
+ attribute = new LinkedList();
- attribute.add(cattr);
+ attribute.add(cattr);
}
/**
* Returns the line number of the source line corresponding to the
* specified bytecode contained in this method.
*
- * @param pos the position of the bytecode (>= 0).
- * an index into the code array.
- * @return -1 if this information is not available.
+ * @param pos the position of the bytecode (>= 0).
+ * an index into the code array.
+ * @return -1 if this information is not available.
*/
public int getLineNumber(int pos) {
- CodeAttribute ca = getCodeAttribute();
- if (ca == null)
- return -1;
+ CodeAttribute ca = getCodeAttribute();
+ if (ca == null)
+ return -1;
- LineNumberAttribute ainfo
- = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag);
- if (ainfo == null)
- return -1;
+ LineNumberAttribute ainfo
+ = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag);
+ if (ainfo == null)
+ return -1;
- return ainfo.toLineNumber(pos);
+ return ainfo.toLineNumber(pos);
}
/**
* <p>This method does not perform anything unless this
* <code>MethodInfo</code> represents a constructor.
*
- * @param superclass the new super class
+ * @param superclass the new super class
*/
public void setSuperclass(String superclass) throws BadBytecode {
- if (!isConstructor())
- return;
-
- CodeAttribute ca = getCodeAttribute();
- byte[] code = ca.getCode();
- CodeIterator iterator = ca.iterator();
- int pos = iterator.skipSuperConstructor();
- if (pos >= 0) { // not this()
- ConstPool cp = constPool;
- int mref = ByteArray.readU16bit(code, pos + 1);
- int nt = cp.getMethodrefNameAndType(mref);
- int sc = cp.addClassInfo(superclass);
- int mref2 = cp.addMethodrefInfo(sc, nt);
- ByteArray.write16bit(mref2, code, pos + 1);
- }
+ if (!isConstructor())
+ return;
+
+ CodeAttribute ca = getCodeAttribute();
+ byte[] code = ca.getCode();
+ CodeIterator iterator = ca.iterator();
+ int pos = iterator.skipSuperConstructor();
+ if (pos >= 0) { // not this()
+ ConstPool cp = constPool;
+ int mref = ByteArray.readU16bit(code, pos + 1);
+ int nt = cp.getMethodrefNameAndType(mref);
+ int sc = cp.addClassInfo(superclass);
+ int mref2 = cp.addMethodrefInfo(sc, nt);
+ ByteArray.write16bit(mref2, code, pos + 1);
+ }
}
private void read(MethodInfo src, String methodname, Map classnames)
- throws BadBytecode
+ throws BadBytecode
{
- ConstPool destCp = constPool;
- accessFlags = src.accessFlags;
- name = destCp.addUtf8Info(methodname);
-
- ConstPool srcCp = src.constPool;
- String desc = srcCp.getUtf8Info(src.descriptor);
- String desc2 = Descriptor.rename(desc, classnames);
- descriptor = destCp.addUtf8Info(desc2);
-
- attribute = new LinkedList();
- ExceptionsAttribute eattr = src.getExceptionsAttribute();
- if (eattr != null)
- attribute.add(eattr.copy(destCp, classnames));
-
- CodeAttribute cattr = src.getCodeAttribute();
- if (cattr != null)
- attribute.add(cattr.copy(destCp, classnames));
+ ConstPool destCp = constPool;
+ accessFlags = src.accessFlags;
+ name = destCp.addUtf8Info(methodname);
+
+ ConstPool srcCp = src.constPool;
+ String desc = srcCp.getUtf8Info(src.descriptor);
+ String desc2 = Descriptor.rename(desc, classnames);
+ descriptor = destCp.addUtf8Info(desc2);
+
+ attribute = new LinkedList();
+ ExceptionsAttribute eattr = src.getExceptionsAttribute();
+ if (eattr != null)
+ attribute.add(eattr.copy(destCp, classnames));
+
+ CodeAttribute cattr = src.getCodeAttribute();
+ if (cattr != null)
+ attribute.add(cattr.copy(destCp, classnames));
}
private void read(DataInputStream in) throws IOException {
- accessFlags = in.readUnsignedShort();
- name = in.readUnsignedShort();
- descriptor = in.readUnsignedShort();
- int n = in.readUnsignedShort();
- attribute = new LinkedList();
- for (int i = 0; i < n; ++i)
- attribute.add(AttributeInfo.read(constPool, in));
+ accessFlags = in.readUnsignedShort();
+ name = in.readUnsignedShort();
+ descriptor = in.readUnsignedShort();
+ int n = in.readUnsignedShort();
+ attribute = new LinkedList();
+ for (int i = 0; i < n; ++i)
+ attribute.add(AttributeInfo.read(constPool, in));
}
void write(DataOutputStream out) throws IOException {
- out.writeShort(accessFlags);
- out.writeShort(name);
- out.writeShort(descriptor);
-
- if (attribute == null)
- out.writeShort(0);
- else {
- out.writeShort(attribute.size());
- AttributeInfo.writeAll(attribute, out);
- }
+ out.writeShort(accessFlags);
+ out.writeShort(name);
+ out.writeShort(descriptor);
+
+ if (attribute == null)
+ out.writeShort(0);
+ else {
+ out.writeShort(attribute.size());
+ AttributeInfo.writeAll(attribute, out);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
/**
* assigned to 186.
*/
String[] OPCODE = {
- "nop", /* 0*/
- "aconst_null", /* 1*/
- "iconst_m1", /* 2*/
- "iconst_0", /* 3*/
- "iconst_1", /* 4*/
- "iconst_2", /* 5*/
- "iconst_3", /* 6*/
- "iconst_4", /* 7*/
- "iconst_5", /* 8*/
- "lconst_0", /* 9*/
- "lconst_1", /* 10*/
- "fconst_0", /* 11*/
- "fconst_1", /* 12*/
- "fconst_2", /* 13*/
- "dconst_0", /* 14*/
- "dconst_1", /* 15*/
- "bipush", /* 16*/
- "sipush", /* 17*/
- "ldc", /* 18*/
- "ldc_w", /* 19*/
- "ldc2_w", /* 20*/
- "iload", /* 21*/
- "lload", /* 22*/
- "fload", /* 23*/
- "dload", /* 24*/
- "aload", /* 25*/
- "iload_0", /* 26*/
- "iload_1", /* 27*/
- "iload_2", /* 28*/
- "iload_3", /* 29*/
- "lload_0", /* 30*/
- "lload_1", /* 31*/
- "lload_2", /* 32*/
- "lload_3", /* 33*/
- "fload_0", /* 34*/
- "fload_1", /* 35*/
- "fload_2", /* 36*/
- "fload_3", /* 37*/
- "dload_0", /* 38*/
- "dload_1", /* 39*/
- "dload_2", /* 40*/
- "dload_3", /* 41*/
- "aload_0", /* 42*/
- "aload_1", /* 43*/
- "aload_2", /* 44*/
- "aload_3", /* 45*/
- "iaload", /* 46*/
- "laload", /* 47*/
- "faload", /* 48*/
- "daload", /* 49*/
- "aaload", /* 50*/
- "baload", /* 51*/
- "caload", /* 52*/
- "saload", /* 53*/
- "istore", /* 54*/
- "lstore", /* 55*/
- "fstore", /* 56*/
- "dstore", /* 57*/
- "astore", /* 58*/
- "istore_0", /* 59*/
- "istore_1", /* 60*/
- "istore_2", /* 61*/
- "istore_3", /* 62*/
- "lstore_0", /* 63*/
- "lstore_1", /* 64*/
- "lstore_2", /* 65*/
- "lstore_3", /* 66*/
- "fstore_0", /* 67*/
- "fstore_1", /* 68*/
- "fstore_2", /* 69*/
- "fstore_3", /* 70*/
- "dstore_0", /* 71*/
- "dstore_1", /* 72*/
- "dstore_2", /* 73*/
- "dstore_3", /* 74*/
- "astore_0", /* 75*/
- "astore_1", /* 76*/
- "astore_2", /* 77*/
- "astore_3", /* 78*/
- "iastore", /* 79*/
- "lastore", /* 80*/
- "fastore", /* 81*/
- "dastore", /* 82*/
- "aastore", /* 83*/
- "bastore", /* 84*/
- "castore", /* 85*/
- "sastore", /* 86*/
- "pop", /* 87*/
- "pop2", /* 88*/
- "dup", /* 89*/
- "dup_x1", /* 90*/
- "dup_x2", /* 91*/
- "dup2", /* 92*/
- "dup2_x1", /* 93*/
- "dup2_x2", /* 94*/
- "swap", /* 95*/
- "iadd", /* 96*/
- "ladd", /* 97*/
- "fadd", /* 98*/
- "dadd", /* 99*/
- "isub", /* 100*/
- "lsub", /* 101*/
- "fsub", /* 102*/
- "dsub", /* 103*/
- "imul", /* 104*/
- "lmul", /* 105*/
- "fmul", /* 106*/
- "dmul", /* 107*/
- "idiv", /* 108*/
- "ldiv", /* 109*/
- "fdiv", /* 110*/
- "ddiv", /* 111*/
- "irem", /* 112*/
- "lrem", /* 113*/
- "frem", /* 114*/
- "drem", /* 115*/
- "ineg", /* 116*/
- "lneg", /* 117*/
- "fneg", /* 118*/
- "dneg", /* 119*/
- "ishl", /* 120*/
- "lshl", /* 121*/
- "ishr", /* 122*/
- "lshr", /* 123*/
- "iushr", /* 124*/
- "lushr", /* 125*/
- "iand", /* 126*/
- "land", /* 127*/
- "ior", /* 128*/
- "lor", /* 129*/
- "ixor", /* 130*/
- "lxor", /* 131*/
- "iinc", /* 132*/
- "i2l", /* 133*/
- "i2f", /* 134*/
- "i2d", /* 135*/
- "l2i", /* 136*/
- "l2f", /* 137*/
- "l2d", /* 138*/
- "f2i", /* 139*/
- "f2l", /* 140*/
- "f2d", /* 141*/
- "d2i", /* 142*/
- "d2l", /* 143*/
- "d2f", /* 144*/
- "i2b", /* 145*/
- "i2c", /* 146*/
- "i2s", /* 147*/
- "lcmp", /* 148*/
- "fcmpl", /* 149*/
- "fcmpg", /* 150*/
- "dcmpl", /* 151*/
- "dcmpg", /* 152*/
- "ifeq", /* 153*/
- "ifne", /* 154*/
- "iflt", /* 155*/
- "ifge", /* 156*/
- "ifgt", /* 157*/
- "ifle", /* 158*/
- "if_icmpeq", /* 159*/
- "if_icmpne", /* 160*/
- "if_icmplt", /* 161*/
- "if_icmpge", /* 162*/
- "if_icmpgt", /* 163*/
- "if_icmple", /* 164*/
- "if_acmpeq", /* 165*/
- "if_acmpne", /* 166*/
- "goto", /* 167*/
- "jsr", /* 168*/
- "ret", /* 169*/
- "tableswitch", /* 170*/
- "lookupswitch", /* 171*/
- "ireturn", /* 172*/
- "lreturn", /* 173*/
- "freturn", /* 174*/
- "dreturn", /* 175*/
- "areturn", /* 176*/
- "return", /* 177*/
- "getstatic", /* 178*/
- "putstatic", /* 179*/
- "getfield", /* 180*/
- "putfield", /* 181*/
- "invokevirtual", /* 182*/
- "invokespecial", /* 183*/
- "invokestatic", /* 184*/
- "invokeinterface", /* 185*/
- null,
- "new", /* 187*/
- "newarray", /* 188*/
- "anewarray", /* 189*/
- "arraylength", /* 190*/
- "athrow", /* 191*/
- "checkcast", /* 192*/
- "instanceof", /* 193*/
- "monitorenter", /* 194*/
- "monitorexit", /* 195*/
- "wide", /* 196*/
- "multianewarray", /* 197*/
- "ifnull", /* 198*/
- "ifnonnull", /* 199*/
- "goto_w", /* 200*/
- "jsr_w" /* 201*/
+ "nop", /* 0*/
+ "aconst_null", /* 1*/
+ "iconst_m1", /* 2*/
+ "iconst_0", /* 3*/
+ "iconst_1", /* 4*/
+ "iconst_2", /* 5*/
+ "iconst_3", /* 6*/
+ "iconst_4", /* 7*/
+ "iconst_5", /* 8*/
+ "lconst_0", /* 9*/
+ "lconst_1", /* 10*/
+ "fconst_0", /* 11*/
+ "fconst_1", /* 12*/
+ "fconst_2", /* 13*/
+ "dconst_0", /* 14*/
+ "dconst_1", /* 15*/
+ "bipush", /* 16*/
+ "sipush", /* 17*/
+ "ldc", /* 18*/
+ "ldc_w", /* 19*/
+ "ldc2_w", /* 20*/
+ "iload", /* 21*/
+ "lload", /* 22*/
+ "fload", /* 23*/
+ "dload", /* 24*/
+ "aload", /* 25*/
+ "iload_0", /* 26*/
+ "iload_1", /* 27*/
+ "iload_2", /* 28*/
+ "iload_3", /* 29*/
+ "lload_0", /* 30*/
+ "lload_1", /* 31*/
+ "lload_2", /* 32*/
+ "lload_3", /* 33*/
+ "fload_0", /* 34*/
+ "fload_1", /* 35*/
+ "fload_2", /* 36*/
+ "fload_3", /* 37*/
+ "dload_0", /* 38*/
+ "dload_1", /* 39*/
+ "dload_2", /* 40*/
+ "dload_3", /* 41*/
+ "aload_0", /* 42*/
+ "aload_1", /* 43*/
+ "aload_2", /* 44*/
+ "aload_3", /* 45*/
+ "iaload", /* 46*/
+ "laload", /* 47*/
+ "faload", /* 48*/
+ "daload", /* 49*/
+ "aaload", /* 50*/
+ "baload", /* 51*/
+ "caload", /* 52*/
+ "saload", /* 53*/
+ "istore", /* 54*/
+ "lstore", /* 55*/
+ "fstore", /* 56*/
+ "dstore", /* 57*/
+ "astore", /* 58*/
+ "istore_0", /* 59*/
+ "istore_1", /* 60*/
+ "istore_2", /* 61*/
+ "istore_3", /* 62*/
+ "lstore_0", /* 63*/
+ "lstore_1", /* 64*/
+ "lstore_2", /* 65*/
+ "lstore_3", /* 66*/
+ "fstore_0", /* 67*/
+ "fstore_1", /* 68*/
+ "fstore_2", /* 69*/
+ "fstore_3", /* 70*/
+ "dstore_0", /* 71*/
+ "dstore_1", /* 72*/
+ "dstore_2", /* 73*/
+ "dstore_3", /* 74*/
+ "astore_0", /* 75*/
+ "astore_1", /* 76*/
+ "astore_2", /* 77*/
+ "astore_3", /* 78*/
+ "iastore", /* 79*/
+ "lastore", /* 80*/
+ "fastore", /* 81*/
+ "dastore", /* 82*/
+ "aastore", /* 83*/
+ "bastore", /* 84*/
+ "castore", /* 85*/
+ "sastore", /* 86*/
+ "pop", /* 87*/
+ "pop2", /* 88*/
+ "dup", /* 89*/
+ "dup_x1", /* 90*/
+ "dup_x2", /* 91*/
+ "dup2", /* 92*/
+ "dup2_x1", /* 93*/
+ "dup2_x2", /* 94*/
+ "swap", /* 95*/
+ "iadd", /* 96*/
+ "ladd", /* 97*/
+ "fadd", /* 98*/
+ "dadd", /* 99*/
+ "isub", /* 100*/
+ "lsub", /* 101*/
+ "fsub", /* 102*/
+ "dsub", /* 103*/
+ "imul", /* 104*/
+ "lmul", /* 105*/
+ "fmul", /* 106*/
+ "dmul", /* 107*/
+ "idiv", /* 108*/
+ "ldiv", /* 109*/
+ "fdiv", /* 110*/
+ "ddiv", /* 111*/
+ "irem", /* 112*/
+ "lrem", /* 113*/
+ "frem", /* 114*/
+ "drem", /* 115*/
+ "ineg", /* 116*/
+ "lneg", /* 117*/
+ "fneg", /* 118*/
+ "dneg", /* 119*/
+ "ishl", /* 120*/
+ "lshl", /* 121*/
+ "ishr", /* 122*/
+ "lshr", /* 123*/
+ "iushr", /* 124*/
+ "lushr", /* 125*/
+ "iand", /* 126*/
+ "land", /* 127*/
+ "ior", /* 128*/
+ "lor", /* 129*/
+ "ixor", /* 130*/
+ "lxor", /* 131*/
+ "iinc", /* 132*/
+ "i2l", /* 133*/
+ "i2f", /* 134*/
+ "i2d", /* 135*/
+ "l2i", /* 136*/
+ "l2f", /* 137*/
+ "l2d", /* 138*/
+ "f2i", /* 139*/
+ "f2l", /* 140*/
+ "f2d", /* 141*/
+ "d2i", /* 142*/
+ "d2l", /* 143*/
+ "d2f", /* 144*/
+ "i2b", /* 145*/
+ "i2c", /* 146*/
+ "i2s", /* 147*/
+ "lcmp", /* 148*/
+ "fcmpl", /* 149*/
+ "fcmpg", /* 150*/
+ "dcmpl", /* 151*/
+ "dcmpg", /* 152*/
+ "ifeq", /* 153*/
+ "ifne", /* 154*/
+ "iflt", /* 155*/
+ "ifge", /* 156*/
+ "ifgt", /* 157*/
+ "ifle", /* 158*/
+ "if_icmpeq", /* 159*/
+ "if_icmpne", /* 160*/
+ "if_icmplt", /* 161*/
+ "if_icmpge", /* 162*/
+ "if_icmpgt", /* 163*/
+ "if_icmple", /* 164*/
+ "if_acmpeq", /* 165*/
+ "if_acmpne", /* 166*/
+ "goto", /* 167*/
+ "jsr", /* 168*/
+ "ret", /* 169*/
+ "tableswitch", /* 170*/
+ "lookupswitch", /* 171*/
+ "ireturn", /* 172*/
+ "lreturn", /* 173*/
+ "freturn", /* 174*/
+ "dreturn", /* 175*/
+ "areturn", /* 176*/
+ "return", /* 177*/
+ "getstatic", /* 178*/
+ "putstatic", /* 179*/
+ "getfield", /* 180*/
+ "putfield", /* 181*/
+ "invokevirtual", /* 182*/
+ "invokespecial", /* 183*/
+ "invokestatic", /* 184*/
+ "invokeinterface", /* 185*/
+ null,
+ "new", /* 187*/
+ "newarray", /* 188*/
+ "anewarray", /* 189*/
+ "arraylength", /* 190*/
+ "athrow", /* 191*/
+ "checkcast", /* 192*/
+ "instanceof", /* 193*/
+ "monitorenter", /* 194*/
+ "monitorexit", /* 195*/
+ "wide", /* 196*/
+ "multianewarray", /* 197*/
+ "ifnull", /* 198*/
+ "ifnonnull", /* 199*/
+ "goto_w", /* 200*/
+ "jsr_w" /* 201*/
};
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
/**
/* how many values are pushed on the operand stack. */
int[] STACK_GROW = {
- 0, // nop, 0
- 1, // aconst_null, 1
- 1, // iconst_m1, 2
- 1, // iconst_0, 3
- 1, // iconst_1, 4
- 1, // iconst_2, 5
- 1, // iconst_3, 6
- 1, // iconst_4, 7
- 1, // iconst_5, 8
- 2, // lconst_0, 9
- 2, // lconst_1, 10
- 1, // fconst_0, 11
- 1, // fconst_1, 12
- 1, // fconst_2, 13
- 2, // dconst_0, 14
- 2, // dconst_1, 15
- 1, // bipush, 16
- 1, // sipush, 17
- 1, // ldc, 18
- 1, // ldc_w, 19
- 2, // ldc2_w, 20
- 1, // iload, 21
- 2, // lload, 22
- 1, // fload, 23
- 2, // dload, 24
- 1, // aload, 25
- 1, // iload_0, 26
- 1, // iload_1, 27
- 1, // iload_2, 28
- 1, // iload_3, 29
- 2, // lload_0, 30
- 2, // lload_1, 31
- 2, // lload_2, 32
- 2, // lload_3, 33
- 1, // fload_0, 34
- 1, // fload_1, 35
- 1, // fload_2, 36
- 1, // fload_3, 37
- 2, // dload_0, 38
- 2, // dload_1, 39
- 2, // dload_2, 40
- 2, // dload_3, 41
- 1, // aload_0, 42
- 1, // aload_1, 43
- 1, // aload_2, 44
- 1, // aload_3, 45
- -1, // iaload, 46
- 0, // laload, 47
- -1, // faload, 48
- 0, // daload, 49
- -1, // aaload, 50
- -1, // baload, 51
- -1, // caload, 52
- -1, // saload, 53
- -1, // istore, 54
- -2, // lstore, 55
- -1, // fstore, 56
- -2, // dstore, 57
- -1, // astore, 58
- -1, // istore_0, 59
- -1, // istore_1, 60
- -1, // istore_2, 61
- -1, // istore_3, 62
- -2, // lstore_0, 63
- -2, // lstore_1, 64
- -2, // lstore_2, 65
- -2, // lstore_3, 66
- -1, // fstore_0, 67
- -1, // fstore_1, 68
- -1, // fstore_2, 69
- -1, // fstore_3, 70
- -2, // dstore_0, 71
- -2, // dstore_1, 72
- -2, // dstore_2, 73
- -2, // dstore_3, 74
- -1, // astore_0, 75
- -1, // astore_1, 76
- -1, // astore_2, 77
- -1, // astore_3, 78
- -3, // iastore, 79
- -4, // lastore, 80
- -3, // fastore, 81
- -4, // dastore, 82
- -3, // aastore, 83
- -3, // bastore, 84
- -3, // castore, 85
- -3, // sastore, 86
- -1, // pop, 87
- -2, // pop2, 88
- 1, // dup, 89
- 1, // dup_x1, 90
- 1, // dup_x2, 91
- 2, // dup2, 92
- 2, // dup2_x1, 93
- 2, // dup2_x2, 94
- 0, // swap, 95
- -1, // iadd, 96
- -2, // ladd, 97
- -1, // fadd, 98
- -2, // dadd, 99
- -1, // isub, 100
- -2, // lsub, 101
- -1, // fsub, 102
- -2, // dsub, 103
- -1, // imul, 104
- -2, // lmul, 105
- -1, // fmul, 106
- -2, // dmul, 107
- -1, // idiv, 108
- -2, // ldiv, 109
- -1, // fdiv, 110
- -2, // ddiv, 111
- -1, // irem, 112
- -2, // lrem, 113
- -1, // frem, 114
- -2, // drem, 115
- 0, // ineg, 116
- 0, // lneg, 117
- 0, // fneg, 118
- 0, // dneg, 119
- -1, // ishl, 120
- -1, // lshl, 121
- -1, // ishr, 122
- -1, // lshr, 123
- -1, // iushr, 124
- -1, // lushr, 125
- -1, // iand, 126
- -2, // land, 127
- -1, // ior, 128
- -2, // lor, 129
- -1, // ixor, 130
- -2, // lxor, 131
- 0, // iinc, 132
- 1, // i2l, 133
- 0, // i2f, 134
- 1, // i2d, 135
- -1, // l2i, 136
- -1, // l2f, 137
- 0, // l2d, 138
- 0, // f2i, 139
- 1, // f2l, 140
- 1, // f2d, 141
- -1, // d2i, 142
- 0, // d2l, 143
- -1, // d2f, 144
- 0, // i2b, 145
- 0, // i2c, 146
- 0, // i2s, 147
- -3, // lcmp, 148
- -1, // fcmpl, 149
- -1, // fcmpg, 150
- -3, // dcmpl, 151
- -3, // dcmpg, 152
- -1, // ifeq, 153
- -1, // ifne, 154
- -1, // iflt, 155
- -1, // ifge, 156
- -1, // ifgt, 157
- -1, // ifle, 158
- -2, // if_icmpeq, 159
- -2, // if_icmpne, 160
- -2, // if_icmplt, 161
- -2, // if_icmpge, 162
- -2, // if_icmpgt, 163
- -2, // if_icmple, 164
- -2, // if_acmpeq, 165
- -2, // if_acmpne, 166
- 0, // goto, 167
- 1, // jsr, 168
- 0, // ret, 169
- -1, // tableswitch, 170
- -1, // lookupswitch, 171
- -1, // ireturn, 172
- -2, // lreturn, 173
- -1, // freturn, 174
- -2, // dreturn, 175
- -1, // areturn, 176
- 0, // return, 177
- 0, // getstatic, 178 depends on the type
- 0, // putstatic, 179 depends on the type
- 0, // getfield, 180 depends on the type
- 0, // putfield, 181 depends on the type
- 0, // invokevirtual, 182 depends on the type
- 0, // invokespecial, 183 depends on the type
- 0, // invokestatic, 184 depends on the type
- 0, // invokeinterface, 185 depends on the type
- 0, // undefined, 186
- 1, // new, 187
- 0, // newarray, 188
- 0, // anewarray, 189
- 0, // arraylength, 190
- 0, // athrow, 191 stack is cleared
- 0, // checkcast, 192
- 0, // instanceof, 193
- -1, // monitorenter, 194
- -1, // monitorexit, 195
- 0, // wide, 196 depends on the following opcode
- 0, // multianewarray, 197 depends on the dimensions
- -1, // ifnull, 198
- -1, // ifnonnull, 199
- 0, // goto_w, 200
- 1 // jsr_w, 201
+ 0, // nop, 0
+ 1, // aconst_null, 1
+ 1, // iconst_m1, 2
+ 1, // iconst_0, 3
+ 1, // iconst_1, 4
+ 1, // iconst_2, 5
+ 1, // iconst_3, 6
+ 1, // iconst_4, 7
+ 1, // iconst_5, 8
+ 2, // lconst_0, 9
+ 2, // lconst_1, 10
+ 1, // fconst_0, 11
+ 1, // fconst_1, 12
+ 1, // fconst_2, 13
+ 2, // dconst_0, 14
+ 2, // dconst_1, 15
+ 1, // bipush, 16
+ 1, // sipush, 17
+ 1, // ldc, 18
+ 1, // ldc_w, 19
+ 2, // ldc2_w, 20
+ 1, // iload, 21
+ 2, // lload, 22
+ 1, // fload, 23
+ 2, // dload, 24
+ 1, // aload, 25
+ 1, // iload_0, 26
+ 1, // iload_1, 27
+ 1, // iload_2, 28
+ 1, // iload_3, 29
+ 2, // lload_0, 30
+ 2, // lload_1, 31
+ 2, // lload_2, 32
+ 2, // lload_3, 33
+ 1, // fload_0, 34
+ 1, // fload_1, 35
+ 1, // fload_2, 36
+ 1, // fload_3, 37
+ 2, // dload_0, 38
+ 2, // dload_1, 39
+ 2, // dload_2, 40
+ 2, // dload_3, 41
+ 1, // aload_0, 42
+ 1, // aload_1, 43
+ 1, // aload_2, 44
+ 1, // aload_3, 45
+ -1, // iaload, 46
+ 0, // laload, 47
+ -1, // faload, 48
+ 0, // daload, 49
+ -1, // aaload, 50
+ -1, // baload, 51
+ -1, // caload, 52
+ -1, // saload, 53
+ -1, // istore, 54
+ -2, // lstore, 55
+ -1, // fstore, 56
+ -2, // dstore, 57
+ -1, // astore, 58
+ -1, // istore_0, 59
+ -1, // istore_1, 60
+ -1, // istore_2, 61
+ -1, // istore_3, 62
+ -2, // lstore_0, 63
+ -2, // lstore_1, 64
+ -2, // lstore_2, 65
+ -2, // lstore_3, 66
+ -1, // fstore_0, 67
+ -1, // fstore_1, 68
+ -1, // fstore_2, 69
+ -1, // fstore_3, 70
+ -2, // dstore_0, 71
+ -2, // dstore_1, 72
+ -2, // dstore_2, 73
+ -2, // dstore_3, 74
+ -1, // astore_0, 75
+ -1, // astore_1, 76
+ -1, // astore_2, 77
+ -1, // astore_3, 78
+ -3, // iastore, 79
+ -4, // lastore, 80
+ -3, // fastore, 81
+ -4, // dastore, 82
+ -3, // aastore, 83
+ -3, // bastore, 84
+ -3, // castore, 85
+ -3, // sastore, 86
+ -1, // pop, 87
+ -2, // pop2, 88
+ 1, // dup, 89
+ 1, // dup_x1, 90
+ 1, // dup_x2, 91
+ 2, // dup2, 92
+ 2, // dup2_x1, 93
+ 2, // dup2_x2, 94
+ 0, // swap, 95
+ -1, // iadd, 96
+ -2, // ladd, 97
+ -1, // fadd, 98
+ -2, // dadd, 99
+ -1, // isub, 100
+ -2, // lsub, 101
+ -1, // fsub, 102
+ -2, // dsub, 103
+ -1, // imul, 104
+ -2, // lmul, 105
+ -1, // fmul, 106
+ -2, // dmul, 107
+ -1, // idiv, 108
+ -2, // ldiv, 109
+ -1, // fdiv, 110
+ -2, // ddiv, 111
+ -1, // irem, 112
+ -2, // lrem, 113
+ -1, // frem, 114
+ -2, // drem, 115
+ 0, // ineg, 116
+ 0, // lneg, 117
+ 0, // fneg, 118
+ 0, // dneg, 119
+ -1, // ishl, 120
+ -1, // lshl, 121
+ -1, // ishr, 122
+ -1, // lshr, 123
+ -1, // iushr, 124
+ -1, // lushr, 125
+ -1, // iand, 126
+ -2, // land, 127
+ -1, // ior, 128
+ -2, // lor, 129
+ -1, // ixor, 130
+ -2, // lxor, 131
+ 0, // iinc, 132
+ 1, // i2l, 133
+ 0, // i2f, 134
+ 1, // i2d, 135
+ -1, // l2i, 136
+ -1, // l2f, 137
+ 0, // l2d, 138
+ 0, // f2i, 139
+ 1, // f2l, 140
+ 1, // f2d, 141
+ -1, // d2i, 142
+ 0, // d2l, 143
+ -1, // d2f, 144
+ 0, // i2b, 145
+ 0, // i2c, 146
+ 0, // i2s, 147
+ -3, // lcmp, 148
+ -1, // fcmpl, 149
+ -1, // fcmpg, 150
+ -3, // dcmpl, 151
+ -3, // dcmpg, 152
+ -1, // ifeq, 153
+ -1, // ifne, 154
+ -1, // iflt, 155
+ -1, // ifge, 156
+ -1, // ifgt, 157
+ -1, // ifle, 158
+ -2, // if_icmpeq, 159
+ -2, // if_icmpne, 160
+ -2, // if_icmplt, 161
+ -2, // if_icmpge, 162
+ -2, // if_icmpgt, 163
+ -2, // if_icmple, 164
+ -2, // if_acmpeq, 165
+ -2, // if_acmpne, 166
+ 0, // goto, 167
+ 1, // jsr, 168
+ 0, // ret, 169
+ -1, // tableswitch, 170
+ -1, // lookupswitch, 171
+ -1, // ireturn, 172
+ -2, // lreturn, 173
+ -1, // freturn, 174
+ -2, // dreturn, 175
+ -1, // areturn, 176
+ 0, // return, 177
+ 0, // getstatic, 178 depends on the type
+ 0, // putstatic, 179 depends on the type
+ 0, // getfield, 180 depends on the type
+ 0, // putfield, 181 depends on the type
+ 0, // invokevirtual, 182 depends on the type
+ 0, // invokespecial, 183 depends on the type
+ 0, // invokestatic, 184 depends on the type
+ 0, // invokeinterface, 185 depends on the type
+ 0, // undefined, 186
+ 1, // new, 187
+ 0, // newarray, 188
+ 0, // anewarray, 189
+ 0, // arraylength, 190
+ 0, // athrow, 191 stack is cleared
+ 0, // checkcast, 192
+ 0, // instanceof, 193
+ -1, // monitorenter, 194
+ -1, // monitorexit, 195
+ 0, // wide, 196 depends on the following opcode
+ 0, // multianewarray, 197 depends on the dimensions
+ -1, // ifnull, 198
+ -1, // ifnonnull, 199
+ 0, // goto_w, 200
+ 1 // jsr_w, 201
};
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
public static final String tag = "SourceFile";
SourceFileAttribute(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, n, in);
+ super(cp, n, in);
}
/**
* Constructs a SourceFile attribute.
*
- * @param cp a constant pool table.
- * @param filename the name of the source file.
+ * @param cp a constant pool table.
+ * @param filename the name of the source file.
*/
public SourceFileAttribute(ConstPool cp, String filename) {
- super(cp, tag);
- int index = cp.addUtf8Info(filename);
- byte[] bvalue = new byte[2];
- bvalue[0] = (byte)(index >>> 8);
- bvalue[1] = (byte)index;
- set(bvalue);
+ super(cp, tag);
+ int index = cp.addUtf8Info(filename);
+ byte[] bvalue = new byte[2];
+ bvalue[0] = (byte)(index >>> 8);
+ bvalue[1] = (byte)index;
+ set(bvalue);
}
/**
* Returns the file name indicated by <code>sourcefile_index</code>.
*/
public String getFileName() {
- return getConstPool().getUtf8Info(ByteArray.readU16bit(get(), 0));
+ return getConstPool().getUtf8Info(ByteArray.readU16bit(get(), 0));
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames pairs of replaced and substituted
- * class names.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames pairs of replaced and substituted
+ * class names.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- return new SourceFileAttribute(newCp, getFileName());
+ return new SourceFileAttribute(newCp, getFileName());
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.bytecode;
import java.io.DataInputStream;
public static final String tag = "Synthetic";
SyntheticAttribute(ConstPool cp, int n, DataInputStream in)
- throws IOException
+ throws IOException
{
- super(cp, n, in);
+ super(cp, n, in);
}
/**
* Constructs a Synthetic attribute.
*
- * @param cp a constant pool table.
- * @param filename the name of the source file.
+ * @param cp a constant pool table.
+ * @param filename the name of the source file.
*/
public SyntheticAttribute(ConstPool cp) {
- super(cp, tag, new byte[0]);
+ super(cp, tag, new byte[0]);
}
/**
* Makes a copy.
*
- * @param newCp the constant pool table used by the new copy.
- * @param classnames should be null.
+ * @param newCp the constant pool table used by the new copy.
+ * @param classnames should be null.
*/
public AttributeInfo copy(ConstPool newCp, Map classnames) {
- return new SyntheticAttribute(newCp);
+ return new SyntheticAttribute(newCp);
}
}
--- /dev/null
+<html>
+<body>
+Bytecode-level API.
+
+<p>This package provides low-level API for editing a raw class file.
+It allows the users to read and modify a constant pool entry, a single
+bytecode instruction, and so on.
+
+<p>The users of this package must know the specifications of
+class file and Java bytecode. For more details, read this book:
+
+<ul>Tim Lindholm and Frank Yellin,
+"The Java Virtual Machine Specification 2nd Ed.",
+Addison-Wesley, 1999.
+</ul>
+
+</body>
+</html>
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import java.util.ArrayList;
/* The following fields are used by atXXX() methods
* for returning the type of the compiled expression.
*/
- protected int exprType; // VOID, NULL, CLASS, BOOLEAN, INT, ...
+ protected int exprType; // VOID, NULL, CLASS, BOOLEAN, INT, ...
protected int arrayDim;
- protected String className; // JVM-internal representation
+ protected String className; // JVM-internal representation
public CodeGen(Bytecode b) {
- bytecode = b;
- tempVar = -1;
- inStaticMethod = false;
- breakList = null;
- continueList = null;
+ bytecode = b;
+ tempVar = -1;
+ inStaticMethod = false;
+ breakList = null;
+ continueList = null;
}
protected static void fatal() throws CompileError {
- throw new CompileError("fatal");
+ throw new CompileError("fatal");
}
public static boolean is2word(int type, int dim) {
- return dim == 0 && (type == DOUBLE || type == LONG);
+ return dim == 0 && (type == DOUBLE || type == LONG);
}
public int getMaxLocals() { return bytecode.getMaxLocals(); }
public void setMaxLocals(int n) {
- bytecode.setMaxLocals(n);
+ bytecode.setMaxLocals(n);
}
protected void incMaxLocals(int size) {
- bytecode.incMaxLocals(size);
+ bytecode.incMaxLocals(size);
}
/**
* stored in.
*/
protected int getTempVar() {
- if (tempVar < 0) {
- tempVar = getMaxLocals();
- incMaxLocals(2);
- }
+ if (tempVar < 0) {
+ tempVar = getMaxLocals();
+ incMaxLocals(2);
+ }
- return tempVar;
+ return tempVar;
}
protected int getLocalVar(Declarator d) {
- int v = d.getLocalVar();
- if (v < 0) {
- v = getMaxLocals(); // delayed variable allocation.
- d.setLocalVar(v);
- incMaxLocals(1);
- }
+ int v = d.getLocalVar();
+ if (v < 0) {
+ v = getMaxLocals(); // delayed variable allocation.
+ d.setLocalVar(v);
+ incMaxLocals(1);
+ }
- return v;
+ return v;
}
/**
* For example, this converts Object into java/lang/Object.
*/
protected abstract String resolveClassName(ASTList name)
- throws CompileError;
+ throws CompileError;
/* Expands a simple class name to java.lang.*.
* For example, this converts Object into java/lang/Object.
*/
protected abstract String resolveClassName(String jvmClassName)
- throws CompileError;
+ throws CompileError;
/**
- * @param name the JVM-internal representation.
- * name is not exapnded to java.lang.*.
+ * @param name the JVM-internal representation.
+ * name is not exapnded to java.lang.*.
*/
protected static String toJvmArrayName(String name, int dim) {
- if (name == null)
- return null;
+ if (name == null)
+ return null;
- if (dim == 0)
- return name;
- else {
- StringBuffer sbuf = new StringBuffer();
- int d = dim;
- while (d-- > 0)
- sbuf.append('[');
+ if (dim == 0)
+ return name;
+ else {
+ StringBuffer sbuf = new StringBuffer();
+ int d = dim;
+ while (d-- > 0)
+ sbuf.append('[');
- sbuf.append('L');
- sbuf.append(name);
- sbuf.append(';');
+ sbuf.append('L');
+ sbuf.append(name);
+ sbuf.append(';');
- return sbuf.toString();
- }
+ return sbuf.toString();
+ }
}
protected static String toJvmTypeName(int type, int dim) {
- char c = 'I';
- switch(type) {
- case BOOLEAN :
- c = 'Z';
- break;
- case BYTE :
- c = 'B';
- break;
- case CHAR :
- c = 'C';
- break;
- case SHORT :
- c = 'S';
- break;
- case INT :
- c = 'I';
- break;
- case LONG :
- c = 'J';
- break;
- case FLOAT :
- c = 'F';
- break;
- case DOUBLE :
- c = 'D';
- break;
- case VOID :
- c = 'V';
- break;
- }
-
- StringBuffer sbuf = new StringBuffer();
- while (dim-- > 0)
- sbuf.append('[');
-
- sbuf.append(c);
- return sbuf.toString();
+ char c = 'I';
+ switch(type) {
+ case BOOLEAN :
+ c = 'Z';
+ break;
+ case BYTE :
+ c = 'B';
+ break;
+ case CHAR :
+ c = 'C';
+ break;
+ case SHORT :
+ c = 'S';
+ break;
+ case INT :
+ c = 'I';
+ break;
+ case LONG :
+ c = 'J';
+ break;
+ case FLOAT :
+ c = 'F';
+ break;
+ case DOUBLE :
+ c = 'D';
+ break;
+ case VOID :
+ c = 'V';
+ break;
+ }
+
+ StringBuffer sbuf = new StringBuffer();
+ while (dim-- > 0)
+ sbuf.append('[');
+
+ sbuf.append(c);
+ return sbuf.toString();
}
public void atSymbol(Symbol n) throws CompileError { fatal(); }
public void atFieldDecl(FieldDecl field) throws CompileError {
- field.getInit().accept(this);
+ field.getInit().accept(this);
}
public void atMethodDecl(MethodDecl method) throws CompileError {
- ASTList mods = method.getModifiers();
- setMaxLocals(1);
- while (mods != null) {
- Keyword k = (Keyword)mods.head();
- mods = mods.tail();
- if (k.get() == STATIC) {
- setMaxLocals(0);
- inStaticMethod = true;
- }
- }
-
- ASTList params = method.getParams();
- while (params != null) {
- atDeclarator((Declarator)params.head());
- params = params.tail();
- }
-
- Stmnt s = method.getBody();
- atMethodBody(s, method.isConstructor(),
- method.getReturn().getType() == VOID);
+ ASTList mods = method.getModifiers();
+ setMaxLocals(1);
+ while (mods != null) {
+ Keyword k = (Keyword)mods.head();
+ mods = mods.tail();
+ if (k.get() == STATIC) {
+ setMaxLocals(0);
+ inStaticMethod = true;
+ }
+ }
+
+ ASTList params = method.getParams();
+ while (params != null) {
+ atDeclarator((Declarator)params.head());
+ params = params.tail();
+ }
+
+ Stmnt s = method.getBody();
+ atMethodBody(s, method.isConstructor(),
+ method.getReturn().getType() == VOID);
}
public void atMethodBody(Stmnt s, boolean isCons, boolean isVoid)
- throws CompileError
+ throws CompileError
{
- if (s == null)
- return;
+ if (s == null)
+ return;
- if (isCons && needsSuperCall(s))
- insertDefaultSuperCall();
+ if (isCons && needsSuperCall(s))
+ insertDefaultSuperCall();
- s.accept(this);
- if (isVoid
- && (bytecode.read(bytecode.currentPc() - 1) & 0xff)
- != Opcode.RETURN) {
- bytecode.addOpcode(Opcode.RETURN);
- }
+ s.accept(this);
+ if (isVoid
+ && (bytecode.read(bytecode.currentPc() - 1) & 0xff)
+ != Opcode.RETURN) {
+ bytecode.addOpcode(Opcode.RETURN);
+ }
}
private boolean needsSuperCall(Stmnt body) {
- if (body.getOperator() == BLOCK) {
- Stmnt first = (Stmnt)body.head();
- if (first != null && first.getOperator() == EXPR) {
- ASTree expr = first.head();
- if (expr != null && expr instanceof Expr
- && ((Expr)expr).getOperator() == CALL) {
- ASTree target = ((Expr)expr).head();
- if (target instanceof Keyword) {
- int token = ((Keyword)target).get();
- return token != THIS && token != SUPER;
- }
- }
- }
- }
-
- return true;
+ if (body.getOperator() == BLOCK) {
+ Stmnt first = (Stmnt)body.head();
+ if (first != null && first.getOperator() == EXPR) {
+ ASTree expr = first.head();
+ if (expr != null && expr instanceof Expr
+ && ((Expr)expr).getOperator() == CALL) {
+ ASTree target = ((Expr)expr).head();
+ if (target instanceof Keyword) {
+ int token = ((Keyword)target).get();
+ return token != THIS && token != SUPER;
+ }
+ }
+ }
+ }
+
+ return true;
}
protected abstract void insertDefaultSuperCall() throws CompileError;
public void atStmnt(Stmnt st) throws CompileError {
- if (st == null)
- return; // empty
-
- int op = st.getOperator();
- if (op == EXPR) {
- ASTree expr = st.getLeft();
- if (expr instanceof AssignExpr)
- atAssignExpr((AssignExpr)expr, false);
- else if (isPlusPlusExpr(expr)) {
- Expr e = (Expr)expr;
- atPlusPlus(e.getOperator(), e.oprand1(), e, false);
- }
- else {
- expr.accept(this);
- if (is2word(exprType, arrayDim))
- bytecode.addOpcode(POP2);
- else if (exprType != VOID)
- bytecode.addOpcode(POP);
- }
- }
- else if (op == DECL || op == BLOCK) {
- ASTList list = st;
- while (list != null) {
- ASTree h = list.head();
- list = list.tail();
- if (h != null)
- h.accept(this);
- }
- }
- else if (op == IF)
- atIfStmnt(st);
- else if (op == WHILE || op == DO)
- atWhileStmnt(st, op == WHILE);
- else if (op == FOR)
- atForStmnt(st);
- else if (op == BREAK || op == CONTINUE)
- atBreakStmnt(st, op == BREAK);
- else if (op == TokenId.RETURN)
- atReturnStmnt(st);
- else if (op == THROW)
- atThrowStmnt(st);
- else if (op == TRY)
- atTryStmnt(st);
- else // LABEL, SWITCH label stament might be null?.
- throw new CompileError(
- "sorry, not supported statement: TokenId " + op);
+ if (st == null)
+ return; // empty
+
+ int op = st.getOperator();
+ if (op == EXPR) {
+ ASTree expr = st.getLeft();
+ if (expr instanceof AssignExpr)
+ atAssignExpr((AssignExpr)expr, false);
+ else if (isPlusPlusExpr(expr)) {
+ Expr e = (Expr)expr;
+ atPlusPlus(e.getOperator(), e.oprand1(), e, false);
+ }
+ else {
+ expr.accept(this);
+ if (is2word(exprType, arrayDim))
+ bytecode.addOpcode(POP2);
+ else if (exprType != VOID)
+ bytecode.addOpcode(POP);
+ }
+ }
+ else if (op == DECL || op == BLOCK) {
+ ASTList list = st;
+ while (list != null) {
+ ASTree h = list.head();
+ list = list.tail();
+ if (h != null)
+ h.accept(this);
+ }
+ }
+ else if (op == IF)
+ atIfStmnt(st);
+ else if (op == WHILE || op == DO)
+ atWhileStmnt(st, op == WHILE);
+ else if (op == FOR)
+ atForStmnt(st);
+ else if (op == BREAK || op == CONTINUE)
+ atBreakStmnt(st, op == BREAK);
+ else if (op == TokenId.RETURN)
+ atReturnStmnt(st);
+ else if (op == THROW)
+ atThrowStmnt(st);
+ else if (op == TRY)
+ atTryStmnt(st);
+ else // LABEL, SWITCH label stament might be null?.
+ throw new CompileError(
+ "sorry, not supported statement: TokenId " + op);
}
private void atIfStmnt(Stmnt st) throws CompileError {
- ASTree expr = st.head();
- Stmnt thenp = (Stmnt)st.tail().head();
- Stmnt elsep = (Stmnt)st.tail().tail().head();
- booleanExpr(false, expr);
- int pc = bytecode.currentPc();
- int pc2 = 0;
- bytecode.addIndex(0); // correct later
+ ASTree expr = st.head();
+ Stmnt thenp = (Stmnt)st.tail().head();
+ Stmnt elsep = (Stmnt)st.tail().tail().head();
+ booleanExpr(false, expr);
+ int pc = bytecode.currentPc();
+ int pc2 = 0;
+ bytecode.addIndex(0); // correct later
- if (thenp != null)
- thenp.accept(this);
+ if (thenp != null)
+ thenp.accept(this);
- if (elsep != null) {
- bytecode.addOpcode(Opcode.GOTO);
- pc2 = bytecode.currentPc();
- bytecode.addIndex(0);
- }
+ if (elsep != null) {
+ bytecode.addOpcode(Opcode.GOTO);
+ pc2 = bytecode.currentPc();
+ bytecode.addIndex(0);
+ }
- bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
+ bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
- if (elsep != null) {
- elsep.accept(this);
- bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1);
- }
+ if (elsep != null) {
+ elsep.accept(this);
+ bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1);
+ }
}
private void atWhileStmnt(Stmnt st, boolean notDo) throws CompileError {
- ArrayList prevBreakList = breakList;
- ArrayList prevContList = continueList;
- breakList = new ArrayList();
- continueList = new ArrayList();
+ ArrayList prevBreakList = breakList;
+ ArrayList prevContList = continueList;
+ breakList = new ArrayList();
+ continueList = new ArrayList();
- ASTree expr = st.head();
- Stmnt body = (Stmnt)st.tail();
+ ASTree expr = st.head();
+ Stmnt body = (Stmnt)st.tail();
- int pc = 0;
- if (notDo) {
- bytecode.addOpcode(Opcode.GOTO);
- pc = bytecode.currentPc();
- bytecode.addIndex(0);
- }
+ int pc = 0;
+ if (notDo) {
+ bytecode.addOpcode(Opcode.GOTO);
+ pc = bytecode.currentPc();
+ bytecode.addIndex(0);
+ }
- int pc2 = bytecode.currentPc();
- if (body != null)
- body.accept(this);
+ int pc2 = bytecode.currentPc();
+ if (body != null)
+ body.accept(this);
- int pc3 = bytecode.currentPc();
- if (notDo)
- bytecode.write16bit(pc, pc3 - pc + 1);
+ int pc3 = bytecode.currentPc();
+ if (notDo)
+ bytecode.write16bit(pc, pc3 - pc + 1);
- booleanExpr(true, expr);
- bytecode.addIndex(pc2 - bytecode.currentPc() + 1);
+ booleanExpr(true, expr);
+ bytecode.addIndex(pc2 - bytecode.currentPc() + 1);
- patchGoto(breakList, bytecode.currentPc());
- patchGoto(continueList, pc3);
- continueList = prevContList;
- breakList = prevBreakList;
+ patchGoto(breakList, bytecode.currentPc());
+ patchGoto(continueList, pc3);
+ continueList = prevContList;
+ breakList = prevBreakList;
}
private void patchGoto(ArrayList list, int targetPc) {
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- int pc = ((Integer)list.get(i)).intValue();
- bytecode.write16bit(pc, targetPc - pc + 1);
- }
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ int pc = ((Integer)list.get(i)).intValue();
+ bytecode.write16bit(pc, targetPc - pc + 1);
+ }
}
private void atForStmnt(Stmnt st) throws CompileError {
- ArrayList prevBreakList = breakList;
- ArrayList prevContList = continueList;
- breakList = new ArrayList();
- continueList = new ArrayList();
+ ArrayList prevBreakList = breakList;
+ ArrayList prevContList = continueList;
+ breakList = new ArrayList();
+ continueList = new ArrayList();
- Stmnt init = (Stmnt)st.head();
- ASTList p = st.tail();
- ASTree expr = p.head();
- p = p.tail();
- Stmnt update = (Stmnt)p.head();
- Stmnt body = (Stmnt)p.tail();
+ Stmnt init = (Stmnt)st.head();
+ ASTList p = st.tail();
+ ASTree expr = p.head();
+ p = p.tail();
+ Stmnt update = (Stmnt)p.head();
+ Stmnt body = (Stmnt)p.tail();
- if (init != null)
- init.accept(this);
+ if (init != null)
+ init.accept(this);
- int pc = bytecode.currentPc();
- int pc2 = 0;
- if (expr != null) {
- booleanExpr(false, expr);
- pc2 = bytecode.currentPc();
- bytecode.addIndex(0);
- }
+ int pc = bytecode.currentPc();
+ int pc2 = 0;
+ if (expr != null) {
+ booleanExpr(false, expr);
+ pc2 = bytecode.currentPc();
+ bytecode.addIndex(0);
+ }
- if (body != null)
- body.accept(this);
+ if (body != null)
+ body.accept(this);
- int pc3 = bytecode.currentPc();
- if (update != null)
- update.accept(this);
+ int pc3 = bytecode.currentPc();
+ if (update != null)
+ update.accept(this);
- bytecode.addOpcode(Opcode.GOTO);
- bytecode.addIndex(pc - bytecode.currentPc() + 1);
+ bytecode.addOpcode(Opcode.GOTO);
+ bytecode.addIndex(pc - bytecode.currentPc() + 1);
- int pc4 = bytecode.currentPc();
- if (expr != null)
- bytecode.write16bit(pc2, pc4 - pc2 + 1);
+ int pc4 = bytecode.currentPc();
+ if (expr != null)
+ bytecode.write16bit(pc2, pc4 - pc2 + 1);
- patchGoto(breakList, pc4);
- patchGoto(continueList, pc3);
- continueList = prevContList;
- breakList = prevBreakList;
+ patchGoto(breakList, pc4);
+ patchGoto(continueList, pc3);
+ continueList = prevContList;
+ breakList = prevBreakList;
}
private void atBreakStmnt(Stmnt st, boolean notCont)
- throws CompileError
+ throws CompileError
{
- if (st.head() != null)
- throw new CompileError(
- "sorry, not support labeled break or continue");
+ if (st.head() != null)
+ throw new CompileError(
+ "sorry, not support labeled break or continue");
- bytecode.addOpcode(Opcode.GOTO);
- Integer pc = new Integer(bytecode.currentPc());
- bytecode.addIndex(0);
- if (notCont)
- breakList.add(pc);
- else
- continueList.add(pc);
+ bytecode.addOpcode(Opcode.GOTO);
+ Integer pc = new Integer(bytecode.currentPc());
+ bytecode.addIndex(0);
+ if (notCont)
+ breakList.add(pc);
+ else
+ continueList.add(pc);
}
protected void atReturnStmnt(Stmnt st) throws CompileError {
- atReturnStmnt2(st.getLeft());
+ atReturnStmnt2(st.getLeft());
}
protected final void atReturnStmnt2(ASTree result) throws CompileError {
- int op;
- if (result == null)
- op = Opcode.RETURN;
- else {
- result.accept(this);
- if (arrayDim > 0)
- op = ARETURN;
- else {
- int type = exprType;
- if (type == DOUBLE)
- op = DRETURN;
- else if (type == FLOAT)
- op = FRETURN;
- else if (type == LONG)
- op = LRETURN;
- else if (isRefType(type))
- op = ARETURN;
- else
- op = IRETURN;
- }
- }
-
- bytecode.addOpcode(op);
+ int op;
+ if (result == null)
+ op = Opcode.RETURN;
+ else {
+ result.accept(this);
+ if (arrayDim > 0)
+ op = ARETURN;
+ else {
+ int type = exprType;
+ if (type == DOUBLE)
+ op = DRETURN;
+ else if (type == FLOAT)
+ op = FRETURN;
+ else if (type == LONG)
+ op = LRETURN;
+ else if (isRefType(type))
+ op = ARETURN;
+ else
+ op = IRETURN;
+ }
+ }
+
+ bytecode.addOpcode(op);
}
private void atThrowStmnt(Stmnt st) throws CompileError {
- ASTree e = st.getLeft();
- e.accept(this);
- if (exprType != CLASS || arrayDim > 0)
- throw new CompileError("bad throw statement");
+ ASTree e = st.getLeft();
+ e.accept(this);
+ if (exprType != CLASS || arrayDim > 0)
+ throw new CompileError("bad throw statement");
- bytecode.addOpcode(ATHROW);
+ bytecode.addOpcode(ATHROW);
}
protected abstract void atTryStmnt(Stmnt st) throws CompileError;
private static boolean isPlusPlusExpr(ASTree expr) {
- if (expr instanceof Expr) {
- int op = ((Expr)expr).getOperator();
- return op == PLUSPLUS || op == MINUSMINUS;
- }
+ if (expr instanceof Expr) {
+ int op = ((Expr)expr).getOperator();
+ return op == PLUSPLUS || op == MINUSMINUS;
+ }
- return false;
+ return false;
}
public void atDeclarator(Declarator d) throws CompileError {
- d.setLocalVar(getMaxLocals());
- d.setClassName(resolveClassName(d.getClassName()));
+ d.setLocalVar(getMaxLocals());
+ d.setClassName(resolveClassName(d.getClassName()));
- int size;
- if (is2word(d.getType(), d.getArrayDim()))
- size = 2;
- else
- size = 1;
+ int size;
+ if (is2word(d.getType(), d.getArrayDim()))
+ size = 2;
+ else
+ size = 1;
- incMaxLocals(size);
+ incMaxLocals(size);
- /* NOTE: Array initializers has not been supported.
- */
- ASTree init = d.getInitializer();
- if (init != null)
- atVariableAssign(null, '=', null, d, init, false);
+ /* NOTE: Array initializers has not been supported.
+ */
+ ASTree init = d.getInitializer();
+ if (init != null)
+ atVariableAssign(null, '=', null, d, init, false);
}
public abstract void atNewExpr(NewExpr n) throws CompileError;
public void atAssignExpr(AssignExpr expr) throws CompileError {
- atAssignExpr(expr, true);
+ atAssignExpr(expr, true);
}
protected void atAssignExpr(AssignExpr expr, boolean doDup)
- throws CompileError
+ throws CompileError
{
- // =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, >>>=
- int op = expr.getOperator();
- ASTree left = expr.oprand1();
- ASTree right = expr.oprand2();
- if (left instanceof Variable)
- atVariableAssign(expr, op, (Variable)left,
- ((Variable)left).getDeclarator(),
- right, doDup);
- else {
- if (left instanceof Expr) {
- Expr e = (Expr)left;
- if (e.getOperator() == ARRAY) {
- atArrayAssign(expr, op, (Expr)left, right, doDup);
- return;
- }
- }
-
- atFieldAssign(expr, op, left, right, doDup);
- }
+ // =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, >>>=
+ int op = expr.getOperator();
+ ASTree left = expr.oprand1();
+ ASTree right = expr.oprand2();
+ if (left instanceof Variable)
+ atVariableAssign(expr, op, (Variable)left,
+ ((Variable)left).getDeclarator(),
+ right, doDup);
+ else {
+ if (left instanceof Expr) {
+ Expr e = (Expr)left;
+ if (e.getOperator() == ARRAY) {
+ atArrayAssign(expr, op, (Expr)left, right, doDup);
+ return;
+ }
+ }
+
+ atFieldAssign(expr, op, left, right, doDup);
+ }
}
protected static void badAssign(Expr expr) throws CompileError {
- String msg;
- if (expr == null)
- msg = "incompatible type for assignment";
- else
- msg = "incompatible type for " + expr.getName();
+ String msg;
+ if (expr == null)
+ msg = "incompatible type for assignment";
+ else
+ msg = "incompatible type for " + expr.getName();
- throw new CompileError(msg);
+ throw new CompileError(msg);
}
/* op is either =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, or >>>=.
* expr and var can be null.
*/
private void atVariableAssign(Expr expr, int op, Variable var,
- Declarator d, ASTree right,
- boolean doDup) throws CompileError
+ Declarator d, ASTree right,
+ boolean doDup) throws CompileError
{
- int varType = d.getType();
- int varArray = d.getArrayDim();
- String varClass = d.getClassName();
- int varNo = getLocalVar(d);
-
- if (op != '=')
- atVariable(var);
-
- atAssignCore(expr, op, right, varType, varArray, varClass);
-
- if (doDup)
- if (is2word(varType, varArray))
- bytecode.addOpcode(DUP2);
- else
- bytecode.addOpcode(DUP);
-
- if (varArray > 0)
- bytecode.addAstore(varNo);
- else if (varType == DOUBLE)
- bytecode.addDstore(varNo);
- else if (varType == FLOAT)
- bytecode.addFstore(varNo);
- else if (varType == LONG)
- bytecode.addLstore(varNo);
- else if (isRefType(varType))
- bytecode.addAstore(varNo);
- else
- bytecode.addIstore(varNo);
-
- exprType = varType;
- arrayDim = varArray;
- className = varClass;
+ int varType = d.getType();
+ int varArray = d.getArrayDim();
+ String varClass = d.getClassName();
+ int varNo = getLocalVar(d);
+
+ if (op != '=')
+ atVariable(var);
+
+ atAssignCore(expr, op, right, varType, varArray, varClass);
+
+ if (doDup)
+ if (is2word(varType, varArray))
+ bytecode.addOpcode(DUP2);
+ else
+ bytecode.addOpcode(DUP);
+
+ if (varArray > 0)
+ bytecode.addAstore(varNo);
+ else if (varType == DOUBLE)
+ bytecode.addDstore(varNo);
+ else if (varType == FLOAT)
+ bytecode.addFstore(varNo);
+ else if (varType == LONG)
+ bytecode.addLstore(varNo);
+ else if (isRefType(varType))
+ bytecode.addAstore(varNo);
+ else
+ bytecode.addIstore(varNo);
+
+ exprType = varType;
+ arrayDim = varArray;
+ className = varClass;
}
private void atArrayAssign(Expr expr, int op, Expr array,
- ASTree right, boolean doDup) throws CompileError
+ ASTree right, boolean doDup) throws CompileError
{
- arrayAccess(array.oprand1(), array.oprand2());
+ arrayAccess(array.oprand1(), array.oprand2());
- if (op != '=') {
- bytecode.addOpcode(DUP2);
- bytecode.addOpcode(getArrayReadOp(exprType, arrayDim));
- }
+ if (op != '=') {
+ bytecode.addOpcode(DUP2);
+ bytecode.addOpcode(getArrayReadOp(exprType, arrayDim));
+ }
- int aType = exprType;
- int aDim = arrayDim;
- String cname = className;
+ int aType = exprType;
+ int aDim = arrayDim;
+ String cname = className;
- atAssignCore(expr, op, right, aType, aDim, cname);
+ atAssignCore(expr, op, right, aType, aDim, cname);
- if (doDup)
- if (is2word(aType, aDim))
- bytecode.addOpcode(DUP2_X2);
- else
- bytecode.addOpcode(DUP_X2);
+ if (doDup)
+ if (is2word(aType, aDim))
+ bytecode.addOpcode(DUP2_X2);
+ else
+ bytecode.addOpcode(DUP_X2);
- bytecode.addOpcode(getArrayWriteOp(aType, aDim));
- exprType = aType;
- arrayDim = aDim;
- className = cname;
+ bytecode.addOpcode(getArrayWriteOp(aType, aDim));
+ exprType = aType;
+ arrayDim = aDim;
+ className = cname;
}
protected abstract void atFieldAssign(Expr expr, int op, ASTree left,
- ASTree right, boolean doDup) throws CompileError;
+ ASTree right, boolean doDup) throws CompileError;
protected void atAssignCore(Expr expr, int op, ASTree right,
- int type, int dim, String cname)
- throws CompileError
+ int type, int dim, String cname)
+ throws CompileError
{
- right.accept(this);
- if (invalidDim(exprType, arrayDim, className, type, dim, cname, false)
- || (op != '=' && dim > 0))
- badAssign(expr);
+ right.accept(this);
+ if (invalidDim(exprType, arrayDim, className, type, dim, cname, false)
+ || (op != '=' && dim > 0))
+ badAssign(expr);
- if (op == PLUS_E && dim == 0 && type == CLASS)
- atStringConcatExpr(expr, type, dim, cname);
- else if (op != '=') {
- int token = assignOps[op - MOD_E];
- int k = lookupBinOp(token);
- if (k < 0)
- fatal();
+ if (op == PLUS_E && dim == 0 && type == CLASS)
+ atStringConcatExpr(expr, type, dim, cname);
+ else if (op != '=') {
+ int token = assignOps[op - MOD_E];
+ int k = lookupBinOp(token);
+ if (k < 0)
+ fatal();
- atArithBinExpr(expr, token, k, type);
- }
+ atArithBinExpr(expr, token, k, type);
+ }
- if (op != '=' || (dim == 0 && !isRefType(type)))
- atNumCastExpr(exprType, type);
+ if (op != '=' || (dim == 0 && !isRefType(type)))
+ atNumCastExpr(exprType, type);
- // type check should be done here.
+ // type check should be done here.
}
private boolean invalidDim(int srcType, int srcDim, String srcClass,
- int destType, int destDim, String destClass,
- boolean isCast)
+ int destType, int destDim, String destClass,
+ boolean isCast)
{
- if (srcDim != destDim)
- if (srcType == NULL)
- return false;
- else if (destDim == 0 && destType == CLASS
- && jvmJavaLangObject.equals(destClass))
- return false;
- else if (isCast && srcDim == 0 && srcType == CLASS
- && jvmJavaLangObject.equals(srcClass))
- return false;
- else
- return true;
+ if (srcDim != destDim)
+ if (srcType == NULL)
+ return false;
+ else if (destDim == 0 && destType == CLASS
+ && jvmJavaLangObject.equals(destClass))
+ return false;
+ else if (isCast && srcDim == 0 && srcType == CLASS
+ && jvmJavaLangObject.equals(srcClass))
+ return false;
+ else
+ return true;
- return false;
+ return false;
}
public void atCondExpr(CondExpr expr) throws CompileError {
- booleanExpr(false, expr.condExpr());
- int pc = bytecode.currentPc();
- bytecode.addIndex(0); // correct later
- expr.thenExpr().accept(this);
- bytecode.addOpcode(Opcode.GOTO);
- int pc2 = bytecode.currentPc();
- bytecode.addIndex(0);
- bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
- expr.elseExpr().accept(this);
- bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1);
+ booleanExpr(false, expr.condExpr());
+ int pc = bytecode.currentPc();
+ bytecode.addIndex(0); // correct later
+ expr.thenExpr().accept(this);
+ bytecode.addOpcode(Opcode.GOTO);
+ int pc2 = bytecode.currentPc();
+ bytecode.addIndex(0);
+ bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
+ expr.elseExpr().accept(this);
+ bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1);
}
private final int[] binOp = {
- '+', DADD, FADD, LADD, IADD,
- '-', DSUB, FSUB, LSUB, ISUB,
- '*', DMUL, FMUL, LMUL, IMUL,
- '/', DDIV, FDIV, LDIV, IDIV,
- '%', DREM, FREM, LREM, IREM,
- '|', NOP, NOP, LOR, IOR,
- '^', NOP, NOP, LXOR, IXOR,
- '&', NOP, NOP, LAND, IAND,
- LSHIFT, NOP, NOP, LSHL, ISHL,
- RSHIFT, NOP, NOP, LSHR, ISHR,
- ARSHIFT, NOP, NOP, LUSHR, IUSHR };
+ '+', DADD, FADD, LADD, IADD,
+ '-', DSUB, FSUB, LSUB, ISUB,
+ '*', DMUL, FMUL, LMUL, IMUL,
+ '/', DDIV, FDIV, LDIV, IDIV,
+ '%', DREM, FREM, LREM, IREM,
+ '|', NOP, NOP, LOR, IOR,
+ '^', NOP, NOP, LXOR, IXOR,
+ '&', NOP, NOP, LAND, IAND,
+ LSHIFT, NOP, NOP, LSHL, ISHL,
+ RSHIFT, NOP, NOP, LSHR, ISHR,
+ ARSHIFT, NOP, NOP, LUSHR, IUSHR };
private int lookupBinOp(int token) {
- int[] code = binOp;
- int s = code.length;
- for (int k = 0; k < s; k = k + 5)
- if (code[k] == token)
- return k;
+ int[] code = binOp;
+ int s = code.length;
+ for (int k = 0; k < s; k = k + 5)
+ if (code[k] == token)
+ return k;
- return -1;
+ return -1;
}
public void atBinExpr(BinExpr expr) throws CompileError {
- int token = expr.getOperator();
-
- /* arithmetic operators: +, -, *, /, %, |, ^, &, <<, >>, >>>
- */
- int k = lookupBinOp(token);
- if (k >= 0) {
- expr.oprand1().accept(this);
- int type1 = exprType;
- int dim1 = arrayDim;
- String cname1 = className;
- expr.oprand2().accept(this);
- if (dim1 != arrayDim)
- throw new CompileError("incompatible array types");
-
- if (token == '+' && dim1 == 0
- && (type1 == CLASS || exprType == CLASS))
- atStringConcatExpr(expr, type1, dim1, cname1);
- else
- atArithBinExpr(expr, token, k, type1);
-
- return;
- }
-
- /* equation: &&, ||, ==, !=, <=, >=, <, >
- */
- booleanExpr(true, expr);
- bytecode.addIndex(7);
- bytecode.addIconst(0); // false
- bytecode.addOpcode(Opcode.GOTO);
- bytecode.addIndex(4);
- bytecode.addIconst(1); // true
+ int token = expr.getOperator();
+
+ /* arithmetic operators: +, -, *, /, %, |, ^, &, <<, >>, >>>
+ */
+ int k = lookupBinOp(token);
+ if (k >= 0) {
+ expr.oprand1().accept(this);
+ int type1 = exprType;
+ int dim1 = arrayDim;
+ String cname1 = className;
+ expr.oprand2().accept(this);
+ if (dim1 != arrayDim)
+ throw new CompileError("incompatible array types");
+
+ if (token == '+' && dim1 == 0
+ && (type1 == CLASS || exprType == CLASS))
+ atStringConcatExpr(expr, type1, dim1, cname1);
+ else
+ atArithBinExpr(expr, token, k, type1);
+
+ return;
+ }
+
+ /* equation: &&, ||, ==, !=, <=, >=, <, >
+ */
+ booleanExpr(true, expr);
+ bytecode.addIndex(7);
+ bytecode.addIconst(0); // false
+ bytecode.addOpcode(Opcode.GOTO);
+ bytecode.addIndex(4);
+ bytecode.addIconst(1); // true
}
/* arrayDim values of the two oprands must be equal.
* throws an exception.
*/
private void atArithBinExpr(Expr expr, int token,
- int index, int type1) throws CompileError
+ int index, int type1) throws CompileError
{
- if (arrayDim != 0)
- badTypes(expr);
-
- int type2 = exprType;
- if (token == LSHIFT || token == RSHIFT || token == ARSHIFT)
- if (type2 == INT || type2 == SHORT
- || type2 == CHAR || type2 == BYTE)
- exprType = type1;
- else
- badTypes(expr);
- else
- convertOprandTypes(type1, type2, expr);
-
- int p = typePrecedence(exprType);
- if (p >= 0) {
- int op = binOp[index + p + 1];
- if (op != NOP) {
- if (p == P_INT)
- exprType = INT; // type1 may be BYTE, ...
-
- bytecode.addOpcode(op);
- return;
- }
- }
-
- badTypes(expr);
+ if (arrayDim != 0)
+ badTypes(expr);
+
+ int type2 = exprType;
+ if (token == LSHIFT || token == RSHIFT || token == ARSHIFT)
+ if (type2 == INT || type2 == SHORT
+ || type2 == CHAR || type2 == BYTE)
+ exprType = type1;
+ else
+ badTypes(expr);
+ else
+ convertOprandTypes(type1, type2, expr);
+
+ int p = typePrecedence(exprType);
+ if (p >= 0) {
+ int op = binOp[index + p + 1];
+ if (op != NOP) {
+ if (p == P_INT)
+ exprType = INT; // type1 may be BYTE, ...
+
+ bytecode.addOpcode(op);
+ return;
+ }
+ }
+
+ badTypes(expr);
}
private void atStringConcatExpr(Expr expr, int type1, int dim1,
- String cname1) throws CompileError
+ String cname1) throws CompileError
{
- int type2 = exprType;
- int dim2 = arrayDim;
- boolean type2Is2 = is2word(type2, dim2);
- boolean type2IsString
- = (type2 == CLASS && jvmJavaLangString.equals(className));
+ int type2 = exprType;
+ int dim2 = arrayDim;
+ boolean type2Is2 = is2word(type2, dim2);
+ boolean type2IsString
+ = (type2 == CLASS && jvmJavaLangString.equals(className));
- if (type2Is2)
- convToString(type2, dim2);
+ if (type2Is2)
+ convToString(type2, dim2);
- if (is2word(type1, dim1)) {
- bytecode.addOpcode(DUP_X2);
- bytecode.addOpcode(POP);
- }
- else
- bytecode.addOpcode(SWAP);
+ if (is2word(type1, dim1)) {
+ bytecode.addOpcode(DUP_X2);
+ bytecode.addOpcode(POP);
+ }
+ else
+ bytecode.addOpcode(SWAP);
- convToString(type1, dim1);
- bytecode.addOpcode(SWAP);
+ convToString(type1, dim1);
+ bytecode.addOpcode(SWAP);
- if (!type2Is2 && !type2IsString)
- convToString(type2, dim2);
+ if (!type2Is2 && !type2IsString)
+ convToString(type2, dim2);
- bytecode.addInvokevirtual(javaLangString, "concat",
- "(Ljava/lang/String;)Ljava/lang/String;");
- exprType = CLASS;
- arrayDim = 0;
- className = jvmJavaLangString;
+ bytecode.addInvokevirtual(javaLangString, "concat",
+ "(Ljava/lang/String;)Ljava/lang/String;");
+ exprType = CLASS;
+ arrayDim = 0;
+ className = jvmJavaLangString;
}
private void convToString(int type, int dim) throws CompileError {
- final String method = "valueOf";
-
- if (isRefType(type) || dim > 0)
- bytecode.addInvokestatic(javaLangString, method,
- "(Ljava/lang/Object;)Ljava/lang/String;");
- else if (type == DOUBLE)
- bytecode.addInvokestatic(javaLangString, method,
- "(D)Ljava/lang/String;");
- else if (type == FLOAT)
- bytecode.addInvokestatic(javaLangString, method,
- "(F)Ljava/lang/String;");
- else if (type == LONG)
- bytecode.addInvokestatic(javaLangString, method,
- "(J)Ljava/lang/String;");
- else if (type == BOOLEAN)
- bytecode.addInvokestatic(javaLangString, method,
- "(Z)Ljava/lang/String;");
- else if (type == CHAR)
- bytecode.addInvokestatic(javaLangString, method,
- "(C)Ljava/lang/String;");
- else if (type == VOID)
- throw new CompileError("void type expression");
- else /* INT, BYTE, SHORT */
- bytecode.addInvokestatic(javaLangString, method,
- "(I)Ljava/lang/String;");
+ final String method = "valueOf";
+
+ if (isRefType(type) || dim > 0)
+ bytecode.addInvokestatic(javaLangString, method,
+ "(Ljava/lang/Object;)Ljava/lang/String;");
+ else if (type == DOUBLE)
+ bytecode.addInvokestatic(javaLangString, method,
+ "(D)Ljava/lang/String;");
+ else if (type == FLOAT)
+ bytecode.addInvokestatic(javaLangString, method,
+ "(F)Ljava/lang/String;");
+ else if (type == LONG)
+ bytecode.addInvokestatic(javaLangString, method,
+ "(J)Ljava/lang/String;");
+ else if (type == BOOLEAN)
+ bytecode.addInvokestatic(javaLangString, method,
+ "(Z)Ljava/lang/String;");
+ else if (type == CHAR)
+ bytecode.addInvokestatic(javaLangString, method,
+ "(C)Ljava/lang/String;");
+ else if (type == VOID)
+ throw new CompileError("void type expression");
+ else /* INT, BYTE, SHORT */
+ bytecode.addInvokestatic(javaLangString, method,
+ "(I)Ljava/lang/String;");
}
/* Produces the opcode to branch if the condition is true.
* false.
*/
private void booleanExpr(boolean branchIf, ASTree expr)
- throws CompileError
+ throws CompileError
{
- boolean isAndAnd;
- int op = getCompOperator(expr);
- if (op == EQ) { // ==, !=, ...
- BinExpr bexpr = (BinExpr)expr;
- int type1 = compileOprands(bexpr);
- compareExpr(branchIf, bexpr.getOperator(), type1, bexpr);
- }
- else if (op == '!')
- booleanExpr(!branchIf, ((Expr)expr).oprand1());
- else if ((isAndAnd = (op == ANDAND)) || op == OROR) {
- BinExpr bexpr = (BinExpr)expr;
- booleanExpr(!isAndAnd, bexpr.oprand1());
- int pc = bytecode.currentPc();
- bytecode.addIndex(0); // correct later
-
- booleanExpr(isAndAnd, bexpr.oprand2());
- bytecode.write16bit(pc, bytecode.currentPc() - pc + 3);
- if (branchIf != isAndAnd) {
- bytecode.addIndex(6); // skip GOTO instruction
- bytecode.addOpcode(Opcode.GOTO);
- }
- }
- else { // others
- expr.accept(this);
- bytecode.addOpcode(branchIf ? IFNE : IFEQ);
- }
-
- exprType = BOOLEAN;
- arrayDim = 0;
+ boolean isAndAnd;
+ int op = getCompOperator(expr);
+ if (op == EQ) { // ==, !=, ...
+ BinExpr bexpr = (BinExpr)expr;
+ int type1 = compileOprands(bexpr);
+ compareExpr(branchIf, bexpr.getOperator(), type1, bexpr);
+ }
+ else if (op == '!')
+ booleanExpr(!branchIf, ((Expr)expr).oprand1());
+ else if ((isAndAnd = (op == ANDAND)) || op == OROR) {
+ BinExpr bexpr = (BinExpr)expr;
+ booleanExpr(!isAndAnd, bexpr.oprand1());
+ int pc = bytecode.currentPc();
+ bytecode.addIndex(0); // correct later
+
+ booleanExpr(isAndAnd, bexpr.oprand2());
+ bytecode.write16bit(pc, bytecode.currentPc() - pc + 3);
+ if (branchIf != isAndAnd) {
+ bytecode.addIndex(6); // skip GOTO instruction
+ bytecode.addOpcode(Opcode.GOTO);
+ }
+ }
+ else { // others
+ expr.accept(this);
+ bytecode.addOpcode(branchIf ? IFNE : IFEQ);
+ }
+
+ exprType = BOOLEAN;
+ arrayDim = 0;
}
private static int getCompOperator(ASTree expr) throws CompileError {
- if (expr instanceof Expr) {
- Expr bexpr = (Expr)expr;
- int token = bexpr.getOperator();
- if (token == '!')
- return '!';
- else if ((bexpr instanceof BinExpr)
- && token != OROR && token != ANDAND
- && token != '&' && token != '|')
- return EQ; // ==, !=, ...
- else
- return token;
- }
-
- return ' '; // others
+ if (expr instanceof Expr) {
+ Expr bexpr = (Expr)expr;
+ int token = bexpr.getOperator();
+ if (token == '!')
+ return '!';
+ else if ((bexpr instanceof BinExpr)
+ && token != OROR && token != ANDAND
+ && token != '&' && token != '|')
+ return EQ; // ==, !=, ...
+ else
+ return token;
+ }
+
+ return ' '; // others
}
private int compileOprands(BinExpr expr) throws CompileError {
- expr.oprand1().accept(this);
- int type1 = exprType;
- int dim1 = arrayDim;
- expr.oprand2().accept(this);
- if (dim1 != arrayDim)
- throw new CompileError("incompatible array types");
+ expr.oprand1().accept(this);
+ int type1 = exprType;
+ int dim1 = arrayDim;
+ expr.oprand2().accept(this);
+ if (dim1 != arrayDim)
+ throw new CompileError("incompatible array types");
- return type1;
+ return type1;
}
private final int ifOp[] = { EQ, IF_ICMPEQ, IF_ICMPNE,
- NEQ, IF_ICMPNE, IF_ICMPEQ,
- LE, IF_ICMPLE, IF_ICMPGT,
- GE, IF_ICMPGE, IF_ICMPLT,
- '<', IF_ICMPLT, IF_ICMPGE,
- '>', IF_ICMPGT, IF_ICMPLE };
+ NEQ, IF_ICMPNE, IF_ICMPEQ,
+ LE, IF_ICMPLE, IF_ICMPGT,
+ GE, IF_ICMPGE, IF_ICMPLT,
+ '<', IF_ICMPLT, IF_ICMPGE,
+ '>', IF_ICMPGT, IF_ICMPLE };
private final int ifOp2[] = { EQ, IFEQ, IFNE,
- NEQ, IFNE, IFEQ,
- LE, IFLE, IFGT,
- GE, IFGE, IFLT,
- '<', IFLT, IFGE,
- '>', IFGT, IFLE };
+ NEQ, IFNE, IFEQ,
+ LE, IFLE, IFGT,
+ GE, IFGE, IFLT,
+ '<', IFLT, IFGE,
+ '>', IFGT, IFLE };
/* Produces the opcode to branch if the condition is true.
* The oprands are not produced.
* Parameter expr - compare expression ==, !=, <=, >=, <, >
*/
private void compareExpr(boolean branchIf,
- int token, int type1, BinExpr expr)
- throws CompileError
+ int token, int type1, BinExpr expr)
+ throws CompileError
{
- if (arrayDim == 0)
- convertOprandTypes(type1, exprType, expr);
-
- int p = typePrecedence(exprType);
- if (p == P_OTHER || arrayDim > 0)
- if (token == EQ)
- bytecode.addOpcode(branchIf ? IF_ACMPEQ : IF_ACMPNE);
- else if (token == NEQ)
- bytecode.addOpcode(branchIf ? IF_ACMPNE : IF_ACMPEQ);
- else
- badTypes(expr);
- else
- if (p == P_INT) {
- int op[] = ifOp;
- for (int i = 0; i < op.length; i += 3)
- if (op[i] == token) {
- bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]);
- return;
- }
-
- badTypes(expr);
- }
- else {
- if (p == P_DOUBLE)
- if (token == '<' || token == LE)
- bytecode.addOpcode(DCMPG);
- else
- bytecode.addOpcode(DCMPL);
- else if (p == P_FLOAT)
- if (token == '<' || token == LE)
- bytecode.addOpcode(FCMPG);
- else
- bytecode.addOpcode(FCMPL);
- else if (p == P_LONG)
- bytecode.addOpcode(LCMP); // 1: >, 0: =, -1: <
- else
- fatal();
-
- int[] op = ifOp2;
- for (int i = 0; i < op.length; i += 3)
- if (op[i] == token) {
- bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]);
- return;
- }
-
- badTypes(expr);
- }
+ if (arrayDim == 0)
+ convertOprandTypes(type1, exprType, expr);
+
+ int p = typePrecedence(exprType);
+ if (p == P_OTHER || arrayDim > 0)
+ if (token == EQ)
+ bytecode.addOpcode(branchIf ? IF_ACMPEQ : IF_ACMPNE);
+ else if (token == NEQ)
+ bytecode.addOpcode(branchIf ? IF_ACMPNE : IF_ACMPEQ);
+ else
+ badTypes(expr);
+ else
+ if (p == P_INT) {
+ int op[] = ifOp;
+ for (int i = 0; i < op.length; i += 3)
+ if (op[i] == token) {
+ bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]);
+ return;
+ }
+
+ badTypes(expr);
+ }
+ else {
+ if (p == P_DOUBLE)
+ if (token == '<' || token == LE)
+ bytecode.addOpcode(DCMPG);
+ else
+ bytecode.addOpcode(DCMPL);
+ else if (p == P_FLOAT)
+ if (token == '<' || token == LE)
+ bytecode.addOpcode(FCMPG);
+ else
+ bytecode.addOpcode(FCMPL);
+ else if (p == P_LONG)
+ bytecode.addOpcode(LCMP); // 1: >, 0: =, -1: <
+ else
+ fatal();
+
+ int[] op = ifOp2;
+ for (int i = 0; i < op.length; i += 3)
+ if (op[i] == token) {
+ bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]);
+ return;
+ }
+
+ badTypes(expr);
+ }
}
protected static void badTypes(Expr expr) throws CompileError {
- throw new CompileError("invalid types for " + expr.getName());
+ throw new CompileError("invalid types for " + expr.getName());
}
private static final int P_DOUBLE = 0;
private static final int P_OTHER = -1;
protected static boolean isRefType(int type) {
- return type == CLASS || type == NULL;
+ return type == CLASS || type == NULL;
}
private static int typePrecedence(int type) {
- if (type == DOUBLE)
- return P_DOUBLE;
- else if (type == FLOAT)
- return P_FLOAT;
- else if (type == LONG)
- return P_LONG;
- else if (isRefType(type))
- return P_OTHER;
- else if (type == VOID)
- return P_OTHER; // this is wrong, but ...
- else
- return P_INT; // BOOLEAN, BYTE, CHAR, SHORT, INT
+ if (type == DOUBLE)
+ return P_DOUBLE;
+ else if (type == FLOAT)
+ return P_FLOAT;
+ else if (type == LONG)
+ return P_LONG;
+ else if (isRefType(type))
+ return P_OTHER;
+ else if (type == VOID)
+ return P_OTHER; // this is wrong, but ...
+ else
+ return P_INT; // BOOLEAN, BYTE, CHAR, SHORT, INT
}
private static final int[] castOp = {
- /* D F L I */
- /* double */ NOP, D2F, D2L, D2I,
- /* float */ F2D, NOP, F2L, F2I,
- /* long */ L2D, L2F, NOP, L2I,
- /* other */ I2D, I2F, I2L, NOP };
+ /* D F L I */
+ /* double */ NOP, D2F, D2L, D2I,
+ /* float */ F2D, NOP, F2L, F2I,
+ /* long */ L2D, L2F, NOP, L2I,
+ /* other */ I2D, I2F, I2L, NOP };
/* do implicit type conversion.
* arrayDim values of the two oprands must be zero.
*/
private void convertOprandTypes(int type1, int type2, Expr expr)
- throws CompileError
+ throws CompileError
{
- boolean rightStrong;
- int type1_p = typePrecedence(type1);
- int type2_p = typePrecedence(type2);
-
- if (type2_p < 0 && type1_p < 0) // not primitive types
- return;
-
- if (type2_p < 0 || type1_p < 0) // either is not a primitive type
- badTypes(expr);
-
- int op, result_type;
- if (type1_p <= type2_p) {
- rightStrong = false;
- exprType = type1;
- op = castOp[type2_p * 4 + type1_p];
- result_type = type1_p;
- }
- else {
- rightStrong = true;
- op = castOp[type1_p * 4 + type2_p];
- result_type = type2_p;
- }
-
- if (rightStrong) {
- if (result_type == P_DOUBLE || result_type == P_LONG) {
- if (type1_p == P_DOUBLE || type1_p == P_LONG)
- bytecode.addOpcode(DUP2_X2);
- else
- bytecode.addOpcode(DUP2_X1);
-
- bytecode.addOpcode(POP2);
- bytecode.addOpcode(op);
- bytecode.addOpcode(DUP2_X2);
- bytecode.addOpcode(POP2);
- }
- else if (result_type == P_FLOAT) {
- bytecode.addOpcode(SWAP);
- bytecode.addOpcode(op);
- bytecode.addOpcode(SWAP);
- }
- else
- fatal();
- }
- else if (op != NOP)
- bytecode.addOpcode(op);
+ boolean rightStrong;
+ int type1_p = typePrecedence(type1);
+ int type2_p = typePrecedence(type2);
+
+ if (type2_p < 0 && type1_p < 0) // not primitive types
+ return;
+
+ if (type2_p < 0 || type1_p < 0) // either is not a primitive type
+ badTypes(expr);
+
+ int op, result_type;
+ if (type1_p <= type2_p) {
+ rightStrong = false;
+ exprType = type1;
+ op = castOp[type2_p * 4 + type1_p];
+ result_type = type1_p;
+ }
+ else {
+ rightStrong = true;
+ op = castOp[type1_p * 4 + type2_p];
+ result_type = type2_p;
+ }
+
+ if (rightStrong) {
+ if (result_type == P_DOUBLE || result_type == P_LONG) {
+ if (type1_p == P_DOUBLE || type1_p == P_LONG)
+ bytecode.addOpcode(DUP2_X2);
+ else
+ bytecode.addOpcode(DUP2_X1);
+
+ bytecode.addOpcode(POP2);
+ bytecode.addOpcode(op);
+ bytecode.addOpcode(DUP2_X2);
+ bytecode.addOpcode(POP2);
+ }
+ else if (result_type == P_FLOAT) {
+ bytecode.addOpcode(SWAP);
+ bytecode.addOpcode(op);
+ bytecode.addOpcode(SWAP);
+ }
+ else
+ fatal();
+ }
+ else if (op != NOP)
+ bytecode.addOpcode(op);
}
public void atCastExpr(CastExpr expr) throws CompileError {
- String cname = resolveClassName(expr.getClassName());
- String toClass = checkCastExpr(expr, cname);
- int srcType = exprType;
- exprType = expr.getType();
- arrayDim = expr.getArrayDim();
- className = cname;
- if (toClass == null)
- atNumCastExpr(srcType, exprType); // built-in type
- else
- bytecode.addCheckcast(toClass);
+ String cname = resolveClassName(expr.getClassName());
+ String toClass = checkCastExpr(expr, cname);
+ int srcType = exprType;
+ exprType = expr.getType();
+ arrayDim = expr.getArrayDim();
+ className = cname;
+ if (toClass == null)
+ atNumCastExpr(srcType, exprType); // built-in type
+ else
+ bytecode.addCheckcast(toClass);
}
public void atInstanceOfExpr(InstanceOfExpr expr) throws CompileError {
- String cname = resolveClassName(expr.getClassName());
- String toClass = checkCastExpr(expr, cname);
- bytecode.addInstanceof(toClass);
- exprType = BOOLEAN;
- arrayDim = 0;
+ String cname = resolveClassName(expr.getClassName());
+ String toClass = checkCastExpr(expr, cname);
+ bytecode.addInstanceof(toClass);
+ exprType = BOOLEAN;
+ arrayDim = 0;
}
private String checkCastExpr(CastExpr expr, String name)
- throws CompileError
+ throws CompileError
{
- final String msg = "invalid cast";
- ASTree oprand = expr.getOprand();
- int dim = expr.getArrayDim();
- int type = expr.getType();
- oprand.accept(this);
- int srcType = exprType;
- if (invalidDim(srcType, arrayDim, className, type, dim, name, true)
- || srcType == VOID || type == VOID)
- throw new CompileError(msg);
-
- if (type == CLASS) {
- if (!isRefType(srcType))
- throw new CompileError(msg);
-
- return toJvmArrayName(name, dim);
- }
- else
- if (dim > 0)
- return toJvmTypeName(type, dim);
- else
- return null; // built-in type
+ final String msg = "invalid cast";
+ ASTree oprand = expr.getOprand();
+ int dim = expr.getArrayDim();
+ int type = expr.getType();
+ oprand.accept(this);
+ int srcType = exprType;
+ if (invalidDim(srcType, arrayDim, className, type, dim, name, true)
+ || srcType == VOID || type == VOID)
+ throw new CompileError(msg);
+
+ if (type == CLASS) {
+ if (!isRefType(srcType))
+ throw new CompileError(msg);
+
+ return toJvmArrayName(name, dim);
+ }
+ else
+ if (dim > 0)
+ return toJvmTypeName(type, dim);
+ else
+ return null; // built-in type
}
void atNumCastExpr(int srcType, int destType)
- throws CompileError
+ throws CompileError
{
- if (srcType == destType)
- return;
-
- int op, op2;
- int stype = typePrecedence(srcType);
- int dtype = typePrecedence(destType);
- if (0 <= stype && stype < 3)
- op = castOp[stype * 4 + dtype];
- else
- op = NOP;
-
- if (destType == DOUBLE)
- op2 = I2D;
- else if (destType == FLOAT)
- op2 = I2F;
- else if (destType == LONG)
- op2 = I2L;
- else if (destType == SHORT)
- op2 = I2S;
- else if (destType == CHAR)
- op2 = I2C;
- else if (destType == BYTE)
- op2 = I2B;
- else
- op2 = NOP;
-
- if (op != NOP)
- bytecode.addOpcode(op);
-
- if (op == NOP || op == L2I || op == F2I || op == D2I)
- if (op2 != NOP)
- bytecode.addOpcode(op2);
+ if (srcType == destType)
+ return;
+
+ int op, op2;
+ int stype = typePrecedence(srcType);
+ int dtype = typePrecedence(destType);
+ if (0 <= stype && stype < 3)
+ op = castOp[stype * 4 + dtype];
+ else
+ op = NOP;
+
+ if (destType == DOUBLE)
+ op2 = I2D;
+ else if (destType == FLOAT)
+ op2 = I2F;
+ else if (destType == LONG)
+ op2 = I2L;
+ else if (destType == SHORT)
+ op2 = I2S;
+ else if (destType == CHAR)
+ op2 = I2C;
+ else if (destType == BYTE)
+ op2 = I2B;
+ else
+ op2 = NOP;
+
+ if (op != NOP)
+ bytecode.addOpcode(op);
+
+ if (op == NOP || op == L2I || op == F2I || op == D2I)
+ if (op2 != NOP)
+ bytecode.addOpcode(op2);
}
public void atExpr(Expr expr) throws CompileError {
- // method call, array access, member access,
- // (unary) +, (unary) -, ++, --, !, ~
-
- int token = expr.getOperator();
- ASTree oprand = expr.oprand1();
- if (token == CALL) // method call
- atMethodCall(expr);
- else if (token == '.')
- if (((Symbol)expr.oprand2()).get().equals("length"))
- atArrayLength(expr);
- else
- atFieldRead(expr);
- else if (token == MEMBER) { // field read
- if (!atClassObject(expr)) // .class
- atFieldRead(expr);
- }
- else if (token == ARRAY)
- atArrayRead(oprand, expr.oprand2());
- else if (token == PLUSPLUS || token == MINUSMINUS)
- atPlusPlus(token, oprand, expr, true);
- else if (token == '!') {
- booleanExpr(false, expr);
- bytecode.addIndex(7);
- bytecode.addIconst(1);
- bytecode.addOpcode(Opcode.GOTO);
- bytecode.addIndex(4);
- bytecode.addIconst(0);
- }
- else {
- expr.oprand1().accept(this);
- int type = typePrecedence(exprType);
- if (arrayDim > 0)
- badType(expr);
-
- if (token == '-') {
- if (type == P_DOUBLE)
- bytecode.addOpcode(DNEG);
- else if (type == P_FLOAT)
- bytecode.addOpcode(FNEG);
- else if (type == P_LONG)
- bytecode.addOpcode(LNEG);
- else if (type == P_INT) {
- bytecode.addOpcode(INEG);
- exprType = INT; // type may be BYTE, ...
- }
- else
- badType(expr);
- }
- else if (token == '~') {
- if (type == P_INT) {
- bytecode.addIconst(-1);
- bytecode.addOpcode(IXOR);
- exprType = INT; // type may be BYTE. ...
- }
- else if (type == P_LONG) {
- bytecode.addLconst(-1);
- bytecode.addOpcode(LXOR);
- }
- else
- badType(expr);
-
- }
- else if (token == '+') {
- if (type == P_OTHER)
- badType(expr);
-
- // do nothing. ignore.
- }
- else
- fatal();
- }
+ // method call, array access, member access,
+ // (unary) +, (unary) -, ++, --, !, ~
+
+ int token = expr.getOperator();
+ ASTree oprand = expr.oprand1();
+ if (token == CALL) // method call
+ atMethodCall(expr);
+ else if (token == '.')
+ if (((Symbol)expr.oprand2()).get().equals("length"))
+ atArrayLength(expr);
+ else
+ atFieldRead(expr);
+ else if (token == MEMBER) { // field read
+ if (!atClassObject(expr)) // .class
+ atFieldRead(expr);
+ }
+ else if (token == ARRAY)
+ atArrayRead(oprand, expr.oprand2());
+ else if (token == PLUSPLUS || token == MINUSMINUS)
+ atPlusPlus(token, oprand, expr, true);
+ else if (token == '!') {
+ booleanExpr(false, expr);
+ bytecode.addIndex(7);
+ bytecode.addIconst(1);
+ bytecode.addOpcode(Opcode.GOTO);
+ bytecode.addIndex(4);
+ bytecode.addIconst(0);
+ }
+ else {
+ expr.oprand1().accept(this);
+ int type = typePrecedence(exprType);
+ if (arrayDim > 0)
+ badType(expr);
+
+ if (token == '-') {
+ if (type == P_DOUBLE)
+ bytecode.addOpcode(DNEG);
+ else if (type == P_FLOAT)
+ bytecode.addOpcode(FNEG);
+ else if (type == P_LONG)
+ bytecode.addOpcode(LNEG);
+ else if (type == P_INT) {
+ bytecode.addOpcode(INEG);
+ exprType = INT; // type may be BYTE, ...
+ }
+ else
+ badType(expr);
+ }
+ else if (token == '~') {
+ if (type == P_INT) {
+ bytecode.addIconst(-1);
+ bytecode.addOpcode(IXOR);
+ exprType = INT; // type may be BYTE. ...
+ }
+ else if (type == P_LONG) {
+ bytecode.addLconst(-1);
+ bytecode.addOpcode(LXOR);
+ }
+ else
+ badType(expr);
+
+ }
+ else if (token == '+') {
+ if (type == P_OTHER)
+ badType(expr);
+
+ // do nothing. ignore.
+ }
+ else
+ fatal();
+ }
}
protected static void badType(Expr expr) throws CompileError {
- throw new CompileError("invalid type for " + expr.getName());
+ throw new CompileError("invalid type for " + expr.getName());
}
protected abstract void atMethodCall(Expr expr) throws CompileError;
protected abstract void atFieldRead(ASTree expr) throws CompileError;
public boolean atClassObject(Expr expr) throws CompileError {
- if (!((Symbol)expr.oprand2()).get().equals("class"))
- return false;
+ if (!((Symbol)expr.oprand2()).get().equals("class"))
+ return false;
- if (resolveClassName((ASTList)expr.oprand1()) == null)
- return false;
+ if (resolveClassName((ASTList)expr.oprand1()) == null)
+ return false;
- throw new CompileError(".class is not supported");
+ throw new CompileError(".class is not supported");
}
public void atArrayLength(Expr expr) throws CompileError {
- expr.oprand1().accept(this);
- if (arrayDim == 0)
- throw new CompileError(".length applied to a non array");
+ expr.oprand1().accept(this);
+ if (arrayDim == 0)
+ throw new CompileError(".length applied to a non array");
- bytecode.addOpcode(ARRAYLENGTH);
- exprType = INT;
- arrayDim = 0;
+ bytecode.addOpcode(ARRAYLENGTH);
+ exprType = INT;
+ arrayDim = 0;
}
public void atArrayRead(ASTree array, ASTree index)
- throws CompileError
+ throws CompileError
{
- int op;
- arrayAccess(array, index);
- bytecode.addOpcode(getArrayReadOp(exprType, arrayDim));
+ int op;
+ arrayAccess(array, index);
+ bytecode.addOpcode(getArrayReadOp(exprType, arrayDim));
}
protected void arrayAccess(ASTree array, ASTree index)
- throws CompileError
+ throws CompileError
{
- array.accept(this);
- int type = exprType;
- int dim = arrayDim;
- if (dim == 0)
- throw new CompileError("bad array access");
+ array.accept(this);
+ int type = exprType;
+ int dim = arrayDim;
+ if (dim == 0)
+ throw new CompileError("bad array access");
- String cname = className;
+ String cname = className;
- index.accept(this);
- if (typePrecedence(exprType) != P_INT || arrayDim > 0)
- throw new CompileError("bad array index");
+ index.accept(this);
+ if (typePrecedence(exprType) != P_INT || arrayDim > 0)
+ throw new CompileError("bad array index");
- exprType = type;
- arrayDim = dim - 1;
- className = cname;
+ exprType = type;
+ arrayDim = dim - 1;
+ className = cname;
}
protected static int getArrayReadOp(int type, int dim) {
- int op;
- if (dim > 0)
- return AALOAD;
-
- switch (type) {
- case DOUBLE :
- return DALOAD;
- case FLOAT :
- return FALOAD;
- case LONG :
- return LALOAD;
- case INT :
- return IALOAD;
- case SHORT :
- return SALOAD;
- case CHAR :
- return CALOAD;
- case BYTE :
- case BOOLEAN :
- return BALOAD;
- default :
- return AALOAD;
- }
+ int op;
+ if (dim > 0)
+ return AALOAD;
+
+ switch (type) {
+ case DOUBLE :
+ return DALOAD;
+ case FLOAT :
+ return FALOAD;
+ case LONG :
+ return LALOAD;
+ case INT :
+ return IALOAD;
+ case SHORT :
+ return SALOAD;
+ case CHAR :
+ return CALOAD;
+ case BYTE :
+ case BOOLEAN :
+ return BALOAD;
+ default :
+ return AALOAD;
+ }
}
protected static int getArrayWriteOp(int type, int dim) {
- int op;
- if (dim > 0)
- return AASTORE;
-
- switch (type) {
- case DOUBLE :
- return DASTORE;
- case FLOAT :
- return FASTORE;
- case LONG :
- return LASTORE;
- case INT :
- return IASTORE;
- case CHAR :
- return CASTORE;
- case BYTE :
- case BOOLEAN :
- return BASTORE;
- default :
- return AASTORE;
- }
+ int op;
+ if (dim > 0)
+ return AASTORE;
+
+ switch (type) {
+ case DOUBLE :
+ return DASTORE;
+ case FLOAT :
+ return FASTORE;
+ case LONG :
+ return LASTORE;
+ case INT :
+ return IASTORE;
+ case CHAR :
+ return CASTORE;
+ case BYTE :
+ case BOOLEAN :
+ return BASTORE;
+ default :
+ return AASTORE;
+ }
}
private void atPlusPlus(int token, ASTree oprand, Expr expr,
- boolean doDup) throws CompileError
+ boolean doDup) throws CompileError
{
- boolean isPost = oprand == null; // ++i or i++?
- if (isPost)
- oprand = expr.oprand2();
-
- if (oprand instanceof Variable) {
- Declarator d = ((Variable)oprand).getDeclarator();
- int t = exprType = d.getType();
- arrayDim = d.getArrayDim();
- int var = getLocalVar(d);
- if (arrayDim > 0)
- badType(expr);
-
- if (t == DOUBLE) {
- bytecode.addDload(var);
- if (doDup && isPost)
- bytecode.addOpcode(DUP2);
-
- bytecode.addDconst(1.0);
- bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);
- if (doDup && !isPost)
- bytecode.addOpcode(DUP2);
-
- bytecode.addDstore(var);
- }
- else if (t == LONG) {
- bytecode.addLload(var);
- if (doDup && isPost)
- bytecode.addOpcode(DUP2);
-
- bytecode.addLconst((long)1);
- bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);
- if (doDup && !isPost)
- bytecode.addOpcode(DUP2);
-
- bytecode.addLstore(var);
- }
- else if (t == FLOAT) {
- bytecode.addFload(var);
- if (doDup && isPost)
- bytecode.addOpcode(DUP);
-
- bytecode.addFconst(1.0f);
- bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);
- if (doDup && !isPost)
- bytecode.addOpcode(DUP);
-
- bytecode.addFstore(var);
- }
- else if (t == BYTE || t == CHAR || t == SHORT || t == INT) {
- if (doDup && isPost)
- bytecode.addIload(var);
-
- bytecode.addOpcode(IINC);
- bytecode.add(var);
- bytecode.add(token == PLUSPLUS ? 1 : -1);
-
- if (doDup && !isPost)
- bytecode.addIload(var);
- }
- else
- badType(expr);
- }
- else {
- if (oprand instanceof Expr) {
- Expr e = (Expr)oprand;
- if (e.getOperator() == ARRAY) {
- atArrayPlusPlus(token, isPost, e, doDup);
- return;
- }
- }
-
- atFieldPlusPlus(token, isPost, oprand, expr, doDup);
- }
+ boolean isPost = oprand == null; // ++i or i++?
+ if (isPost)
+ oprand = expr.oprand2();
+
+ if (oprand instanceof Variable) {
+ Declarator d = ((Variable)oprand).getDeclarator();
+ int t = exprType = d.getType();
+ arrayDim = d.getArrayDim();
+ int var = getLocalVar(d);
+ if (arrayDim > 0)
+ badType(expr);
+
+ if (t == DOUBLE) {
+ bytecode.addDload(var);
+ if (doDup && isPost)
+ bytecode.addOpcode(DUP2);
+
+ bytecode.addDconst(1.0);
+ bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);
+ if (doDup && !isPost)
+ bytecode.addOpcode(DUP2);
+
+ bytecode.addDstore(var);
+ }
+ else if (t == LONG) {
+ bytecode.addLload(var);
+ if (doDup && isPost)
+ bytecode.addOpcode(DUP2);
+
+ bytecode.addLconst((long)1);
+ bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);
+ if (doDup && !isPost)
+ bytecode.addOpcode(DUP2);
+
+ bytecode.addLstore(var);
+ }
+ else if (t == FLOAT) {
+ bytecode.addFload(var);
+ if (doDup && isPost)
+ bytecode.addOpcode(DUP);
+
+ bytecode.addFconst(1.0f);
+ bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);
+ if (doDup && !isPost)
+ bytecode.addOpcode(DUP);
+
+ bytecode.addFstore(var);
+ }
+ else if (t == BYTE || t == CHAR || t == SHORT || t == INT) {
+ if (doDup && isPost)
+ bytecode.addIload(var);
+
+ bytecode.addOpcode(IINC);
+ bytecode.add(var);
+ bytecode.add(token == PLUSPLUS ? 1 : -1);
+
+ if (doDup && !isPost)
+ bytecode.addIload(var);
+ }
+ else
+ badType(expr);
+ }
+ else {
+ if (oprand instanceof Expr) {
+ Expr e = (Expr)oprand;
+ if (e.getOperator() == ARRAY) {
+ atArrayPlusPlus(token, isPost, e, doDup);
+ return;
+ }
+ }
+
+ atFieldPlusPlus(token, isPost, oprand, expr, doDup);
+ }
}
public void atArrayPlusPlus(int token, boolean isPost,
- Expr expr, boolean doDup) throws CompileError
+ Expr expr, boolean doDup) throws CompileError
{
- arrayAccess(expr.oprand1(), expr.oprand2());
- int t = exprType;
- int dim = arrayDim;
- if (dim > 0)
- badType(expr);
+ arrayAccess(expr.oprand1(), expr.oprand2());
+ int t = exprType;
+ int dim = arrayDim;
+ if (dim > 0)
+ badType(expr);
- bytecode.addOpcode(DUP2);
- bytecode.addOpcode(getArrayReadOp(t, arrayDim));
- int dup_code = is2word(t, dim) ? DUP2_X2 : DUP_X2;
- atPlusPlusCore(dup_code, doDup, token, isPost, expr);
- bytecode.addOpcode(getArrayWriteOp(t, dim));
+ bytecode.addOpcode(DUP2);
+ bytecode.addOpcode(getArrayReadOp(t, arrayDim));
+ int dup_code = is2word(t, dim) ? DUP2_X2 : DUP_X2;
+ atPlusPlusCore(dup_code, doDup, token, isPost, expr);
+ bytecode.addOpcode(getArrayWriteOp(t, dim));
}
protected void atPlusPlusCore(int dup_code, boolean doDup,
- int token, boolean isPost,
- Expr expr) throws CompileError
+ int token, boolean isPost,
+ Expr expr) throws CompileError
{
- int t = exprType;
-
- if (doDup && isPost)
- bytecode.addOpcode(dup_code);
-
- if (t == INT || t == BYTE || t == CHAR || t == SHORT) {
- bytecode.addIconst(1);
- bytecode.addOpcode(token == PLUSPLUS ? IADD : ISUB);
- exprType = INT;
- }
- else if (t == LONG) {
- bytecode.addLconst((long)1);
- bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);
- }
- else if (t == FLOAT) {
- bytecode.addFconst(1.0f);
- bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);
- }
- else if (t == DOUBLE) {
- bytecode.addDconst(1.0);
- bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);
- }
- else
- badType(expr);
-
- if (doDup && !isPost)
- bytecode.addOpcode(dup_code);
+ int t = exprType;
+
+ if (doDup && isPost)
+ bytecode.addOpcode(dup_code);
+
+ if (t == INT || t == BYTE || t == CHAR || t == SHORT) {
+ bytecode.addIconst(1);
+ bytecode.addOpcode(token == PLUSPLUS ? IADD : ISUB);
+ exprType = INT;
+ }
+ else if (t == LONG) {
+ bytecode.addLconst((long)1);
+ bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);
+ }
+ else if (t == FLOAT) {
+ bytecode.addFconst(1.0f);
+ bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);
+ }
+ else if (t == DOUBLE) {
+ bytecode.addDconst(1.0);
+ bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);
+ }
+ else
+ badType(expr);
+
+ if (doDup && !isPost)
+ bytecode.addOpcode(dup_code);
}
protected abstract void atFieldPlusPlus(int token, boolean isPost,
- ASTree oprand, Expr expr, boolean doDup) throws CompileError;
+ ASTree oprand, Expr expr, boolean doDup) throws CompileError;
public abstract void atMember(Member n) throws CompileError;
public void atVariable(Variable v) throws CompileError {
- Declarator d = v.getDeclarator();
- exprType = d.getType();
- arrayDim = d.getArrayDim();
- className = d.getClassName();
- int var = getLocalVar(d);
-
- if (arrayDim > 0)
- bytecode.addAload(var);
- else
- switch (exprType) {
- case CLASS :
- bytecode.addAload(var);
- break;
- case LONG :
- bytecode.addLload(var);
- break;
- case FLOAT :
- bytecode.addFload(var);
- break;
- case DOUBLE :
- bytecode.addDload(var);
- break;
- default : // BOOLEAN, BYTE, CHAR, SHORT, INT
- bytecode.addIload(var);
- break;
- }
+ Declarator d = v.getDeclarator();
+ exprType = d.getType();
+ arrayDim = d.getArrayDim();
+ className = d.getClassName();
+ int var = getLocalVar(d);
+
+ if (arrayDim > 0)
+ bytecode.addAload(var);
+ else
+ switch (exprType) {
+ case CLASS :
+ bytecode.addAload(var);
+ break;
+ case LONG :
+ bytecode.addLload(var);
+ break;
+ case FLOAT :
+ bytecode.addFload(var);
+ break;
+ case DOUBLE :
+ bytecode.addDload(var);
+ break;
+ default : // BOOLEAN, BYTE, CHAR, SHORT, INT
+ bytecode.addIload(var);
+ break;
+ }
}
public void atKeyword(Keyword k) throws CompileError {
- arrayDim = 0;
- int token = k.get();
- switch (token) {
- case TRUE :
- bytecode.addIconst(1);
- exprType = BOOLEAN;
- break;
- case FALSE :
- bytecode.addIconst(0);
- exprType = BOOLEAN;
- break;
- case NULL :
- bytecode.addOpcode(ACONST_NULL);
- exprType = NULL;
- break;
- case THIS :
- case SUPER :
- if (inStaticMethod)
- throw new CompileError("not-available: "
- + (token == THIS ? "this" : "super"));
-
- bytecode.addAload(0);
- exprType = CLASS;
- if (token == THIS)
- className = getThisName();
- else
- className = getSuperName();
- break;
- default :
- fatal();
- }
+ arrayDim = 0;
+ int token = k.get();
+ switch (token) {
+ case TRUE :
+ bytecode.addIconst(1);
+ exprType = BOOLEAN;
+ break;
+ case FALSE :
+ bytecode.addIconst(0);
+ exprType = BOOLEAN;
+ break;
+ case NULL :
+ bytecode.addOpcode(ACONST_NULL);
+ exprType = NULL;
+ break;
+ case THIS :
+ case SUPER :
+ if (inStaticMethod)
+ throw new CompileError("not-available: "
+ + (token == THIS ? "this" : "super"));
+
+ bytecode.addAload(0);
+ exprType = CLASS;
+ if (token == THIS)
+ className = getThisName();
+ else
+ className = getSuperName();
+ break;
+ default :
+ fatal();
+ }
}
public void atStringL(StringL s) throws CompileError {
- exprType = CLASS;
- arrayDim = 0;
- className = "java/lang/String";
- bytecode.addLdc(s.get());
+ exprType = CLASS;
+ arrayDim = 0;
+ className = "java/lang/String";
+ bytecode.addLdc(s.get());
}
public void atIntConst(IntConst i) throws CompileError {
- arrayDim = 0;
- long value = i.get();
- int type = i.getType();
- if (type == IntConstant || type == CharConstant) {
- exprType = (type == IntConstant ? INT : CHAR);
- bytecode.addIconst((int)value);
- }
- else {
- exprType = LONG;
- bytecode.addLconst(value);
- }
+ arrayDim = 0;
+ long value = i.get();
+ int type = i.getType();
+ if (type == IntConstant || type == CharConstant) {
+ exprType = (type == IntConstant ? INT : CHAR);
+ bytecode.addIconst((int)value);
+ }
+ else {
+ exprType = LONG;
+ bytecode.addLconst(value);
+ }
}
public void atDoubleConst(DoubleConst d) throws CompileError {
- arrayDim = 0;
- if (d.getType() == DoubleConstant) {
- exprType = DOUBLE;
- bytecode.addDconst(d.get());
- }
- else {
- exprType = FLOAT;
- bytecode.addFconst((float)d.get());
- }
+ arrayDim = 0;
+ if (d.getType() == DoubleConstant) {
+ exprType = DOUBLE;
+ bytecode.addDconst(d.get());
+ }
+ else {
+ exprType = FLOAT;
+ bytecode.addFconst((float)d.get());
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
public class CompileError extends Exception {
private String reason;
public CompileError(String s, Lex l) {
- reason = s;
- lex = l;
+ reason = s;
+ lex = l;
}
public CompileError(String s) {
- reason = s;
- lex = null;
+ reason = s;
+ lex = null;
}
public String getMessage() {
- return reason;
+ return reason;
}
public String toString() {
- return "compile error: " + reason;
+ return "compile error: " + reason;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import javassist.CtClass;
/**
* Constructs a compiler.
*
- * @param thisClass the class that a compiled method/field
- * belongs to.
+ * @param thisClass the class that a compiled method/field
+ * belongs to.
*/
public Javac(CtClass thisClass) {
- this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0),
- thisClass);
+ this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0),
+ thisClass);
}
/**
* The produced bytecode is stored in the <code>Bytecode</code> object
* specified by <code>b</code>.
*
- * @param thisClass the class that a compiled method/field
- * belongs to.
+ * @param thisClass the class that a compiled method/field
+ * belongs to.
*/
public Javac(Bytecode b, CtClass thisClass) {
- gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool());
- stable = new SymbolTable();
- bytecode = b;
+ gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool());
+ stable = new SymbolTable();
+ bytecode = b;
}
/**
* <p>In a method or constructor body, $0, $1, ... and $_
* are not available.
*
- * @return a <code>CtMethod</code>, <code>CtConstructor</code>,
- * or <code>CtField</code> object.
+ * @return a <code>CtMethod</code>, <code>CtConstructor</code>,
+ * or <code>CtField</code> object.
* @see #recordProceed(String,String)
*/
public CtMember compile(String src) throws CompileError {
- Parser p = new Parser(new Lex(src));
- ASTList mem = p.parseMember1(stable);
- try {
- if (mem instanceof FieldDecl)
- return compileField((FieldDecl)mem);
- else
- return compileMethod(p, (MethodDecl)mem);
- }
- catch (CannotCompileException e) {
- throw new CompileError(e.getMessage());
- }
+ Parser p = new Parser(new Lex(src));
+ ASTList mem = p.parseMember1(stable);
+ try {
+ if (mem instanceof FieldDecl)
+ return compileField((FieldDecl)mem);
+ else
+ return compileMethod(p, (MethodDecl)mem);
+ }
+ catch (CannotCompileException e) {
+ throw new CompileError(e.getMessage());
+ }
}
public static class CtFieldWithInit extends CtField {
- private ASTree init;
+ private ASTree init;
- CtFieldWithInit(CtClass type, String name, CtClass declaring)
- throws CannotCompileException
- {
- super(type, name, declaring);
- init = null;
- }
+ CtFieldWithInit(CtClass type, String name, CtClass declaring)
+ throws CannotCompileException
+ {
+ super(type, name, declaring);
+ init = null;
+ }
- protected void setInit(ASTree i) { init = i; }
+ protected void setInit(ASTree i) { init = i; }
- protected ASTree getInitAST() {
- return init;
- }
+ protected ASTree getInitAST() {
+ return init;
+ }
}
private CtField compileField(FieldDecl fd)
- throws CompileError, CannotCompileException
+ throws CompileError, CannotCompileException
{
- CtFieldWithInit f;
- Declarator d = fd.getDeclarator();
- f = new CtFieldWithInit(gen.lookupClass(d), d.getVariable().get(),
- gen.getThisClass());
- f.setModifiers(gen.getModifiers(fd.getModifiers()));
- if (fd.getInit() != null)
- f.setInit(fd.getInit());
-
- return f;
+ CtFieldWithInit f;
+ Declarator d = fd.getDeclarator();
+ f = new CtFieldWithInit(gen.lookupClass(d), d.getVariable().get(),
+ gen.getThisClass());
+ f.setModifiers(gen.getModifiers(fd.getModifiers()));
+ if (fd.getInit() != null)
+ f.setInit(fd.getInit());
+
+ return f;
}
private CtMember compileMethod(Parser p, MethodDecl md)
- throws CompileError
+ throws CompileError
{
- int mod = gen.getModifiers(md.getModifiers());
- CtClass[] plist = gen.makeParamList(md);
- CtClass[] tlist = gen.makeThrowsList(md);
- recordParams(plist, Modifier.isStatic(mod));
- md = p.parseMethod2(stable, md);
- try {
- if (md.isConstructor()) {
- CtConstructor cons = new CtConstructor(plist,
- gen.getThisClass());
- cons.setModifiers(mod);
- md.accept(gen);
- cons.getMethodInfo().setCodeAttribute(
- bytecode.toCodeAttribute());
- cons.setExceptionTypes(tlist);
- return cons;
- }
- else {
- Declarator r = md.getReturn();
- CtClass rtype = gen.lookupClass(r);
- recordReturnType(rtype, false);
- CtMethod method = new CtMethod(rtype, r.getVariable().get(),
- plist, gen.getThisClass());
- method.setModifiers(mod);
- gen.setThisMethod(method);
- md.accept(gen);
- if (md.getBody() != null)
- method.getMethodInfo().setCodeAttribute(
- bytecode.toCodeAttribute());
- else
- method.setModifiers(mod | Modifier.ABSTRACT);
-
- method.setExceptionTypes(tlist);
- return method;
- }
- }
- catch (NotFoundException e) {
- throw new CompileError(e.toString());
- }
+ int mod = gen.getModifiers(md.getModifiers());
+ CtClass[] plist = gen.makeParamList(md);
+ CtClass[] tlist = gen.makeThrowsList(md);
+ recordParams(plist, Modifier.isStatic(mod));
+ md = p.parseMethod2(stable, md);
+ try {
+ if (md.isConstructor()) {
+ CtConstructor cons = new CtConstructor(plist,
+ gen.getThisClass());
+ cons.setModifiers(mod);
+ md.accept(gen);
+ cons.getMethodInfo().setCodeAttribute(
+ bytecode.toCodeAttribute());
+ cons.setExceptionTypes(tlist);
+ return cons;
+ }
+ else {
+ Declarator r = md.getReturn();
+ CtClass rtype = gen.lookupClass(r);
+ recordReturnType(rtype, false);
+ CtMethod method = new CtMethod(rtype, r.getVariable().get(),
+ plist, gen.getThisClass());
+ method.setModifiers(mod);
+ gen.setThisMethod(method);
+ md.accept(gen);
+ if (md.getBody() != null)
+ method.getMethodInfo().setCodeAttribute(
+ bytecode.toCodeAttribute());
+ else
+ method.setModifiers(mod | Modifier.ABSTRACT);
+
+ method.setExceptionTypes(tlist);
+ return method;
+ }
+ }
+ catch (NotFoundException e) {
+ throw new CompileError(e.toString());
+ }
}
/**
* Compiles a method (or constructor) body.
*/
public Bytecode compileBody(CtBehavior method, String src)
- throws CompileError
+ throws CompileError
{
- try {
- int mod = method.getModifiers();
- recordParams(method.getParameterTypes(), Modifier.isStatic(mod));
-
- CtClass rtype;
- if (method instanceof CtMethod) {
- gen.setThisMethod((CtMethod)method);
- rtype = ((CtMethod)method).getReturnType();
- }
- else
- rtype = CtClass.voidType;
-
- recordReturnType(rtype, false);
- boolean isVoid = rtype == CtClass.voidType;
-
- Parser p = new Parser(new Lex(src));
- SymbolTable stb = new SymbolTable(stable);
- Stmnt s = p.parseStatement(stb);
- gen.atMethodBody(s, method instanceof CtConstructor, isVoid);
- return bytecode;
- }
- catch (NotFoundException e) {
- throw new CompileError(e.toString());
- }
+ try {
+ int mod = method.getModifiers();
+ recordParams(method.getParameterTypes(), Modifier.isStatic(mod));
+
+ CtClass rtype;
+ if (method instanceof CtMethod) {
+ gen.setThisMethod((CtMethod)method);
+ rtype = ((CtMethod)method).getReturnType();
+ }
+ else
+ rtype = CtClass.voidType;
+
+ recordReturnType(rtype, false);
+ boolean isVoid = rtype == CtClass.voidType;
+
+ Parser p = new Parser(new Lex(src));
+ SymbolTable stb = new SymbolTable(stable);
+ Stmnt s = p.parseStatement(stb);
+ gen.atMethodBody(s, method instanceof CtConstructor, isVoid);
+ return bytecode;
+ }
+ catch (NotFoundException e) {
+ throw new CompileError(e.toString());
+ }
}
/**
* <code>isStatic</code> must be recorded before compilation.
*/
public void recordParams(CtClass[] params, boolean isStatic)
- throws CompileError
+ throws CompileError
{
- gen.recordParams(params, isStatic, "$", "$args", "$$", stable);
+ gen.recordParams(params, isStatic, "$", "$args", "$$", stable);
}
/**
* <code>compileExpr()</code>. The correct value of
* <code>isStatic</code> must be recorded before compilation.
*
- * @paaram use0 true if $0 is used.
- * @param varNo the register number of $0 (use0 is true)
- * or $1 (otherwise).
- * @param target the type of $0 (it can be null if use0 is false).
- * @param isStatic true if the method in which the compiled bytecode
- * is embedded is static.
+ * @paaram use0 true if $0 is used.
+ * @param varNo the register number of $0 (use0 is true)
+ * or $1 (otherwise).
+ * @param target the type of $0 (it can be null if use0 is false).
+ * @param isStatic true if the method in which the compiled bytecode
+ * is embedded is static.
*/
public void recordParams(String target, CtClass[] params,
- boolean use0, int varNo, boolean isStatic)
- throws CompileError
+ boolean use0, int varNo, boolean isStatic)
+ throws CompileError
{
- gen.recordParams(params, isStatic, "$", "$args", "$$",
- use0, varNo, target, stable);
+ gen.recordParams(params, isStatic, "$", "$args", "$$",
+ use0, varNo, target, stable);
}
/**
* <p>If the return type is void, ($r) does nothing.
* The type of $_ is java.lang.Object.
*
- * @param useResultVar true if $_ is used.
- * @return -1 or the variable index assigned to $_.
+ * @param useResultVar true if $_ is used.
+ * @return -1 or the variable index assigned to $_.
*/
public int recordReturnType(CtClass type, boolean useResultVar)
- throws CompileError
+ throws CompileError
{
- gen.recordType(type);
- return gen.recordReturnType(type, "$r",
- (useResultVar ? resultVarName : null), stable);
+ gen.recordType(type);
+ return gen.recordReturnType(type, "$r",
+ (useResultVar ? resultVarName : null), stable);
}
/**
* the value of $type.
*/
public void recordType(CtClass t) {
- gen.recordType(t);
+ gen.recordType(t);
}
/**
* Makes the given variable available.
*
- * @param type variable type
- * @param name variable name
+ * @param type variable type
+ * @param name variable name
*/
public int recordVariable(CtClass type, String name)
- throws CompileError
+ throws CompileError
{
- return gen.recordVariable(type, name, stable);
+ return gen.recordVariable(type, name, stable);
}
/**
* If the return type of $proceed() is void, null is pushed on the
* stack.
*
- * @param target an expression specifying the target object.
- * if null, "this" is the target.
- * @param method the method name.
+ * @param target an expression specifying the target object.
+ * if null, "this" is the target.
+ * @param method the method name.
*/
public void recordProceed(String target, String method)
- throws CompileError
+ throws CompileError
{
- Parser p = new Parser(new Lex(target));
- final ASTree texpr = p.parseExpression(stable);
- final String m = method;
-
- ProceedHandler h = new ProceedHandler() {
- public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
- throws CompileError
- {
- ASTree expr = new Member(m);
- if (texpr != null)
- expr = Expr.make('.', texpr, expr);
-
- expr = Expr.make(TokenId.CALL, expr, args);
- expr.accept(gen);
- gen.addNullIfVoid();
- }
- };
-
- gen.setProceedHandler(h, proceedName);
+ Parser p = new Parser(new Lex(target));
+ final ASTree texpr = p.parseExpression(stable);
+ final String m = method;
+
+ ProceedHandler h = new ProceedHandler() {
+ public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
+ throws CompileError
+ {
+ ASTree expr = new Member(m);
+ if (texpr != null)
+ expr = Expr.make('.', texpr, expr);
+
+ expr = Expr.make(TokenId.CALL, expr, args);
+ expr.accept(gen);
+ gen.addNullIfVoid();
+ }
+ };
+
+ gen.setProceedHandler(h, proceedName);
}
/**
* Prepares to use $proceed().
*/
public void recordProceed(ProceedHandler h) {
- gen.setProceedHandler(h, proceedName);
+ gen.setProceedHandler(h, proceedName);
}
/**
* ($0, $1, ..) are available.
*/
public void compileStmnt(String src) throws CompileError {
- Parser p = new Parser(new Lex(src));
- SymbolTable stb = new SymbolTable(stable);
+ Parser p = new Parser(new Lex(src));
+ SymbolTable stb = new SymbolTable(stable);
// while (p.hasMore()) {
- Stmnt s = p.parseStatement(stb);
- if (s != null)
- s.accept(gen);
+ Stmnt s = p.parseStatement(stb);
+ if (s != null)
+ s.accept(gen);
// }
}
* have been invoked.
*/
public void compileExpr(String src) throws CompileError {
- Parser p = new Parser(new Lex(src));
- ASTree e = p.parseExpression(stable);
- compileExpr(e);
+ Parser p = new Parser(new Lex(src));
+ ASTree e = p.parseExpression(stable);
+ compileExpr(e);
}
/**
* have been invoked.
*/
public void compileExpr(ASTree e) throws CompileError {
- if (e != null)
- e.accept(gen);
+ if (e != null)
+ e.accept(gen);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import javassist.*;
private String paramArrayName = null;
private String paramListName = null;
private CtClass[] paramTypeList = null;
- private int paramVarBase = 0; // variable index for $0 or $1.
- private boolean useParam0 = false; // true if $0 is used.
- private String param0Type = null; // JVM name
+ private int paramVarBase = 0; // variable index for $0 or $1.
+ private boolean useParam0 = false; // true if $0 is used.
+ private String param0Type = null; // JVM name
private static final String sigName = "$sig";
private static final String dollarTypeName = "$type";
private static final String clazzName = "$class";
private CtClass dollarType = null;
private CtClass returnType = null;
private String returnCastName = null;
- private String returnVarName = null; // null if $_ is not used.
+ private String returnVarName = null; // null if $_ is not used.
private static final String wrapperCastName = "$w";
private String proceedName = null;
private static final String cflowName = "$cflow";
- private ProceedHandler procHandler = null; // null if not used.
+ private ProceedHandler procHandler = null; // null if not used.
public JvstCodeGen(Bytecode b, CtClass cc, ClassPool cp) {
- super(b, cc, cp);
+ super(b, cc, cp);
}
/* Index of $1.
*/
private int indexOfParam1() {
- return paramVarBase + (useParam0 ? 1 : 0);
+ return paramVarBase + (useParam0 ? 1 : 0);
}
/* Records a ProceedHandler obejct.
*
- * @param name the name of the special method call.
- * it is usually $proceed.
+ * @param name the name of the special method call.
+ * it is usually $proceed.
*/
public void setProceedHandler(ProceedHandler h, String name) {
- proceedName = name;
- procHandler = h;
+ proceedName = name;
+ procHandler = h;
}
/* If the type of the expression compiled last is void,
* add ACONST_NULL and change exprType, arrayDim, className.
*/
public void addNullIfVoid() {
- if (exprType == VOID) {
- bytecode.addOpcode(ACONST_NULL);
- exprType = CLASS;
- arrayDim = 0;
- className = jvmJavaLangObject;
- }
+ if (exprType == VOID) {
+ bytecode.addOpcode(ACONST_NULL);
+ exprType = CLASS;
+ arrayDim = 0;
+ className = jvmJavaLangObject;
+ }
}
/* To support $args, $sig, and $type.
* $args is an array of parameter list.
*/
public void atMember(Member mem) throws CompileError {
- String name = mem.get();
- if (name.equals(paramArrayName)) {
- compileParameterList(bytecode, paramTypeList, indexOfParam1());
- exprType = CLASS;
- arrayDim = 1;
- className = jvmJavaLangObject;
- }
- else if (name.equals(sigName)) {
- bytecode.addLdc(Descriptor.ofMethod(returnType, paramTypeList));
- bytecode.addInvokestatic("javassist/runtime/Desc", "getParams",
- "(Ljava/lang/String;)[Ljava/lang/Class;");
- exprType = CLASS;
- arrayDim = 1;
- className = "java/lang/Class";
- }
- else if (name.equals(dollarTypeName)) {
- if (dollarType == null)
- throw new CompileError(dollarType + " is not available");
-
- bytecode.addLdc(Descriptor.of(dollarType));
- callGetType("getType");
- }
- else if (name.equals(clazzName)) {
- if (param0Type == null)
- throw new CompileError(clazzName + " is not available");
-
- bytecode.addLdc(param0Type);
- callGetType("getClazz");
- }
- else
- super.atMember(mem);
+ String name = mem.get();
+ if (name.equals(paramArrayName)) {
+ compileParameterList(bytecode, paramTypeList, indexOfParam1());
+ exprType = CLASS;
+ arrayDim = 1;
+ className = jvmJavaLangObject;
+ }
+ else if (name.equals(sigName)) {
+ bytecode.addLdc(Descriptor.ofMethod(returnType, paramTypeList));
+ bytecode.addInvokestatic("javassist/runtime/Desc", "getParams",
+ "(Ljava/lang/String;)[Ljava/lang/Class;");
+ exprType = CLASS;
+ arrayDim = 1;
+ className = "java/lang/Class";
+ }
+ else if (name.equals(dollarTypeName)) {
+ if (dollarType == null)
+ throw new CompileError(dollarType + " is not available");
+
+ bytecode.addLdc(Descriptor.of(dollarType));
+ callGetType("getType");
+ }
+ else if (name.equals(clazzName)) {
+ if (param0Type == null)
+ throw new CompileError(clazzName + " is not available");
+
+ bytecode.addLdc(param0Type);
+ callGetType("getClazz");
+ }
+ else
+ super.atMember(mem);
}
private void callGetType(String method) {
- bytecode.addInvokestatic("javassist/runtime/Desc", method,
- "(Ljava/lang/String;)Ljava/lang/Class;");
- exprType = CLASS;
- arrayDim = 0;
- className = "java/lang/Class";
+ bytecode.addInvokestatic("javassist/runtime/Desc", method,
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+ exprType = CLASS;
+ arrayDim = 0;
+ className = "java/lang/Class";
}
private void atSigOrType(String sig) throws CompileError {
}
protected void atFieldAssign(Expr expr, int op, ASTree left,
- ASTree right, boolean doDup) throws CompileError
+ ASTree right, boolean doDup) throws CompileError
{
- if (left instanceof Member
- && ((Member)left).get().equals(paramArrayName)) {
- if (op != '=')
- throw new CompileError("bad operator for " + paramArrayName);
+ if (left instanceof Member
+ && ((Member)left).get().equals(paramArrayName)) {
+ if (op != '=')
+ throw new CompileError("bad operator for " + paramArrayName);
- right.accept(this);
- if (arrayDim != 1 || exprType != CLASS)
- throw new CompileError("invalid type for " + paramArrayName);
+ right.accept(this);
+ if (arrayDim != 1 || exprType != CLASS)
+ throw new CompileError("invalid type for " + paramArrayName);
- atAssignParamList(paramTypeList, bytecode);
- if (!doDup)
- bytecode.addOpcode(POP);
- }
- else
- super.atFieldAssign(expr, op, left, right, doDup);
+ atAssignParamList(paramTypeList, bytecode);
+ if (!doDup)
+ bytecode.addOpcode(POP);
+ }
+ else
+ super.atFieldAssign(expr, op, left, right, doDup);
}
protected void atAssignParamList(CtClass[] params, Bytecode code)
- throws CompileError
+ throws CompileError
{
- if (params == null)
- return;
+ if (params == null)
+ return;
- int varNo = indexOfParam1();
- int n = params.length;
- for (int i = 0; i < n; ++i) {
- code.addOpcode(DUP);
- code.addIconst(i);
- code.addOpcode(AALOAD);
- compileUnwrapValue(params[i], code);
- code.addStore(varNo, params[i]);
- varNo += is2word(exprType, arrayDim) ? 2 : 1;
- }
+ int varNo = indexOfParam1();
+ int n = params.length;
+ for (int i = 0; i < n; ++i) {
+ code.addOpcode(DUP);
+ code.addIconst(i);
+ code.addOpcode(AALOAD);
+ compileUnwrapValue(params[i], code);
+ code.addStore(varNo, params[i]);
+ varNo += is2word(exprType, arrayDim) ? 2 : 1;
+ }
}
public void atCastExpr(CastExpr expr) throws CompileError {
- ASTList classname = expr.getClassName();
- if (classname != null && expr.getArrayDim() == 0) {
- ASTree p = classname.head();
- if (p instanceof Symbol && classname.tail() == null) {
- String typename = ((Symbol)p).get();
- if (typename.equals(returnCastName)) {
- atCastToRtype(expr);
- return;
- }
- else if (typename.equals(wrapperCastName)) {
- atCastToWrapper(expr);
- return;
- }
- }
- }
-
- super.atCastExpr(expr);
+ ASTList classname = expr.getClassName();
+ if (classname != null && expr.getArrayDim() == 0) {
+ ASTree p = classname.head();
+ if (p instanceof Symbol && classname.tail() == null) {
+ String typename = ((Symbol)p).get();
+ if (typename.equals(returnCastName)) {
+ atCastToRtype(expr);
+ return;
+ }
+ else if (typename.equals(wrapperCastName)) {
+ atCastToWrapper(expr);
+ return;
+ }
+ }
+ }
+
+ super.atCastExpr(expr);
}
/**
* If the return type is void, this does nothing.
*/
protected void atCastToRtype(CastExpr expr) throws CompileError {
- expr.getOprand().accept(this);
- if (!isRefType(exprType) || arrayDim > 0)
- throw new CompileError("invalid type for " + returnCastName);
+ expr.getOprand().accept(this);
+ if (!isRefType(exprType) || arrayDim > 0)
+ throw new CompileError("invalid type for " + returnCastName);
- compileUnwrapValue(returnType, bytecode);
+ compileUnwrapValue(returnType, bytecode);
}
protected void atCastToWrapper(CastExpr expr) throws CompileError {
- expr.getOprand().accept(this);
- if (isRefType(exprType) || arrayDim > 0)
- return; // Object type. do nothing.
-
- CtClass clazz = lookupClass(exprType, arrayDim, className);
- if (clazz instanceof CtPrimitiveType) {
- CtPrimitiveType pt = (CtPrimitiveType)clazz;
- String wrapper = pt.getWrapperName();
- bytecode.addNew(wrapper); // new <wrapper>
- bytecode.addOpcode(DUP); // dup
- if (pt.getDataSize() > 1)
- bytecode.addOpcode(DUP2_X2); // dup2_x2
- else
- bytecode.addOpcode(DUP2_X1); // dup2_x1
-
- bytecode.addOpcode(POP2); // pop2
- bytecode.addInvokespecial(wrapper, "<init>",
- "(" + pt.getDescriptor() + ")V");
- // invokespecial
- exprType = CLASS;
- arrayDim = 0;
- className = jvmJavaLangObject;
- }
+ expr.getOprand().accept(this);
+ if (isRefType(exprType) || arrayDim > 0)
+ return; // Object type. do nothing.
+
+ CtClass clazz = lookupClass(exprType, arrayDim, className);
+ if (clazz instanceof CtPrimitiveType) {
+ CtPrimitiveType pt = (CtPrimitiveType)clazz;
+ String wrapper = pt.getWrapperName();
+ bytecode.addNew(wrapper); // new <wrapper>
+ bytecode.addOpcode(DUP); // dup
+ if (pt.getDataSize() > 1)
+ bytecode.addOpcode(DUP2_X2); // dup2_x2
+ else
+ bytecode.addOpcode(DUP2_X1); // dup2_x1
+
+ bytecode.addOpcode(POP2); // pop2
+ bytecode.addInvokespecial(wrapper, "<init>",
+ "(" + pt.getDescriptor() + ")V");
+ // invokespecial
+ exprType = CLASS;
+ arrayDim = 0;
+ className = jvmJavaLangObject;
+ }
}
/* Delegates to a ProcHandler object if the method call is
* $proceed(). It may process $cflow().
*/
protected void atMethodCall(Expr expr) throws CompileError {
- ASTree method = expr.oprand1();
- if (method instanceof Member) {
- String name = ((Member)method).get();
- if (procHandler != null && name.equals(proceedName)) {
- procHandler.doit(this, bytecode, (ASTList)expr.oprand2());
- return;
- }
- else if (name.equals(cflowName)) {
- atCflow((ASTList)expr.oprand2());
- return;
- }
- }
-
- super.atMethodCall(expr);
+ ASTree method = expr.oprand1();
+ if (method instanceof Member) {
+ String name = ((Member)method).get();
+ if (procHandler != null && name.equals(proceedName)) {
+ procHandler.doit(this, bytecode, (ASTList)expr.oprand2());
+ return;
+ }
+ else if (name.equals(cflowName)) {
+ atCflow((ASTList)expr.oprand2());
+ return;
+ }
+ }
+
+ super.atMethodCall(expr);
}
/* To support $cflow().
*/
protected void atCflow(ASTList cname) throws CompileError {
- StringBuffer sbuf = new StringBuffer();
- if (cname == null || cname.tail() != null)
- throw new CompileError("bad " + cflowName);
+ StringBuffer sbuf = new StringBuffer();
+ if (cname == null || cname.tail() != null)
+ throw new CompileError("bad " + cflowName);
- makeCflowName(sbuf, cname.head());
- String name = sbuf.toString();
- Object[] names = classPool.lookupCflow(name);
- if (names == null)
- throw new CompileError("no such a " + cflowName + ": " + name);
+ makeCflowName(sbuf, cname.head());
+ String name = sbuf.toString();
+ Object[] names = classPool.lookupCflow(name);
+ if (names == null)
+ throw new CompileError("no such a " + cflowName + ": " + name);
- bytecode.addGetstatic((String)names[0], (String)names[1],
- "Ljavassist/runtime/Cflow;");
- bytecode.addInvokevirtual("javassist.runtime.Cflow",
- "value", "()I");
- exprType = INT;
- arrayDim = 0;
- className = null;
+ bytecode.addGetstatic((String)names[0], (String)names[1],
+ "Ljavassist/runtime/Cflow;");
+ bytecode.addInvokevirtual("javassist.runtime.Cflow",
+ "value", "()I");
+ exprType = INT;
+ arrayDim = 0;
+ className = null;
}
/* Syntax:
* <cflow name> : <identifier> ('.' <identifier>)*
*/
private static void makeCflowName(StringBuffer sbuf, ASTree name)
- throws CompileError
+ throws CompileError
{
- if (name instanceof Symbol) {
- sbuf.append(((Symbol)name).get());
- return;
- }
- else if (name instanceof Expr) {
- Expr expr = (Expr)name;
- if (expr.getOperator() == '.') {
- makeCflowName(sbuf, expr.oprand1());
- sbuf.append('.');
- makeCflowName(sbuf, expr.oprand2());
- return;
- }
- }
-
- throw new CompileError("bad " + cflowName);
+ if (name instanceof Symbol) {
+ sbuf.append(((Symbol)name).get());
+ return;
+ }
+ else if (name instanceof Expr) {
+ Expr expr = (Expr)name;
+ if (expr.getOperator() == '.') {
+ makeCflowName(sbuf, expr.oprand1());
+ sbuf.append('.');
+ makeCflowName(sbuf, expr.oprand2());
+ return;
+ }
+ }
+
+ throw new CompileError("bad " + cflowName);
}
/* To support $$. ($$) is equivalent to ($1, ..., $n).
* It can be used only as a parameter list of method call.
*/
public boolean isParamListName(ASTList args) {
- if (paramTypeList != null
- && args != null && args.tail() == null) {
- ASTree left = args.head();
- return (left instanceof Member
- && ((Member)left).get().equals(paramListName));
- }
- else
- return false;
+ if (paramTypeList != null
+ && args != null && args.tail() == null) {
+ ASTree left = args.head();
+ return (left instanceof Member
+ && ((Member)left).get().equals(paramListName));
+ }
+ else
+ return false;
}
/*
public int atMethodArgsLength(ASTList args) {
- if (!isParamListName(args))
- return super.atMethodArgsLength(args);
+ if (!isParamListName(args))
+ return super.atMethodArgsLength(args);
- return paramTypeList.length;
+ return paramTypeList.length;
}
*/
public int atMethodArgsLength(ASTList args) {
- String pname = paramListName;
- int n = 0;
- while (args != null) {
- ASTree a = args.head();
- if (a instanceof Member && ((Member)a).get().equals(pname)) {
- if (paramTypeList != null)
- n += paramTypeList.length;
- }
- else
- ++n;
+ String pname = paramListName;
+ int n = 0;
+ while (args != null) {
+ ASTree a = args.head();
+ if (a instanceof Member && ((Member)a).get().equals(pname)) {
+ if (paramTypeList != null)
+ n += paramTypeList.length;
+ }
+ else
+ ++n;
- args = args.tail();
- }
+ args = args.tail();
+ }
- return n;
+ return n;
}
public void atMethodArgs(ASTList args, int[] types, int[] dims,
- String[] cnames) throws CompileError {
- CtClass[] params = paramTypeList;
- String pname = paramListName;
- int i = 0;
- while (args != null) {
- ASTree a = args.head();
- if (a instanceof Member && ((Member)a).get().equals(pname)) {
- if (params != null) {
- int n = params.length;
- int regno = indexOfParam1();
- for (int k = 0; k < n; ++k) {
- CtClass p = params[k];
- regno += bytecode.addLoad(regno, p);
- setType(p);
- types[i] = exprType;
- dims[i] = arrayDim;
- cnames[i] = className;
- ++i;
- }
- }
- }
- else {
- a.accept(this);
- types[i] = exprType;
- dims[i] = arrayDim;
- cnames[i] = className;
- ++i;
- }
-
- args = args.tail();
- }
+ String[] cnames) throws CompileError {
+ CtClass[] params = paramTypeList;
+ String pname = paramListName;
+ int i = 0;
+ while (args != null) {
+ ASTree a = args.head();
+ if (a instanceof Member && ((Member)a).get().equals(pname)) {
+ if (params != null) {
+ int n = params.length;
+ int regno = indexOfParam1();
+ for (int k = 0; k < n; ++k) {
+ CtClass p = params[k];
+ regno += bytecode.addLoad(regno, p);
+ setType(p);
+ types[i] = exprType;
+ dims[i] = arrayDim;
+ cnames[i] = className;
+ ++i;
+ }
+ }
+ }
+ else {
+ a.accept(this);
+ types[i] = exprType;
+ dims[i] = arrayDim;
+ cnames[i] = className;
+ ++i;
+ }
+
+ args = args.tail();
+ }
}
/*
public void atMethodArgs(ASTList args, int[] types, int[] dims,
- String[] cnames) throws CompileError {
- if (!isParamListName(args)) {
- super.atMethodArgs(args, types, dims, cnames);
- return;
- }
-
- CtClass[] params = paramTypeList;
- if (params == null)
- return;
-
- int n = params.length;
- int regno = indexOfParam1();
- for (int i = 0; i < n; ++i) {
- CtClass p = params[i];
- regno += bytecode.addLoad(regno, p);
- setType(p);
- types[i] = exprType;
- dims[i] = arrayDim;
- cnames[i] = className;
- }
+ String[] cnames) throws CompileError {
+ if (!isParamListName(args)) {
+ super.atMethodArgs(args, types, dims, cnames);
+ return;
+ }
+
+ CtClass[] params = paramTypeList;
+ if (params == null)
+ return;
+
+ int n = params.length;
+ int regno = indexOfParam1();
+ for (int i = 0; i < n; ++i) {
+ CtClass p = params[i];
+ regno += bytecode.addLoad(regno, p);
+ setType(p);
+ types[i] = exprType;
+ dims[i] = arrayDim;
+ cnames[i] = className;
+ }
}
*/
* Makes it valid to write "return <expr>;" for a void method.
*/
protected void atReturnStmnt(Stmnt st) throws CompileError {
- ASTree result = st.getLeft();
- if (result != null && returnType == CtClass.voidType) {
- result.accept(this);
- if (is2word(exprType, arrayDim))
- bytecode.addOpcode(POP2);
- else if (exprType != VOID)
- bytecode.addOpcode(POP);
+ ASTree result = st.getLeft();
+ if (result != null && returnType == CtClass.voidType) {
+ result.accept(this);
+ if (is2word(exprType, arrayDim))
+ bytecode.addOpcode(POP2);
+ else if (exprType != VOID)
+ bytecode.addOpcode(POP);
- result = null;
- }
+ result = null;
+ }
- atReturnStmnt2(result);
+ atReturnStmnt2(result);
}
/**
* <p>If the return type is void, ($r) does nothing.
* The type of $_ is java.lang.Object.
*
- * @param resultName null if $_ is not used.
- * @return -1 or the variable index assigned to $_.
+ * @param resultName null if $_ is not used.
+ * @return -1 or the variable index assigned to $_.
*/
public int recordReturnType(CtClass type, String castName,
- String resultName, SymbolTable tbl) throws CompileError
+ String resultName, SymbolTable tbl) throws CompileError
{
- returnType = type;
- returnCastName = castName;
- returnVarName = resultName;
- if (resultName == null)
- return -1;
- else {
- int varNo = getMaxLocals();
- int locals = varNo + recordVar(type, resultName, varNo, tbl);
- setMaxLocals(locals);
- return varNo;
- }
+ returnType = type;
+ returnCastName = castName;
+ returnVarName = resultName;
+ if (resultName == null)
+ return -1;
+ else {
+ int varNo = getMaxLocals();
+ int locals = varNo + recordVar(type, resultName, varNo, tbl);
+ setMaxLocals(locals);
+ return varNo;
+ }
}
/**
* Makes $type available.
*/
public void recordType(CtClass t) {
- dollarType = t;
+ dollarType = t;
}
/**
* if the method is static, then $0 is not available.
*/
public void recordParams(CtClass[] params, boolean isStatic,
- String prefix, String paramVarName,
- String paramsName, SymbolTable tbl)
- throws CompileError
+ String prefix, String paramVarName,
+ String paramsName, SymbolTable tbl)
+ throws CompileError
{
- recordParams(params, isStatic, prefix, paramVarName,
- paramsName, !isStatic, 0, getThisName(), tbl);
+ recordParams(params, isStatic, prefix, paramVarName,
+ paramsName, !isStatic, 0, getThisName(), tbl);
}
/**
* $0 is available only if use0 is true. It might not be equivalent
* to THIS.
*
- * @paaram use0 true if $0 is used.
- * @param paramBase the register number of $0 (use0 is true)
- * or $1 (otherwise).
- * @param target the class of $0. If use0 is false, target
- * can be null.
- * @param isStatic true if the method in which the compiled bytecode
- * is embedded is static.
+ * @paaram use0 true if $0 is used.
+ * @param paramBase the register number of $0 (use0 is true)
+ * or $1 (otherwise).
+ * @param target the class of $0. If use0 is false, target
+ * can be null.
+ * @param isStatic true if the method in which the compiled bytecode
+ * is embedded is static.
*/
public void recordParams(CtClass[] params, boolean isStatic,
- String prefix, String paramVarName,
- String paramsName, boolean use0,
- int paramBase, String target,
- SymbolTable tbl)
- throws CompileError
+ String prefix, String paramVarName,
+ String paramsName, boolean use0,
+ int paramBase, String target,
+ SymbolTable tbl)
+ throws CompileError
{
- int varNo;
+ int varNo;
- paramTypeList = params;
- paramArrayName = paramVarName;
- paramListName = paramsName;
- paramVarBase = paramBase;
- useParam0 = use0;
+ paramTypeList = params;
+ paramArrayName = paramVarName;
+ paramListName = paramsName;
+ paramVarBase = paramBase;
+ useParam0 = use0;
- param0Type = jvmToJavaName(target);
+ param0Type = jvmToJavaName(target);
- inStaticMethod = isStatic;
- varNo = paramBase;
- if (use0) {
- String varName = prefix + "0";
- Declarator decl
- = new Declarator(CLASS, javaToJvmName(target), 0, varNo++,
- new Symbol(varName));
- tbl.append(varName, decl);
- }
+ inStaticMethod = isStatic;
+ varNo = paramBase;
+ if (use0) {
+ String varName = prefix + "0";
+ Declarator decl
+ = new Declarator(CLASS, javaToJvmName(target), 0, varNo++,
+ new Symbol(varName));
+ tbl.append(varName, decl);
+ }
- for (int i = 0; i < params.length; ++i)
- varNo += recordVar(params[i], prefix + (i + 1), varNo, tbl);
+ for (int i = 0; i < params.length; ++i)
+ varNo += recordVar(params[i], prefix + (i + 1), varNo, tbl);
- if (getMaxLocals() < varNo)
- setMaxLocals(varNo);
+ if (getMaxLocals() < varNo)
+ setMaxLocals(varNo);
}
/**
* Makes the given variable name available.
*
- * @param type variable type
- * @param varName variable name
+ * @param type variable type
+ * @param varName variable name
*/
public int recordVariable(CtClass type, String varName, SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- if (varName == null)
- return -1;
- else {
- int varNo = getMaxLocals();
- int locals = varNo + recordVar(type, varName, varNo, tbl);
- setMaxLocals(locals);
- return varNo;
- }
+ if (varName == null)
+ return -1;
+ else {
+ int varNo = getMaxLocals();
+ int locals = varNo + recordVar(type, varName, varNo, tbl);
+ setMaxLocals(locals);
+ return varNo;
+ }
}
private int recordVar(CtClass cc, String varName, int varNo,
- SymbolTable tbl) throws CompileError
+ SymbolTable tbl) throws CompileError
{
- if (cc == CtClass.voidType) {
- exprType = CLASS;
- arrayDim = 0;
- className = jvmJavaLangObject;
- }
- else
- setType(cc);
+ if (cc == CtClass.voidType) {
+ exprType = CLASS;
+ arrayDim = 0;
+ className = jvmJavaLangObject;
+ }
+ else
+ setType(cc);
- Declarator decl
- = new Declarator(exprType, className, arrayDim,
- varNo, new Symbol(varName));
- tbl.append(varName, decl);
- return is2word(exprType, arrayDim) ? 2 : 1;
+ Declarator decl
+ = new Declarator(exprType, className, arrayDim,
+ varNo, new Symbol(varName));
+ tbl.append(varName, decl);
+ return is2word(exprType, arrayDim) ? 2 : 1;
}
/* compileParameterList() returns the stack size used
*
* This method correctly computes the max_stack value.
*
- * @param regno the index of the local variable in which
- * the first argument is received.
- * (0: static method, 1: regular method.)
+ * @param regno the index of the local variable in which
+ * the first argument is received.
+ * (0: static method, 1: regular method.)
*/
public static int compileParameterList(Bytecode code,
- CtClass[] params, int regno) {
- if (params == null) {
- code.addIconst(0); // iconst_0
- code.addAnewarray(javaLangObject); // anewarray Object
- return 1;
- }
- else {
- CtClass[] args = new CtClass[1];
- int n = params.length;
- code.addIconst(n); // iconst_<n>
- code.addAnewarray(javaLangObject); // anewarray Object
- for (int i = 0; i < n; ++i) {
- code.addOpcode(Bytecode.DUP); // dup
- code.addIconst(i); // iconst_<i>
- if (params[i].isPrimitive()) {
- CtPrimitiveType pt = (CtPrimitiveType)params[i];
- String wrapper = pt.getWrapperName();
- code.addNew(wrapper); // new <wrapper>
- code.addOpcode(Bytecode.DUP); // dup
- int s = code.addLoad(regno, pt); // ?load <regno>
- regno += s;
- args[0] = pt;
- code.addInvokespecial(wrapper, "<init>",
- Descriptor.ofMethod(CtClass.voidType, args));
- // invokespecial
- }
- else {
- code.addAload(regno); // aload <regno>
- ++regno;
- }
-
- code.addOpcode(Bytecode.AASTORE); // aastore
- }
-
- return 8;
- }
+ CtClass[] params, int regno) {
+ if (params == null) {
+ code.addIconst(0); // iconst_0
+ code.addAnewarray(javaLangObject); // anewarray Object
+ return 1;
+ }
+ else {
+ CtClass[] args = new CtClass[1];
+ int n = params.length;
+ code.addIconst(n); // iconst_<n>
+ code.addAnewarray(javaLangObject); // anewarray Object
+ for (int i = 0; i < n; ++i) {
+ code.addOpcode(Bytecode.DUP); // dup
+ code.addIconst(i); // iconst_<i>
+ if (params[i].isPrimitive()) {
+ CtPrimitiveType pt = (CtPrimitiveType)params[i];
+ String wrapper = pt.getWrapperName();
+ code.addNew(wrapper); // new <wrapper>
+ code.addOpcode(Bytecode.DUP); // dup
+ int s = code.addLoad(regno, pt); // ?load <regno>
+ regno += s;
+ args[0] = pt;
+ code.addInvokespecial(wrapper, "<init>",
+ Descriptor.ofMethod(CtClass.voidType, args));
+ // invokespecial
+ }
+ else {
+ code.addAload(regno); // aload <regno>
+ ++regno;
+ }
+
+ code.addOpcode(Bytecode.AASTORE); // aastore
+ }
+
+ return 8;
+ }
}
protected void compileUnwrapValue(CtClass type, Bytecode code)
- throws CompileError
+ throws CompileError
{
- if (type instanceof CtPrimitiveType) {
- CtPrimitiveType pt = (CtPrimitiveType)type;
- if (pt != CtClass.voidType) {
- String wrapper = pt.getWrapperName();
- code.addCheckcast(wrapper);
- code.addInvokevirtual(wrapper, pt.getGetMethodName(),
- pt.getGetMethodDescriptor());
- setType(type);
- }
- }
- else {
- code.addCheckcast(type);
- setType(type);
- }
+ if (type instanceof CtPrimitiveType) {
+ CtPrimitiveType pt = (CtPrimitiveType)type;
+ if (pt != CtClass.voidType) {
+ String wrapper = pt.getWrapperName();
+ code.addCheckcast(wrapper);
+ code.addInvokevirtual(wrapper, pt.getGetMethodName(),
+ pt.getGetMethodDescriptor());
+ setType(type);
+ }
+ }
+ else {
+ code.addCheckcast(type);
+ setType(type);
+ }
}
/* Sets exprType, arrayDim, and className;
* If type is void, then this method does nothing.
*/
public void setType(CtClass type) throws CompileError {
- setType(type, 0);
+ setType(type, 0);
}
private void setType(CtClass type, int dim) throws CompileError {
- if (type.isPrimitive()) {
- CtPrimitiveType pt = (CtPrimitiveType)type;
- exprType = descToType(pt.getDescriptor());
- arrayDim = dim;
- className = null;
- }
- else if (type.isArray())
- try {
- setType(type.getComponentType(), dim + 1);
- }
- catch (NotFoundException e) {
- throw new CompileError("undefined type: " + type.getName());
- }
- else {
- exprType = CLASS;
- arrayDim = dim;
- className = javaToJvmName(type.getName());
- }
+ if (type.isPrimitive()) {
+ CtPrimitiveType pt = (CtPrimitiveType)type;
+ exprType = descToType(pt.getDescriptor());
+ arrayDim = dim;
+ className = null;
+ }
+ else if (type.isArray())
+ try {
+ setType(type.getComponentType(), dim + 1);
+ }
+ catch (NotFoundException e) {
+ throw new CompileError("undefined type: " + type.getName());
+ }
+ else {
+ exprType = CLASS;
+ arrayDim = dim;
+ className = javaToJvmName(type.getName());
+ }
}
/* Performs implicit coercion from exprType to type.
*/
public void doNumCast(CtClass type) throws CompileError {
- if (arrayDim == 0 && !isRefType(exprType))
- if (type instanceof CtPrimitiveType) {
- CtPrimitiveType pt = (CtPrimitiveType)type;
- atNumCastExpr(exprType, descToType(pt.getDescriptor()));
- }
- else
- throw new CompileError("type mismatch");
+ if (arrayDim == 0 && !isRefType(exprType))
+ if (type instanceof CtPrimitiveType) {
+ CtPrimitiveType pt = (CtPrimitiveType)type;
+ atNumCastExpr(exprType, descToType(pt.getDescriptor()));
+ }
+ else
+ throw new CompileError("type mismatch");
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
final class KeywordTable extends java.util.HashMap {
public KeywordTable() { super(); }
public int lookup(String name) {
- Object found = get(name);
- if (found == null)
- return -1;
- else
- return ((Integer)found).intValue();
+ Object found = get(name);
+ if (found == null)
+ return -1;
+ else
+ return ((Integer)found).intValue();
}
public void append(String name, int t) {
- put(name, new Integer(t));
+ put(name, new Integer(t));
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
class Token {
* Constructs a lexical analyzer.
*/
public Lex(String s) {
- lastChar = -1;
- textBuffer = new StringBuffer();
- currentToken = new Token();
- lookAheadTokens = null;
-
- input = s;
- position = 0;
- maxlen = s.length();
- lineNumber = 0;
+ lastChar = -1;
+ textBuffer = new StringBuffer();
+ currentToken = new Token();
+ lookAheadTokens = null;
+
+ input = s;
+ position = 0;
+ maxlen = s.length();
+ lineNumber = 0;
}
public int get() {
- if (lookAheadTokens == null)
- return get(currentToken);
- else {
- Token t;
- currentToken = t = lookAheadTokens;
- lookAheadTokens = lookAheadTokens.next;
- return t.tokenId;
- }
+ if (lookAheadTokens == null)
+ return get(currentToken);
+ else {
+ Token t;
+ currentToken = t = lookAheadTokens;
+ lookAheadTokens = lookAheadTokens.next;
+ return t.tokenId;
+ }
}
/**
* Looks at the next token.
*/
public int lookAhead() {
- return lookAhead(0);
+ return lookAhead(0);
}
public int lookAhead(int i) {
- Token tk = lookAheadTokens;
- if (tk == null) {
- lookAheadTokens = tk = currentToken; // reuse an object!
- tk.next = null;
- get(tk);
- }
-
- for (; i-- > 0; tk = tk.next)
- if (tk.next == null) {
- Token tk2;
- tk.next = tk2 = new Token();
- get(tk2);
- }
-
- currentToken = tk;
- return tk.tokenId;
+ Token tk = lookAheadTokens;
+ if (tk == null) {
+ lookAheadTokens = tk = currentToken; // reuse an object!
+ tk.next = null;
+ get(tk);
+ }
+
+ for (; i-- > 0; tk = tk.next)
+ if (tk.next == null) {
+ Token tk2;
+ tk.next = tk2 = new Token();
+ get(tk2);
+ }
+
+ currentToken = tk;
+ return tk.tokenId;
}
public String getString() {
- return currentToken.textValue;
+ return currentToken.textValue;
}
public long getLong() {
- return currentToken.longValue;
+ return currentToken.longValue;
}
public double getDouble() {
- return currentToken.doubleValue;
+ return currentToken.doubleValue;
}
private int get(Token token) {
- int t;
- do {
- t = readLine(token);
- } while (t == '\n');
- token.tokenId = t;
- return t;
+ int t;
+ do {
+ t = readLine(token);
+ } while (t == '\n');
+ token.tokenId = t;
+ return t;
}
private int readLine(Token token) {
- int c = getNextNonWhiteChar();
- if(c < 0)
- return c;
- else if(c == '\n') {
- ++lineNumber;
- return '\n';
- }
- else if (c == '\'')
- return readCharConst(token);
- else if (c == '"')
- return readStringL(token);
- else if ('0' <= c && c <= '9')
- return readNumber(c, token);
- else if(c == '.'){
- c = getc();
- if ('0' <= c && c <= '9') {
- StringBuffer tbuf = textBuffer;
- tbuf.setLength(0);
- tbuf.append('.');
- return readDouble(tbuf, c, token);
- }
- else{
- ungetc(c);
- return readSeparator('.');
- }
- }
- else if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_'
- || c == '$')
- return readIdentifier(c, token);
- else
- return readSeparator(c);
+ int c = getNextNonWhiteChar();
+ if(c < 0)
+ return c;
+ else if(c == '\n') {
+ ++lineNumber;
+ return '\n';
+ }
+ else if (c == '\'')
+ return readCharConst(token);
+ else if (c == '"')
+ return readStringL(token);
+ else if ('0' <= c && c <= '9')
+ return readNumber(c, token);
+ else if(c == '.'){
+ c = getc();
+ if ('0' <= c && c <= '9') {
+ StringBuffer tbuf = textBuffer;
+ tbuf.setLength(0);
+ tbuf.append('.');
+ return readDouble(tbuf, c, token);
+ }
+ else{
+ ungetc(c);
+ return readSeparator('.');
+ }
+ }
+ else if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_'
+ || c == '$')
+ return readIdentifier(c, token);
+ else
+ return readSeparator(c);
}
private int getNextNonWhiteChar() {
- int c;
- do {
- c = getc();
- if (c == '/') {
- c = getc();
- if (c == '/')
- do {
- c = getc();
- } while (c != '\n' && c != '\r' && c != -1);
- else if (c == '*')
- while (true) {
- c = getc();
- if (c == -1)
- break;
- else if (c == '*')
- if ((c = getc()) == '/') {
- c = ' ';
- break;
- }
- else
- ungetc(c);
- }
- else {
- ungetc(c);
- c = '/';
- }
- }
- } while(isBlank(c));
- return c;
+ int c;
+ do {
+ c = getc();
+ if (c == '/') {
+ c = getc();
+ if (c == '/')
+ do {
+ c = getc();
+ } while (c != '\n' && c != '\r' && c != -1);
+ else if (c == '*')
+ while (true) {
+ c = getc();
+ if (c == -1)
+ break;
+ else if (c == '*')
+ if ((c = getc()) == '/') {
+ c = ' ';
+ break;
+ }
+ else
+ ungetc(c);
+ }
+ else {
+ ungetc(c);
+ c = '/';
+ }
+ }
+ } while(isBlank(c));
+ return c;
}
private int readCharConst(Token token) {
- int c;
- int value = 0;
- while ((c = getc()) != '\'')
- if (c == '\\')
- value = readEscapeChar();
- else if (c < 0x20) {
- if (c == '\n')
- ++lineNumber;
-
- return BadToken;
- }
- else
- value = c;
-
- token.longValue = value;
- return CharConstant;
+ int c;
+ int value = 0;
+ while ((c = getc()) != '\'')
+ if (c == '\\')
+ value = readEscapeChar();
+ else if (c < 0x20) {
+ if (c == '\n')
+ ++lineNumber;
+
+ return BadToken;
+ }
+ else
+ value = c;
+
+ token.longValue = value;
+ return CharConstant;
}
private int readEscapeChar() {
- int c = getc();
- if (c == 'n')
- c = '\n';
- else if (c == 't')
- c = '\t';
- else if (c == 'r')
- c = '\r';
- else if (c == 'f')
- c = '\f';
- else if (c == '\n')
- ++lineNumber;
-
- return c;
+ int c = getc();
+ if (c == 'n')
+ c = '\n';
+ else if (c == 't')
+ c = '\t';
+ else if (c == 'r')
+ c = '\r';
+ else if (c == 'f')
+ c = '\f';
+ else if (c == '\n')
+ ++lineNumber;
+
+ return c;
}
private int readStringL(Token token) {
- int c;
- StringBuffer tbuf = textBuffer;
- tbuf.setLength(0);
- for (;;) {
- while ((c = getc()) != '"') {
- if (c == '\\')
- c = readEscapeChar();
- else if (c == '\n' || c < 0) {
- ++lineNumber;
- return BadToken;
- }
-
- tbuf.append((char)c);
- }
-
- for (;;) {
- c = getc();
- if (c == '\n')
- ++lineNumber;
- else if (!isBlank(c))
- break;
- }
-
- if (c != '"') {
- ungetc(c);
- break;
- }
- }
-
- token.textValue = tbuf.toString();
- return StringL;
+ int c;
+ StringBuffer tbuf = textBuffer;
+ tbuf.setLength(0);
+ for (;;) {
+ while ((c = getc()) != '"') {
+ if (c == '\\')
+ c = readEscapeChar();
+ else if (c == '\n' || c < 0) {
+ ++lineNumber;
+ return BadToken;
+ }
+
+ tbuf.append((char)c);
+ }
+
+ for (;;) {
+ c = getc();
+ if (c == '\n')
+ ++lineNumber;
+ else if (!isBlank(c))
+ break;
+ }
+
+ if (c != '"') {
+ ungetc(c);
+ break;
+ }
+ }
+
+ token.textValue = tbuf.toString();
+ return StringL;
}
private int readNumber(int c, Token token) {
- long value = 0;
- int c2 = getc();
- if (c == '0')
- if (c2 == 'X' || c2 == 'x')
- for (;;) {
- c = getc();
- if ('0' <= c && c <= '9')
- value = value * 16 + (long)(c - '0');
- else if ('A' <= c && c <= 'F')
- value = value * 16 + (long)(c - 'A' + 10);
- else if ('a' <= c && c <= 'f')
- value = value * 16 + (long)(c - 'a' + 10);
- else {
- token.longValue = value;
- if (c == 'L' || c == 'l')
- return LongConstant;
- else {
- ungetc(c);
- return IntConstant;
- }
- }
- }
- else if ('0' <= c2 && c2 <= '7') {
- value = c2 - '0';
- for (;;) {
- c = getc();
- if ('0' <= c && c <= '7')
- value = value * 8 + (long)(c - '0');
- else {
- token.longValue = value;
- if (c == 'L' || c == 'l')
- return LongConstant;
- else {
- ungetc(c);
- return IntConstant;
- }
- }
- }
- }
-
- value = c - '0';
- while ('0' <= c2 && c2 <= '9') {
- value = value * 10 + c2 - '0';
- c2 = getc();
- }
-
- token.longValue = value;
- if (c2 == 'F' || c2 == 'f') {
- token.doubleValue = (double)value;
- return FloatConstant;
- }
- else if (c2 == 'E' || c2 == 'e' || c2 == '.') {
- StringBuffer tbuf = textBuffer;
- tbuf.setLength(0);
- tbuf.append(value);
- return readDouble(tbuf, c2, token);
- }
- else if (c2 == 'L' || c2 == 'l')
- return LongConstant;
- else {
- ungetc(c2);
- return IntConstant;
- }
+ long value = 0;
+ int c2 = getc();
+ if (c == '0')
+ if (c2 == 'X' || c2 == 'x')
+ for (;;) {
+ c = getc();
+ if ('0' <= c && c <= '9')
+ value = value * 16 + (long)(c - '0');
+ else if ('A' <= c && c <= 'F')
+ value = value * 16 + (long)(c - 'A' + 10);
+ else if ('a' <= c && c <= 'f')
+ value = value * 16 + (long)(c - 'a' + 10);
+ else {
+ token.longValue = value;
+ if (c == 'L' || c == 'l')
+ return LongConstant;
+ else {
+ ungetc(c);
+ return IntConstant;
+ }
+ }
+ }
+ else if ('0' <= c2 && c2 <= '7') {
+ value = c2 - '0';
+ for (;;) {
+ c = getc();
+ if ('0' <= c && c <= '7')
+ value = value * 8 + (long)(c - '0');
+ else {
+ token.longValue = value;
+ if (c == 'L' || c == 'l')
+ return LongConstant;
+ else {
+ ungetc(c);
+ return IntConstant;
+ }
+ }
+ }
+ }
+
+ value = c - '0';
+ while ('0' <= c2 && c2 <= '9') {
+ value = value * 10 + c2 - '0';
+ c2 = getc();
+ }
+
+ token.longValue = value;
+ if (c2 == 'F' || c2 == 'f') {
+ token.doubleValue = (double)value;
+ return FloatConstant;
+ }
+ else if (c2 == 'E' || c2 == 'e' || c2 == '.') {
+ StringBuffer tbuf = textBuffer;
+ tbuf.setLength(0);
+ tbuf.append(value);
+ return readDouble(tbuf, c2, token);
+ }
+ else if (c2 == 'L' || c2 == 'l')
+ return LongConstant;
+ else {
+ ungetc(c2);
+ return IntConstant;
+ }
}
private int readDouble(StringBuffer sbuf, int c, Token token) {
- if (c != 'E' && c != 'e') {
- sbuf.append((char)c);
- for (;;) {
- c = getc();
- if ('0' <= c && c <= '9')
- sbuf.append((char)c);
- else
- break;
- }
- }
-
- if (c == 'E' || c == 'e') {
- sbuf.append((char)c);
- c = getc();
- if (c == '+' || c == '-') {
- sbuf.append((char)c);
- c = getc();
- }
-
- while ('0' <= c && c <= '9') {
- sbuf.append((char)c);
- c = getc();
- }
- }
-
- try {
- token.doubleValue = Double.parseDouble(sbuf.toString());
- }
- catch (NumberFormatException e) {
- return BadToken;
- }
-
- if (c == 'F' || c == 'f')
- return FloatConstant;
- else {
- ungetc(c);
- return DoubleConstant;
- }
+ if (c != 'E' && c != 'e') {
+ sbuf.append((char)c);
+ for (;;) {
+ c = getc();
+ if ('0' <= c && c <= '9')
+ sbuf.append((char)c);
+ else
+ break;
+ }
+ }
+
+ if (c == 'E' || c == 'e') {
+ sbuf.append((char)c);
+ c = getc();
+ if (c == '+' || c == '-') {
+ sbuf.append((char)c);
+ c = getc();
+ }
+
+ while ('0' <= c && c <= '9') {
+ sbuf.append((char)c);
+ c = getc();
+ }
+ }
+
+ try {
+ token.doubleValue = Double.parseDouble(sbuf.toString());
+ }
+ catch (NumberFormatException e) {
+ return BadToken;
+ }
+
+ if (c == 'F' || c == 'f')
+ return FloatConstant;
+ else {
+ ungetc(c);
+ return DoubleConstant;
+ }
}
// !"#$%&'( )*+,-./0 12345678 9:;<=>?
private static final int[] equalOps
- = { NEQ, 0, 0, 0, MOD_E, AND_E, 0, 0,
- 0, MUL_E, PLUS_E, 0, MINUS_E, 0, DIV_E, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, LE, EQ, GE, 0 };
+ = { NEQ, 0, 0, 0, MOD_E, AND_E, 0, 0,
+ 0, MUL_E, PLUS_E, 0, MINUS_E, 0, DIV_E, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, LE, EQ, GE, 0 };
private int readSeparator(int c) {
- int c2, c3;
- if ('!' <= c && c <= '?') {
- int t = equalOps[c - '!'];
- if (t == 0)
- return c;
- else {
- c2 = getc();
- if (c == c2)
- switch (c) {
- case '=' :
- return EQ;
- case '+' :
- return PLUSPLUS;
- case '-' :
- return MINUSMINUS;
- case '&' :
- return ANDAND;
- case '<' :
- c3 = getc();
- if (c3 == '=')
- return LSHIFT_E;
- else {
- ungetc(c3);
- return LSHIFT;
- }
- case '>' :
- c3 = getc();
- if (c3 == '=')
- return RSHIFT_E;
- else if (c3 == '>') {
- c3 = getc();
- if (c3 == '=')
- return ARSHIFT_E;
- else {
- ungetc(c3);
- return ARSHIFT;
- }
- }
- else {
- ungetc(c3);
- return RSHIFT;
- }
- default :
- break;
- }
- else if (c2 == '=')
- return t;
- }
- }
- else if (c == '^') {
- c2 = getc();
- if (c2 == '=')
- return EXOR_E;
- }
- else if (c == '|') {
- c2 = getc();
- if (c2 == '=')
- return OR_E;
- else if (c2 == '|')
- return OROR;
- }
- else
- return c;
-
- ungetc(c2);
- return c;
+ int c2, c3;
+ if ('!' <= c && c <= '?') {
+ int t = equalOps[c - '!'];
+ if (t == 0)
+ return c;
+ else {
+ c2 = getc();
+ if (c == c2)
+ switch (c) {
+ case '=' :
+ return EQ;
+ case '+' :
+ return PLUSPLUS;
+ case '-' :
+ return MINUSMINUS;
+ case '&' :
+ return ANDAND;
+ case '<' :
+ c3 = getc();
+ if (c3 == '=')
+ return LSHIFT_E;
+ else {
+ ungetc(c3);
+ return LSHIFT;
+ }
+ case '>' :
+ c3 = getc();
+ if (c3 == '=')
+ return RSHIFT_E;
+ else if (c3 == '>') {
+ c3 = getc();
+ if (c3 == '=')
+ return ARSHIFT_E;
+ else {
+ ungetc(c3);
+ return ARSHIFT;
+ }
+ }
+ else {
+ ungetc(c3);
+ return RSHIFT;
+ }
+ default :
+ break;
+ }
+ else if (c2 == '=')
+ return t;
+ }
+ }
+ else if (c == '^') {
+ c2 = getc();
+ if (c2 == '=')
+ return EXOR_E;
+ }
+ else if (c == '|') {
+ c2 = getc();
+ if (c2 == '=')
+ return OR_E;
+ else if (c2 == '|')
+ return OROR;
+ }
+ else
+ return c;
+
+ ungetc(c2);
+ return c;
}
private int readIdentifier(int c, Token token) {
- StringBuffer tbuf = textBuffer;
- tbuf.setLength(0);
-
- do {
- tbuf.append((char)c);
- c = getc();
- } while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_'
- || c == '$' || '0' <= c && c <= '9');
-
- ungetc(c);
-
- String name = tbuf.toString();
- int t = ktable.lookup(name);
- if (t >= 0)
- return t;
- else {
- /* tbuf.toString() is executed quickly since it does not
- * need memory copy. Using a hand-written extensible
- * byte-array class instead of StringBuffer is not a good idea
- * for execution speed. Converting a byte array to a String
- * object is very slow. Using an extensible char array
- * might be OK.
- */
- token.textValue = name;
- return Identifier;
- }
+ StringBuffer tbuf = textBuffer;
+ tbuf.setLength(0);
+
+ do {
+ tbuf.append((char)c);
+ c = getc();
+ } while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_'
+ || c == '$' || '0' <= c && c <= '9');
+
+ ungetc(c);
+
+ String name = tbuf.toString();
+ int t = ktable.lookup(name);
+ if (t >= 0)
+ return t;
+ else {
+ /* tbuf.toString() is executed quickly since it does not
+ * need memory copy. Using a hand-written extensible
+ * byte-array class instead of StringBuffer is not a good idea
+ * for execution speed. Converting a byte array to a String
+ * object is very slow. Using an extensible char array
+ * might be OK.
+ */
+ token.textValue = name;
+ return Identifier;
+ }
}
private static final KeywordTable ktable = new KeywordTable();
static {
- ktable.append("abstract", ABSTRACT);
- ktable.append("boolean", BOOLEAN);
- ktable.append("break", BREAK);
- ktable.append("byte", BYTE);
- ktable.append("case", CASE);
- ktable.append("catch", CATCH);
- ktable.append("char", CHAR);
- ktable.append("class", CLASS);
- ktable.append("const", CONST);
- ktable.append("continue", CONTINUE);
- ktable.append("default", DEFAULT);
- ktable.append("do", DO);
- ktable.append("double", DOUBLE);
- ktable.append("else", ELSE);
- ktable.append("extends", EXTENDS);
- ktable.append("false", FALSE);
- ktable.append("final", FINAL);
- ktable.append("finally", FINALLY);
- ktable.append("float", FLOAT);
- ktable.append("for", FOR);
- ktable.append("goto", GOTO);
- ktable.append("if", IF);
- ktable.append("implements", IMPLEMENTS);
- ktable.append("import", IMPORT);
- ktable.append("instanceof", INSTANCEOF);
- ktable.append("int", INT);
- ktable.append("interface", INTERFACE);
- ktable.append("long", LONG);
- ktable.append("native", NATIVE);
- ktable.append("new", NEW);
- ktable.append("null", NULL);
- ktable.append("package", PACKAGE);
- ktable.append("private", PRIVATE);
- ktable.append("protected", PROTECTED);
- ktable.append("public", PUBLIC);
- ktable.append("return", RETURN);
- ktable.append("short", SHORT);
- ktable.append("static", STATIC);
- ktable.append("strict", STRICT);
- ktable.append("super", SUPER);
- ktable.append("switch", SWITCH);
- ktable.append("synchronized", SYNCHRONIZED);
- ktable.append("this", THIS);
- ktable.append("throw", THROW);
- ktable.append("throws", THROWS);
- ktable.append("transient", TRANSIENT);
- ktable.append("true", TRUE);
- ktable.append("try", TRY);
- ktable.append("void", VOID);
- ktable.append("volatile", VOLATILE);
- ktable.append("while", WHILE);
+ ktable.append("abstract", ABSTRACT);
+ ktable.append("boolean", BOOLEAN);
+ ktable.append("break", BREAK);
+ ktable.append("byte", BYTE);
+ ktable.append("case", CASE);
+ ktable.append("catch", CATCH);
+ ktable.append("char", CHAR);
+ ktable.append("class", CLASS);
+ ktable.append("const", CONST);
+ ktable.append("continue", CONTINUE);
+ ktable.append("default", DEFAULT);
+ ktable.append("do", DO);
+ ktable.append("double", DOUBLE);
+ ktable.append("else", ELSE);
+ ktable.append("extends", EXTENDS);
+ ktable.append("false", FALSE);
+ ktable.append("final", FINAL);
+ ktable.append("finally", FINALLY);
+ ktable.append("float", FLOAT);
+ ktable.append("for", FOR);
+ ktable.append("goto", GOTO);
+ ktable.append("if", IF);
+ ktable.append("implements", IMPLEMENTS);
+ ktable.append("import", IMPORT);
+ ktable.append("instanceof", INSTANCEOF);
+ ktable.append("int", INT);
+ ktable.append("interface", INTERFACE);
+ ktable.append("long", LONG);
+ ktable.append("native", NATIVE);
+ ktable.append("new", NEW);
+ ktable.append("null", NULL);
+ ktable.append("package", PACKAGE);
+ ktable.append("private", PRIVATE);
+ ktable.append("protected", PROTECTED);
+ ktable.append("public", PUBLIC);
+ ktable.append("return", RETURN);
+ ktable.append("short", SHORT);
+ ktable.append("static", STATIC);
+ ktable.append("strict", STRICT);
+ ktable.append("super", SUPER);
+ ktable.append("switch", SWITCH);
+ ktable.append("synchronized", SYNCHRONIZED);
+ ktable.append("this", THIS);
+ ktable.append("throw", THROW);
+ ktable.append("throws", THROWS);
+ ktable.append("transient", TRANSIENT);
+ ktable.append("true", TRUE);
+ ktable.append("try", TRY);
+ ktable.append("void", VOID);
+ ktable.append("volatile", VOLATILE);
+ ktable.append("while", WHILE);
}
private static boolean isBlank(int c) {
- return c == ' ' || c == '\t' || c == '\f' || c == '\r'
- || c == '\n';
+ return c == ' ' || c == '\t' || c == '\f' || c == '\r'
+ || c == '\n';
}
private static boolean isDigit(int c) {
- return '0' <= c && c <= '9';
+ return '0' <= c && c <= '9';
}
private void ungetc(int c) {
- lastChar = c;
+ lastChar = c;
}
private int getc() {
- if (lastChar < 0)
- if (position < maxlen)
- return input.charAt(position++);
- else
- return -1;
- else {
- int c = lastChar;
- lastChar = -1;
- return c;
- }
+ if (lastChar < 0)
+ if (position < maxlen)
+ return input.charAt(position++);
+ else
+ return -1;
+ else {
+ int c = lastChar;
+ lastChar = -1;
+ return c;
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import java.util.List;
protected boolean resultStatic;
public MemberCodeGen(Bytecode b, CtClass cc, ClassPool cp) {
- super(b);
- classPool = cp;
- thisClass = cc;
- thisMethod = null;
+ super(b);
+ classPool = cp;
+ thisClass = cc;
+ thisMethod = null;
}
/**
* Records the currently compiled method.
*/
public void setThisMethod(CtMethod m) {
- thisMethod = m.getMethodInfo2();
+ thisMethod = m.getMethodInfo2();
}
public CtClass getThisClass() { return thisClass; }
* Returns the JVM-internal representation of this class name.
*/
protected String getThisName() {
- return javaToJvmName(thisClass.getName());
+ return javaToJvmName(thisClass.getName());
}
/**
* Returns the JVM-internal representation of this super class name.
*/
protected String getSuperName() throws CompileError {
- return javaToJvmName(getSuperclass(thisClass).getName());
+ return javaToJvmName(getSuperclass(thisClass).getName());
}
protected void insertDefaultSuperCall() throws CompileError {
- bytecode.addAload(0);
- bytecode.addInvokespecial(getSuperclass(thisClass), "<init>", "()V");
+ bytecode.addAload(0);
+ bytecode.addInvokespecial(getSuperclass(thisClass), "<init>", "()V");
}
protected void atTryStmnt(Stmnt st) throws CompileError {
- Stmnt body = (Stmnt)st.getLeft();
- if (body == null)
- return;
-
- int start = bytecode.currentPc();
- body.accept(this);
- int end = bytecode.currentPc();
-
- bytecode.addOpcode(Opcode.GOTO);
- int pc = bytecode.currentPc();
- bytecode.addIndex(0); // correct later
-
- int var = getMaxLocals();
- incMaxLocals(1);
- ASTList catchList = (ASTList)st.getRight().getLeft();
- while (catchList != null) {
- Pair p = (Pair)catchList.head();
- catchList = catchList.tail();
- Declarator decl = (Declarator)p.getLeft();
- Stmnt block = (Stmnt)p.getRight();
-
- decl.setLocalVar(var);
-
- CtClass type = lookupClass(decl.getClassName());
- decl.setClassName(javaToJvmName(type.getName()));
- bytecode.addExceptionHandler(start, end, bytecode.currentPc(),
- type);
- if (block != null) {
- bytecode.addAstore(var);
- block.accept(this);
- }
-
- bytecode.addOpcode(Opcode.GOTO);
- bytecode.addIndex(pc - bytecode.currentPc());
- }
-
- Stmnt finallyBlock = (Stmnt)st.getRight().getRight().getLeft();
- if (finallyBlock != null)
- throw new CompileError(
- "sorry, finally has not been supported yet");
-
- bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
+ Stmnt body = (Stmnt)st.getLeft();
+ if (body == null)
+ return;
+
+ int start = bytecode.currentPc();
+ body.accept(this);
+ int end = bytecode.currentPc();
+
+ bytecode.addOpcode(Opcode.GOTO);
+ int pc = bytecode.currentPc();
+ bytecode.addIndex(0); // correct later
+
+ int var = getMaxLocals();
+ incMaxLocals(1);
+ ASTList catchList = (ASTList)st.getRight().getLeft();
+ while (catchList != null) {
+ Pair p = (Pair)catchList.head();
+ catchList = catchList.tail();
+ Declarator decl = (Declarator)p.getLeft();
+ Stmnt block = (Stmnt)p.getRight();
+
+ decl.setLocalVar(var);
+
+ CtClass type = lookupClass(decl.getClassName());
+ decl.setClassName(javaToJvmName(type.getName()));
+ bytecode.addExceptionHandler(start, end, bytecode.currentPc(),
+ type);
+ if (block != null) {
+ bytecode.addAstore(var);
+ block.accept(this);
+ }
+
+ bytecode.addOpcode(Opcode.GOTO);
+ bytecode.addIndex(pc - bytecode.currentPc());
+ }
+
+ Stmnt finallyBlock = (Stmnt)st.getRight().getRight().getLeft();
+ if (finallyBlock != null)
+ throw new CompileError(
+ "sorry, finally has not been supported yet");
+
+ bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
}
public void atNewExpr(NewExpr expr) throws CompileError {
- if (expr.isArray())
- atNewArrayExpr(expr);
- else {
- CtClass clazz = lookupClass(expr.getClassName());
- String cname = clazz.getName();
- ASTList args = expr.getArguments();
- bytecode.addNew(cname);
- bytecode.addOpcode(DUP);
-
- atMethodCall2(clazz, MethodInfo.nameInit, args, false, true);
-
- exprType = CLASS;
- arrayDim = 0;
- className = javaToJvmName(cname);
- }
+ if (expr.isArray())
+ atNewArrayExpr(expr);
+ else {
+ CtClass clazz = lookupClass(expr.getClassName());
+ String cname = clazz.getName();
+ ASTList args = expr.getArguments();
+ bytecode.addNew(cname);
+ bytecode.addOpcode(DUP);
+
+ atMethodCall2(clazz, MethodInfo.nameInit, args, false, true);
+
+ exprType = CLASS;
+ arrayDim = 0;
+ className = javaToJvmName(cname);
+ }
}
public void atNewArrayExpr(NewExpr expr) throws CompileError {
- if (expr.getInitializer() != null)
- throw new CompileError("array initializer is not supported");
-
- int type = expr.getArrayType();
- ASTList size = expr.getArraySize();
- ASTList classname = expr.getClassName();
- if (size.length() > 1) {
- atMultiNewArray(type, classname, size);
- return;
- }
-
- size.head().accept(this);
- exprType = type;
- arrayDim = 1;
- if (type == CLASS) {
- className = resolveClassName(classname);
- bytecode.addAnewarray(jvmToJavaName(className));
- }
- else {
- className = null;
- int atype = 0;
- switch (type) {
- case BOOLEAN :
- atype = T_BOOLEAN;
- break;
- case CHAR :
- atype = T_CHAR;
- break;
- case FLOAT :
- atype = T_FLOAT;
- break;
- case DOUBLE :
- atype = T_DOUBLE;
- break;
- case BYTE :
- atype = T_BYTE;
- break;
- case SHORT :
- atype = T_SHORT;
- break;
- case INT :
- atype = T_INT;
- break;
- case LONG :
- atype = T_LONG;
- break;
- default :
- badNewExpr();
- break;
- }
-
- bytecode.addOpcode(NEWARRAY);
- bytecode.add(atype);
- }
+ if (expr.getInitializer() != null)
+ throw new CompileError("array initializer is not supported");
+
+ int type = expr.getArrayType();
+ ASTList size = expr.getArraySize();
+ ASTList classname = expr.getClassName();
+ if (size.length() > 1) {
+ atMultiNewArray(type, classname, size);
+ return;
+ }
+
+ size.head().accept(this);
+ exprType = type;
+ arrayDim = 1;
+ if (type == CLASS) {
+ className = resolveClassName(classname);
+ bytecode.addAnewarray(jvmToJavaName(className));
+ }
+ else {
+ className = null;
+ int atype = 0;
+ switch (type) {
+ case BOOLEAN :
+ atype = T_BOOLEAN;
+ break;
+ case CHAR :
+ atype = T_CHAR;
+ break;
+ case FLOAT :
+ atype = T_FLOAT;
+ break;
+ case DOUBLE :
+ atype = T_DOUBLE;
+ break;
+ case BYTE :
+ atype = T_BYTE;
+ break;
+ case SHORT :
+ atype = T_SHORT;
+ break;
+ case INT :
+ atype = T_INT;
+ break;
+ case LONG :
+ atype = T_LONG;
+ break;
+ default :
+ badNewExpr();
+ break;
+ }
+
+ bytecode.addOpcode(NEWARRAY);
+ bytecode.add(atype);
+ }
}
private static void badNewExpr() throws CompileError {
- throw new CompileError("bad new expression");
+ throw new CompileError("bad new expression");
}
protected void atMultiNewArray(int type, ASTList classname, ASTList size)
- throws CompileError
+ throws CompileError
{
- int count, dim;
- dim = size.length();
- for (count = 0; size != null; size = size.tail()) {
- ASTree s = size.head();
- if (s == null)
- break; // int[][][] a = new int[3][4][];
-
- ++count;
- s.accept(this);
- if (exprType != INT)
- throw new CompileError("bad type for array size");
- }
-
- String desc;
- exprType = type;
- arrayDim = dim;
- if (type == CLASS) {
- className = resolveClassName(classname);
- desc = toJvmArrayName(className, dim);
- }
- else
- desc = toJvmTypeName(type, dim);
-
- bytecode.addMultiNewarray(desc, count);
+ int count, dim;
+ dim = size.length();
+ for (count = 0; size != null; size = size.tail()) {
+ ASTree s = size.head();
+ if (s == null)
+ break; // int[][][] a = new int[3][4][];
+
+ ++count;
+ s.accept(this);
+ if (exprType != INT)
+ throw new CompileError("bad type for array size");
+ }
+
+ String desc;
+ exprType = type;
+ arrayDim = dim;
+ if (type == CLASS) {
+ className = resolveClassName(classname);
+ desc = toJvmArrayName(className, dim);
+ }
+ else
+ desc = toJvmTypeName(type, dim);
+
+ bytecode.addMultiNewarray(desc, count);
}
protected void atMethodCall(Expr expr) throws CompileError {
- String mname = null;
- CtClass targetClass = null;
- ASTree method = expr.oprand1();
- ASTList args = (ASTList)expr.oprand2();
- boolean isStatic = false;
- boolean isSpecial = false;
-
- if (method instanceof Member) {
- mname = ((Member)method).get();
- targetClass = thisClass;
- bytecode.addAload(0); // this
- }
- else if (method instanceof Keyword) { // constructor
- isSpecial = true;
- mname = MethodInfo.nameInit; // <init>
- targetClass = thisClass;
- bytecode.addAload(0); // this
- if (((Keyword)method).get() == SUPER)
- targetClass = getSuperclass(targetClass);
- }
- else if (method instanceof Expr) {
- Expr e = (Expr)method;
- mname = ((Symbol)e.oprand2()).get();
- int op = e.getOperator();
- if (op == MEMBER) { // static method
- targetClass = lookupClass((ASTList)e.oprand1());
- isStatic = true;
- }
- else if (op == '.') {
- ASTree target = e.oprand1();
- if (target instanceof Keyword)
- if (((Keyword)target).get() == SUPER)
- isSpecial = true;
-
- try {
- target.accept(this);
- }
- catch (NoFieldException nfe) {
- if (nfe.getExpr() != target)
- throw nfe;
-
- // it should be a static method.
- exprType = CLASS;
- arrayDim = 0;
- className = nfe.getField(); // JVM-internal
- isStatic = true;
- }
-
- if (arrayDim > 0)
- targetClass = lookupClass2(javaLangObject);
- else if (exprType == CLASS /* && arrayDim == 0 */)
- targetClass = lookupClass(className);
- else
- badMethod();
- }
- else
- badMethod();
- }
- else
- fatal();
-
- atMethodCall2(targetClass, mname, args, isStatic, isSpecial);
+ String mname = null;
+ CtClass targetClass = null;
+ ASTree method = expr.oprand1();
+ ASTList args = (ASTList)expr.oprand2();
+ boolean isStatic = false;
+ boolean isSpecial = false;
+
+ if (method instanceof Member) {
+ mname = ((Member)method).get();
+ targetClass = thisClass;
+ bytecode.addAload(0); // this
+ }
+ else if (method instanceof Keyword) { // constructor
+ isSpecial = true;
+ mname = MethodInfo.nameInit; // <init>
+ targetClass = thisClass;
+ bytecode.addAload(0); // this
+ if (((Keyword)method).get() == SUPER)
+ targetClass = getSuperclass(targetClass);
+ }
+ else if (method instanceof Expr) {
+ Expr e = (Expr)method;
+ mname = ((Symbol)e.oprand2()).get();
+ int op = e.getOperator();
+ if (op == MEMBER) { // static method
+ targetClass = lookupClass((ASTList)e.oprand1());
+ isStatic = true;
+ }
+ else if (op == '.') {
+ ASTree target = e.oprand1();
+ if (target instanceof Keyword)
+ if (((Keyword)target).get() == SUPER)
+ isSpecial = true;
+
+ try {
+ target.accept(this);
+ }
+ catch (NoFieldException nfe) {
+ if (nfe.getExpr() != target)
+ throw nfe;
+
+ // it should be a static method.
+ exprType = CLASS;
+ arrayDim = 0;
+ className = nfe.getField(); // JVM-internal
+ isStatic = true;
+ }
+
+ if (arrayDim > 0)
+ targetClass = lookupClass2(javaLangObject);
+ else if (exprType == CLASS /* && arrayDim == 0 */)
+ targetClass = lookupClass(className);
+ else
+ badMethod();
+ }
+ else
+ badMethod();
+ }
+ else
+ fatal();
+
+ atMethodCall2(targetClass, mname, args, isStatic, isSpecial);
}
private static void badMethod() throws CompileError {
- throw new CompileError("bad method");
+ throw new CompileError("bad method");
}
private static CtClass getSuperclass(CtClass c) throws CompileError {
- try {
- return c.getSuperclass();
- }
- catch (NotFoundException e) {
- throw new CompileError("cannot find the super class of "
- + c.getName());
- }
+ try {
+ return c.getSuperclass();
+ }
+ catch (NotFoundException e) {
+ throw new CompileError("cannot find the super class of "
+ + c.getName());
+ }
}
public void atMethodCall2(CtClass targetClass, String mname,
- ASTList args, boolean isStatic, boolean isSpecial)
- throws CompileError
+ ASTList args, boolean isStatic, boolean isSpecial)
+ throws CompileError
{
- int nargs = atMethodArgsLength(args);
- int[] types = new int[nargs];
- int[] dims = new int[nargs];
- String[] cnames = new String[nargs];
-
- int stack = bytecode.getStackDepth();
-
- atMethodArgs(args, types, dims, cnames);
-
- // used by invokeinterface
- int count = bytecode.getStackDepth() - stack + 1;
-
- Object[] found = lookupMethod(targetClass, thisMethod, mname,
- types, dims, cnames, false);
- if (found == null) {
- String msg;
- if (mname.equals(MethodInfo.nameInit))
- msg = "constructor not found";
- else
- msg = "Method " + mname + " not found in "
- + targetClass.getName();
-
- throw new CompileError(msg);
- }
-
- CtClass declClass = (CtClass)found[0];
- MethodInfo minfo = (MethodInfo)found[1];
- String desc = minfo.getDescriptor();
- int acc = minfo.getAccessFlags();
-
- if (mname.equals(MethodInfo.nameInit)) {
- isSpecial = true;
- if (declClass != targetClass)
- throw new CompileError("no such a constructor");
- }
- else if ((acc & AccessFlag.PRIVATE) != 0) {
- isSpecial = true;
- if (declClass != targetClass)
- throw new CompileError("Method " + mname + "is private");
- }
-
- boolean popTarget = false;
- if ((acc & AccessFlag.STATIC) != 0) {
- if (!isStatic) {
- /* this method is static but the target object is
- on stack. It must be popped out.
- */
- isStatic = true;
- popTarget = true;
- }
-
- bytecode.addInvokestatic(declClass, mname, desc);
- }
- else if (isSpecial)
- bytecode.addInvokespecial(declClass, mname, desc);
- else if (declClass.isInterface())
- bytecode.addInvokeinterface(declClass, mname, desc, count);
- else
- bytecode.addInvokevirtual(declClass, mname, desc);
-
- setReturnType(desc, isStatic, popTarget);
+ int nargs = atMethodArgsLength(args);
+ int[] types = new int[nargs];
+ int[] dims = new int[nargs];
+ String[] cnames = new String[nargs];
+
+ int stack = bytecode.getStackDepth();
+
+ atMethodArgs(args, types, dims, cnames);
+
+ // used by invokeinterface
+ int count = bytecode.getStackDepth() - stack + 1;
+
+ Object[] found = lookupMethod(targetClass, thisMethod, mname,
+ types, dims, cnames, false);
+ if (found == null) {
+ String msg;
+ if (mname.equals(MethodInfo.nameInit))
+ msg = "constructor not found";
+ else
+ msg = "Method " + mname + " not found in "
+ + targetClass.getName();
+
+ throw new CompileError(msg);
+ }
+
+ CtClass declClass = (CtClass)found[0];
+ MethodInfo minfo = (MethodInfo)found[1];
+ String desc = minfo.getDescriptor();
+ int acc = minfo.getAccessFlags();
+
+ if (mname.equals(MethodInfo.nameInit)) {
+ isSpecial = true;
+ if (declClass != targetClass)
+ throw new CompileError("no such a constructor");
+ }
+ else if ((acc & AccessFlag.PRIVATE) != 0) {
+ isSpecial = true;
+ if (declClass != targetClass)
+ throw new CompileError("Method " + mname + "is private");
+ }
+
+ boolean popTarget = false;
+ if ((acc & AccessFlag.STATIC) != 0) {
+ if (!isStatic) {
+ /* this method is static but the target object is
+ on stack. It must be popped out.
+ */
+ isStatic = true;
+ popTarget = true;
+ }
+
+ bytecode.addInvokestatic(declClass, mname, desc);
+ }
+ else if (isSpecial)
+ bytecode.addInvokespecial(declClass, mname, desc);
+ else if (declClass.isInterface())
+ bytecode.addInvokeinterface(declClass, mname, desc, count);
+ else
+ bytecode.addInvokevirtual(declClass, mname, desc);
+
+ setReturnType(desc, isStatic, popTarget);
}
public int atMethodArgsLength(ASTList args) {
- return ASTList.length(args);
+ return ASTList.length(args);
}
public void atMethodArgs(ASTList args, int[] types, int[] dims,
- String[] cnames) throws CompileError {
- int i = 0;
- while (args != null) {
- ASTree a = args.head();
- a.accept(this);
- types[i] = exprType;
- dims[i] = arrayDim;
- cnames[i] = className;
- ++i;
- args = args.tail();
- }
+ String[] cnames) throws CompileError {
+ int i = 0;
+ while (args != null) {
+ ASTree a = args.head();
+ a.accept(this);
+ types[i] = exprType;
+ dims[i] = arrayDim;
+ cnames[i] = className;
+ ++i;
+ args = args.tail();
+ }
}
private void setReturnType(String desc, boolean isStatic,
- boolean popTarget)
- throws CompileError
+ boolean popTarget)
+ throws CompileError
{
- int i = desc.indexOf(')');
- if (i < 0)
- badMethod();
-
- char c = desc.charAt(++i);
- int dim = 0;
- while (c == '[') {
- ++dim;
- c = desc.charAt(++i);
- }
-
- arrayDim = dim;
- if (c == 'L') {
- int j = desc.indexOf(';', i + 1);
- if (j < 0)
- badMethod();
-
- exprType = CLASS;
- className = desc.substring(i + 1, j);
- }
- else {
- exprType = descToType(c);
- className = null;
- }
-
- int etype = exprType;
- if (isStatic) {
- if (popTarget) {
- if (is2word(etype, dim)) {
- bytecode.addOpcode(DUP2_X1);
- bytecode.addOpcode(POP2);
- bytecode.addOpcode(POP);
- }
- else if (etype == VOID)
- bytecode.addOpcode(POP);
- else {
- bytecode.addOpcode(SWAP);
- bytecode.addOpcode(POP);
- }
- }
- }
+ int i = desc.indexOf(')');
+ if (i < 0)
+ badMethod();
+
+ char c = desc.charAt(++i);
+ int dim = 0;
+ while (c == '[') {
+ ++dim;
+ c = desc.charAt(++i);
+ }
+
+ arrayDim = dim;
+ if (c == 'L') {
+ int j = desc.indexOf(';', i + 1);
+ if (j < 0)
+ badMethod();
+
+ exprType = CLASS;
+ className = desc.substring(i + 1, j);
+ }
+ else {
+ exprType = descToType(c);
+ className = null;
+ }
+
+ int etype = exprType;
+ if (isStatic) {
+ if (popTarget) {
+ if (is2word(etype, dim)) {
+ bytecode.addOpcode(DUP2_X1);
+ bytecode.addOpcode(POP2);
+ bytecode.addOpcode(POP);
+ }
+ else if (etype == VOID)
+ bytecode.addOpcode(POP);
+ else {
+ bytecode.addOpcode(SWAP);
+ bytecode.addOpcode(POP);
+ }
+ }
+ }
}
private Object[] lookupMethod(CtClass clazz, MethodInfo current,
- String methodName,
- int[] argTypes, int[] argDims,
- String[] argClassNames, boolean onlyExact)
- throws CompileError
+ String methodName,
+ int[] argTypes, int[] argDims,
+ String[] argClassNames, boolean onlyExact)
+ throws CompileError
{
- Object[] maybe = null;
-
- if (current != null)
- if (current.getName().equals(methodName)) {
- int res = compareSignature(current.getDescriptor(),
- argTypes, argDims, argClassNames);
- Object[] r = new Object[] { clazz, current };
- if (res == YES)
- return r;
- else if (res == MAYBE && maybe == null)
- maybe = r;
- }
-
- List list = clazz.getClassFile2().getMethods();
- int n = list.size();
- for (int i = 0; i < n; ++i) {
- MethodInfo minfo = (MethodInfo)list.get(i);
- if (minfo.getName().equals(methodName)) {
- int res = compareSignature(minfo.getDescriptor(),
- argTypes, argDims, argClassNames);
- Object[] r = new Object[] { clazz, minfo };
- if (res == YES)
- return r;
- else if (res == MAYBE && maybe == null)
- maybe = r;
- }
- }
-
- try {
- CtClass pclazz = clazz.getSuperclass();
- if (pclazz != null) {
- Object[] r = lookupMethod(pclazz, null, methodName, argTypes,
- argDims, argClassNames,
- (onlyExact || maybe != null));
- if (r != null)
- return r;
- }
- }
- catch (NotFoundException e) {}
-
- /* -- not necessary to search implemented interfaces.
- try {
- CtClass[] ifs = clazz.getInterfaces();
- int size = ifs.length;
- for (int i = 0; i < size; ++i) {
- Object[] r = lookupMethod(ifs[i], methodName, argTypes,
- argDims, argClassNames);
- if (r != null)
- return r;
- }
- }
- catch (NotFoundException e) {}
- */
-
- if (onlyExact)
- return null;
- else
- return maybe;
+ Object[] maybe = null;
+
+ if (current != null)
+ if (current.getName().equals(methodName)) {
+ int res = compareSignature(current.getDescriptor(),
+ argTypes, argDims, argClassNames);
+ Object[] r = new Object[] { clazz, current };
+ if (res == YES)
+ return r;
+ else if (res == MAYBE && maybe == null)
+ maybe = r;
+ }
+
+ List list = clazz.getClassFile2().getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ if (minfo.getName().equals(methodName)) {
+ int res = compareSignature(minfo.getDescriptor(),
+ argTypes, argDims, argClassNames);
+ Object[] r = new Object[] { clazz, minfo };
+ if (res == YES)
+ return r;
+ else if (res == MAYBE && maybe == null)
+ maybe = r;
+ }
+ }
+
+ try {
+ CtClass pclazz = clazz.getSuperclass();
+ if (pclazz != null) {
+ Object[] r = lookupMethod(pclazz, null, methodName, argTypes,
+ argDims, argClassNames,
+ (onlyExact || maybe != null));
+ if (r != null)
+ return r;
+ }
+ }
+ catch (NotFoundException e) {}
+
+ /* -- not necessary to search implemented interfaces.
+ try {
+ CtClass[] ifs = clazz.getInterfaces();
+ int size = ifs.length;
+ for (int i = 0; i < size; ++i) {
+ Object[] r = lookupMethod(ifs[i], methodName, argTypes,
+ argDims, argClassNames);
+ if (r != null)
+ return r;
+ }
+ }
+ catch (NotFoundException e) {}
+ */
+
+ if (onlyExact)
+ return null;
+ else
+ return maybe;
}
private static final int YES = 2;
* algorithm.
*/
private int compareSignature(String desc, int[] argTypes,
- int[] argDims, String[] argClassNames)
- throws CompileError
+ int[] argDims, String[] argClassNames)
+ throws CompileError
{
- int result = YES;
- int i = 1;
- int nArgs = argTypes.length;
- if (nArgs != Descriptor.numOfParameters(desc))
- return NO;
-
- int len = desc.length();
- for (int n = 0; i < len; ++n) {
- char c = desc.charAt(i++);
- if (c == ')')
- return (n == nArgs ? result : NO);
- else if (n >= nArgs)
- return NO;
-
- int dim = 0;
- while (c == '[') {
- ++dim;
- c = desc.charAt(i++);
- }
-
- if (argTypes[n] == NULL) {
- if (dim == 0 && c != 'L')
- return NO;
- }
- else if (argDims[n] != dim) {
- if (!(dim == 0 && c == 'L'
- && desc.startsWith("java/lang/Object;", i)))
- return NO;
-
- // if the thread reaches here, c must be 'L'.
- i = desc.indexOf(';', i) + 1;
- result = MAYBE;
- if (i <= 0)
- return NO; // invalid descriptor?
- }
- else if (c == 'L') { // not compare
- int j = desc.indexOf(';', i);
- if (j < 0 || argTypes[n] != CLASS)
- return NO;
-
- String cname = desc.substring(i, j);
- if (!cname.equals(argClassNames[n])) {
- CtClass clazz = lookupClass(argClassNames[n]);
- try {
- if (clazz.subtypeOf(lookupClass(cname)))
- result = MAYBE;
- else
- return NO;
- }
- catch (NotFoundException e) {
- result = MAYBE; // should be NO?
- }
- }
-
- i = j + 1;
- }
- else {
- int t = descToType(c);
- int at = argTypes[n];
- if (t != at)
- if (t == INT
- && (at == SHORT || at == BYTE || at == CHAR))
- result = MAYBE;
- else
- return NO;
- }
- }
-
- return NO;
+ int result = YES;
+ int i = 1;
+ int nArgs = argTypes.length;
+ if (nArgs != Descriptor.numOfParameters(desc))
+ return NO;
+
+ int len = desc.length();
+ for (int n = 0; i < len; ++n) {
+ char c = desc.charAt(i++);
+ if (c == ')')
+ return (n == nArgs ? result : NO);
+ else if (n >= nArgs)
+ return NO;
+
+ int dim = 0;
+ while (c == '[') {
+ ++dim;
+ c = desc.charAt(i++);
+ }
+
+ if (argTypes[n] == NULL) {
+ if (dim == 0 && c != 'L')
+ return NO;
+ }
+ else if (argDims[n] != dim) {
+ if (!(dim == 0 && c == 'L'
+ && desc.startsWith("java/lang/Object;", i)))
+ return NO;
+
+ // if the thread reaches here, c must be 'L'.
+ i = desc.indexOf(';', i) + 1;
+ result = MAYBE;
+ if (i <= 0)
+ return NO; // invalid descriptor?
+ }
+ else if (c == 'L') { // not compare
+ int j = desc.indexOf(';', i);
+ if (j < 0 || argTypes[n] != CLASS)
+ return NO;
+
+ String cname = desc.substring(i, j);
+ if (!cname.equals(argClassNames[n])) {
+ CtClass clazz = lookupClass(argClassNames[n]);
+ try {
+ if (clazz.subtypeOf(lookupClass(cname)))
+ result = MAYBE;
+ else
+ return NO;
+ }
+ catch (NotFoundException e) {
+ result = MAYBE; // should be NO?
+ }
+ }
+
+ i = j + 1;
+ }
+ else {
+ int t = descToType(c);
+ int at = argTypes[n];
+ if (t != at)
+ if (t == INT
+ && (at == SHORT || at == BYTE || at == CHAR))
+ result = MAYBE;
+ else
+ return NO;
+ }
+ }
+
+ return NO;
}
protected static int descToType(char c) throws CompileError {
- switch (c) {
- case 'Z' :
- return BOOLEAN;
- case 'C' :
- return CHAR;
- case 'B' :
- return BYTE;
- case 'S' :
- return SHORT;
- case 'I' :
- return INT;
- case 'J' :
- return LONG;
- case 'F' :
- return FLOAT;
- case 'D' :
- return DOUBLE;
- case 'V' :
- return VOID;
- case 'L' :
- case '[' :
- return CLASS;
- default :
- fatal();
- return VOID;
- }
+ switch (c) {
+ case 'Z' :
+ return BOOLEAN;
+ case 'C' :
+ return CHAR;
+ case 'B' :
+ return BYTE;
+ case 'S' :
+ return SHORT;
+ case 'I' :
+ return INT;
+ case 'J' :
+ return LONG;
+ case 'F' :
+ return FLOAT;
+ case 'D' :
+ return DOUBLE;
+ case 'V' :
+ return VOID;
+ case 'L' :
+ case '[' :
+ return CLASS;
+ default :
+ fatal();
+ return VOID;
+ }
}
protected void atFieldAssign(Expr expr, int op, ASTree left,
- ASTree right, boolean doDup) throws CompileError
+ ASTree right, boolean doDup) throws CompileError
{
- CtField f = fieldAccess(left);
- boolean is_static = resultStatic;
- if (op != '=' && !is_static)
- bytecode.addOpcode(DUP);
-
- int fi = atFieldRead(f, is_static, op == '=');
- int fType = exprType;
- int fDim = arrayDim;
- String cname = className;
-
- atAssignCore(expr, op, right, fType, fDim, cname);
-
- boolean is2w = is2word(fType, fDim);
- if (doDup) {
- int dup_code;
- if (is_static)
- dup_code = (is2w ? DUP2 : DUP);
- else
- dup_code = (is2w ? DUP2_X1 : DUP_X1);
-
- bytecode.addOpcode(dup_code);
- }
-
- if (is_static) {
- bytecode.add(PUTSTATIC);
- bytecode.growStack(is2w ? -2 : -1);
- }
- else {
- bytecode.add(PUTFIELD);
- bytecode.growStack(is2w ? -3 : -2);
- }
-
- bytecode.addIndex(fi);
- exprType = fType;
- arrayDim = fDim;
- className = cname;
+ CtField f = fieldAccess(left);
+ boolean is_static = resultStatic;
+ if (op != '=' && !is_static)
+ bytecode.addOpcode(DUP);
+
+ int fi = atFieldRead(f, is_static, op == '=');
+ int fType = exprType;
+ int fDim = arrayDim;
+ String cname = className;
+
+ atAssignCore(expr, op, right, fType, fDim, cname);
+
+ boolean is2w = is2word(fType, fDim);
+ if (doDup) {
+ int dup_code;
+ if (is_static)
+ dup_code = (is2w ? DUP2 : DUP);
+ else
+ dup_code = (is2w ? DUP2_X1 : DUP_X1);
+
+ bytecode.addOpcode(dup_code);
+ }
+
+ if (is_static) {
+ bytecode.add(PUTSTATIC);
+ bytecode.growStack(is2w ? -2 : -1);
+ }
+ else {
+ bytecode.add(PUTFIELD);
+ bytecode.growStack(is2w ? -3 : -2);
+ }
+
+ bytecode.addIndex(fi);
+ exprType = fType;
+ arrayDim = fDim;
+ className = cname;
}
/* overwritten in JvstCodeGen.
*/
public void atMember(Member mem) throws CompileError {
- atFieldRead(mem);
+ atFieldRead(mem);
}
protected void atFieldRead(ASTree expr) throws CompileError
{
- CtField f = fieldAccess(expr);
- boolean is_static = resultStatic;
- atFieldRead(f, is_static, false);
+ CtField f = fieldAccess(expr);
+ boolean is_static = resultStatic;
+ atFieldRead(f, is_static, false);
}
private int atFieldRead(CtField f, boolean isStatic, boolean noRead)
- throws CompileError
+ throws CompileError
{
- FieldInfo finfo = f.getFieldInfo2();
- String type = finfo.getDescriptor();
-
- int fi = addFieldrefInfo(f, finfo, type);
-
- int i = 0;
- char c = type.charAt(i);
- boolean is2byte = (c == 'J' || c == 'D');
- exprType = descToType(c);
- arrayDim = 0;
- if (c == '[') {
- i = 1;
- while ((c = type.charAt(i)) == '[')
- ++i;
-
- arrayDim = i;
- }
-
- if (c == 'L')
- className = type.substring(i + 1, type.indexOf(';', i + 1));
-
- if (noRead)
- return fi;
-
- if (isStatic) {
- bytecode.add(GETSTATIC);
- bytecode.growStack(is2byte ? 2 : 1);
- }
- else {
- bytecode.add(GETFIELD);
- bytecode.growStack(is2byte ? 1 : 0);
- }
-
- bytecode.addIndex(fi);
- return fi;
+ FieldInfo finfo = f.getFieldInfo2();
+ String type = finfo.getDescriptor();
+
+ int fi = addFieldrefInfo(f, finfo, type);
+
+ int i = 0;
+ char c = type.charAt(i);
+ boolean is2byte = (c == 'J' || c == 'D');
+ exprType = descToType(c);
+ arrayDim = 0;
+ if (c == '[') {
+ i = 1;
+ while ((c = type.charAt(i)) == '[')
+ ++i;
+
+ arrayDim = i;
+ }
+
+ if (c == 'L')
+ className = type.substring(i + 1, type.indexOf(';', i + 1));
+
+ if (noRead)
+ return fi;
+
+ if (isStatic) {
+ bytecode.add(GETSTATIC);
+ bytecode.growStack(is2byte ? 2 : 1);
+ }
+ else {
+ bytecode.add(GETFIELD);
+ bytecode.growStack(is2byte ? 1 : 0);
+ }
+
+ bytecode.addIndex(fi);
+ return fi;
}
protected int addFieldrefInfo(CtField f, FieldInfo finfo, String type) {
- ConstPool cp = bytecode.getConstPool();
- String cname = f.getDeclaringClass().getName();
- int ci = cp.addClassInfo(cname);
- String name = finfo.getName();
- return cp.addFieldrefInfo(ci, name, type);
+ ConstPool cp = bytecode.getConstPool();
+ String cname = f.getDeclaringClass().getName();
+ int ci = cp.addClassInfo(cname);
+ String name = finfo.getName();
+ return cp.addFieldrefInfo(ci, name, type);
}
protected void atFieldPlusPlus(int token, boolean isPost,
- ASTree oprand, Expr expr, boolean doDup)
- throws CompileError
+ ASTree oprand, Expr expr, boolean doDup)
+ throws CompileError
{
- CtField f = fieldAccess(oprand);
- boolean is_static = resultStatic;
- if (!is_static)
- bytecode.addOpcode(DUP);
-
- int fi = atFieldRead(f, is_static, false);
- int t = exprType;
- boolean is2w = is2word(t, arrayDim);
-
- int dup_code;
- if (is_static)
- dup_code = (is2w ? DUP2 : DUP);
- else
- dup_code = (is2w ? DUP2_X1 : DUP_X1);
-
- atPlusPlusCore(dup_code, doDup, token, isPost, expr);
-
- if (is_static) {
- bytecode.add(PUTSTATIC);
- bytecode.growStack(is2w ? -2 : -1);
- }
- else {
- bytecode.add(PUTFIELD);
- bytecode.growStack(is2w ? -3 : -2);
- }
-
- bytecode.addIndex(fi);
+ CtField f = fieldAccess(oprand);
+ boolean is_static = resultStatic;
+ if (!is_static)
+ bytecode.addOpcode(DUP);
+
+ int fi = atFieldRead(f, is_static, false);
+ int t = exprType;
+ boolean is2w = is2word(t, arrayDim);
+
+ int dup_code;
+ if (is_static)
+ dup_code = (is2w ? DUP2 : DUP);
+ else
+ dup_code = (is2w ? DUP2_X1 : DUP_X1);
+
+ atPlusPlusCore(dup_code, doDup, token, isPost, expr);
+
+ if (is_static) {
+ bytecode.add(PUTSTATIC);
+ bytecode.growStack(is2w ? -2 : -1);
+ }
+ else {
+ bytecode.add(PUTFIELD);
+ bytecode.growStack(is2w ? -3 : -2);
+ }
+
+ bytecode.addIndex(fi);
}
/* This method also returns a value in resultStatic.
*/
protected CtField fieldAccess(ASTree expr) throws CompileError {
- CtField f = null;
- boolean is_static = false;
- if (expr instanceof Member) {
- String name = ((Member)expr).get();
- try {
- f = thisClass.getField(name);
- }
- catch (NotFoundException e) {
- // EXPR might be part of a static member access?
- throw new NoFieldException(name, expr);
- }
-
- is_static = Modifier.isStatic(f.getModifiers());
- if (!is_static)
- if (inStaticMethod)
- throw new CompileError(
- "not available in a static method: " + name);
- else
- bytecode.addAload(0); // this
- }
- else if (expr instanceof Expr) {
- Expr e = (Expr)expr;
- int op = e.getOperator();
- if (op == MEMBER) {
- f = lookupField((ASTList)e.oprand1(), (Symbol)e.oprand2());
- is_static = true;
- }
- else if (op == '.') {
- try {
- e.oprand1().accept(this);
- if (exprType == CLASS && arrayDim == 0)
- f = lookupField(className, (Symbol)e.oprand2());
- else
- badLvalue();
-
- is_static = Modifier.isStatic(f.getModifiers());
- if (is_static)
- bytecode.addOpcode(POP);
- }
- catch (NoFieldException nfe) {
- if (nfe.getExpr() != e.oprand1())
- throw nfe;
-
- Symbol fname = (Symbol)e.oprand2();
- // it should be a static field.
- try {
- f = lookupField(nfe.getField(), fname);
- is_static = true;
- }
- catch (CompileError ce) {
- // EXPR might be part of a qualified class name.
- throw new NoFieldException(nfe.getField() + "/"
- + fname.get(), expr);
- }
- }
- }
- else
- badLvalue();
- }
- else
- badLvalue();
-
- resultStatic = is_static;
- return f;
+ CtField f = null;
+ boolean is_static = false;
+ if (expr instanceof Member) {
+ String name = ((Member)expr).get();
+ try {
+ f = thisClass.getField(name);
+ }
+ catch (NotFoundException e) {
+ // EXPR might be part of a static member access?
+ throw new NoFieldException(name, expr);
+ }
+
+ is_static = Modifier.isStatic(f.getModifiers());
+ if (!is_static)
+ if (inStaticMethod)
+ throw new CompileError(
+ "not available in a static method: " + name);
+ else
+ bytecode.addAload(0); // this
+ }
+ else if (expr instanceof Expr) {
+ Expr e = (Expr)expr;
+ int op = e.getOperator();
+ if (op == MEMBER) {
+ f = lookupField((ASTList)e.oprand1(), (Symbol)e.oprand2());
+ is_static = true;
+ }
+ else if (op == '.') {
+ try {
+ e.oprand1().accept(this);
+ if (exprType == CLASS && arrayDim == 0)
+ f = lookupField(className, (Symbol)e.oprand2());
+ else
+ badLvalue();
+
+ is_static = Modifier.isStatic(f.getModifiers());
+ if (is_static)
+ bytecode.addOpcode(POP);
+ }
+ catch (NoFieldException nfe) {
+ if (nfe.getExpr() != e.oprand1())
+ throw nfe;
+
+ Symbol fname = (Symbol)e.oprand2();
+ // it should be a static field.
+ try {
+ f = lookupField(nfe.getField(), fname);
+ is_static = true;
+ }
+ catch (CompileError ce) {
+ // EXPR might be part of a qualified class name.
+ throw new NoFieldException(nfe.getField() + "/"
+ + fname.get(), expr);
+ }
+ }
+ }
+ else
+ badLvalue();
+ }
+ else
+ badLvalue();
+
+ resultStatic = is_static;
+ return f;
}
private static void badLvalue() throws CompileError {
- throw new CompileError("bad l-value");
+ throw new CompileError("bad l-value");
}
public CtClass[] makeParamList(MethodDecl md) throws CompileError {
- CtClass[] params;
- ASTList plist = md.getParams();
- if (plist == null)
- params = new CtClass[0];
- else {
- int i = 0;
- params = new CtClass[plist.length()];
- while (plist != null) {
- params[i++] = lookupClass((Declarator)plist.head());
- plist = plist.tail();
- }
- }
-
- return params;
+ CtClass[] params;
+ ASTList plist = md.getParams();
+ if (plist == null)
+ params = new CtClass[0];
+ else {
+ int i = 0;
+ params = new CtClass[plist.length()];
+ while (plist != null) {
+ params[i++] = lookupClass((Declarator)plist.head());
+ plist = plist.tail();
+ }
+ }
+
+ return params;
}
public CtClass[] makeThrowsList(MethodDecl md) throws CompileError {
- CtClass[] clist;
- ASTList list = md.getThrows();
- if (list == null)
- return null;
- else {
- int i = 0;
- clist = new CtClass[list.length()];
- while (list != null) {
- clist[i++] = lookupClass((ASTList)list.head());
- list = list.tail();
- }
-
- return clist;
- }
+ CtClass[] clist;
+ ASTList list = md.getThrows();
+ if (list == null)
+ return null;
+ else {
+ int i = 0;
+ clist = new CtClass[list.length()];
+ while (list != null) {
+ clist[i++] = lookupClass((ASTList)list.head());
+ list = list.tail();
+ }
+
+ return clist;
+ }
}
public static int getModifiers(ASTList mods) {
- int m = 0;
- while (mods != null) {
- Keyword k = (Keyword)mods.head();
- mods = mods.tail();
- switch (k.get()) {
- case STATIC :
- m |= Modifier.STATIC;
- break;
- case FINAL :
- m |= Modifier.FINAL;
- break;
- case SYNCHRONIZED :
- m |= Modifier.SYNCHRONIZED;
- break;
- case ABSTRACT :
- m |= Modifier.ABSTRACT;
- break;
- case PUBLIC :
- m |= Modifier.PUBLIC;
- break;
- case PROTECTED :
- m |= Modifier.PROTECTED;
- break;
- case PRIVATE :
- m |= Modifier.PRIVATE;
- break;
- case VOLATILE :
- m |= Modifier.VOLATILE;
- break;
- case TRANSIENT :
- m |= Modifier.TRANSIENT;
- break;
- case STRICT :
- m |= Modifier.STRICT;
- break;
- }
- }
-
- return m;
+ int m = 0;
+ while (mods != null) {
+ Keyword k = (Keyword)mods.head();
+ mods = mods.tail();
+ switch (k.get()) {
+ case STATIC :
+ m |= Modifier.STATIC;
+ break;
+ case FINAL :
+ m |= Modifier.FINAL;
+ break;
+ case SYNCHRONIZED :
+ m |= Modifier.SYNCHRONIZED;
+ break;
+ case ABSTRACT :
+ m |= Modifier.ABSTRACT;
+ break;
+ case PUBLIC :
+ m |= Modifier.PUBLIC;
+ break;
+ case PROTECTED :
+ m |= Modifier.PROTECTED;
+ break;
+ case PRIVATE :
+ m |= Modifier.PRIVATE;
+ break;
+ case VOLATILE :
+ m |= Modifier.VOLATILE;
+ break;
+ case TRANSIENT :
+ m |= Modifier.TRANSIENT;
+ break;
+ case STRICT :
+ m |= Modifier.STRICT;
+ break;
+ }
+ }
+
+ return m;
}
/* Converts a class name into a JVM-internal representation.
* For example, this converts Object into java/lang/Object.
*/
protected String resolveClassName(ASTList name) throws CompileError {
- if (name == null)
- return null;
- else
- return javaToJvmName(lookupClass(name).getName());
+ if (name == null)
+ return null;
+ else
+ return javaToJvmName(lookupClass(name).getName());
}
/* Expands a simple class name to java.lang.*.
* For example, this converts Object into java/lang/Object.
*/
protected String resolveClassName(String jvmName) throws CompileError {
- if (jvmName == null)
- return null;
- else
- return javaToJvmName(lookupClass(jvmName).getName());
+ if (jvmName == null)
+ return null;
+ else
+ return javaToJvmName(lookupClass(jvmName).getName());
}
protected CtClass lookupClass(Declarator decl) throws CompileError {
- return lookupClass(decl.getType(), decl.getArrayDim(),
- decl.getClassName());
+ return lookupClass(decl.getType(), decl.getArrayDim(),
+ decl.getClassName());
}
protected CtClass lookupClass(int type, int dim, String classname)
- throws CompileError
+ throws CompileError
{
- String cname = "";
- CtClass clazz;
- switch (type) {
- case CLASS :
- clazz = lookupClass(classname);
- if (dim > 0)
- cname = clazz.getName();
- else
- return clazz;
-
- break;
- case BOOLEAN :
- cname = "boolean";
- break;
- case CHAR :
- cname = "char";
- break;
- case BYTE :
- cname = "byte";
- break;
- case SHORT :
- cname = "short";
- break;
- case INT :
- cname = "int";
- break;
- case LONG :
- cname = "long";
- break;
- case FLOAT :
- cname = "float";
- break;
- case DOUBLE :
- cname = "double";
- break;
- case VOID :
- cname = "void";
- break;
- default :
- fatal();
- }
-
- while (dim-- > 0)
- cname += "[]";
-
- return lookupClass2(cname);
+ String cname = "";
+ CtClass clazz;
+ switch (type) {
+ case CLASS :
+ clazz = lookupClass(classname);
+ if (dim > 0)
+ cname = clazz.getName();
+ else
+ return clazz;
+
+ break;
+ case BOOLEAN :
+ cname = "boolean";
+ break;
+ case CHAR :
+ cname = "char";
+ break;
+ case BYTE :
+ cname = "byte";
+ break;
+ case SHORT :
+ cname = "short";
+ break;
+ case INT :
+ cname = "int";
+ break;
+ case LONG :
+ cname = "long";
+ break;
+ case FLOAT :
+ cname = "float";
+ break;
+ case DOUBLE :
+ cname = "double";
+ break;
+ case VOID :
+ cname = "void";
+ break;
+ default :
+ fatal();
+ }
+
+ while (dim-- > 0)
+ cname += "[]";
+
+ return lookupClass2(cname);
}
protected CtClass lookupClass(ASTList name) throws CompileError {
- return lookupClass2(Declarator.astToClassName(name, '.'));
+ return lookupClass2(Declarator.astToClassName(name, '.'));
}
protected CtClass lookupClass(String jvmName) throws CompileError {
- return lookupClass2(jvmToJavaName(jvmName));
+ return lookupClass2(jvmToJavaName(jvmName));
}
/**
- * @param name a qualified class name. e.g. java.lang.String
+ * @param name a qualified class name. e.g. java.lang.String
*/
private CtClass lookupClass2(String name) throws CompileError {
- try {
- return classPool.get(name);
- }
- catch (NotFoundException e) {}
-
- try {
- if (name.indexOf('.') < 0)
- return classPool.get("java.lang." + name);
- }
- catch (NotFoundException e) {}
-
- throw new CompileError("no such class: " + name);
+ try {
+ return classPool.get(name);
+ }
+ catch (NotFoundException e) {}
+
+ try {
+ if (name.indexOf('.') < 0)
+ return classPool.get("java.lang." + name);
+ }
+ catch (NotFoundException e) {}
+
+ throw new CompileError("no such class: " + name);
}
public CtField lookupField(ASTList className, Symbol fieldName)
- throws CompileError
+ throws CompileError
{
- return lookupField2(Declarator.astToClassName(className, '.'),
- fieldName);
+ return lookupField2(Declarator.astToClassName(className, '.'),
+ fieldName);
}
public CtField lookupField(String className, Symbol fieldName)
- throws CompileError
+ throws CompileError
{
- return lookupField2(jvmToJavaName(className), fieldName);
+ return lookupField2(jvmToJavaName(className), fieldName);
}
/**
- * @param name a qualified class name. e.g. java.lang.String
+ * @param name a qualified class name. e.g. java.lang.String
*/
private CtField lookupField2(String className, Symbol fieldName)
- throws CompileError
+ throws CompileError
{
- CtClass cc = lookupClass(className);
- try {
- return cc.getField(fieldName.get());
- }
- catch (NotFoundException e) {}
- throw new CompileError("no such field: " + fieldName.get());
+ CtClass cc = lookupClass(className);
+ try {
+ return cc.getField(fieldName.get());
+ }
+ catch (NotFoundException e) {}
+ throw new CompileError("no such field: " + fieldName.get());
}
protected static String javaToJvmName(String classname) {
- return classname.replace('.', '/');
+ return classname.replace('.', '/');
}
protected static String jvmToJavaName(String classname) {
- return classname.replace('/', '.');
+ return classname.replace('/', '.');
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import javassist.compiler.ast.ASTree;
/* NAME must be JVM-internal representation.
*/
public NoFieldException(String name, ASTree e) {
- super("no such field: " + name);
- fieldName = name;
- expr = e;
+ super("no such field: " + name);
+ fieldName = name;
+ expr = e;
}
/* The returned name should be JVM-internal representation.
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import javassist.compiler.ast.*;
private Lex lex;
public Parser(Lex lex) {
- this.lex = lex;
+ this.lex = lex;
}
public boolean hasMore() { return lex.lookAhead() >= 0; }
* : method.declaration | field.declaration
*/
public ASTList parseMember(SymbolTable tbl) throws CompileError {
- ASTList mem = parseMember1(tbl);
- if (mem instanceof MethodDecl)
- return parseMethod2(tbl, (MethodDecl)mem);
- else
- return mem;
+ ASTList mem = parseMember1(tbl);
+ if (mem instanceof MethodDecl)
+ return parseMethod2(tbl, (MethodDecl)mem);
+ else
+ return mem;
}
/* A method body is not parsed.
*/
public ASTList parseMember1(SymbolTable tbl) throws CompileError {
- ASTList mods = parseMemberMods();
- Declarator d;
- boolean isConstructor = false;
- if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') {
- d = new Declarator(VOID, 0);
- isConstructor = true;
- }
- else
- d = parseFormalType(tbl);
-
- if (lex.get() != Identifier)
- throw new SyntaxError(lex);
-
- String name;
- if (isConstructor)
- name = MethodDecl.initName;
- else
- name = lex.getString();
-
- d.setVariable(new Symbol(name));
- if (isConstructor || lex.lookAhead() == '(')
- return parseMethod1(tbl, isConstructor, mods, d);
- else
- return parseField(tbl, mods, d);
+ ASTList mods = parseMemberMods();
+ Declarator d;
+ boolean isConstructor = false;
+ if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') {
+ d = new Declarator(VOID, 0);
+ isConstructor = true;
+ }
+ else
+ d = parseFormalType(tbl);
+
+ if (lex.get() != Identifier)
+ throw new SyntaxError(lex);
+
+ String name;
+ if (isConstructor)
+ name = MethodDecl.initName;
+ else
+ name = lex.getString();
+
+ d.setVariable(new Symbol(name));
+ if (isConstructor || lex.lookAhead() == '(')
+ return parseMethod1(tbl, isConstructor, mods, d);
+ else
+ return parseField(tbl, mods, d);
}
/* field.declaration
* [ "=" expression ] ";"
*/
private FieldDecl parseField(SymbolTable tbl, ASTList mods,
- Declarator d) throws CompileError
+ Declarator d) throws CompileError
{
- ASTree expr = null;
- if (lex.lookAhead() == '=') {
- lex.get();
- expr = parseExpression(tbl);
- }
-
- int c = lex.get();
- if (c == ';')
- return new FieldDecl(mods, new ASTList(d, new ASTList(expr)));
- else if (c == ',')
- throw new CompileError(
- "only one field can be declared in one declaration", lex);
- else
- throw new SyntaxError(lex);
+ ASTree expr = null;
+ if (lex.lookAhead() == '=') {
+ lex.get();
+ expr = parseExpression(tbl);
+ }
+
+ int c = lex.get();
+ if (c == ';')
+ return new FieldDecl(mods, new ASTList(d, new ASTList(expr)));
+ else if (c == ',')
+ throw new CompileError(
+ "only one field can be declared in one declaration", lex);
+ else
+ throw new SyntaxError(lex);
}
/* method.declaration
* Note that a method body is not parsed.
*/
private MethodDecl parseMethod1(SymbolTable tbl, boolean isConstructor,
- ASTList mods, Declarator d)
- throws CompileError
+ ASTList mods, Declarator d)
+ throws CompileError
{
- if (lex.get() != '(')
- throw new SyntaxError(lex);
-
- ASTList parms = null;
- if (lex.lookAhead() != ')')
- while (true) {
- parms = ASTList.append(parms, parseFormalParam(tbl));
- int t = lex.lookAhead();
- if (t == ',')
- lex.get();
- else if (t == ')')
- break;
- }
-
- lex.get(); // ')'
- d.addArrayDim(parseArrayDimension());
- if (isConstructor && d.getArrayDim() > 0)
- throw new SyntaxError(lex);
-
- ASTList throwsList = null;
- if (lex.lookAhead() == THROWS) {
- lex.get();
- while (true) {
- throwsList = ASTList.append(throwsList, parseClassType(tbl));
- if (lex.lookAhead() == ',')
- lex.get();
- else
- break;
- }
- }
-
- return new MethodDecl(mods, new ASTList(d,
- ASTList.make(parms, throwsList, null)));
+ if (lex.get() != '(')
+ throw new SyntaxError(lex);
+
+ ASTList parms = null;
+ if (lex.lookAhead() != ')')
+ while (true) {
+ parms = ASTList.append(parms, parseFormalParam(tbl));
+ int t = lex.lookAhead();
+ if (t == ',')
+ lex.get();
+ else if (t == ')')
+ break;
+ }
+
+ lex.get(); // ')'
+ d.addArrayDim(parseArrayDimension());
+ if (isConstructor && d.getArrayDim() > 0)
+ throw new SyntaxError(lex);
+
+ ASTList throwsList = null;
+ if (lex.lookAhead() == THROWS) {
+ lex.get();
+ while (true) {
+ throwsList = ASTList.append(throwsList, parseClassType(tbl));
+ if (lex.lookAhead() == ',')
+ lex.get();
+ else
+ break;
+ }
+ }
+
+ return new MethodDecl(mods, new ASTList(d,
+ ASTList.make(parms, throwsList, null)));
}
/* Parses a method body.
*/
public MethodDecl parseMethod2(SymbolTable tbl, MethodDecl md)
- throws CompileError
+ throws CompileError
{
- Stmnt body = null;
- if (lex.lookAhead() == ';')
- lex.get();
- else {
- body = parseBlock(tbl);
- if (body == null)
- body = new Stmnt(BLOCK);
- }
-
- md.sublist(4).setHead(body);
- return md;
+ Stmnt body = null;
+ if (lex.lookAhead() == ';')
+ lex.get();
+ else {
+ body = parseBlock(tbl);
+ if (body == null)
+ body = new Stmnt(BLOCK);
+ }
+
+ md.sublist(4).setHead(body);
+ return md;
}
/* member.modifiers
* | VOLATILE | TRANSIENT | STRICT )*
*/
private ASTList parseMemberMods() {
- int t;
- ASTList list = null;
- while (true) {
- t = lex.lookAhead();
- if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED
- || t == PRIVATE || t == SYNCHRONIZED || t == STATIC
- || t == VOLATILE || t == TRANSIENT || t == STRICT)
- list = new ASTList(new Keyword(lex.get()), list);
- else
- break;
- }
-
- return list;
+ int t;
+ ASTList list = null;
+ while (true) {
+ t = lex.lookAhead();
+ if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED
+ || t == PRIVATE || t == SYNCHRONIZED || t == STATIC
+ || t == VOLATILE || t == TRANSIENT || t == STRICT)
+ list = new ASTList(new Keyword(lex.get()), list);
+ else
+ break;
+ }
+
+ return list;
}
/* formal.type : ( build-in-type | class.type ) array.dimension
*/
private Declarator parseFormalType(SymbolTable tbl) throws CompileError {
- int t = lex.lookAhead();
- if (isBuiltinType(t) || t == VOID) {
- lex.get(); // primitive type
- int dim = parseArrayDimension();
- return new Declarator(t, dim);
- }
- else {
- ASTList name = parseClassType(tbl);
- int dim = parseArrayDimension();
- return new Declarator(name, dim);
- }
+ int t = lex.lookAhead();
+ if (isBuiltinType(t) || t == VOID) {
+ lex.get(); // primitive type
+ int dim = parseArrayDimension();
+ return new Declarator(t, dim);
+ }
+ else {
+ ASTList name = parseClassType(tbl);
+ int dim = parseArrayDimension();
+ return new Declarator(name, dim);
+ }
}
private static boolean isBuiltinType(int t) {
- return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT
- || t == INT || t == LONG || t == FLOAT || t == DOUBLE);
+ return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT
+ || t == INT || t == LONG || t == FLOAT || t == DOUBLE);
}
/* formal.parameter : formal.type Identifier array.dimension
*/
private Declarator parseFormalParam(SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- Declarator d = parseFormalType(tbl);
- if (lex.get() != Identifier)
- throw new SyntaxError(lex);
-
- String name = lex.getString();
- d.setVariable(new Symbol(name));
- d.addArrayDim(parseArrayDimension());
- tbl.append(name, d);
- return d;
+ Declarator d = parseFormalType(tbl);
+ if (lex.get() != Identifier)
+ throw new SyntaxError(lex);
+
+ String name = lex.getString();
+ d.setVariable(new Symbol(name));
+ d.addArrayDim(parseArrayDimension());
+ tbl.append(name, d);
+ return d;
}
/* statement : [ label ":" ]* labeled.statement
*
* labeled.statement
- * : block.statement
- * | if.statement
- * | while.statement
- * | do.statement
- * | for.statement
- * | switch.statement
- * | try.statement
- * | return.statement
- * | thorw.statement
- * | break.statement
- * | continue.statement
- * | declaration.or.expression
- * | ";"
+ * : block.statement
+ * | if.statement
+ * | while.statement
+ * | do.statement
+ * | for.statement
+ * | switch.statement
+ * | try.statement
+ * | return.statement
+ * | thorw.statement
+ * | break.statement
+ * | continue.statement
+ * | declaration.or.expression
+ * | ";"
*
* This method may return null (empty statement).
*/
public Stmnt parseStatement(SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- int t = lex.lookAhead();
- if (t == '{')
- return parseBlock(tbl);
- else if (t == ';') {
- lex.get();
- return new Stmnt(BLOCK); // empty statement
- }
- else if (t == Identifier && lex.lookAhead(1) == ':') {
- lex.get(); // Identifier
- String label = lex.getString();
- lex.get(); // ':'
- return Stmnt.make(LABEL, new Symbol(label), parseStatement(tbl));
- }
- else if (t == IF)
- return parseIf(tbl);
- else if (t == WHILE)
- return parseWhile(tbl);
- else if (t == DO)
- return parseDo(tbl);
- else if (t == FOR)
- return parseFor(tbl);
- else if (t == TRY)
- return parseTry(tbl);
- else if (t == SWITCH)
- return parseSwitch(tbl);
- else if (t == RETURN)
- return parseReturn(tbl);
- else if (t == THROW)
- return parseThrow(tbl);
- else if (t == BREAK)
- return parseBreak(tbl);
- else if (t == CONTINUE)
- return parseContinue(tbl);
- else
- return parseDeclarationOrExpression(tbl, false);
+ int t = lex.lookAhead();
+ if (t == '{')
+ return parseBlock(tbl);
+ else if (t == ';') {
+ lex.get();
+ return new Stmnt(BLOCK); // empty statement
+ }
+ else if (t == Identifier && lex.lookAhead(1) == ':') {
+ lex.get(); // Identifier
+ String label = lex.getString();
+ lex.get(); // ':'
+ return Stmnt.make(LABEL, new Symbol(label), parseStatement(tbl));
+ }
+ else if (t == IF)
+ return parseIf(tbl);
+ else if (t == WHILE)
+ return parseWhile(tbl);
+ else if (t == DO)
+ return parseDo(tbl);
+ else if (t == FOR)
+ return parseFor(tbl);
+ else if (t == TRY)
+ return parseTry(tbl);
+ else if (t == SWITCH)
+ return parseSwitch(tbl);
+ else if (t == RETURN)
+ return parseReturn(tbl);
+ else if (t == THROW)
+ return parseThrow(tbl);
+ else if (t == BREAK)
+ return parseBreak(tbl);
+ else if (t == CONTINUE)
+ return parseContinue(tbl);
+ else
+ return parseDeclarationOrExpression(tbl, false);
}
/* block.statement : "{" statement* "}"
*/
private Stmnt parseBlock(SymbolTable tbl) throws CompileError {
- if (lex.get() != '{')
- throw new SyntaxError(lex);
-
- Stmnt body = null;
- SymbolTable tbl2 = new SymbolTable(tbl);
- while (lex.lookAhead() != '}') {
- Stmnt s = parseStatement(tbl2);
- if (s != null)
- body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s));
- }
-
- lex.get(); // '}'
- if (body == null)
- return new Stmnt(BLOCK); // empty block
- else
- return body;
+ if (lex.get() != '{')
+ throw new SyntaxError(lex);
+
+ Stmnt body = null;
+ SymbolTable tbl2 = new SymbolTable(tbl);
+ while (lex.lookAhead() != '}') {
+ Stmnt s = parseStatement(tbl2);
+ if (s != null)
+ body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s));
+ }
+
+ lex.get(); // '}'
+ if (body == null)
+ return new Stmnt(BLOCK); // empty block
+ else
+ return body;
}
/* if.statement : IF "(" expression ")" statement
- * [ ELSE statement ]
+ * [ ELSE statement ]
*/
private Stmnt parseIf(SymbolTable tbl) throws CompileError {
- int t = lex.get(); // IF
- if (lex.get() != '(')
- throw new SyntaxError(lex);
-
- ASTree expr = parseExpression(tbl);
- if (lex.get() != ')')
- throw new SyntaxError(lex);
-
- Stmnt thenp = parseStatement(tbl);
- Stmnt elsep;
- if (lex.lookAhead() == ELSE) {
- lex.get();
- elsep = parseStatement(tbl);
- }
- else
- elsep = null;
-
- return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep)));
+ int t = lex.get(); // IF
+ if (lex.get() != '(')
+ throw new SyntaxError(lex);
+
+ ASTree expr = parseExpression(tbl);
+ if (lex.get() != ')')
+ throw new SyntaxError(lex);
+
+ Stmnt thenp = parseStatement(tbl);
+ Stmnt elsep;
+ if (lex.lookAhead() == ELSE) {
+ lex.get();
+ elsep = parseStatement(tbl);
+ }
+ else
+ elsep = null;
+
+ return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep)));
}
/* while.statement : WHILE "(" expression ")" statement
*/
private Stmnt parseWhile(SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- int t = lex.get(); // WHILE
- if (lex.get() != '(')
- throw new SyntaxError(lex);
+ int t = lex.get(); // WHILE
+ if (lex.get() != '(')
+ throw new SyntaxError(lex);
- ASTree expr = parseExpression(tbl);
- if (lex.get() != ')')
- throw new SyntaxError(lex);
+ ASTree expr = parseExpression(tbl);
+ if (lex.get() != ')')
+ throw new SyntaxError(lex);
- Stmnt body = parseStatement(tbl);
- return new Stmnt(t, expr, body);
+ Stmnt body = parseStatement(tbl);
+ return new Stmnt(t, expr, body);
}
/* do.statement : DO statement WHILE "(" expression ")" ";"
*/
private Stmnt parseDo(SymbolTable tbl) throws CompileError {
- int t = lex.get(); // DO
- Stmnt body = parseStatement(tbl);
- if (lex.get() != WHILE || lex.get() != '(')
- throw new SyntaxError(lex);
+ int t = lex.get(); // DO
+ Stmnt body = parseStatement(tbl);
+ if (lex.get() != WHILE || lex.get() != '(')
+ throw new SyntaxError(lex);
- ASTree expr = parseExpression(tbl);
- if (lex.get() != ')' || lex.get() != ';')
- throw new SyntaxError(lex);
+ ASTree expr = parseExpression(tbl);
+ if (lex.get() != ')' || lex.get() != ';')
+ throw new SyntaxError(lex);
- return new Stmnt(t, expr, body);
+ return new Stmnt(t, expr, body);
}
/* for.statement : FOR "(" decl.or.expr expression ";" expression ")"
- * statement
+ * statement
*/
private Stmnt parseFor(SymbolTable tbl) throws CompileError {
- Stmnt expr1, expr3;
- ASTree expr2;
- int t = lex.get(); // FOR
+ Stmnt expr1, expr3;
+ ASTree expr2;
+ int t = lex.get(); // FOR
- SymbolTable tbl2 = new SymbolTable(tbl);
+ SymbolTable tbl2 = new SymbolTable(tbl);
- if (lex.get() != '(')
- throw new SyntaxError(lex);
+ if (lex.get() != '(')
+ throw new SyntaxError(lex);
- if (lex.lookAhead() == ';') {
- lex.get();
- expr1 = null;
- }
- else
- expr1 = parseDeclarationOrExpression(tbl2, true);
+ if (lex.lookAhead() == ';') {
+ lex.get();
+ expr1 = null;
+ }
+ else
+ expr1 = parseDeclarationOrExpression(tbl2, true);
- if (lex.lookAhead() == ';')
- expr2 = null;
- else
- expr2 = parseExpression(tbl2);
+ if (lex.lookAhead() == ';')
+ expr2 = null;
+ else
+ expr2 = parseExpression(tbl2);
- if (lex.get() != ';')
- throw new CompileError("; is missing", lex);
+ if (lex.get() != ';')
+ throw new CompileError("; is missing", lex);
- if (lex.lookAhead() == ')')
- expr3 = null;
- else
- expr3 = parseExprList(tbl2);
+ if (lex.lookAhead() == ')')
+ expr3 = null;
+ else
+ expr3 = parseExprList(tbl2);
- if (lex.get() != ')')
- throw new CompileError(") is missing", lex);
+ if (lex.get() != ')')
+ throw new CompileError(") is missing", lex);
- Stmnt body = parseStatement(tbl2);
- return new Stmnt(t, expr1, new ASTList(expr2,
- new ASTList(expr3, body)));
+ Stmnt body = parseStatement(tbl2);
+ return new Stmnt(t, expr1, new ASTList(expr2,
+ new ASTList(expr3, body)));
}
/* switch.statement : SWITCH "(" expression ")" "{" switch.block "}"
* swtich.block : ( switch.label* statement )*
*
* swtich.label : DEFAULT ":"
- * | CASE const.expression ":"
+ * | CASE const.expression ":"
*/
private Stmnt parseSwitch(SymbolTable tbl) throws CompileError {
- throw new CompileError("switch is not supported", lex);
+ throw new CompileError("switch is not supported", lex);
}
/* try.statement
* : TRY block.statement
- * [ CATCH "(" class.type Identifier ")" block.statement ]*
- * [ FINALLY block.statement ]*
+ * [ CATCH "(" class.type Identifier ")" block.statement ]*
+ * [ FINALLY block.statement ]*
*/
private Stmnt parseTry(SymbolTable tbl) throws CompileError {
- lex.get(); // TRY
- Stmnt block = parseBlock(tbl);
- ASTList catchList = null;
- while (lex.lookAhead() == CATCH) {
- lex.get(); // CATCH
- if (lex.get() != '(')
- throw new SyntaxError(lex);
-
- SymbolTable tbl2 = new SymbolTable(tbl);
- Declarator d = parseFormalParam(tbl2);
- if (d.getArrayDim() > 0 || d.getType() != CLASS)
- throw new SyntaxError(lex);
-
- if (lex.get() != ')')
- throw new SyntaxError(lex);
-
- Stmnt b = parseBlock(tbl2);
- catchList = ASTList.append(catchList, new Pair(d, b));
- }
-
- Stmnt finallyBlock = null;
- if (lex.lookAhead() == FINALLY) {
- lex.get(); // FINALLY
- finallyBlock = parseBlock(tbl);
- }
-
- return Stmnt.make(TRY, block, catchList, finallyBlock);
+ lex.get(); // TRY
+ Stmnt block = parseBlock(tbl);
+ ASTList catchList = null;
+ while (lex.lookAhead() == CATCH) {
+ lex.get(); // CATCH
+ if (lex.get() != '(')
+ throw new SyntaxError(lex);
+
+ SymbolTable tbl2 = new SymbolTable(tbl);
+ Declarator d = parseFormalParam(tbl2);
+ if (d.getArrayDim() > 0 || d.getType() != CLASS)
+ throw new SyntaxError(lex);
+
+ if (lex.get() != ')')
+ throw new SyntaxError(lex);
+
+ Stmnt b = parseBlock(tbl2);
+ catchList = ASTList.append(catchList, new Pair(d, b));
+ }
+
+ Stmnt finallyBlock = null;
+ if (lex.lookAhead() == FINALLY) {
+ lex.get(); // FINALLY
+ finallyBlock = parseBlock(tbl);
+ }
+
+ return Stmnt.make(TRY, block, catchList, finallyBlock);
}
/* return.statement : RETURN [ expression ] ";"
*/
private Stmnt parseReturn(SymbolTable tbl) throws CompileError {
- int t = lex.get(); // RETURN
- Stmnt s = new Stmnt(t);
- if (lex.lookAhead() != ';')
- s.setLeft(parseExpression(tbl));
+ int t = lex.get(); // RETURN
+ Stmnt s = new Stmnt(t);
+ if (lex.lookAhead() != ';')
+ s.setLeft(parseExpression(tbl));
- if (lex.get() != ';')
- throw new CompileError("; is missing", lex);
+ if (lex.get() != ';')
+ throw new CompileError("; is missing", lex);
- return s;
+ return s;
}
/* throw.statement : THROW expression ";"
*/
private Stmnt parseThrow(SymbolTable tbl) throws CompileError {
- int t = lex.get(); // THROW
- ASTree expr = parseExpression(tbl);
- if (lex.get() != ';')
- throw new CompileError("; is missing", lex);
+ int t = lex.get(); // THROW
+ ASTree expr = parseExpression(tbl);
+ if (lex.get() != ';')
+ throw new CompileError("; is missing", lex);
- return new Stmnt(t, expr);
+ return new Stmnt(t, expr);
}
/* break.statement : BREAK [ Identifier ] ";"
*/
private Stmnt parseBreak(SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- return parseContinue(tbl);
+ return parseContinue(tbl);
}
/* continue.statement : CONTINUE [ Identifier ] ";"
*/
private Stmnt parseContinue(SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- int t = lex.get(); // CONTINUE
- Stmnt s = new Stmnt(t);
- int t2 = lex.get();
- if (t2 == Identifier) {
- s.setLeft(new Symbol(lex.getString()));
- t2 = lex.get();
- }
-
- if (t2 != ';')
- throw new CompileError("; is missing", lex);
-
- return s;
+ int t = lex.get(); // CONTINUE
+ Stmnt s = new Stmnt(t);
+ int t2 = lex.get();
+ if (t2 == Identifier) {
+ s.setLeft(new Symbol(lex.getString()));
+ t2 = lex.get();
+ }
+
+ if (t2 != ';')
+ throw new CompileError("; is missing", lex);
+
+ return s;
}
/* declaration.or.expression
* : [ FINAL ] built-in-type array.dimension declarators
* | [ FINAL ] class.type array.dimension declarators
* | expression ';'
- * | expr.list ';' if exprList is true
+ * | expr.list ';' if exprList is true
*
* Note: FINAL is currently ignored. This must be fixed
* in future.
*/
private Stmnt parseDeclarationOrExpression(SymbolTable tbl,
- boolean exprList)
- throws CompileError
+ boolean exprList)
+ throws CompileError
{
- int t = lex.lookAhead();
- while (t == FINAL) {
- lex.get();
- t = lex.lookAhead();
- }
-
- if (isBuiltinType(t)) {
- t = lex.get();
- int dim = parseArrayDimension();
- return parseDeclarators(tbl, new Declarator(t, dim));
- }
- else if (t == Identifier) {
- int i = nextIsClassType(0);
- if (i >= 0)
- if (lex.lookAhead(i) == Identifier) {
- ASTList name = parseClassType(tbl);
- int dim = parseArrayDimension();
- return parseDeclarators(tbl, new Declarator(name, dim));
- }
- }
-
- Stmnt expr;
- if (exprList)
- expr = parseExprList(tbl);
- else
- expr = new Stmnt(EXPR, parseExpression(tbl));
-
- if (lex.get() != ';')
- throw new CompileError("; is missing", lex);
-
- return expr;
+ int t = lex.lookAhead();
+ while (t == FINAL) {
+ lex.get();
+ t = lex.lookAhead();
+ }
+
+ if (isBuiltinType(t)) {
+ t = lex.get();
+ int dim = parseArrayDimension();
+ return parseDeclarators(tbl, new Declarator(t, dim));
+ }
+ else if (t == Identifier) {
+ int i = nextIsClassType(0);
+ if (i >= 0)
+ if (lex.lookAhead(i) == Identifier) {
+ ASTList name = parseClassType(tbl);
+ int dim = parseArrayDimension();
+ return parseDeclarators(tbl, new Declarator(name, dim));
+ }
+ }
+
+ Stmnt expr;
+ if (exprList)
+ expr = parseExprList(tbl);
+ else
+ expr = new Stmnt(EXPR, parseExpression(tbl));
+
+ if (lex.get() != ';')
+ throw new CompileError("; is missing", lex);
+
+ return expr;
}
/* expr.list : ( expression ',')* expression
*/
private Stmnt parseExprList(SymbolTable tbl) throws CompileError {
- Stmnt expr = null;
- for (;;) {
- Stmnt e = new Stmnt(EXPR, parseExpression(tbl));
- expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e));
- if (lex.lookAhead() == ',')
- lex.get();
- else
- return expr;
- }
+ Stmnt expr = null;
+ for (;;) {
+ Stmnt e = new Stmnt(EXPR, parseExpression(tbl));
+ expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e));
+ if (lex.lookAhead() == ',')
+ lex.get();
+ else
+ return expr;
+ }
}
/* declarators : declarator [ ',' declarator ]* ';'
*/
private Stmnt parseDeclarators(SymbolTable tbl, Declarator d)
- throws CompileError
+ throws CompileError
{
- Stmnt decl = null;
- for (;;) {
- decl = (Stmnt)ASTList.concat(decl,
- new Stmnt(DECL, parseDeclarator(tbl, d)));
- int t = lex.get();
- if (t == ';')
- return decl;
- else if (t != ',')
- throw new CompileError("; is missing", lex);
- }
+ Stmnt decl = null;
+ for (;;) {
+ decl = (Stmnt)ASTList.concat(decl,
+ new Stmnt(DECL, parseDeclarator(tbl, d)));
+ int t = lex.get();
+ if (t == ';')
+ return decl;
+ else if (t != ',')
+ throw new CompileError("; is missing", lex);
+ }
}
/* declarator : Identifier array.dimension [ '=' initializer ]
*/
private Declarator parseDeclarator(SymbolTable tbl, Declarator d)
- throws CompileError
+ throws CompileError
{
- if (lex.get() != Identifier || d.getType() == VOID)
- throw new SyntaxError(lex);
-
- String name = lex.getString();
- Symbol symbol = new Symbol(name);
- int dim = parseArrayDimension();
- ASTree init = null;
- if (lex.lookAhead() == '=') {
- lex.get();
- init = parseInitializer(tbl);
- }
-
- Declarator decl = d.make(symbol, dim, init);
- tbl.append(name, decl);
- return decl;
+ if (lex.get() != Identifier || d.getType() == VOID)
+ throw new SyntaxError(lex);
+
+ String name = lex.getString();
+ Symbol symbol = new Symbol(name);
+ int dim = parseArrayDimension();
+ ASTree init = null;
+ if (lex.lookAhead() == '=') {
+ lex.get();
+ init = parseInitializer(tbl);
+ }
+
+ Declarator decl = d.make(symbol, dim, init);
+ tbl.append(name, decl);
+ return decl;
}
/* initializer : expression | array.initializer
*/
private ASTree parseInitializer(SymbolTable tbl) throws CompileError {
- if (lex.lookAhead() == '{')
- return parseArrayInitializer(tbl);
- else
- return parseExpression(tbl);
+ if (lex.lookAhead() == '{')
+ return parseArrayInitializer(tbl);
+ else
+ return parseExpression(tbl);
}
/* array.initializer :
* '{' (( array.initializer | expression ) ',')* '}'
*/
private ASTree parseArrayInitializer(SymbolTable tbl)
- throws CompileError
+ throws CompileError
{
- lex.get(); // '{'
- throw new CompileError("array initializer is not supported", lex);
+ lex.get(); // '{'
+ throw new CompileError("array initializer is not supported", lex);
}
/* expression : conditional.expr
- * | conditional.expr assign.op expression (right-to-left)
+ * | conditional.expr assign.op expression (right-to-left)
*/
public ASTree parseExpression(SymbolTable tbl) throws CompileError {
- ASTree left = parseConditionalExpr(tbl);
- if (!isAssignOp(lex.lookAhead()))
- return left;
+ ASTree left = parseConditionalExpr(tbl);
+ if (!isAssignOp(lex.lookAhead()))
+ return left;
- int t = lex.get();
- ASTree right = parseExpression(tbl);
- return AssignExpr.makeAssign(t, left, right);
+ int t = lex.get();
+ ASTree right = parseExpression(tbl);
+ return AssignExpr.makeAssign(t, left, right);
}
private static boolean isAssignOp(int t) {
- return t == '=' || t == MOD_E || t == AND_E
- || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E
- || t == EXOR_E || t == OR_E || t == LSHIFT_E
- || t == RSHIFT_E || t == ARSHIFT_E;
+ return t == '=' || t == MOD_E || t == AND_E
+ || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E
+ || t == EXOR_E || t == OR_E || t == LSHIFT_E
+ || t == RSHIFT_E || t == ARSHIFT_E;
}
- /* conditional.expr (right-to-left)
- * : logical.or.expr [ '?' expression ':' conditional.expr ]
+ /* conditional.expr (right-to-left)
+ * : logical.or.expr [ '?' expression ':' conditional.expr ]
*/
private ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError {
- ASTree cond = parseBinaryExpr(tbl);
- if (lex.lookAhead() == '?') {
- lex.get();
- ASTree thenExpr = parseExpression(tbl);
- if (lex.get() != ':')
- throw new CompileError(": is missing", lex);
-
- ASTree elseExpr = parseExpression(tbl);
- return new CondExpr(cond, thenExpr, elseExpr);
- }
- else
- return cond;
+ ASTree cond = parseBinaryExpr(tbl);
+ if (lex.lookAhead() == '?') {
+ lex.get();
+ ASTree thenExpr = parseExpression(tbl);
+ if (lex.get() != ':')
+ throw new CompileError(": is missing", lex);
+
+ ASTree elseExpr = parseExpression(tbl);
+ return new CondExpr(cond, thenExpr, elseExpr);
+ }
+ else
+ return cond;
}
- /* logical.or.expr 10 (operator precedence)
+ /* logical.or.expr 10 (operator precedence)
* : logical.and.expr
- * | logical.or.expr OROR logical.and.expr left-to-right
+ * | logical.or.expr OROR logical.and.expr left-to-right
*
- * logical.and.expr 9
+ * logical.and.expr 9
* : inclusive.or.expr
* | logical.and.expr ANDAND inclusive.or.expr
*
- * inclusive.or.expr 8
+ * inclusive.or.expr 8
* : exclusive.or.expr
* | inclusive.or.expr "|" exclusive.or.expr
*
- * exclusive.or.expr 7
+ * exclusive.or.expr 7
* : and.expr
* | exclusive.or.expr "^" and.expr
*
- * and.expr 6
+ * and.expr 6
* : equality.expr
* | and.expr "&" equality.expr
*
- * equality.expr 5
+ * equality.expr 5
* : relational.expr
* | equality.expr (EQ | NEQ) relational.expr
*
- * relational.expr 4
+ * relational.expr 4
* : shift.expr
* | relational.expr (LE | GE | "<" | ">") shift.expr
* | relational.expr INSTANCEOF class.type ("[" "]")*
*
- * shift.expr 3
+ * shift.expr 3
* : additive.expr
* | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr
*
- * additive.expr 2
+ * additive.expr 2
* : multiply.expr
* | additive.expr ("+" | "-") multiply.expr
*
- * multiply.expr 1
+ * multiply.expr 1
* : unary.expr
* | multiply.expr ("*" | "/" | "%") unary.expr
*/
private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError {
- ASTree expr = parseUnaryExpr(tbl);
- for (;;) {
- int t = lex.lookAhead();
- int p = getOpPrecedence(t);
- if (p == 0)
- return expr;
- else
- expr = binaryExpr2(tbl, expr, p);
- }
+ ASTree expr = parseUnaryExpr(tbl);
+ for (;;) {
+ int t = lex.lookAhead();
+ int p = getOpPrecedence(t);
+ if (p == 0)
+ return expr;
+ else
+ expr = binaryExpr2(tbl, expr, p);
+ }
}
private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr)
- throws CompileError
+ throws CompileError
{
- int t = lex.lookAhead();
- if (isBuiltinType(t)) {
- lex.get(); // primitive type
- int dim = parseArrayDimension();
- return new InstanceOfExpr(t, dim, expr);
- }
- else {
- ASTList name = parseClassType(tbl);
- int dim = parseArrayDimension();
- return new InstanceOfExpr(name, dim, expr);
- }
+ int t = lex.lookAhead();
+ if (isBuiltinType(t)) {
+ lex.get(); // primitive type
+ int dim = parseArrayDimension();
+ return new InstanceOfExpr(t, dim, expr);
+ }
+ else {
+ ASTList name = parseClassType(tbl);
+ int dim = parseArrayDimension();
+ return new InstanceOfExpr(name, dim, expr);
+ }
}
private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec)
- throws CompileError
+ throws CompileError
{
- int t = lex.get();
- if (t == INSTANCEOF)
- return parseInstanceOf(tbl, expr);
-
- ASTree expr2 = parseUnaryExpr(tbl);
- for (;;) {
- int t2 = lex.lookAhead();
- int p2 = getOpPrecedence(t2);
- if (p2 != 0 && prec > p2)
- expr2 = binaryExpr2(tbl, expr2, p2);
- else
- return BinExpr.makeBin(t, expr, expr2);
- }
+ int t = lex.get();
+ if (t == INSTANCEOF)
+ return parseInstanceOf(tbl, expr);
+
+ ASTree expr2 = parseUnaryExpr(tbl);
+ for (;;) {
+ int t2 = lex.lookAhead();
+ int p2 = getOpPrecedence(t2);
+ if (p2 != 0 && prec > p2)
+ expr2 = binaryExpr2(tbl, expr2, p2);
+ else
+ return BinExpr.makeBin(t, expr, expr2);
+ }
}
// !"#$%&'( )*+,-./0 12345678 9:;<=>?
private static final int[] binaryOpPrecedence
- = { 0, 0, 0, 0, 1, 6, 0, 0,
- 0, 1, 2, 0, 2, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 4, 0, 4, 0 };
+ = { 0, 0, 0, 0, 1, 6, 0, 0,
+ 0, 1, 2, 0, 2, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 4, 0 };
private int getOpPrecedence(int c) {
- if ('!' <= c && c <= '?')
- return binaryOpPrecedence[c - '!'];
- else if (c == '^')
- return 7;
- else if (c == '|')
- return 8;
- else if (c == ANDAND)
- return 9;
- else if (c == OROR)
- return 10;
- else if (c == EQ || c == NEQ)
- return 5;
- else if (c == LE || c == GE || c == INSTANCEOF)
- return 4;
- else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT)
- return 3;
- else
- return 0; // not a binary operator
+ if ('!' <= c && c <= '?')
+ return binaryOpPrecedence[c - '!'];
+ else if (c == '^')
+ return 7;
+ else if (c == '|')
+ return 8;
+ else if (c == ANDAND)
+ return 9;
+ else if (c == OROR)
+ return 10;
+ else if (c == EQ || c == NEQ)
+ return 5;
+ else if (c == LE || c == GE || c == INSTANCEOF)
+ return 4;
+ else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT)
+ return 3;
+ else
+ return 0; // not a binary operator
}
/* unary.expr : "++"|"--" unary.expr
- | "+"|"-" unary.expr
- | "!"|"~" unary.expr
- | cast.expr
- | postfix.expr
+ | "+"|"-" unary.expr
+ | "!"|"~" unary.expr
+ | cast.expr
+ | postfix.expr
unary.expr.not.plus.minus is a unary expression starting without
"+", "-", "++", or "--".
*/
private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError {
- int t;
- switch (lex.lookAhead()) {
- case '+' :
- case '-' :
- case PLUSPLUS :
- case MINUSMINUS :
- case '!' :
- case '~' :
- t = lex.get();
- return new Expr(t, parseUnaryExpr(tbl));
- case '(' :
- return parseCast(tbl);
- default :
- return parsePostfix(tbl);
- }
+ int t;
+ switch (lex.lookAhead()) {
+ case '+' :
+ case '-' :
+ case PLUSPLUS :
+ case MINUSMINUS :
+ case '!' :
+ case '~' :
+ t = lex.get();
+ return new Expr(t, parseUnaryExpr(tbl));
+ case '(' :
+ return parseCast(tbl);
+ default :
+ return parsePostfix(tbl);
+ }
}
/* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr
- | "(" class.type ("[" "]")* ")" unary.expr2
+ | "(" class.type ("[" "]")* ")" unary.expr2
unary.expr2 is a unary.expr begining with "(", NULL, StringL,
Identifier, THIS, SUPER, or NEW.
*/
private ASTree parseCast(SymbolTable tbl) throws CompileError {
- int t = lex.lookAhead(1);
- if (isBuiltinType(t)) {
- lex.get(); // '('
- lex.get(); // primitive type
- int dim = parseArrayDimension();
- if (lex.get() != ')')
- throw new CompileError(") is missing", lex);
-
- return new CastExpr(t, dim, parseUnaryExpr(tbl));
- }
- else if (t == Identifier && nextIsClassCast()) {
- lex.get(); // '('
- ASTList name = parseClassType(tbl);
- int dim = parseArrayDimension();
- if (lex.get() != ')')
- throw new CompileError(") is missing", lex);
-
- return new CastExpr(name, dim, parseUnaryExpr(tbl));
- }
- else
- return parsePostfix(tbl);
+ int t = lex.lookAhead(1);
+ if (isBuiltinType(t)) {
+ lex.get(); // '('
+ lex.get(); // primitive type
+ int dim = parseArrayDimension();
+ if (lex.get() != ')')
+ throw new CompileError(") is missing", lex);
+
+ return new CastExpr(t, dim, parseUnaryExpr(tbl));
+ }
+ else if (t == Identifier && nextIsClassCast()) {
+ lex.get(); // '('
+ ASTList name = parseClassType(tbl);
+ int dim = parseArrayDimension();
+ if (lex.get() != ')')
+ throw new CompileError(") is missing", lex);
+
+ return new CastExpr(name, dim, parseUnaryExpr(tbl));
+ }
+ else
+ return parsePostfix(tbl);
}
private boolean nextIsClassCast() {
- int i = nextIsClassType(1);
- if (i < 0)
- return false;
-
- int t = lex.lookAhead(i);
- if (t != ')')
- return false;
-
- t = lex.lookAhead(i + 1);
- return t == '(' || t == NULL || t == StringL
- || t == Identifier || t == THIS || t == SUPER || t == NEW
- || t == TRUE || t == FALSE || t == LongConstant
- || t == IntConstant || t == CharConstant
- || t == DoubleConstant || t == FloatConstant;
+ int i = nextIsClassType(1);
+ if (i < 0)
+ return false;
+
+ int t = lex.lookAhead(i);
+ if (t != ')')
+ return false;
+
+ t = lex.lookAhead(i + 1);
+ return t == '(' || t == NULL || t == StringL
+ || t == Identifier || t == THIS || t == SUPER || t == NEW
+ || t == TRUE || t == FALSE || t == LongConstant
+ || t == IntConstant || t == CharConstant
+ || t == DoubleConstant || t == FloatConstant;
}
private int nextIsClassType(int i) {
- int t;
- while (lex.lookAhead(++i) == '.')
- if (lex.lookAhead(++i) != Identifier)
- return -1;
+ int t;
+ while (lex.lookAhead(++i) == '.')
+ if (lex.lookAhead(++i) != Identifier)
+ return -1;
- while ((t = lex.lookAhead(i++)) == '[')
- if (lex.lookAhead(i++) != ']')
- return -1;
+ while ((t = lex.lookAhead(i++)) == '[')
+ if (lex.lookAhead(i++) != ']')
+ return -1;
- return i - 1;
+ return i - 1;
}
/* array.dimension : [ "[" "]" ]*
*/
private int parseArrayDimension() throws CompileError {
- int arrayDim = 0;
- while (lex.lookAhead() == '[') {
- ++arrayDim;
- lex.get();
- if (lex.get() != ']')
- throw new CompileError("] is missing", lex);
- }
-
- return arrayDim;
+ int arrayDim = 0;
+ while (lex.lookAhead() == '[') {
+ ++arrayDim;
+ lex.get();
+ if (lex.get() != ']')
+ throw new CompileError("] is missing", lex);
+ }
+
+ return arrayDim;
}
/* class.type : Identifier ( "." Identifier )*
*/
private ASTList parseClassType(SymbolTable tbl) throws CompileError {
- ASTList list = null;
- for (;;) {
- if (lex.get() != Identifier)
- throw new SyntaxError(lex);
-
- list = ASTList.append(list, new Symbol(lex.getString()));
- if (lex.lookAhead() == '.')
- lex.get();
- else
- break;
- }
-
- return list;
+ ASTList list = null;
+ for (;;) {
+ if (lex.get() != Identifier)
+ throw new SyntaxError(lex);
+
+ list = ASTList.append(list, new Symbol(lex.getString()));
+ if (lex.lookAhead() == '.')
+ lex.get();
+ else
+ break;
+ }
+
+ return list;
}
/* postfix.expr : number.literal
- * | primary.expr
- * | method.expr
- * | postfix.expr "++" | "--"
- * | postfix.expr "[" array.size "]"
- * | postfix.expr "." Identifier
- * | postfix.expr "#" Identifier
+ * | primary.expr
+ * | method.expr
+ * | postfix.expr "++" | "--"
+ * | postfix.expr "[" array.size "]"
+ * | postfix.expr "." Identifier
+ * | postfix.expr "#" Identifier
*
* "#" is not an operator of regular Java. It separates
* a class name and a member name in an expression for static member
* access. For example,
- * java.lang.Integer.toString(3) in regular Java
+ * java.lang.Integer.toString(3) in regular Java
* must be written like this:
- * java.lang.Integer#toString(3) for this compiler.
+ * java.lang.Integer#toString(3) for this compiler.
*/
private ASTree parsePostfix(SymbolTable tbl) throws CompileError {
- int token = lex.lookAhead();
- switch (token) {
- case LongConstant :
- case IntConstant :
- case CharConstant :
- lex.get();
- return new IntConst(lex.getLong(), token);
- case DoubleConstant :
- case FloatConstant :
- lex.get();
- return new DoubleConst(lex.getDouble(), token);
- default :
- break;
- }
-
- String str;
- ASTree index;
- ASTree expr = parsePrimaryExpr(tbl);
- int t;
- while (true) {
- switch (lex.lookAhead()) {
- case '(' :
- expr = parseMethodCall(tbl, expr);
- break;
- case '[' :
- index = parseArrayIndex(tbl);
- if (index == null)
- throw new SyntaxError(lex);
-
- expr = Expr.make(ARRAY, expr, index);
- break;
- case PLUSPLUS :
- case MINUSMINUS :
- t = lex.get();
- expr = Expr.make(t, null, expr);
- break;
- case '.' :
- lex.get();
- if (lex.get() != Identifier)
- throw new CompileError("missing member name", lex);
-
- expr = Expr.make('.', expr, new Member(lex.getString()));
- break;
- case '#' :
- lex.get();
- t = lex.get();
- if (t == CLASS)
- str = "class";
- else if (t == Identifier)
- str = lex.getString();
- else
- throw new CompileError("missing static member name", lex);
-
- expr = Expr.make(MEMBER, toClassName(expr, null),
- new Member(str));
- break;
- default :
- return expr;
- }
- }
+ int token = lex.lookAhead();
+ switch (token) {
+ case LongConstant :
+ case IntConstant :
+ case CharConstant :
+ lex.get();
+ return new IntConst(lex.getLong(), token);
+ case DoubleConstant :
+ case FloatConstant :
+ lex.get();
+ return new DoubleConst(lex.getDouble(), token);
+ default :
+ break;
+ }
+
+ String str;
+ ASTree index;
+ ASTree expr = parsePrimaryExpr(tbl);
+ int t;
+ while (true) {
+ switch (lex.lookAhead()) {
+ case '(' :
+ expr = parseMethodCall(tbl, expr);
+ break;
+ case '[' :
+ index = parseArrayIndex(tbl);
+ if (index == null)
+ throw new SyntaxError(lex);
+
+ expr = Expr.make(ARRAY, expr, index);
+ break;
+ case PLUSPLUS :
+ case MINUSMINUS :
+ t = lex.get();
+ expr = Expr.make(t, null, expr);
+ break;
+ case '.' :
+ lex.get();
+ if (lex.get() != Identifier)
+ throw new CompileError("missing member name", lex);
+
+ expr = Expr.make('.', expr, new Member(lex.getString()));
+ break;
+ case '#' :
+ lex.get();
+ t = lex.get();
+ if (t == CLASS)
+ str = "class";
+ else if (t == Identifier)
+ str = lex.getString();
+ else
+ throw new CompileError("missing static member name", lex);
+
+ expr = Expr.make(MEMBER, toClassName(expr, null),
+ new Member(str));
+ break;
+ default :
+ return expr;
+ }
+ }
}
/* method.call : method.expr "(" argument.list ")"
* method.expr : THIS | SUPER | Identifier
- * | postfix.expr "." Identifier
- * | postfix.expr "#" Identifier
+ * | postfix.expr "." Identifier
+ * | postfix.expr "#" Identifier
*/
private ASTree parseMethodCall(SymbolTable tbl, ASTree expr)
- throws CompileError
+ throws CompileError
{
- if (expr instanceof Keyword) {
- int token = ((Keyword)expr).get();
- if (token != THIS && token != SUPER)
- throw new SyntaxError(lex);
- }
- else if (expr instanceof Symbol) // Identifier
- ;
- else if (expr instanceof Expr) {
- int op = ((Expr)expr).getOperator();
- if (op != '.' && op != MEMBER)
- throw new SyntaxError(lex);
- }
-
- return Expr.make(CALL, expr, parseArgumentList(tbl));
+ if (expr instanceof Keyword) {
+ int token = ((Keyword)expr).get();
+ if (token != THIS && token != SUPER)
+ throw new SyntaxError(lex);
+ }
+ else if (expr instanceof Symbol) // Identifier
+ ;
+ else if (expr instanceof Expr) {
+ int op = ((Expr)expr).getOperator();
+ if (op != '.' && op != MEMBER)
+ throw new SyntaxError(lex);
+ }
+
+ return Expr.make(CALL, expr, parseArgumentList(tbl));
}
private ASTList toClassName(ASTree name, ASTList tail)
- throws CompileError
+ throws CompileError
{
- if (name instanceof Symbol)
- return new ASTList(name, tail);
- else if (name instanceof Expr) {
- Expr expr = (Expr)name;
- if (expr.getOperator() == '.')
- return toClassName(expr.oprand1(),
- new ASTList(expr.oprand2(), tail));
- }
-
- throw new CompileError("bad static member access", lex);
+ if (name instanceof Symbol)
+ return new ASTList(name, tail);
+ else if (name instanceof Expr) {
+ Expr expr = (Expr)name;
+ if (expr.getOperator() == '.')
+ return toClassName(expr.oprand1(),
+ new ASTList(expr.oprand2(), tail));
+ }
+
+ throw new CompileError("bad static member access", lex);
}
/* primary.expr : THIS | SUPER | TRUE | FALSE | NULL
- * | StringL
- * | Identifier
- * | NEW new.expr
- * | "(" expression ")"
+ * | StringL
+ * | Identifier
+ * | NEW new.expr
+ * | "(" expression ")"
*
* Identifier represents either a local variable name, a member name,
* or a class name.
*/
private ASTree parsePrimaryExpr(SymbolTable tbl) throws CompileError {
- int t;
- String name;
- Declarator decl;
- ASTree expr;
-
- switch (t = lex.get()) {
- case THIS :
- case SUPER :
- case TRUE :
- case FALSE :
- case NULL :
- return new Keyword(t);
- case Identifier :
- name = lex.getString();
- decl = tbl.lookup(name);
- if (decl == null)
- return new Member(name); // this or static member
- else
- return new Variable(name, decl); // local variable
- case StringL :
- return new StringL(lex.getString());
- case NEW :
- return parseNew(tbl);
- case '(' :
- expr = parseExpression(tbl);
- if (lex.get() == ')')
- return expr;
- else
- throw new CompileError(") is missing", lex);
- default :
- throw new SyntaxError(lex);
- }
+ int t;
+ String name;
+ Declarator decl;
+ ASTree expr;
+
+ switch (t = lex.get()) {
+ case THIS :
+ case SUPER :
+ case TRUE :
+ case FALSE :
+ case NULL :
+ return new Keyword(t);
+ case Identifier :
+ name = lex.getString();
+ decl = tbl.lookup(name);
+ if (decl == null)
+ return new Member(name); // this or static member
+ else
+ return new Variable(name, decl); // local variable
+ case StringL :
+ return new StringL(lex.getString());
+ case NEW :
+ return parseNew(tbl);
+ case '(' :
+ expr = parseExpression(tbl);
+ if (lex.get() == ')')
+ return expr;
+ else
+ throw new CompileError(") is missing", lex);
+ default :
+ throw new SyntaxError(lex);
+ }
}
/* new.expr : class.type "(" argument.list ")"
- * | class.type array.size [ array.initializer ]
- * | primitive.type array.size [ array.initializer ]
+ * | class.type array.size [ array.initializer ]
+ * | primitive.type array.size [ array.initializer ]
*/
private NewExpr parseNew(SymbolTable tbl) throws CompileError {
- ASTree init = null;
- int t = lex.lookAhead();
- if (isBuiltinType(t)) {
- lex.get();
- ASTList size = parseArraySize(tbl);
- if (lex.lookAhead() == '{')
- init = parseArrayInitializer(tbl);
-
- return new NewExpr(t, size, init);
- }
- else if (t == Identifier) {
- ASTList name = parseClassType(tbl);
- t = lex.lookAhead();
- if (t == '(') {
- ASTList args = parseArgumentList(tbl);
- return new NewExpr(name, args);
- }
- else if (t == '[') {
- ASTList size = parseArraySize(tbl);
- if (lex.lookAhead() == '{')
- init = parseArrayInitializer(tbl);
-
- return NewExpr.makeObjectArray(name, size, init);
- }
- }
-
- throw new SyntaxError(lex);
+ ASTree init = null;
+ int t = lex.lookAhead();
+ if (isBuiltinType(t)) {
+ lex.get();
+ ASTList size = parseArraySize(tbl);
+ if (lex.lookAhead() == '{')
+ init = parseArrayInitializer(tbl);
+
+ return new NewExpr(t, size, init);
+ }
+ else if (t == Identifier) {
+ ASTList name = parseClassType(tbl);
+ t = lex.lookAhead();
+ if (t == '(') {
+ ASTList args = parseArgumentList(tbl);
+ return new NewExpr(name, args);
+ }
+ else if (t == '[') {
+ ASTList size = parseArraySize(tbl);
+ if (lex.lookAhead() == '{')
+ init = parseArrayInitializer(tbl);
+
+ return NewExpr.makeObjectArray(name, size, init);
+ }
+ }
+
+ throw new SyntaxError(lex);
}
/* array.size : [ array.index ]*
*/
private ASTList parseArraySize(SymbolTable tbl) throws CompileError {
- ASTList list = null;
- while (lex.lookAhead() == '[')
- list = ASTList.append(list, parseArrayIndex(tbl));
+ ASTList list = null;
+ while (lex.lookAhead() == '[')
+ list = ASTList.append(list, parseArrayIndex(tbl));
- return list;
+ return list;
}
/* array.index : "[" [ expression ] "]"
*/
private ASTree parseArrayIndex(SymbolTable tbl) throws CompileError {
- lex.get(); // '['
- if (lex.lookAhead() == ']') {
- lex.get();
- return null;
- }
- else {
- ASTree index = parseExpression(tbl);
- if (lex.get() != ']')
- throw new CompileError("] is missing", lex);
-
- return index;
- }
+ lex.get(); // '['
+ if (lex.lookAhead() == ']') {
+ lex.get();
+ return null;
+ }
+ else {
+ ASTree index = parseExpression(tbl);
+ if (lex.get() != ']')
+ throw new CompileError("] is missing", lex);
+
+ return index;
+ }
}
/* argument.list : "(" [ expression [ "," expression ]* ] ")"
*/
private ASTList parseArgumentList(SymbolTable tbl) throws CompileError {
- if (lex.get() != '(')
- throw new CompileError("( is missing", lex);
-
- ASTList list = null;
- if (lex.lookAhead() != ')')
- for (;;) {
- list = ASTList.append(list, parseExpression(tbl));
- if (lex.lookAhead() == ',')
- lex.get();
- else
- break;
- }
-
- if (lex.get() != ')')
- throw new CompileError(") is missing", lex);
-
- return list;
+ if (lex.get() != '(')
+ throw new CompileError("( is missing", lex);
+
+ ASTList list = null;
+ if (lex.lookAhead() != ')')
+ for (;;) {
+ list = ASTList.append(list, parseExpression(tbl));
+ if (lex.lookAhead() == ',')
+ lex.get();
+ else
+ break;
+ }
+
+ if (lex.get() != ')')
+ throw new CompileError(") is missing", lex);
+
+ return list;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import javassist.bytecode.Bytecode;
*/
public interface ProceedHandler {
void doit(JvstCodeGen gen, Bytecode b, ASTList args)
- throws CompileError;
+ throws CompileError;
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
import java.util.HashMap;
public SymbolTable() { this(null); }
public SymbolTable(SymbolTable p) {
- super();
- parent = p;
+ super();
+ parent = p;
}
public SymbolTable getParent() { return parent; }
public Declarator lookup(String name) {
- Declarator found = (Declarator)get(name);
- if (found == null && parent != null)
- return parent.lookup(name);
- else
- return found;
+ Declarator found = (Declarator)get(name);
+ if (found == null && parent != null)
+ return parent.lookup(name);
+ else
+ return found;
}
public void append(String name, Declarator value) {
- put(name, value);
+ put(name, value);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
public class SyntaxError extends CompileError {
public SyntaxError(Lex l) {
- super("syntax error", l);
+ super("syntax error", l);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler;
public interface TokenId {
int CATCH = 305;
int CHAR = 306;
int CLASS = 307;
- int CONST = 308; // reserved keyword
+ int CONST = 308; // reserved keyword
int CONTINUE = 309;
int DEFAULT = 310;
int DO = 311;
int FINALLY = 316;
int FLOAT = 317;
int FOR = 318;
- int GOTO = 319; // reserved keyword
+ int GOTO = 319; // reserved keyword
int IF = 320;
int IMPLEMENTS = 321;
int IMPORT = 322;
int WHILE = 346;
int STRICT = 347;
- int NEQ = 350; // !=
- int MOD_E = 351; // %=
- int AND_E = 352; // &=
- int MUL_E = 353; // *=
- int PLUS_E = 354; // +=
- int MINUS_E = 355; // -=
- int DIV_E = 356; // /=
- int LE = 357; // <=
- int EQ = 358; // ==
- int GE = 359; // >=
- int EXOR_E = 360; // ^=
- int OR_E = 361; // |=
- int PLUSPLUS = 362; // ++
- int MINUSMINUS = 363; // --
- int LSHIFT = 364; // <<
- int LSHIFT_E = 365; // <<=
- int RSHIFT = 366; // >>
- int RSHIFT_E = 367; // >>=
- int OROR = 368; // ||
- int ANDAND = 369; // &&
- int ARSHIFT = 370; // >>>
- int ARSHIFT_E = 371; // >>>=
+ int NEQ = 350; // !=
+ int MOD_E = 351; // %=
+ int AND_E = 352; // &=
+ int MUL_E = 353; // *=
+ int PLUS_E = 354; // +=
+ int MINUS_E = 355; // -=
+ int DIV_E = 356; // /=
+ int LE = 357; // <=
+ int EQ = 358; // ==
+ int GE = 359; // >=
+ int EXOR_E = 360; // ^=
+ int OR_E = 361; // |=
+ int PLUSPLUS = 362; // ++
+ int MINUSMINUS = 363; // --
+ int LSHIFT = 364; // <<
+ int LSHIFT_E = 365; // <<=
+ int RSHIFT = 366; // >>
+ int RSHIFT_E = 367; // >>=
+ int OROR = 368; // ||
+ int ANDAND = 369; // &&
+ int ARSHIFT = 370; // >>>
+ int ARSHIFT_E = 371; // >>>=
// operators from NEQ to ARSHIFT_E
String opNames[] = { "!=", "%=", "&=", "*=", "+=", "-=", "/=",
- "<=", "==", ">=", "^=", "|=", "++", "--",
- "<<", "<<=", ">>", ">>=", "||", "&&", ">>>",
- ">>>=" };
+ "<=", "==", ">=", "^=", "|=", "++", "--",
+ "<<", "<<=", ">>", ">>=", "||", "&&", ">>>",
+ ">>>=" };
// operators from MOD_E to ARSHIFT_E
int assignOps[] = { '%', '&', '*', '+', '-', '/', 0, 0, 0,
- '^', '|', 0, 0, 0, LSHIFT, 0, RSHIFT, 0, 0, 0,
- ARSHIFT };
+ '^', '|', 0, 0, 0, LSHIFT, 0, RSHIFT, 0, 0, 0,
+ ARSHIFT };
int Identifier = 400;
int CharConstant = 401;
int FALSE = 411;
int NULL = 412;
- int CALL = 'C'; // method call
- int ARRAY = 'A'; // array access
- int MEMBER = '#'; // static member access
+ int CALL = 'C'; // method call
+ int ARRAY = 'A'; // array access
+ int MEMBER = '#'; // static member access
- int EXPR = 'E'; // expression statement
- int LABEL = 'L'; // label statement
- int BLOCK = 'B'; // block statement
- int DECL = 'D'; // declaration statement
+ int EXPR = 'E'; // expression statement
+ int LABEL = 'L'; // label statement
+ int BLOCK = 'B'; // block statement
+ int DECL = 'D'; // declaration statement
int BadToken = 500;
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
private ASTList right;
public ASTList(ASTree _head, ASTList _tail) {
- left = _head;
- right = _tail;
+ left = _head;
+ right = _tail;
}
public ASTList(ASTree _head) {
- left = _head;
- right = null;
+ left = _head;
+ right = null;
}
public static ASTList make(ASTree e1, ASTree e2, ASTree e3) {
- return new ASTList(e1, new ASTList(e2, new ASTList(e3)));
+ return new ASTList(e1, new ASTList(e2, new ASTList(e3)));
}
public ASTree getLeft() { return left; }
public void setLeft(ASTree _left) { left = _left; }
public void setRight(ASTree _right) {
- right = (ASTList)_right;
+ right = (ASTList)_right;
}
/**
public ASTree head() { return left; }
public void setHead(ASTree _head) {
- left = _head;
+ left = _head;
}
/**
public ASTList tail() { return right; }
public void setTail(ASTList _tail) {
- right = _tail;
+ right = _tail;
}
public void accept(Visitor v) throws CompileError { v.atASTList(this); }
public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("(<");
- sbuf.append(getTag());
- sbuf.append('>');
- ASTList list = this;
- while (list != null) {
- sbuf.append(' ');
- ASTree a = list.left;
- sbuf.append(a == null ? "<null>" : a.toString());
- list = list.right;
- }
-
- sbuf.append(')');
- return sbuf.toString();
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append("(<");
+ sbuf.append(getTag());
+ sbuf.append('>');
+ ASTList list = this;
+ while (list != null) {
+ sbuf.append(' ');
+ ASTree a = list.left;
+ sbuf.append(a == null ? "<null>" : a.toString());
+ list = list.right;
+ }
+
+ sbuf.append(')');
+ return sbuf.toString();
}
/**
* Returns the number of the elements in this list.
*/
public int length() {
- return length(this);
+ return length(this);
}
public static int length(ASTList list) {
- if (list == null)
- return 0;
+ if (list == null)
+ return 0;
- int n = 0;
- while (list != null) {
- list = list.right;
- ++n;
- }
+ int n = 0;
+ while (list != null) {
+ list = list.right;
+ ++n;
+ }
- return n;
+ return n;
}
/**
* Returns a sub list of the list. The sub list begins with the
* n-th element of the list.
*
- * @param nth zero or more than zero.
+ * @param nth zero or more than zero.
*/
public ASTList sublist(int nth) {
- ASTList list = this;
- while (nth-- > 0)
- list = list.right;
+ ASTList list = this;
+ while (nth-- > 0)
+ list = list.right;
- return list;
+ return list;
}
/**
* list.
*/
public boolean subst(ASTree newObj, ASTree oldObj) {
- for (ASTList list = this; list != null; list = list.right)
- if (list.left == oldObj) {
- list.left = newObj;
- return true;
- }
+ for (ASTList list = this; list != null; list = list.right)
+ if (list.left == oldObj) {
+ list.left = newObj;
+ return true;
+ }
- return false;
+ return false;
}
/**
* Appends an object to a list.
*/
public static ASTList append(ASTList a, ASTree b) {
- return concat(a, new ASTList(b));
+ return concat(a, new ASTList(b));
}
/**
* Concatenates two lists.
*/
public static ASTList concat(ASTList a, ASTList b) {
- if (a == null)
- return b;
- else {
- ASTList list = a;
- while (list.right != null)
- list = list.right;
-
- list.right = b;
- return a;
- }
+ if (a == null)
+ return b;
+ else {
+ ASTList list = a;
+ while (list.right != null)
+ list = list.right;
+
+ list.right = b;
+ return a;
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import java.io.Serializable;
public abstract void accept(Visitor v) throws CompileError;
public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append('<');
- sbuf.append(getTag());
- sbuf.append('>');
- return sbuf.toString();
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append('<');
+ sbuf.append(getTag());
+ sbuf.append('>');
+ return sbuf.toString();
}
/**
* <code>toString()</code>.
*/
protected String getTag() {
- String name = getClass().getName();
- return name.substring(name.lastIndexOf('.') + 1);
+ String name = getClass().getName();
+ return name.substring(name.lastIndexOf('.') + 1);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
*/
public AssignExpr(int op, ASTree _head, ASTList _tail) {
- super(op, _head, _tail);
+ super(op, _head, _tail);
}
public static AssignExpr makeAssign(int op, ASTree oprand1,
- ASTree oprand2) {
- return new AssignExpr(op, oprand1, new ASTList(oprand2));
+ ASTree oprand2) {
+ return new AssignExpr(op, oprand1, new ASTList(oprand2));
}
public void accept(Visitor v) throws CompileError {
- v.atAssignExpr(this);
+ v.atAssignExpr(this);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
*/
public BinExpr(int op, ASTree _head, ASTList _tail) {
- super(op, _head, _tail);
+ super(op, _head, _tail);
}
public static BinExpr makeBin(int op, ASTree oprand1, ASTree oprand2) {
- return new BinExpr(op, oprand1, new ASTList(oprand2));
+ return new BinExpr(op, oprand1, new ASTList(oprand2));
}
public void accept(Visitor v) throws CompileError { v.atBinExpr(this); }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.TokenId;
protected int arrayDim;
public CastExpr(ASTList className, int dim, ASTree expr) {
- super(className, new ASTList(expr));
- castType = CLASS;
- arrayDim = dim;
+ super(className, new ASTList(expr));
+ castType = CLASS;
+ arrayDim = dim;
}
public CastExpr(int type, int dim, ASTree expr) {
- super(null, new ASTList(expr));
- castType = type;
- arrayDim = dim;
+ super(null, new ASTList(expr));
+ castType = type;
+ arrayDim = dim;
}
/* Returns CLASS, BOOLEAN, INT, or ...
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
*/
public class CondExpr extends ASTList {
public CondExpr(ASTree cond, ASTree thenp, ASTree elsep) {
- super(cond, new ASTList(thenp, new ASTList(elsep)));
+ super(cond, new ASTList(thenp, new ASTList(elsep)));
}
public ASTree condExpr() { return head(); }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.TokenId;
protected int varType;
protected int arrayDim;
protected int localVar;
- protected String qualifiedClass; // JVM-internal representation
+ protected String qualifiedClass; // JVM-internal representation
public Declarator(int type, int dim) {
- super(null);
- varType = type;
- arrayDim = dim;
- localVar = -1;
- qualifiedClass = null;
+ super(null);
+ varType = type;
+ arrayDim = dim;
+ localVar = -1;
+ qualifiedClass = null;
}
public Declarator(ASTList className, int dim) {
- super(null);
- varType = CLASS;
- arrayDim = dim;
- localVar = -1;
- qualifiedClass = astToClassName(className, '/');
+ super(null);
+ varType = CLASS;
+ arrayDim = dim;
+ localVar = -1;
+ qualifiedClass = astToClassName(className, '/');
}
/* For declaring a pre-defined? local variable.
*/
public Declarator(int type, String jvmClassName, int dim,
- int var, Symbol sym) {
- super(null);
- varType = type;
- arrayDim = dim;
- localVar = var;
- qualifiedClass = jvmClassName;
- setLeft(sym);
- append(this, null); // initializer
+ int var, Symbol sym) {
+ super(null);
+ varType = type;
+ arrayDim = dim;
+ localVar = var;
+ qualifiedClass = jvmClassName;
+ setLeft(sym);
+ append(this, null); // initializer
}
public Declarator make(Symbol sym, int dim, ASTree init) {
- Declarator d = new Declarator(this.varType, this.arrayDim + dim);
- d.qualifiedClass = this.qualifiedClass;
- d.setLeft(sym);
- d.append(d, init);
- return d;
+ Declarator d = new Declarator(this.varType, this.arrayDim + dim);
+ d.qualifiedClass = this.qualifiedClass;
+ d.setLeft(sym);
+ d.append(d, init);
+ return d;
}
/* Returns CLASS, BOOLEAN, BYTE, CHAR, SHORT, INT, LONG, FLOAT,
public void setVariable(Symbol sym) { setLeft(sym); }
public ASTree getInitializer() {
- ASTList t = tail();
- if (t != null)
- return t.head();
- else
- return null;
+ ASTList t = tail();
+ if (t != null)
+ return t.head();
+ else
+ return null;
}
public void setLocalVar(int n) { localVar = n; }
public String getTag() { return "decl"; }
public void accept(Visitor v) throws CompileError {
- v.atDeclarator(this);
+ v.atDeclarator(this);
}
public static String astToClassName(ASTList name, char sep) {
- if (name == null)
- return null;
+ if (name == null)
+ return null;
- StringBuffer sbuf = new StringBuffer();
- for (;;) {
- sbuf.append(((Symbol)name.head()).get());
- name = name.tail();
- if (name == null)
- break;
+ StringBuffer sbuf = new StringBuffer();
+ for (;;) {
+ sbuf.append(((Symbol)name.head()).get());
+ name = name.tail();
+ if (name == null)
+ break;
- sbuf.append(sep);
- }
+ sbuf.append(sep);
+ }
- return sbuf.toString();
+ return sbuf.toString();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
public String toString() { return Double.toString(value); }
public void accept(Visitor v) throws CompileError {
- v.atDoubleConst(this);
+ v.atDoubleConst(this);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.TokenId;
protected int operatorId;
public Expr(int op, ASTree _head, ASTList _tail) {
- super(_head, _tail);
- operatorId = op;
+ super(_head, _tail);
+ operatorId = op;
}
public Expr(int op, ASTree _head) {
- super(_head);
- operatorId = op;
+ super(_head);
+ operatorId = op;
}
public static Expr make(int op, ASTree oprand1, ASTree oprand2) {
- return new Expr(op, oprand1, new ASTList(oprand2));
+ return new Expr(op, oprand1, new ASTList(oprand2));
}
public int getOperator() { return operatorId; }
public void accept(Visitor v) throws CompileError { v.atExpr(this); }
public String getName() {
- int id = operatorId;
- if (id < 128)
- return String.valueOf((char)id);
- else if (NEQ <= id && id <= ARSHIFT_E)
- return opNames[id - NEQ];
- else if (id == INSTANCEOF)
- return "instanceof";
- else
- return String.valueOf(id);
+ int id = operatorId;
+ if (id < 128)
+ return String.valueOf((char)id);
+ else if (NEQ <= id && id <= ARSHIFT_E)
+ return opNames[id - NEQ];
+ else if (id == INSTANCEOF)
+ return "instanceof";
+ else
+ return String.valueOf(id);
}
protected String getTag() {
- return "op:" + getName();
+ return "op:" + getName();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
public class FieldDecl extends ASTList {
public FieldDecl(ASTree _head, ASTList _tail) {
- super(_head, _tail);
+ super(_head, _tail);
}
public ASTList getModifiers() { return (ASTList)getLeft(); }
public ASTree getInit() { return (ASTree)sublist(2).head(); }
public void accept(Visitor v) throws CompileError {
- v.atFieldDecl(this);
+ v.atFieldDecl(this);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
*/
public class InstanceOfExpr extends CastExpr {
public InstanceOfExpr(ASTList className, int dim, ASTree expr) {
- super(className, dim, expr);
+ super(className, dim, expr);
}
public InstanceOfExpr(int type, int dim, ASTree expr) {
- super(type, dim, expr);
+ super(type, dim, expr);
}
public String getTag() {
- return "instanceof:" + castType + ":" + arrayDim;
+ return "instanceof:" + castType + ":" + arrayDim;
}
public void accept(Visitor v) throws CompileError {
- v.atInstanceOfExpr(this);
+ v.atInstanceOfExpr(this);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
public String toString() { return Long.toString(value); }
public void accept(Visitor v) throws CompileError {
- v.atIntConst(this);
+ v.atIntConst(this);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
protected int tokenId;
public Keyword(int token) {
- tokenId = token;
+ tokenId = token;
}
public int get() { return tokenId; }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
*/
public class Member extends Symbol {
public Member(String name) {
- super(name);
+ super(name);
}
public void accept(Visitor v) throws CompileError { v.atMember(this); }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
public static final String initName = "<init>";
public MethodDecl(ASTree _head, ASTList _tail) {
- super(_head, _tail);
+ super(_head, _tail);
}
public boolean isConstructor() {
- Symbol sym = getReturn().getVariable();
- return sym != null && initName.equals(sym.get());
+ Symbol sym = getReturn().getVariable();
+ return sym != null && initName.equals(sym.get());
}
public ASTList getModifiers() { return (ASTList)getLeft(); }
public Stmnt getBody() { return (Stmnt)sublist(4).head(); }
public void accept(Visitor v) throws CompileError {
- v.atMethodDecl(this);
+ v.atMethodDecl(this);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.TokenId;
protected int arrayType;
public NewExpr(ASTList className, ASTList args) {
- super(className, new ASTList(args));
- newArray = false;
- arrayType = CLASS;
+ super(className, new ASTList(args));
+ newArray = false;
+ arrayType = CLASS;
}
public NewExpr(int type, ASTList arraySize, ASTree init) {
- super(null, new ASTList(arraySize));
- newArray = true;
- arrayType = type;
- if (init != null)
- append(this, init);
+ super(null, new ASTList(arraySize));
+ newArray = true;
+ arrayType = type;
+ if (init != null)
+ append(this, init);
}
public static NewExpr makeObjectArray(ASTList className,
- ASTList arraySize, ASTree init) {
- NewExpr e = new NewExpr(className, arraySize);
- e.newArray = true;
- if (init != null)
- append(e, init);
+ ASTList arraySize, ASTree init) {
+ NewExpr e = new NewExpr(className, arraySize);
+ e.newArray = true;
+ if (init != null)
+ append(e, init);
- return e;
+ return e;
}
public boolean isArray() { return newArray; }
public ASTList getArraySize() { return getArguments(); }
public ASTree getInitializer() {
- ASTree t = getRight().getRight();
- if (t == null)
- return null;
- else
- return t.getLeft();
+ ASTree t = getRight().getRight();
+ if (t == null)
+ return null;
+ else
+ return t.getLeft();
}
public void accept(Visitor v) throws CompileError { v.atNewExpr(this); }
protected String getTag() {
- return newArray ? "new[]" : "new";
+ return newArray ? "new[]" : "new";
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
protected ASTree left, right;
public Pair(ASTree _left, ASTree _right) {
- left = _left;
- right = _right;
+ left = _left;
+ right = _right;
}
public void accept(Visitor v) throws CompileError { v.atPair(this); }
public String toString() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("(<Pair> ");
- sbuf.append(left == null ? "<null>" : left.toString());
- sbuf.append(" . ");
- sbuf.append(right == null ? "<null>" : right.toString());
- sbuf.append(')');
- return sbuf.toString();
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append("(<Pair> ");
+ sbuf.append(left == null ? "<null>" : left.toString());
+ sbuf.append(" . ");
+ sbuf.append(right == null ? "<null>" : right.toString());
+ sbuf.append(')');
+ return sbuf.toString();
}
public ASTree getLeft() { return left; }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.TokenId;
protected int operatorId;
public Stmnt(int op, ASTree _head, ASTList _tail) {
- super(_head, _tail);
- operatorId = op;
+ super(_head, _tail);
+ operatorId = op;
}
public Stmnt(int op, ASTree _head) {
- super(_head);
- operatorId = op;
+ super(_head);
+ operatorId = op;
}
public Stmnt(int op) {
- this(op, null);
+ this(op, null);
}
public static Stmnt make(int op, ASTree oprand1, ASTree oprand2) {
- return new Stmnt(op, oprand1, new ASTList(oprand2));
+ return new Stmnt(op, oprand1, new ASTList(oprand2));
}
public static Stmnt make(int op, ASTree op1, ASTree op2, ASTree op3) {
- return new Stmnt(op, op1, new ASTList(op2, new ASTList(op3)));
+ return new Stmnt(op, op1, new ASTList(op2, new ASTList(op3)));
}
public void accept(Visitor v) throws CompileError { v.atStmnt(this); }
public int getOperator() { return operatorId; }
protected String getTag() {
- if (operatorId < 128)
- return "stmnt:" + (char)operatorId;
- else
- return "stmnt:" + operatorId;
+ if (operatorId < 128)
+ return "stmnt:" + (char)operatorId;
+ else
+ return "stmnt:" + operatorId;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
protected String text;
public StringL(String t) {
- text = t;
+ text = t;
}
public String get() { return text; }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
protected String identifier;
public Symbol(String sym) {
- identifier = sym;
+ identifier = sym;
}
public String get() { return identifier; }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
protected Declarator declarator;
public Variable(String sym, Declarator d) {
- super(sym);
- declarator = d;
+ super(sym);
+ declarator = d;
}
public Declarator getDeclarator() { return declarator; }
public String toString() {
- return identifier + ":" + declarator.getType();
+ return identifier + ":" + declarator.getType();
}
public void accept(Visitor v) throws CompileError { v.atVariable(this); }
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.compiler.ast;
import javassist.compiler.CompileError;
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.CtClass;
public class TransformAfter extends TransformBefore {
public TransformAfter(Transformer next,
- CtMethod origMethod, CtMethod afterMethod)
- throws NotFoundException
+ CtMethod origMethod, CtMethod afterMethod)
+ throws NotFoundException
{
- super(next, origMethod, afterMethod);
+ super(next, origMethod, afterMethod);
}
protected int match2(int pos, CodeIterator iterator) throws BadBytecode {
- iterator.move(pos);
- iterator.insert(saveCode);
- iterator.insert(loadCode);
- int p = iterator.insertGap(3);
- iterator.insert(loadCode);
- pos = iterator.next();
- iterator.writeByte(iterator.byteAt(pos), p);
- iterator.write16bit(iterator.u16bitAt(pos + 1), p + 1);
- iterator.writeByte(INVOKESTATIC, pos);
- iterator.write16bit(newIndex, pos + 1);
- iterator.move(p);
- return iterator.next();
+ iterator.move(pos);
+ iterator.insert(saveCode);
+ iterator.insert(loadCode);
+ int p = iterator.insertGap(3);
+ iterator.insert(loadCode);
+ pos = iterator.next();
+ iterator.writeByte(iterator.byteAt(pos), p);
+ iterator.write16bit(iterator.u16bitAt(pos + 1), p + 1);
+ iterator.writeByte(INVOKESTATIC, pos);
+ iterator.write16bit(newIndex, pos + 1);
+ iterator.move(p);
+ return iterator.next();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.CtClass;
protected byte[] saveCode, loadCode;
public TransformBefore(Transformer next,
- CtMethod origMethod, CtMethod beforeMethod)
- throws NotFoundException
+ CtMethod origMethod, CtMethod beforeMethod)
+ throws NotFoundException
{
- super(next, origMethod, beforeMethod);
- parameterTypes = origMethod.getParameterTypes();
- locals = 0;
- maxLocals = 0;
- saveCode = loadCode = null;
+ super(next, origMethod, beforeMethod);
+ parameterTypes = origMethod.getParameterTypes();
+ locals = 0;
+ maxLocals = 0;
+ saveCode = loadCode = null;
}
public void initialize(ConstPool cp, CodeAttribute attr) {
- super.initialize(cp, attr);
- locals = 0;
- maxLocals = attr.getMaxLocals();
- saveCode = loadCode = null;
+ super.initialize(cp, attr);
+ locals = 0;
+ maxLocals = attr.getMaxLocals();
+ saveCode = loadCode = null;
}
protected int match(int c, int pos, CodeIterator iterator,
- int typedesc, ConstPool cp) throws BadBytecode
+ int typedesc, ConstPool cp) throws BadBytecode
{
- if (newIndex == 0) {
- String desc = Descriptor.ofParameters(parameterTypes) + 'V';
- desc = Descriptor.insertParameter(classname, desc);
- int nt = cp.addNameAndTypeInfo(newMethodname, desc);
- int ci = cp.addClassInfo(newClassname);
- newIndex = cp.addMethodrefInfo(ci, nt);
- constPool = cp;
- }
+ if (newIndex == 0) {
+ String desc = Descriptor.ofParameters(parameterTypes) + 'V';
+ desc = Descriptor.insertParameter(classname, desc);
+ int nt = cp.addNameAndTypeInfo(newMethodname, desc);
+ int ci = cp.addClassInfo(newClassname);
+ newIndex = cp.addMethodrefInfo(ci, nt);
+ constPool = cp;
+ }
- if (saveCode == null)
- makeCode(parameterTypes, cp);
+ if (saveCode == null)
+ makeCode(parameterTypes, cp);
- return match2(pos, iterator);
+ return match2(pos, iterator);
}
protected int match2(int pos, CodeIterator iterator) throws BadBytecode {
- iterator.move(pos);
- iterator.insert(saveCode);
- iterator.insert(loadCode);
- int p = iterator.insertGap(3);
- iterator.writeByte(INVOKESTATIC, p);
- iterator.write16bit(newIndex, p + 1);
- iterator.insert(loadCode);
- return iterator.next();
+ iterator.move(pos);
+ iterator.insert(saveCode);
+ iterator.insert(loadCode);
+ int p = iterator.insertGap(3);
+ iterator.writeByte(INVOKESTATIC, p);
+ iterator.write16bit(newIndex, p + 1);
+ iterator.insert(loadCode);
+ return iterator.next();
}
public int extraLocals() { return locals; }
protected void makeCode(CtClass[] paramTypes, ConstPool cp) {
- Bytecode save = new Bytecode(cp, 0, 0);
- Bytecode load = new Bytecode(cp, 0, 0);
+ Bytecode save = new Bytecode(cp, 0, 0);
+ Bytecode load = new Bytecode(cp, 0, 0);
- int var = maxLocals;
- int len = (paramTypes == null) ? 0 : paramTypes.length;
- load.addAload(var);
- makeCode2(save, load, 0, len, paramTypes, var + 1);
- save.addAstore(var);
+ int var = maxLocals;
+ int len = (paramTypes == null) ? 0 : paramTypes.length;
+ load.addAload(var);
+ makeCode2(save, load, 0, len, paramTypes, var + 1);
+ save.addAstore(var);
- saveCode = save.get();
- loadCode = load.get();
+ saveCode = save.get();
+ loadCode = load.get();
}
private void makeCode2(Bytecode save, Bytecode load,
- int i, int n, CtClass[] paramTypes, int var)
+ int i, int n, CtClass[] paramTypes, int var)
{
- if (i < n) {
- int size = load.addLoad(var, paramTypes[i]);
- makeCode2(save, load, i + 1, n, paramTypes, var + size);
- save.addStore(var, paramTypes[i]);
- }
- else
- locals = var - maxLocals;
+ if (i < n) {
+ int size = load.addLoad(var, paramTypes[i]);
+ makeCode2(save, load, i + 1, n, paramTypes, var + size);
+ save.addStore(var, paramTypes[i]);
+ }
+ else
+ locals = var - maxLocals;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.CtClass;
protected ConstPool constPool;
public TransformCall(Transformer next, CtMethod origMethod,
- CtMethod substMethod)
+ CtMethod substMethod)
{
- super(next);
- this.classname = origMethod.getDeclaringClass().getName();
- this.methodname = origMethod.getName();
- this.methodDescriptor = origMethod.getMethodInfo2().getDescriptor();
- this.newClassname = substMethod.getDeclaringClass().getName();
- this.newMethodname = substMethod.getName();
- this.constPool = null;
+ super(next);
+ this.classname = origMethod.getDeclaringClass().getName();
+ this.methodname = origMethod.getName();
+ this.methodDescriptor = origMethod.getMethodInfo2().getDescriptor();
+ this.newClassname = substMethod.getDeclaringClass().getName();
+ this.newMethodname = substMethod.getName();
+ this.constPool = null;
}
public void initialize(ConstPool cp, CodeAttribute attr) {
- if (constPool != cp)
- newIndex = 0;
+ if (constPool != cp)
+ newIndex = 0;
}
/**
* so that a different method is invoked.
*/
public int transform(CtClass clazz, int pos, CodeIterator iterator,
- ConstPool cp) throws BadBytecode
+ ConstPool cp) throws BadBytecode
{
- int c = iterator.byteAt(pos);
- if (c == INVOKEINTERFACE || c == INVOKESPECIAL
- || c == INVOKESTATIC || c == INVOKEVIRTUAL) {
- int index = iterator.u16bitAt(pos + 1);
- int typedesc = cp.isMember(classname, methodname, index);
- if (typedesc != 0)
- if (cp.getUtf8Info(typedesc).equals(methodDescriptor))
- pos = match(c, pos, iterator, typedesc, cp);
- }
+ int c = iterator.byteAt(pos);
+ if (c == INVOKEINTERFACE || c == INVOKESPECIAL
+ || c == INVOKESTATIC || c == INVOKEVIRTUAL) {
+ int index = iterator.u16bitAt(pos + 1);
+ int typedesc = cp.isMember(classname, methodname, index);
+ if (typedesc != 0)
+ if (cp.getUtf8Info(typedesc).equals(methodDescriptor))
+ pos = match(c, pos, iterator, typedesc, cp);
+ }
- return pos;
+ return pos;
}
protected int match(int c, int pos, CodeIterator iterator,
- int typedesc, ConstPool cp) throws BadBytecode
+ int typedesc, ConstPool cp) throws BadBytecode
{
- if (newIndex == 0) {
- int nt = cp.addNameAndTypeInfo(cp.addUtf8Info(newMethodname),
- typedesc);
- int ci = cp.addClassInfo(newClassname);
- if (c == INVOKEINTERFACE)
- newIndex = cp.addInterfaceMethodrefInfo(ci, nt);
- else
- newIndex = cp.addMethodrefInfo(ci, nt);
+ if (newIndex == 0) {
+ int nt = cp.addNameAndTypeInfo(cp.addUtf8Info(newMethodname),
+ typedesc);
+ int ci = cp.addClassInfo(newClassname);
+ if (c == INVOKEINTERFACE)
+ newIndex = cp.addInterfaceMethodrefInfo(ci, nt);
+ else
+ newIndex = cp.addMethodrefInfo(ci, nt);
- constPool = cp;
- }
+ constPool = cp;
+ }
- iterator.write16bit(newIndex, pos + 1);
- return pos;
+ iterator.write16bit(newIndex, pos + 1);
+ return pos;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.bytecode.*;
private ConstPool constPool;
public TransformFieldAccess(Transformer next, CtField field,
- String newClassname, String newFieldname)
+ String newClassname, String newFieldname)
{
- super(next);
- this.fieldClass = field.getDeclaringClass();
- this.fieldname = field.getName();
- this.isPrivate = Modifier.isPrivate(field.getModifiers());
- this.newClassname = newClassname;
- this.newFieldname = newFieldname;
- this.constPool = null;
+ super(next);
+ this.fieldClass = field.getDeclaringClass();
+ this.fieldname = field.getName();
+ this.isPrivate = Modifier.isPrivate(field.getModifiers());
+ this.newClassname = newClassname;
+ this.newFieldname = newFieldname;
+ this.constPool = null;
}
public void initialize(ConstPool cp, CodeAttribute attr) {
- if (constPool != cp)
- newIndex = 0;
+ if (constPool != cp)
+ newIndex = 0;
}
/**
* declared.
*/
public int transform(CtClass clazz, int pos,
- CodeIterator iterator, ConstPool cp)
+ CodeIterator iterator, ConstPool cp)
{
- int c = iterator.byteAt(pos);
- if (c == GETFIELD || c == GETSTATIC
- || c == PUTFIELD || c == PUTSTATIC) {
- int index = iterator.u16bitAt(pos + 1);
- String typedesc
- = TransformReadField.isField(clazz.getClassPool(), cp,
- fieldClass, fieldname, isPrivate, index);
- if (typedesc != null) {
- if (newIndex == 0) {
- int nt = cp.addNameAndTypeInfo(newFieldname,
- typedesc);
- newIndex = cp.addFieldrefInfo(
- cp.addClassInfo(newClassname), nt);
- constPool = cp;
- }
+ int c = iterator.byteAt(pos);
+ if (c == GETFIELD || c == GETSTATIC
+ || c == PUTFIELD || c == PUTSTATIC) {
+ int index = iterator.u16bitAt(pos + 1);
+ String typedesc
+ = TransformReadField.isField(clazz.getClassPool(), cp,
+ fieldClass, fieldname, isPrivate, index);
+ if (typedesc != null) {
+ if (newIndex == 0) {
+ int nt = cp.addNameAndTypeInfo(newFieldname,
+ typedesc);
+ newIndex = cp.addFieldrefInfo(
+ cp.addClassInfo(newClassname), nt);
+ constPool = cp;
+ }
- iterator.write16bit(newIndex, pos + 1);
- }
- }
+ iterator.write16bit(newIndex, pos + 1);
+ }
+ }
- return pos;
+ return pos;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.bytecode.*;
private String classname, trapClass, trapMethod;
public TransformNew(Transformer next,
- String classname, String trapClass, String trapMethod) {
- super(next);
- this.classname = classname;
- this.trapClass = trapClass;
- this.trapMethod = trapMethod;
+ String classname, String trapClass, String trapMethod) {
+ super(next);
+ this.classname = classname;
+ this.trapClass = trapClass;
+ this.trapMethod = trapMethod;
}
public void initialize(ConstPool cp, CodeAttribute attr) {
- nested = 0;
+ nested = 0;
}
/**
* INVOKESTATIC trapMethod in trapClass
*/
public int transform(CtClass clazz, int pos, CodeIterator iterator,
- ConstPool cp) throws CannotCompileException
+ ConstPool cp) throws CannotCompileException
{
- int index;
- int c = iterator.byteAt(pos);
- if (c == NEW) {
- index = iterator.u16bitAt(pos + 1);
- if (cp.getClassInfo(index).equals(classname)) {
- if (iterator.byteAt(pos + 3) != DUP)
- throw new CannotCompileException(
- "NEW followed by no DUP was found");
+ int index;
+ int c = iterator.byteAt(pos);
+ if (c == NEW) {
+ index = iterator.u16bitAt(pos + 1);
+ if (cp.getClassInfo(index).equals(classname)) {
+ if (iterator.byteAt(pos + 3) != DUP)
+ throw new CannotCompileException(
+ "NEW followed by no DUP was found");
- iterator.writeByte(NOP, pos);
- iterator.writeByte(NOP, pos + 1);
- iterator.writeByte(NOP, pos + 2);
- iterator.writeByte(NOP, pos + 3);
- ++nested;
- }
- }
- else if (c == INVOKESPECIAL) {
- index = iterator.u16bitAt(pos + 1);
- int typedesc = cp.isConstructor(classname, index);
- if (typedesc != 0 && nested > 0) {
- int methodref = computeMethodref(typedesc, cp);
- iterator.writeByte(INVOKESTATIC, pos);
- iterator.write16bit(methodref, pos + 1);
- --nested;
- }
- }
+ iterator.writeByte(NOP, pos);
+ iterator.writeByte(NOP, pos + 1);
+ iterator.writeByte(NOP, pos + 2);
+ iterator.writeByte(NOP, pos + 3);
+ ++nested;
+ }
+ }
+ else if (c == INVOKESPECIAL) {
+ index = iterator.u16bitAt(pos + 1);
+ int typedesc = cp.isConstructor(classname, index);
+ if (typedesc != 0 && nested > 0) {
+ int methodref = computeMethodref(typedesc, cp);
+ iterator.writeByte(INVOKESTATIC, pos);
+ iterator.write16bit(methodref, pos + 1);
+ --nested;
+ }
+ }
- return pos;
+ return pos;
}
private int computeMethodref(int typedesc, ConstPool cp) {
- int classIndex = cp.addClassInfo(trapClass);
- int mnameIndex = cp.addUtf8Info(trapMethod);
- typedesc = cp.addUtf8Info(
- Descriptor.changeReturnType(classname,
- cp.getUtf8Info(typedesc)));
- return cp.addMethodrefInfo(classIndex,
- cp.addNameAndTypeInfo(mnameIndex, typedesc));
+ int classIndex = cp.addClassInfo(trapClass);
+ int mnameIndex = cp.addUtf8Info(trapMethod);
+ typedesc = cp.addUtf8Info(
+ Descriptor.changeReturnType(classname,
+ cp.getUtf8Info(typedesc)));
+ return cp.addMethodrefInfo(classIndex,
+ cp.addNameAndTypeInfo(mnameIndex, typedesc));
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.bytecode.*;
protected String methodClassname, methodName;
public TransformReadField(Transformer next, CtField field,
- String methodClassname, String methodName)
+ String methodClassname, String methodName)
{
- super(next);
- this.fieldClass = field.getDeclaringClass();
- this.fieldname = field.getName();
- this.methodClassname = methodClassname;
- this.methodName = methodName;
- this.isPrivate = Modifier.isPrivate(field.getModifiers());
+ super(next);
+ this.fieldClass = field.getDeclaringClass();
+ this.fieldname = field.getName();
+ this.methodClassname = methodClassname;
+ this.methodName = methodName;
+ this.isPrivate = Modifier.isPrivate(field.getModifiers());
}
static String isField(ClassPool pool, ConstPool cp, CtClass fclass,
- String fname, boolean is_private, int index) {
- if (!cp.getFieldrefName(index).equals(fname))
- return null;
+ String fname, boolean is_private, int index) {
+ if (!cp.getFieldrefName(index).equals(fname))
+ return null;
- try {
- CtClass c = pool.get(cp.getFieldrefClassName(index));
- if (is_private ? c == fclass : c.subclassOf(fclass))
- return cp.getFieldrefType(index);
- }
- catch (NotFoundException e) {}
- return null;
+ try {
+ CtClass c = pool.get(cp.getFieldrefClassName(index));
+ if (is_private ? c == fclass : c.subclassOf(fclass))
+ return cp.getFieldrefType(index);
+ }
+ catch (NotFoundException e) {}
+ return null;
}
public int transform(CtClass tclazz, int pos, CodeIterator iterator,
- ConstPool cp) throws BadBytecode
+ ConstPool cp) throws BadBytecode
{
- int c = iterator.byteAt(pos);
- if (c == GETFIELD || c == GETSTATIC) {
- int index = iterator.u16bitAt(pos + 1);
- String typedesc = isField(tclazz.getClassPool(), cp,
- fieldClass, fieldname, isPrivate, index);
- if (typedesc != null) {
- if (c == GETSTATIC) {
- iterator.move(pos);
- iterator.insertGap(1); // insertGap() may insert 4 bytes.
- iterator.writeByte(ACONST_NULL, pos);
- pos = iterator.next();
- }
+ int c = iterator.byteAt(pos);
+ if (c == GETFIELD || c == GETSTATIC) {
+ int index = iterator.u16bitAt(pos + 1);
+ String typedesc = isField(tclazz.getClassPool(), cp,
+ fieldClass, fieldname, isPrivate, index);
+ if (typedesc != null) {
+ if (c == GETSTATIC) {
+ iterator.move(pos);
+ iterator.insertGap(1); // insertGap() may insert 4 bytes.
+ iterator.writeByte(ACONST_NULL, pos);
+ pos = iterator.next();
+ }
- String type = "(Ljava/lang/Object;)" + typedesc;
- int mi = cp.addClassInfo(methodClassname);
- int methodref = cp.addMethodrefInfo(mi, methodName, type);
- iterator.writeByte(INVOKESTATIC, pos);
- iterator.write16bit(methodref, pos + 1);
- return pos;
- }
- }
+ String type = "(Ljava/lang/Object;)" + typedesc;
+ int mi = cp.addClassInfo(methodClassname);
+ int methodref = cp.addMethodrefInfo(mi, methodName, type);
+ iterator.writeByte(INVOKESTATIC, pos);
+ iterator.write16bit(methodref, pos + 1);
+ return pos;
+ }
+ }
- return pos;
+ return pos;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.CtClass;
final public class TransformWriteField extends TransformReadField {
public TransformWriteField(Transformer next, CtField field,
- String methodClassname, String methodName)
+ String methodClassname, String methodName)
{
- super(next, field, methodClassname, methodName);
+ super(next, field, methodClassname, methodName);
}
public int transform(CtClass tclazz, int pos, CodeIterator iterator,
- ConstPool cp) throws BadBytecode
+ ConstPool cp) throws BadBytecode
{
- int c = iterator.byteAt(pos);
- if (c == PUTFIELD || c == PUTSTATIC) {
- int index = iterator.u16bitAt(pos + 1);
- String typedesc = isField(tclazz.getClassPool(), cp,
- fieldClass, fieldname, isPrivate, index);
- if (typedesc != null) {
- if (c == PUTSTATIC) {
- CodeAttribute ca = iterator.get();
- iterator.move(pos);
- char c0 = typedesc.charAt(0);
- if (c0 == 'J' || c0 == 'D') { // long or double
- // insertGap() may insert 4 bytes.
- iterator.insertGap(3);
- iterator.writeByte(ACONST_NULL, pos);
- iterator.writeByte(DUP_X2, pos + 1);
- iterator.writeByte(POP, pos + 2);
- ca.setMaxStack(ca.getMaxStack() + 2);
- }
- else {
- // insertGap() may insert 4 bytes.
- iterator.insertGap(2);
- iterator.writeByte(ACONST_NULL, pos);
- iterator.writeByte(SWAP, pos + 1);
- ca.setMaxStack(ca.getMaxStack() + 1);
- }
+ int c = iterator.byteAt(pos);
+ if (c == PUTFIELD || c == PUTSTATIC) {
+ int index = iterator.u16bitAt(pos + 1);
+ String typedesc = isField(tclazz.getClassPool(), cp,
+ fieldClass, fieldname, isPrivate, index);
+ if (typedesc != null) {
+ if (c == PUTSTATIC) {
+ CodeAttribute ca = iterator.get();
+ iterator.move(pos);
+ char c0 = typedesc.charAt(0);
+ if (c0 == 'J' || c0 == 'D') { // long or double
+ // insertGap() may insert 4 bytes.
+ iterator.insertGap(3);
+ iterator.writeByte(ACONST_NULL, pos);
+ iterator.writeByte(DUP_X2, pos + 1);
+ iterator.writeByte(POP, pos + 2);
+ ca.setMaxStack(ca.getMaxStack() + 2);
+ }
+ else {
+ // insertGap() may insert 4 bytes.
+ iterator.insertGap(2);
+ iterator.writeByte(ACONST_NULL, pos);
+ iterator.writeByte(SWAP, pos + 1);
+ ca.setMaxStack(ca.getMaxStack() + 1);
+ }
- pos = iterator.next();
- }
+ pos = iterator.next();
+ }
- int mi = cp.addClassInfo(methodClassname);
- String type = "(Ljava/lang/Object;" + typedesc + ")V";
- int methodref = cp.addMethodrefInfo(mi, methodName, type);
- iterator.writeByte(INVOKESTATIC, pos);
- iterator.write16bit(methodref, pos + 1);
- }
- }
+ int mi = cp.addClassInfo(methodClassname);
+ String type = "(Ljava/lang/Object;" + typedesc + ")V";
+ int methodref = cp.addMethodrefInfo(mi, methodName, type);
+ iterator.writeByte(INVOKESTATIC, pos);
+ iterator.write16bit(methodref, pos + 1);
+ }
+ }
- return pos;
+ return pos;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.convert;
import javassist.bytecode.*;
private Transformer next;
public Transformer(Transformer t) {
- next = t;
+ next = t;
}
public Transformer getNext() { return next; }
public void clean() {}
public abstract int transform(CtClass clazz, int pos, CodeIterator it,
- ConstPool cp) throws CannotCompileException, BadBytecode;
+ ConstPool cp) throws CannotCompileException, BadBytecode;
public int extraLocals() { return 0; }
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.*;
* Undocumented constructor. Do not use; internal-use only.
*/
Cast(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {
- super(pos, i, declaring, m);
+ super(pos, i, declaring, m);
}
/**
* Returns the line number of the source line containing the
* type-cast expression.
*
- * @return -1 if this information is not available.
+ * @return -1 if this information is not available.
*/
public int getLineNumber() {
- return super.getLineNumber();
+ return super.getLineNumber();
}
/**
* Returns the source file containing the type-cast expression.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getFileName() {
- return super.getFileName();
+ return super.getFileName();
}
/**
* the type specified by the cast.
*/
public CtClass getType() throws NotFoundException {
- ConstPool cp = getConstPool();
- int pos = currentPos;
- int index = iterator.u16bitAt(pos + 1);
- String name = cp.getClassInfo(index);
- return Descriptor.toCtClass(name, thisClass.getClassPool());
+ ConstPool cp = getConstPool();
+ int pos = currentPos;
+ int index = iterator.u16bitAt(pos + 1);
+ String name = cp.getClassInfo(index);
+ return Descriptor.toCtClass(name, thisClass.getClassPool());
}
/**
* the throws declaration allows the method to throw.
*/
public CtClass[] mayThrow() {
- return super.mayThrow();
+ return super.mayThrow();
}
/**
*
* <p>$0 is available but the value is <code>null</code>.
*
- * @param statement a Java statement.
+ * @param statement a Java statement.
*/
public void replace(String statement) throws CannotCompileException {
- ConstPool constPool = getConstPool();
- int pos = currentPos;
- int index = iterator.u16bitAt(pos + 1);
-
- Javac jc = new Javac(thisClass);
- ClassPool cp = thisClass.getClassPool();
- CodeAttribute ca = iterator.get();
-
- try {
- CtClass[] params
- = new CtClass[] { cp.get(javaLangObject) };
- CtClass retType = getType();
-
- int paramVar = ca.getMaxLocals();
- jc.recordParams(javaLangObject, params, true, paramVar,
- withinStatic());
- int retVar = jc.recordReturnType(retType, true);
- jc.recordProceed(new ProceedForCast(index, retType));
-
- /* Is $_ included in the source code?
- */
- checkResultValue(retType, statement);
-
- Bytecode bytecode = jc.getBytecode();
- storeStack(params, true, paramVar, bytecode);
- jc.compileStmnt(statement);
- bytecode.addLoad(retVar, retType);
-
- replace0(pos, bytecode, 3);
- }
- catch (CompileError e) { throw new CannotCompileException(e); }
- catch (NotFoundException e) { throw new CannotCompileException(e); }
- catch (BadBytecode e) {
- throw new CannotCompileException("broken method");
- }
+ ConstPool constPool = getConstPool();
+ int pos = currentPos;
+ int index = iterator.u16bitAt(pos + 1);
+
+ Javac jc = new Javac(thisClass);
+ ClassPool cp = thisClass.getClassPool();
+ CodeAttribute ca = iterator.get();
+
+ try {
+ CtClass[] params
+ = new CtClass[] { cp.get(javaLangObject) };
+ CtClass retType = getType();
+
+ int paramVar = ca.getMaxLocals();
+ jc.recordParams(javaLangObject, params, true, paramVar,
+ withinStatic());
+ int retVar = jc.recordReturnType(retType, true);
+ jc.recordProceed(new ProceedForCast(index, retType));
+
+ /* Is $_ included in the source code?
+ */
+ checkResultValue(retType, statement);
+
+ Bytecode bytecode = jc.getBytecode();
+ storeStack(params, true, paramVar, bytecode);
+ jc.compileStmnt(statement);
+ bytecode.addLoad(retVar, retType);
+
+ replace0(pos, bytecode, 3);
+ }
+ catch (CompileError e) { throw new CannotCompileException(e); }
+ catch (NotFoundException e) { throw new CannotCompileException(e); }
+ catch (BadBytecode e) {
+ throw new CannotCompileException("broken method");
+ }
}
/* <type> $proceed(Object obj)
*/
static class ProceedForCast implements ProceedHandler {
- int index;
- CtClass retType;
-
- ProceedForCast(int i, CtClass t) {
- index = i;
- retType = t;
- }
-
- public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
- throws CompileError
- {
- if (gen.atMethodArgsLength(args) != 1)
- throw new CompileError(Javac.proceedName
- + "() cannot take more than one parameter "
- + "for cast");
-
- gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
- bytecode.addOpcode(Opcode.CHECKCAST);
- bytecode.addIndex(index);
- gen.setType(retType);
- }
+ int index;
+ CtClass retType;
+
+ ProceedForCast(int i, CtClass t) {
+ index = i;
+ retType = t;
+ }
+
+ public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
+ throws CompileError
+ {
+ if (gen.atMethodArgsLength(args) != 1)
+ throw new CompileError(Javac.proceedName
+ + "() cannot take more than one parameter "
+ + "for cast");
+
+ gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
+ bytecode.addOpcode(Opcode.CHECKCAST);
+ bytecode.addIndex(index);
+ gen.setType(retType);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.*;
static final String javaLangObject = "java.lang.Object";
Expr(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {
- currentPos = pos;
- iterator = i;
- thisClass = declaring;
- thisMethod = m;
+ currentPos = pos;
+ iterator = i;
+ thisClass = declaring;
+ thisMethod = m;
}
final ConstPool getConstPool() {
- return thisMethod.getConstPool();
+ return thisMethod.getConstPool();
}
final boolean edited() { return edited; }
* Returns true if this method is static.
*/
final boolean withinStatic() {
- return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0;
+ return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0;
}
/**
* Returns the constructor or method containing the expression.
*/
public CtBehavior where() {
- MethodInfo mi = thisMethod;
- CtBehavior[] cb = thisClass.getDeclaredBehaviors();
- for (int i = cb.length - 1; i >= 0; --i)
- if (cb[i].getMethodInfo() == mi)
- return cb[i];
+ MethodInfo mi = thisMethod;
+ CtBehavior[] cb = thisClass.getDeclaredBehaviors();
+ for (int i = cb.length - 1; i >= 0; --i)
+ if (cb[i].getMethodInfo() == mi)
+ return cb[i];
- throw new RuntimeException("fatal: not found");
+ throw new RuntimeException("fatal: not found");
}
/**
* the throws declaration allows the method to throw.
*/
public CtClass[] mayThrow() {
- ClassPool pool = thisClass.getClassPool();
- ConstPool cp = thisMethod.getConstPool();
- LinkedList list = new LinkedList();
- try {
- CodeAttribute ca = thisMethod.getCodeAttribute();
- ExceptionTable et = ca.getExceptionTable();
- int pos = currentPos;
- int n = et.size();
- for (int i = 0; i < n; ++i)
- if (et.startPc(i) <= pos && pos < et.endPc(i)) {
- int t = et.catchType(i);
- if (t > 0)
- try {
- addClass(list, pool.get(cp.getClassInfo(t)));
- }
- catch (NotFoundException e) {}
- }
- }
- catch (NullPointerException e) {}
-
- ExceptionsAttribute ea = thisMethod.getExceptionsAttribute();
- if (ea != null) {
- String[] exceptions = ea.getExceptions();
- if (exceptions != null) {
- int n = exceptions.length;
- for (int i = 0; i < n; ++i)
- try {
- addClass(list, pool.get(exceptions[i]));
- }
- catch (NotFoundException e) {}
- }
- }
-
- return (CtClass[])list.toArray(new CtClass[list.size()]);
+ ClassPool pool = thisClass.getClassPool();
+ ConstPool cp = thisMethod.getConstPool();
+ LinkedList list = new LinkedList();
+ try {
+ CodeAttribute ca = thisMethod.getCodeAttribute();
+ ExceptionTable et = ca.getExceptionTable();
+ int pos = currentPos;
+ int n = et.size();
+ for (int i = 0; i < n; ++i)
+ if (et.startPc(i) <= pos && pos < et.endPc(i)) {
+ int t = et.catchType(i);
+ if (t > 0)
+ try {
+ addClass(list, pool.get(cp.getClassInfo(t)));
+ }
+ catch (NotFoundException e) {}
+ }
+ }
+ catch (NullPointerException e) {}
+
+ ExceptionsAttribute ea = thisMethod.getExceptionsAttribute();
+ if (ea != null) {
+ String[] exceptions = ea.getExceptions();
+ if (exceptions != null) {
+ int n = exceptions.length;
+ for (int i = 0; i < n; ++i)
+ try {
+ addClass(list, pool.get(exceptions[i]));
+ }
+ catch (NotFoundException e) {}
+ }
+ }
+
+ return (CtClass[])list.toArray(new CtClass[list.size()]);
}
private static void addClass(LinkedList list, CtClass c) {
- Iterator it = list.iterator();
- while (it.hasNext())
- if (it.next() == c)
- return;
+ Iterator it = list.iterator();
+ while (it.hasNext())
+ if (it.next() == c)
+ return;
- list.add(c);
+ list.add(c);
}
/**
* Returns the line number of the source line containing the
* expression.
*
- * @return -1 if this information is not available.
+ * @return -1 if this information is not available.
*/
public int getLineNumber() {
- return thisMethod.getLineNumber(currentPos);
+ return thisMethod.getLineNumber(currentPos);
}
/**
* Returns the source file containing the expression.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getFileName() {
- ClassFile cf = thisClass.getClassFile2();
- if (cf == null)
- return null;
- else
- return cf.getSourceFile();
+ ClassFile cf = thisClass.getClassFile2();
+ if (cf == null)
+ return null;
+ else
+ return cf.getSourceFile();
}
static final boolean checkResultValue(CtClass retType, String prog)
- throws CannotCompileException
+ throws CannotCompileException
{
- /* Is $_ included in the source code?
- */
- boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0);
- if (!hasIt && retType != CtClass.voidType)
- throw new CannotCompileException(
- "the resulting value is not stored in "
- + Javac.resultVarName);
-
- return hasIt;
+ /* Is $_ included in the source code?
+ */
+ boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0);
+ if (!hasIt && retType != CtClass.voidType)
+ throw new CannotCompileException(
+ "the resulting value is not stored in "
+ + Javac.resultVarName);
+
+ return hasIt;
}
/* If isStaticCall is true, null is assigned to $0. So $0 must
* be less than 0.
*/
static final void storeStack(CtClass[] params, boolean isStaticCall,
- int regno, Bytecode bytecode) {
- storeStack0(0, params.length, params, regno + 1, bytecode);
- if (isStaticCall)
- bytecode.addOpcode(ACONST_NULL);
+ int regno, Bytecode bytecode) {
+ storeStack0(0, params.length, params, regno + 1, bytecode);
+ if (isStaticCall)
+ bytecode.addOpcode(ACONST_NULL);
- bytecode.addAstore(regno);
+ bytecode.addAstore(regno);
}
private static void storeStack0(int i, int n, CtClass[] params,
- int regno, Bytecode bytecode) {
- if (i >= n)
- return;
- else {
- CtClass c = params[i];
- int size;
- if (c instanceof CtPrimitiveType)
- size = ((CtPrimitiveType)c).getDataSize();
- else
- size = 1;
-
- storeStack0(i + 1, n, params, regno + size, bytecode);
- bytecode.addStore(regno, c);
- }
+ int regno, Bytecode bytecode) {
+ if (i >= n)
+ return;
+ else {
+ CtClass c = params[i];
+ int size;
+ if (c instanceof CtPrimitiveType)
+ size = ((CtPrimitiveType)c).getDataSize();
+ else
+ size = 1;
+
+ storeStack0(i + 1, n, params, regno + size, bytecode);
+ bytecode.addStore(regno, c);
+ }
}
protected void replace0(int pos, Bytecode bytecode, int size)
- throws BadBytecode
+ throws BadBytecode
{
- byte[] code = bytecode.get();
- edited = true;
- int gap = code.length - size;
- if (gap > 0)
- iterator.insertGap(pos, gap);
- else
- for (int i = 0; i < size; ++i)
- iterator.writeByte(NOP, pos + i);
-
- iterator.write(code, pos);
- iterator.insert(bytecode.getExceptionTable(), pos);
- maxLocals = bytecode.getMaxLocals();
- maxStack = bytecode.getMaxStack();
+ byte[] code = bytecode.get();
+ edited = true;
+ int gap = code.length - size;
+ for (int i = 0; i < size; ++i)
+ iterator.writeByte(NOP, pos + i);
+
+ if (gap > 0)
+ iterator.insertGap(pos, gap);
+
+ iterator.write(code, pos);
+ iterator.insert(bytecode.getExceptionTable(), pos);
+ maxLocals = bytecode.getMaxLocals();
+ maxStack = bytecode.getMaxStack();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.bytecode.*;
public ExprEditor() {}
static class NewOp {
- NewOp next;
- int pos;
- String type;
-
- NewOp(NewOp n, int p, String t) {
- next = n;
- pos = p;
- type = t;
- }
+ NewOp next;
+ int pos;
+ String type;
+
+ NewOp(NewOp n, int p, String t) {
+ next = n;
+ pos = p;
+ type = t;
+ }
}
/**
* Undocumented method. Do not use; internal-use only.
*/
public boolean doit(CtClass clazz, MethodInfo minfo)
- throws CannotCompileException
+ throws CannotCompileException
{
- CodeAttribute codeAttr = minfo.getCodeAttribute();
- if (codeAttr == null)
- return false;
-
- CodeIterator iterator = codeAttr.iterator();
- boolean edited = false;
- int maxLocals = codeAttr.getMaxLocals();
- int maxStack = 0;
-
- NewOp newList = null;
- ConstPool cp = minfo.getConstPool();
-
- while (iterator.hasNext())
- try {
- Expr expr = null;
- int pos = iterator.next();
- int c = iterator.byteAt(pos);
-
- if (c == Opcode.INVOKESTATIC || c == Opcode.INVOKEINTERFACE
- || c == Opcode.INVOKEVIRTUAL) {
- expr = new MethodCall(pos, iterator, clazz, minfo);
- edit((MethodCall)expr);
- }
- else if (c == Opcode.GETFIELD || c == Opcode.GETSTATIC
- || c == Opcode.PUTFIELD || c == Opcode.PUTSTATIC) {
- expr = new FieldAccess(pos, iterator, clazz, minfo, c);
- edit((FieldAccess)expr);
- }
- else if (c == Opcode.NEW) {
- int index = iterator.u16bitAt(pos + 1);
- newList = new NewOp(newList, pos,
- cp.getClassInfo(index));
- }
- else if (c == Opcode.INVOKESPECIAL) {
- if (newList != null && cp.isConstructor(newList.type,
- iterator.u16bitAt(pos + 1)) > 0) {
- expr = new NewExpr(pos, iterator, clazz, minfo,
- newList.type, newList.pos);
- edit((NewExpr)expr);
- newList = newList.next;
- }
- else {
- expr = new MethodCall(pos, iterator, clazz, minfo);
- MethodCall mcall = (MethodCall)expr;
- if (!mcall.getMethodName().equals(
- MethodInfo.nameInit))
- edit(mcall);
- }
- }
- else if (c == Opcode.INSTANCEOF) {
- expr = new Instanceof(pos, iterator, clazz, minfo);
- edit((Instanceof)expr);
- }
- else if (c == Opcode.CHECKCAST) {
- expr = new Cast(pos, iterator, clazz, minfo);
- edit((Cast)expr);
- }
-
- if (expr != null && expr.edited()) {
- edited = true;
- if (maxLocals < expr.locals())
- maxLocals = expr.locals();
-
- if (maxStack < expr.stack())
- maxStack = expr.stack();
- }
- }
- catch (BadBytecode e) {
- throw new CannotCompileException(e);
- }
-
- codeAttr.setMaxLocals(maxLocals);
- codeAttr.setMaxStack(codeAttr.getMaxStack() + maxStack);
- return edited;
+ CodeAttribute codeAttr = minfo.getCodeAttribute();
+ if (codeAttr == null)
+ return false;
+
+ CodeIterator iterator = codeAttr.iterator();
+ boolean edited = false;
+ int maxLocals = codeAttr.getMaxLocals();
+ int maxStack = 0;
+
+ NewOp newList = null;
+ ConstPool cp = minfo.getConstPool();
+
+ while (iterator.hasNext())
+ try {
+ Expr expr = null;
+ int pos = iterator.next();
+ int c = iterator.byteAt(pos);
+
+ if (c == Opcode.INVOKESTATIC || c == Opcode.INVOKEINTERFACE
+ || c == Opcode.INVOKEVIRTUAL) {
+ expr = new MethodCall(pos, iterator, clazz, minfo);
+ edit((MethodCall)expr);
+ }
+ else if (c == Opcode.GETFIELD || c == Opcode.GETSTATIC
+ || c == Opcode.PUTFIELD || c == Opcode.PUTSTATIC) {
+ expr = new FieldAccess(pos, iterator, clazz, minfo, c);
+ edit((FieldAccess)expr);
+ }
+ else if (c == Opcode.NEW) {
+ int index = iterator.u16bitAt(pos + 1);
+ newList = new NewOp(newList, pos,
+ cp.getClassInfo(index));
+ }
+ else if (c == Opcode.INVOKESPECIAL) {
+ if (newList != null && cp.isConstructor(newList.type,
+ iterator.u16bitAt(pos + 1)) > 0) {
+ expr = new NewExpr(pos, iterator, clazz, minfo,
+ newList.type, newList.pos);
+ edit((NewExpr)expr);
+ newList = newList.next;
+ }
+ else {
+ expr = new MethodCall(pos, iterator, clazz, minfo);
+ MethodCall mcall = (MethodCall)expr;
+ if (!mcall.getMethodName().equals(
+ MethodInfo.nameInit))
+ edit(mcall);
+ }
+ }
+ else if (c == Opcode.INSTANCEOF) {
+ expr = new Instanceof(pos, iterator, clazz, minfo);
+ edit((Instanceof)expr);
+ }
+ else if (c == Opcode.CHECKCAST) {
+ expr = new Cast(pos, iterator, clazz, minfo);
+ edit((Cast)expr);
+ }
+
+ if (expr != null && expr.edited()) {
+ edited = true;
+ maxLocals = max(maxLocals, expr.locals());
+ maxStack = max(maxStack, expr.stack());
+ }
+ }
+ catch (BadBytecode e) {
+ throw new CannotCompileException(e);
+ }
+
+ ExceptionTable et = codeAttr.getExceptionTable();
+ int n = et.size();
+ for (int i = 0; i < n; ++i) {
+ Handler h = new Handler(et, i, iterator, clazz, minfo);
+ edit(h);
+ if (h.edited()) {
+ edited = true;
+ maxLocals = max(maxLocals, h.locals());
+ maxStack = max(maxStack, h.stack());
+ }
+ }
+
+ codeAttr.setMaxLocals(maxLocals);
+ codeAttr.setMaxStack(codeAttr.getMaxStack() + maxStack);
+ return edited;
+ }
+
+ private int max(int i, int j) {
+ return i > j ? i : j;
}
/**
* Edits a <tt>new</tt> expression (overridable).
* The default implementation performs nothing.
*
- * @param e the <tt>new</tt> expression creating an object.
+ * @param e the <tt>new</tt> expression creating an object.
*/
public void edit(NewExpr e) throws CannotCompileException {}
* The default implementation performs nothing.
*/
public void edit(Cast c) throws CannotCompileException {}
+
+ /**
+ * Edits a catch clause (overridable).
+ * The default implementation performs nothing.
+ */
+ public void edit(Handler h) throws CannotCompileException {}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.*;
int opcode;
FieldAccess(int pos, CodeIterator i, CtClass declaring, MethodInfo m,
- int op) {
- super(pos, i, declaring, m);
- opcode = op;
+ int op) {
+ super(pos, i, declaring, m);
+ opcode = op;
}
/**
* Returns the line number of the source line containing the
* field access.
*
- * @return -1 if this information is not available.
+ * @return -1 if this information is not available.
*/
public int getLineNumber() {
- return super.getLineNumber();
+ return super.getLineNumber();
}
/**
* Returns the source file containing the field access.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getFileName() {
- return super.getFileName();
+ return super.getFileName();
}
/**
* Returns true if the field is static.
*/
public boolean isStatic() {
- return isStatic(opcode);
+ return isStatic(opcode);
}
static boolean isStatic(int c) {
- return c == Opcode.GETSTATIC || c == Opcode.PUTSTATIC;
+ return c == Opcode.GETSTATIC || c == Opcode.PUTSTATIC;
}
/**
* Returns true if the field is read.
*/
public boolean isReader() {
- return opcode == Opcode.GETFIELD || opcode == Opcode.GETSTATIC;
+ return opcode == Opcode.GETFIELD || opcode == Opcode.GETSTATIC;
}
/**
* Returns true if the field is written in.
*/
public boolean isWriter() {
- return opcode == Opcode.PUTFIELD || opcode == Opcode.PUTSTATIC;
+ return opcode == Opcode.PUTFIELD || opcode == Opcode.PUTSTATIC;
}
/**
* Returns the class in which the field is declared.
*/
private CtClass getCtClass() throws NotFoundException {
- return thisClass.getClassPool().get(getClassName());
+ return thisClass.getClassPool().get(getClassName());
}
/**
* Returns the name of the class in which the field is declared.
*/
public String getClassName() {
- int index = iterator.u16bitAt(currentPos + 1);
- return getConstPool().getFieldrefClassName(index);
+ int index = iterator.u16bitAt(currentPos + 1);
+ return getConstPool().getFieldrefClassName(index);
}
/**
* Returns the name of the field.
*/
public String getFieldName() {
- int index = iterator.u16bitAt(currentPos + 1);
- return getConstPool().getFieldrefName(index);
+ int index = iterator.u16bitAt(currentPos + 1);
+ return getConstPool().getFieldrefName(index);
}
/**
* Returns the field accessed by this expression.
*/
public CtField getField() throws NotFoundException {
- CtClass cc = getCtClass();
- return cc.getField(getFieldName());
+ CtClass cc = getCtClass();
+ return cc.getField(getFieldName());
}
/**
* the throws declaration allows the method to throw.
*/
public CtClass[] mayThrow() {
- return super.mayThrow();
+ return super.mayThrow();
}
/*
* Returns the type of the field.
public CtClass getFieldType() throws NotFoundException {
- int index = iterator.u16bitAt(currentPos + 1);
- String type = getConstPool().getFieldrefType(index);
- return Descriptor.toCtClass(type, thisClass.getClassPool());
+ int index = iterator.u16bitAt(currentPos + 1);
+ String type = getConstPool().getFieldrefType(index);
+ return Descriptor.toCtClass(type, thisClass.getClassPool());
}
*/
* If the field access is writing, $_ is available but the value
* of $_ is ignored.
*
- * @param statement a Java statement.
+ * @param statement a Java statement.
*/
public void replace(String statement) throws CannotCompileException {
- ConstPool constPool = getConstPool();
- int pos = currentPos;
- int index = iterator.u16bitAt(pos + 1);
-
- Javac jc = new Javac(thisClass);
- CodeAttribute ca = iterator.get();
- try {
- CtClass[] params;
- CtClass retType;
- CtClass fieldType
- = Descriptor.toCtClass(constPool.getFieldrefType(index),
- thisClass.getClassPool());
- boolean read = isReader();
- if (read) {
- params = new CtClass[0];
- retType = fieldType;
- }
- else {
- params = new CtClass[1];
- params[0] = fieldType;
- retType = CtClass.voidType;
- }
-
- int paramVar = ca.getMaxLocals();
- jc.recordParams(constPool.getFieldrefClassName(index), params,
- true, paramVar, withinStatic());
-
- /* Is $_ included in the source code?
- */
- boolean included = checkResultValue(retType, statement);
-
- int retVar = jc.recordReturnType(retType, included);
- if (read)
- jc.recordProceed(new ProceedForRead(retType, opcode,
- index, paramVar));
- else {
- // because $type is not the return type...
- jc.recordType(fieldType);
- jc.recordProceed(new ProceedForWrite(params[0], opcode,
- index, paramVar));
- }
-
- Bytecode bytecode = jc.getBytecode();
- storeStack(params, isStatic(), paramVar, bytecode);
- jc.compileStmnt(statement);
- if (read)
- bytecode.addLoad(retVar, retType);
-
- replace0(pos, bytecode, 3);
- }
- catch (CompileError e) { throw new CannotCompileException(e); }
- catch (NotFoundException e) { throw new CannotCompileException(e); }
- catch (BadBytecode e) {
- throw new CannotCompileException("broken method");
- }
+ ConstPool constPool = getConstPool();
+ int pos = currentPos;
+ int index = iterator.u16bitAt(pos + 1);
+
+ Javac jc = new Javac(thisClass);
+ CodeAttribute ca = iterator.get();
+ try {
+ CtClass[] params;
+ CtClass retType;
+ CtClass fieldType
+ = Descriptor.toCtClass(constPool.getFieldrefType(index),
+ thisClass.getClassPool());
+ boolean read = isReader();
+ if (read) {
+ params = new CtClass[0];
+ retType = fieldType;
+ }
+ else {
+ params = new CtClass[1];
+ params[0] = fieldType;
+ retType = CtClass.voidType;
+ }
+
+ int paramVar = ca.getMaxLocals();
+ jc.recordParams(constPool.getFieldrefClassName(index), params,
+ true, paramVar, withinStatic());
+
+ /* Is $_ included in the source code?
+ */
+ boolean included = checkResultValue(retType, statement);
+
+ int retVar = jc.recordReturnType(retType, included);
+ if (read)
+ jc.recordProceed(new ProceedForRead(retType, opcode,
+ index, paramVar));
+ else {
+ // because $type is not the return type...
+ jc.recordType(fieldType);
+ jc.recordProceed(new ProceedForWrite(params[0], opcode,
+ index, paramVar));
+ }
+
+ Bytecode bytecode = jc.getBytecode();
+ storeStack(params, isStatic(), paramVar, bytecode);
+ jc.compileStmnt(statement);
+ if (read)
+ bytecode.addLoad(retVar, retType);
+
+ replace0(pos, bytecode, 3);
+ }
+ catch (CompileError e) { throw new CannotCompileException(e); }
+ catch (NotFoundException e) { throw new CannotCompileException(e); }
+ catch (BadBytecode e) {
+ throw new CannotCompileException("broken method");
+ }
}
/* <field type> $proceed()
*/
static class ProceedForRead implements ProceedHandler {
- CtClass fieldType;
- int opcode;
- int targetVar, index;
-
- ProceedForRead(CtClass type, int op, int i, int var) {
- fieldType = type;
- targetVar = var;
- opcode = op;
- index = i;
- }
-
- public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
- throws CompileError
- {
- if (args != null && !gen.isParamListName(args))
- throw new CompileError(Javac.proceedName
- + "() cannot take a parameter for field reading");
-
- int stack;
- if (isStatic(opcode))
- stack = 0;
- else {
- stack = -1;
- bytecode.addAload(targetVar);
- }
-
- if (fieldType instanceof CtPrimitiveType)
- stack += ((CtPrimitiveType)fieldType).getDataSize();
- else
- ++stack;
-
- bytecode.add(opcode);
- bytecode.addIndex(index);
- bytecode.growStack(stack);
- gen.setType(fieldType);
- }
+ CtClass fieldType;
+ int opcode;
+ int targetVar, index;
+
+ ProceedForRead(CtClass type, int op, int i, int var) {
+ fieldType = type;
+ targetVar = var;
+ opcode = op;
+ index = i;
+ }
+
+ public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
+ throws CompileError
+ {
+ if (args != null && !gen.isParamListName(args))
+ throw new CompileError(Javac.proceedName
+ + "() cannot take a parameter for field reading");
+
+ int stack;
+ if (isStatic(opcode))
+ stack = 0;
+ else {
+ stack = -1;
+ bytecode.addAload(targetVar);
+ }
+
+ if (fieldType instanceof CtPrimitiveType)
+ stack += ((CtPrimitiveType)fieldType).getDataSize();
+ else
+ ++stack;
+
+ bytecode.add(opcode);
+ bytecode.addIndex(index);
+ bytecode.growStack(stack);
+ gen.setType(fieldType);
+ }
}
/* void $proceed(<field type>)
- * the return type is not the field type but void.
+ * the return type is not the field type but void.
*/
static class ProceedForWrite implements ProceedHandler {
- CtClass fieldType;
- int opcode;
- int targetVar, index;
-
- ProceedForWrite(CtClass type, int op, int i, int var) {
- fieldType = type;
- targetVar = var;
- opcode = op;
- index = i;
- }
-
- public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
- throws CompileError
- {
- if (gen.atMethodArgsLength(args) != 1)
- throw new CompileError(Javac.proceedName
- + "() cannot take more than one parameter "
- + "for field writing");
-
- int stack;
- if (isStatic(opcode))
- stack = 0;
- else {
- stack = -1;
- bytecode.addAload(targetVar);
- }
-
- gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
- gen.doNumCast(fieldType);
- if (fieldType instanceof CtPrimitiveType)
- stack -= ((CtPrimitiveType)fieldType).getDataSize();
- else
- --stack;
-
- bytecode.add(opcode);
- bytecode.addIndex(index);
- bytecode.growStack(stack);
- gen.setType(CtClass.voidType);
- gen.addNullIfVoid();
- }
+ CtClass fieldType;
+ int opcode;
+ int targetVar, index;
+
+ ProceedForWrite(CtClass type, int op, int i, int var) {
+ fieldType = type;
+ targetVar = var;
+ opcode = op;
+ index = i;
+ }
+
+ public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
+ throws CompileError
+ {
+ if (gen.atMethodArgsLength(args) != 1)
+ throw new CompileError(Javac.proceedName
+ + "() cannot take more than one parameter "
+ + "for field writing");
+
+ int stack;
+ if (isStatic(opcode))
+ stack = 0;
+ else {
+ stack = -1;
+ bytecode.addAload(targetVar);
+ }
+
+ gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
+ gen.doNumCast(fieldType);
+ if (fieldType instanceof CtPrimitiveType)
+ stack -= ((CtPrimitiveType)fieldType).getDataSize();
+ else
+ --stack;
+
+ bytecode.add(opcode);
+ bytecode.addIndex(index);
+ bytecode.growStack(stack);
+ gen.setType(CtClass.voidType);
+ gen.addNullIfVoid();
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.*;
* Undocumented constructor. Do not use; internal-use only.
*/
Instanceof(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {
- super(pos, i, declaring, m);
+ super(pos, i, declaring, m);
}
/**
* Returns the line number of the source line containing the
* instanceof expression.
*
- * @return -1 if this information is not available.
+ * @return -1 if this information is not available.
*/
public int getLineNumber() {
- return super.getLineNumber();
+ return super.getLineNumber();
}
/**
* Returns the source file containing the
* instanceof expression.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getFileName() {
- return super.getFileName();
+ return super.getFileName();
}
/**
* of the instanceof operator.
*/
public CtClass getType() throws NotFoundException {
- ConstPool cp = getConstPool();
- int pos = currentPos;
- int index = iterator.u16bitAt(pos + 1);
- String name = cp.getClassInfo(index);
- return Descriptor.toCtClass(name, thisClass.getClassPool());
+ ConstPool cp = getConstPool();
+ int pos = currentPos;
+ int index = iterator.u16bitAt(pos + 1);
+ String name = cp.getClassInfo(index);
+ return Descriptor.toCtClass(name, thisClass.getClassPool());
}
/**
* the throws declaration allows the method to throw.
*/
public CtClass[] mayThrow() {
- return super.mayThrow();
+ return super.mayThrow();
}
/**
*
* <p>$0 is available but the value is <code>null</code>.
*
- * @param statement a Java statement.
+ * @param statement a Java statement.
*/
public void replace(String statement) throws CannotCompileException {
- ConstPool constPool = getConstPool();
- int pos = currentPos;
- int index = iterator.u16bitAt(pos + 1);
-
- Javac jc = new Javac(thisClass);
- ClassPool cp = thisClass.getClassPool();
- CodeAttribute ca = iterator.get();
-
- try {
- CtClass[] params
- = new CtClass[] { cp.get(javaLangObject) };
- CtClass retType = CtClass.booleanType;
-
- int paramVar = ca.getMaxLocals();
- jc.recordParams(javaLangObject, params, true, paramVar,
- withinStatic());
- int retVar = jc.recordReturnType(retType, true);
- jc.recordProceed(new ProceedForInstanceof(index));
-
- // because $type is not the return type...
- jc.recordType(getType());
-
- /* Is $_ included in the source code?
- */
- checkResultValue(retType, statement);
-
- Bytecode bytecode = jc.getBytecode();
- storeStack(params, true, paramVar, bytecode);
- jc.compileStmnt(statement);
- bytecode.addLoad(retVar, retType);
-
- replace0(pos, bytecode, 3);
- }
- catch (CompileError e) { throw new CannotCompileException(e); }
- catch (NotFoundException e) { throw new CannotCompileException(e); }
- catch (BadBytecode e) {
- throw new CannotCompileException("broken method");
- }
+ ConstPool constPool = getConstPool();
+ int pos = currentPos;
+ int index = iterator.u16bitAt(pos + 1);
+
+ Javac jc = new Javac(thisClass);
+ ClassPool cp = thisClass.getClassPool();
+ CodeAttribute ca = iterator.get();
+
+ try {
+ CtClass[] params
+ = new CtClass[] { cp.get(javaLangObject) };
+ CtClass retType = CtClass.booleanType;
+
+ int paramVar = ca.getMaxLocals();
+ jc.recordParams(javaLangObject, params, true, paramVar,
+ withinStatic());
+ int retVar = jc.recordReturnType(retType, true);
+ jc.recordProceed(new ProceedForInstanceof(index));
+
+ // because $type is not the return type...
+ jc.recordType(getType());
+
+ /* Is $_ included in the source code?
+ */
+ checkResultValue(retType, statement);
+
+ Bytecode bytecode = jc.getBytecode();
+ storeStack(params, true, paramVar, bytecode);
+ jc.compileStmnt(statement);
+ bytecode.addLoad(retVar, retType);
+
+ replace0(pos, bytecode, 3);
+ }
+ catch (CompileError e) { throw new CannotCompileException(e); }
+ catch (NotFoundException e) { throw new CannotCompileException(e); }
+ catch (BadBytecode e) {
+ throw new CannotCompileException("broken method");
+ }
}
/* boolean $proceed(Object obj)
*/
static class ProceedForInstanceof implements ProceedHandler {
- int index;
-
- ProceedForInstanceof(int i) {
- index = i;
- }
-
- public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
- throws CompileError
- {
- if (gen.atMethodArgsLength(args) != 1)
- throw new CompileError(Javac.proceedName
- + "() cannot take more than one parameter "
- + "for instanceof");
-
- gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
- bytecode.addOpcode(Opcode.INSTANCEOF);
- bytecode.addIndex(index);
- gen.setType(CtClass.booleanType);
- }
+ int index;
+
+ ProceedForInstanceof(int i) {
+ index = i;
+ }
+
+ public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
+ throws CompileError
+ {
+ if (gen.atMethodArgsLength(args) != 1)
+ throw new CompileError(Javac.proceedName
+ + "() cannot take more than one parameter "
+ + "for instanceof");
+
+ gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
+ bytecode.addOpcode(Opcode.INSTANCEOF);
+ bytecode.addIndex(index);
+ gen.setType(CtClass.booleanType);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.*;
* Undocumented constructor. Do not use; internal-use only.
*/
MethodCall(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {
- super(pos, i, declaring, m);
+ super(pos, i, declaring, m);
}
private int getNameAndType(ConstPool cp) {
- String cname;
- int pos = currentPos;
- int c = iterator.byteAt(pos);
- int index = iterator.u16bitAt(pos + 1);
-
- if (c == INVOKEINTERFACE)
- return cp.getInterfaceMethodrefNameAndType(index);
- else
- return cp.getMethodrefNameAndType(index);
+ String cname;
+ int pos = currentPos;
+ int c = iterator.byteAt(pos);
+ int index = iterator.u16bitAt(pos + 1);
+
+ if (c == INVOKEINTERFACE)
+ return cp.getInterfaceMethodrefNameAndType(index);
+ else
+ return cp.getMethodrefNameAndType(index);
}
/**
* Returns the line number of the source line containing the
* method call.
*
- * @return -1 if this information is not available.
+ * @return -1 if this information is not available.
*/
public int getLineNumber() {
- return super.getLineNumber();
+ return super.getLineNumber();
}
/**
* Returns the source file containing the method call.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getFileName() {
- return super.getFileName();
+ return super.getFileName();
}
/**
* which the method is called on.
*/
private CtClass getCtClass() throws NotFoundException {
- return thisClass.getClassPool().get(getClassName());
+ return thisClass.getClassPool().get(getClassName());
}
/**
* which the method is called on.
*/
public String getClassName() {
- String cname;
+ String cname;
- ConstPool cp = getConstPool();
- int pos = currentPos;
- int c = iterator.byteAt(pos);
- int index = iterator.u16bitAt(pos + 1);
+ ConstPool cp = getConstPool();
+ int pos = currentPos;
+ int c = iterator.byteAt(pos);
+ int index = iterator.u16bitAt(pos + 1);
- if (c == INVOKEINTERFACE)
- cname = cp.getInterfaceMethodrefClassName(index);
- else
- cname = cp.getMethodrefClassName(index);
+ if (c == INVOKEINTERFACE)
+ cname = cp.getInterfaceMethodrefClassName(index);
+ else
+ cname = cp.getMethodrefClassName(index);
- return cname;
+ return cname;
}
/**
* Returns the name of the called method.
*/
public String getMethodName() {
- ConstPool cp = getConstPool();
- int nt = getNameAndType(cp);
- return cp.getUtf8Info(cp.getNameAndTypeName(nt));
+ ConstPool cp = getConstPool();
+ int nt = getNameAndType(cp);
+ return cp.getUtf8Info(cp.getNameAndTypeName(nt));
}
/**
* Returns the called method.
*/
public CtMethod getMethod() throws NotFoundException {
- return getCtClass().getMethod(getMethodName(), getMethodDesc());
+ return getCtClass().getMethod(getMethodName(), getMethodDesc());
}
private String getMethodDesc() {
- ConstPool cp = getConstPool();
- int nt = getNameAndType(cp);
- return cp.getUtf8Info(cp.getNameAndTypeDescriptor(nt));
+ ConstPool cp = getConstPool();
+ int nt = getNameAndType(cp);
+ return cp.getUtf8Info(cp.getNameAndTypeDescriptor(nt));
}
/**
* the throws declaration allows the method to throw.
*/
public CtClass[] mayThrow() {
- return super.mayThrow();
+ return super.mayThrow();
}
/*
* Returns the parameter types of the called method.
public CtClass[] getParameterTypes() throws NotFoundException {
- return Descriptor.getParameterTypes(getMethodDesc(),
- thisClass.getClassPool());
+ return Descriptor.getParameterTypes(getMethodDesc(),
+ thisClass.getClassPool());
}
*/
* Returns the return type of the called method.
public CtClass getReturnType() throws NotFoundException {
- return Descriptor.getReturnType(getMethodDesc(),
- thisClass.getClassPool());
+ return Descriptor.getReturnType(getMethodDesc(),
+ thisClass.getClassPool());
}
*/
*
* <p>$0 is available even if the called method is static.
*
- * @param statement a Java statement.
+ * @param statement a Java statement.
*/
public void replace(String statement) throws CannotCompileException {
- ConstPool constPool = getConstPool();
- int pos = currentPos;
- int index = iterator.u16bitAt(pos + 1);
-
- String classname, methodname, signature;
- int opcodeSize;
- int c = iterator.byteAt(pos);
- if (c == INVOKEINTERFACE) {
- opcodeSize = 5;
- classname = constPool.getInterfaceMethodrefClassName(index);
- methodname = constPool.getInterfaceMethodrefName(index);
- signature = constPool.getInterfaceMethodrefType(index);
- }
- else if (c == INVOKESTATIC
- || c == INVOKESPECIAL || c == INVOKEVIRTUAL) {
- opcodeSize = 3;
- classname = constPool.getMethodrefClassName(index);
- methodname = constPool.getMethodrefName(index);
- signature = constPool.getMethodrefType(index);
- }
- else
- throw new CannotCompileException("not method invocation");
-
- Javac jc = new Javac(thisClass);
- ClassPool cp = thisClass.getClassPool();
- CodeAttribute ca = iterator.get();
- try {
- CtClass[] params = Descriptor.getParameterTypes(signature, cp);
- CtClass retType = Descriptor.getReturnType(signature, cp);
- int paramVar = ca.getMaxLocals();
- jc.recordParams(classname, params,
- true, paramVar, withinStatic());
- int retVar = jc.recordReturnType(retType, true);
- jc.recordProceed(Javac.param0Name, methodname);
-
- /* Is $_ included in the source code?
- */
- checkResultValue(retType, statement);
-
- Bytecode bytecode = jc.getBytecode();
- storeStack(params, c == INVOKESTATIC, paramVar, bytecode);
- jc.compileStmnt(statement);
- if (retType != CtClass.voidType)
- bytecode.addLoad(retVar, retType);
-
- replace0(pos, bytecode, opcodeSize);
- }
- catch (CompileError e) { throw new CannotCompileException(e); }
- catch (NotFoundException e) { throw new CannotCompileException(e); }
- catch (BadBytecode e) {
- throw new CannotCompileException("broken method");
- }
+ ConstPool constPool = getConstPool();
+ int pos = currentPos;
+ int index = iterator.u16bitAt(pos + 1);
+
+ String classname, methodname, signature;
+ int opcodeSize;
+ int c = iterator.byteAt(pos);
+ if (c == INVOKEINTERFACE) {
+ opcodeSize = 5;
+ classname = constPool.getInterfaceMethodrefClassName(index);
+ methodname = constPool.getInterfaceMethodrefName(index);
+ signature = constPool.getInterfaceMethodrefType(index);
+ }
+ else if (c == INVOKESTATIC
+ || c == INVOKESPECIAL || c == INVOKEVIRTUAL) {
+ opcodeSize = 3;
+ classname = constPool.getMethodrefClassName(index);
+ methodname = constPool.getMethodrefName(index);
+ signature = constPool.getMethodrefType(index);
+ }
+ else
+ throw new CannotCompileException("not method invocation");
+
+ Javac jc = new Javac(thisClass);
+ ClassPool cp = thisClass.getClassPool();
+ CodeAttribute ca = iterator.get();
+ try {
+ CtClass[] params = Descriptor.getParameterTypes(signature, cp);
+ CtClass retType = Descriptor.getReturnType(signature, cp);
+ int paramVar = ca.getMaxLocals();
+ jc.recordParams(classname, params,
+ true, paramVar, withinStatic());
+ int retVar = jc.recordReturnType(retType, true);
+ jc.recordProceed(Javac.param0Name, methodname);
+
+ /* Is $_ included in the source code?
+ */
+ checkResultValue(retType, statement);
+
+ Bytecode bytecode = jc.getBytecode();
+ storeStack(params, c == INVOKESTATIC, paramVar, bytecode);
+ jc.compileStmnt(statement);
+ if (retType != CtClass.voidType)
+ bytecode.addLoad(retVar, retType);
+
+ replace0(pos, bytecode, opcodeSize);
+ }
+ catch (CompileError e) { throw new CannotCompileException(e); }
+ catch (NotFoundException e) { throw new CannotCompileException(e); }
+ catch (BadBytecode e) {
+ throw new CannotCompileException("broken method");
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.expr;
import javassist.*;
* Undocumented constructor. Do not use; internal-use only.
*/
NewExpr(int pos, CodeIterator i, CtClass declaring, MethodInfo m,
- String type, int np)
+ String type, int np)
{
- super(pos, i, declaring, m);
- newTypeName = type;
- newPos = np;
+ super(pos, i, declaring, m);
+ newTypeName = type;
+ newPos = np;
}
private int getNameAndType(ConstPool cp) {
- String cname;
- int pos = currentPos;
- int c = iterator.byteAt(pos);
- int index = iterator.u16bitAt(pos + 1);
-
- if (c == INVOKEINTERFACE)
- return cp.getInterfaceMethodrefNameAndType(index);
- else
- return cp.getMethodrefNameAndType(index);
+ String cname;
+ int pos = currentPos;
+ int c = iterator.byteAt(pos);
+ int index = iterator.u16bitAt(pos + 1);
+
+ if (c == INVOKEINTERFACE)
+ return cp.getInterfaceMethodrefNameAndType(index);
+ else
+ return cp.getMethodrefNameAndType(index);
}
/**
* Returns the line number of the source line containing the
* <tt>new</tt> expression.
*
- * @return -1 if this information is not available.
+ * @return -1 if this information is not available.
*/
public int getLineNumber() {
- return super.getLineNumber();
+ return super.getLineNumber();
}
/**
* Returns the source file containing the <tt>new</tt> expression.
*
- * @return null if this information is not available.
+ * @return null if this information is not available.
*/
public String getFileName() {
- return super.getFileName();
+ return super.getFileName();
}
/**
* Returns the class of the created object.
*/
private CtClass getCtClass() throws NotFoundException {
- return thisClass.getClassPool().get(newTypeName);
+ return thisClass.getClassPool().get(newTypeName);
}
/**
* Returns the class name of the created object.
*/
public String getClassName() {
- return newTypeName;
+ return newTypeName;
}
/**
* Returns the constructor called for creating the object.
*/
public CtConstructor getConstructor() throws NotFoundException {
- ConstPool cp = getConstPool();
- int index = iterator.u16bitAt(currentPos + 1);
- String desc = cp.getMethodrefType(index);
- return getCtClass().getConstructor(desc);
+ ConstPool cp = getConstPool();
+ int index = iterator.u16bitAt(currentPos + 1);
+ String desc = cp.getMethodrefType(index);
+ return getCtClass().getConstructor(desc);
}
/**
* the throws declaration allows the method to throw.
*/
public CtClass[] mayThrow() {
- return super.mayThrow();
+ return super.mayThrow();
}
/*
* Returns the parameter types of the constructor.
public CtClass[] getParameterTypes() throws NotFoundException {
- ConstPool cp = getConstPool();
- int index = iterator.u16bitAt(currentPos + 1);
- String desc = cp.getMethodrefType(index);
- return Descriptor.getParameterTypes(desc, thisClass.getClassPool());
+ ConstPool cp = getConstPool();
+ int index = iterator.u16bitAt(currentPos + 1);
+ String desc = cp.getMethodrefType(index);
+ return Descriptor.getParameterTypes(desc, thisClass.getClassPool());
}
*/
private int canReplace() throws CannotCompileException {
- int op = iterator.byteAt(newPos + 3);
- if (op == Opcode.DUP)
- return 4;
- else if (op == Opcode.DUP_X1
- && iterator.byteAt(newPos + 4) == Opcode.SWAP)
- return 5;
- else
- throw new CannotCompileException(
- "sorry, cannot edit NEW followed by no DUP");
+ int op = iterator.byteAt(newPos + 3);
+ if (op == Opcode.DUP)
+ return 4;
+ else if (op == Opcode.DUP_X1
+ && iterator.byteAt(newPos + 4) == Opcode.SWAP)
+ return 5;
+ else
+ throw new CannotCompileException(
+ "sorry, cannot edit NEW followed by no DUP");
}
/**
*
* <p>$0 is available but the value is null.
*
- * @param statement a Java statement.
+ * @param statement a Java statement.
*/
public void replace(String statement) throws CannotCompileException {
- final int bytecodeSize = 3;
- int pos = newPos;
-
- int newIndex = iterator.u16bitAt(pos + 1);
-
- /* delete the preceding NEW and DUP (or DUP_X1, SWAP) instructions.
- */
- int end = pos + canReplace();
- for (int i = pos; i < end; ++i)
- iterator.writeByte(NOP, i);
-
- ConstPool constPool = getConstPool();
- pos = currentPos;
- int methodIndex = iterator.u16bitAt(pos + 1); // constructor
-
- String signature = constPool.getMethodrefType(methodIndex);
-
- Javac jc = new Javac(thisClass);
- ClassPool cp = thisClass.getClassPool();
- CodeAttribute ca = iterator.get();
- try {
- CtClass[] params = Descriptor.getParameterTypes(signature, cp);
- CtClass newType = cp.get(newTypeName);
- int paramVar = ca.getMaxLocals();
- jc.recordParams(newTypeName, params,
- true, paramVar, withinStatic());
- int retVar = jc.recordReturnType(newType, true);
- jc.recordProceed(new ProceedForNew(newType, newIndex,
- methodIndex));
-
- /* Is $_ included in the source code?
- */
- checkResultValue(newType, statement);
-
- Bytecode bytecode = jc.getBytecode();
- storeStack(params, true, paramVar, bytecode);
- jc.compileStmnt(statement);
- bytecode.addAload(retVar);
-
- replace0(pos, bytecode, bytecodeSize);
- }
- catch (CompileError e) { throw new CannotCompileException(e); }
- catch (NotFoundException e) { throw new CannotCompileException(e); }
- catch (BadBytecode e) {
- throw new CannotCompileException("broken method");
- }
+ final int bytecodeSize = 3;
+ int pos = newPos;
+
+ int newIndex = iterator.u16bitAt(pos + 1);
+
+ /* delete the preceding NEW and DUP (or DUP_X1, SWAP) instructions.
+ */
+ int end = pos + canReplace();
+ for (int i = pos; i < end; ++i)
+ iterator.writeByte(NOP, i);
+
+ ConstPool constPool = getConstPool();
+ pos = currentPos;
+ int methodIndex = iterator.u16bitAt(pos + 1); // constructor
+
+ String signature = constPool.getMethodrefType(methodIndex);
+
+ Javac jc = new Javac(thisClass);
+ ClassPool cp = thisClass.getClassPool();
+ CodeAttribute ca = iterator.get();
+ try {
+ CtClass[] params = Descriptor.getParameterTypes(signature, cp);
+ CtClass newType = cp.get(newTypeName);
+ int paramVar = ca.getMaxLocals();
+ jc.recordParams(newTypeName, params,
+ true, paramVar, withinStatic());
+ int retVar = jc.recordReturnType(newType, true);
+ jc.recordProceed(new ProceedForNew(newType, newIndex,
+ methodIndex));
+
+ /* Is $_ included in the source code?
+ */
+ checkResultValue(newType, statement);
+
+ Bytecode bytecode = jc.getBytecode();
+ storeStack(params, true, paramVar, bytecode);
+ jc.compileStmnt(statement);
+ bytecode.addAload(retVar);
+
+ replace0(pos, bytecode, bytecodeSize);
+ }
+ catch (CompileError e) { throw new CannotCompileException(e); }
+ catch (NotFoundException e) { throw new CannotCompileException(e); }
+ catch (BadBytecode e) {
+ throw new CannotCompileException("broken method");
+ }
}
static class ProceedForNew implements ProceedHandler {
- CtClass newType;
- int newIndex, methodIndex;
-
- ProceedForNew(CtClass nt, int ni, int mi) {
- newType = nt;
- newIndex = ni;
- methodIndex = mi;
- }
-
- public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
- throws CompileError
- {
- bytecode.addOpcode(NEW);
- bytecode.addIndex(newIndex);
- bytecode.addOpcode(DUP);
- gen.atMethodCall2(newType, MethodInfo.nameInit,
- args, false, true);
- gen.setType(newType);
- }
+ CtClass newType;
+ int newIndex, methodIndex;
+
+ ProceedForNew(CtClass nt, int ni, int mi) {
+ newType = nt;
+ newIndex = ni;
+ methodIndex = mi;
+ }
+
+ public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
+ throws CompileError
+ {
+ bytecode.addOpcode(NEW);
+ bytecode.addIndex(newIndex);
+ bytecode.addOpcode(DUP);
+ gen.atMethodCall2(newType, MethodInfo.nameInit,
+ args, false, true);
+ gen.setType(newType);
+ }
}
}
--- /dev/null
+<html>
+<body>
+
+<p>This package contains the classes for modifying a method body.
+See <code>ExprEditor</code> (expression editor) for more details.
+
+</body>
+</html>
--- /dev/null
+<html>
+<body>
+The Javassist Core API.
+
+<p>Javassist (<i>Java</i> programming <i>assist</i>ant) is yet another
+reflective system for Java. It is a class library for editing
+bytecode in Java; it enables Java programs to define a new class at
+runtime and to modify a given class file when the JVM loads it.
+
+<p>The most significant class of this package is <code>CtClass</code>.
+See the description of this class first.
+
+</body>
+</html>
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.preproc;
import javassist.CtClass;
* }
* </pre></uL>
*
- * @param cp class pool
- * @param importname the class imported by the declaration
- * @param args the parameters specified by the annotation
- * @return the classes imported in the java source
- * program produced by the preprocessor.
+ * @param cp class pool
+ * @param importname the class imported by the declaration
+ * @param args the parameters specified by the annotation
+ * @return the classes imported in the java source
+ * program produced by the preprocessor.
*/
public CtClass[] assist(ClassPool cp, String importname,
- String[] args) throws CannotCompileException;
+ String[] args) throws CannotCompileException;
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.preproc;
import java.io.IOException;
/**
* Constructs a <code>Compiler</code> with a source file.
*
- * @param inputname the name of the source file.
+ * @param inputname the name of the source file.
*/
public Compiler(String inputname) throws CannotCompileException {
- try {
- input = new BufferedReader(new FileReader(inputname));
- }
- catch (IOException e) {
- throw new CannotCompileException("cannot open: " + inputname);
- }
-
- String outputname = getOutputFilename(inputname);
- if (outputname.equals(inputname))
- throw new CannotCompileException("invalid source name: "
- + inputname);
-
- try {
- output = new BufferedWriter(new FileWriter(outputname));
- }
- catch (IOException e) {
- throw new CannotCompileException("cannot open: " + outputname);
- }
-
- classPool = ClassPool.getDefault();
+ try {
+ input = new BufferedReader(new FileReader(inputname));
+ }
+ catch (IOException e) {
+ throw new CannotCompileException("cannot open: " + inputname);
+ }
+
+ String outputname = getOutputFilename(inputname);
+ if (outputname.equals(inputname))
+ throw new CannotCompileException("invalid source name: "
+ + inputname);
+
+ try {
+ output = new BufferedWriter(new FileWriter(outputname));
+ }
+ catch (IOException e) {
+ throw new CannotCompileException("cannot open: " + outputname);
+ }
+
+ classPool = ClassPool.getDefault();
}
/**
* Starts preprocessing.
*/
public void process() throws IOException, CannotCompileException {
- int c;
- CommentSkipper reader = new CommentSkipper(input, output);
- while ((c = reader.read()) != -1) {
- output.write(c);
- if (c == 'p') {
- if (skipPackage(reader))
- break;
- }
- else if (c == 'i')
- readImport(reader);
- else if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
- break;
- }
-
- while ((c = input.read()) != -1)
- output.write(c);
-
- input.close();
- output.close();
+ int c;
+ CommentSkipper reader = new CommentSkipper(input, output);
+ while ((c = reader.read()) != -1) {
+ output.write(c);
+ if (c == 'p') {
+ if (skipPackage(reader))
+ break;
+ }
+ else if (c == 'i')
+ readImport(reader);
+ else if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
+ break;
+ }
+
+ while ((c = input.read()) != -1)
+ output.write(c);
+
+ input.close();
+ output.close();
}
private boolean skipPackage(CommentSkipper reader) throws IOException {
- int c;
- c = reader.read();
- output.write(c);
- if (c != 'a')
- return true;
-
- while ((c = reader.read()) != -1) {
- output.write(c);
- if (c == ';')
- break;
- }
-
- return false;
+ int c;
+ c = reader.read();
+ output.write(c);
+ if (c != 'a')
+ return true;
+
+ while ((c = reader.read()) != -1) {
+ output.write(c);
+ if (c == ';')
+ break;
+ }
+
+ return false;
}
private void readImport(CommentSkipper reader)
- throws IOException, CannotCompileException
+ throws IOException, CannotCompileException
{
- int word[] = new int[5];
- int c;
- for (int i = 0; i < 5; ++i) {
- word[i] = reader.read();
- output.write(word[i]);
- }
-
- if (word[0] != 'm' || word[1] != 'p' || word[2] != 'o'
- || word[3] != 'r' || word[4] != 't')
- return; // syntax error?
-
- c = skipSpaces(reader, ' ');
- StringBuffer classbuf = new StringBuffer();
- while (c != ' ' && c != '\t' && c != '\n' && c != '\r'
- && c != ';' && c != -1) {
- classbuf.append((char)c);
- c = reader.read();
- }
-
- String importclass = classbuf.toString();
- c = skipSpaces(reader, c);
- if (c == ';') {
- output.write(importclass);
- output.write(';');
- return;
- }
- if (c != 'b')
- syntaxError(importclass);
-
- reader.read(); // skip 'y'
-
- StringBuffer assistant = new StringBuffer();
- Vector args = new Vector();
- c = readAssistant(reader, importclass, assistant, args);
- c = skipSpaces(reader, c);
- if (c != ';')
- syntaxError(importclass);
-
- runAssistant(importclass, assistant.toString(), args);
+ int word[] = new int[5];
+ int c;
+ for (int i = 0; i < 5; ++i) {
+ word[i] = reader.read();
+ output.write(word[i]);
+ }
+
+ if (word[0] != 'm' || word[1] != 'p' || word[2] != 'o'
+ || word[3] != 'r' || word[4] != 't')
+ return; // syntax error?
+
+ c = skipSpaces(reader, ' ');
+ StringBuffer classbuf = new StringBuffer();
+ while (c != ' ' && c != '\t' && c != '\n' && c != '\r'
+ && c != ';' && c != -1) {
+ classbuf.append((char)c);
+ c = reader.read();
+ }
+
+ String importclass = classbuf.toString();
+ c = skipSpaces(reader, c);
+ if (c == ';') {
+ output.write(importclass);
+ output.write(';');
+ return;
+ }
+ if (c != 'b')
+ syntaxError(importclass);
+
+ reader.read(); // skip 'y'
+
+ StringBuffer assistant = new StringBuffer();
+ Vector args = new Vector();
+ c = readAssistant(reader, importclass, assistant, args);
+ c = skipSpaces(reader, c);
+ if (c != ';')
+ syntaxError(importclass);
+
+ runAssistant(importclass, assistant.toString(), args);
}
void syntaxError(String importclass) throws CannotCompileException {
- throw new CannotCompileException("Syntax error. Cannot import "
- + importclass);
+ throw new CannotCompileException("Syntax error. Cannot import "
+ + importclass);
}
int readAssistant(CommentSkipper reader, String importclass,
- StringBuffer assistant, Vector args)
- throws IOException, CannotCompileException
+ StringBuffer assistant, Vector args)
+ throws IOException, CannotCompileException
{
- int c = readArgument(reader, assistant);
- c = skipSpaces(reader, c);
- if (c == '(') {
- do {
- StringBuffer arg = new StringBuffer();
- c = readArgument(reader, arg);
- args.addElement(arg.toString());
- c = skipSpaces(reader, c);
- } while (c == ',');
-
- if (c != ')')
- syntaxError(importclass);
-
- return reader.read();
- }
-
- return c;
+ int c = readArgument(reader, assistant);
+ c = skipSpaces(reader, c);
+ if (c == '(') {
+ do {
+ StringBuffer arg = new StringBuffer();
+ c = readArgument(reader, arg);
+ args.addElement(arg.toString());
+ c = skipSpaces(reader, c);
+ } while (c == ',');
+
+ if (c != ')')
+ syntaxError(importclass);
+
+ return reader.read();
+ }
+
+ return c;
}
int readArgument(CommentSkipper reader, StringBuffer buf)
- throws IOException
+ throws IOException
{
- int c = skipSpaces(reader, ' ');
- while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
- || '0' <= c && c <= '9' || c == '.' || c == '_') {
- buf.append((char)c);
- c = reader.read();
- }
-
- return c;
+ int c = skipSpaces(reader, ' ');
+ while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
+ || '0' <= c && c <= '9' || c == '.' || c == '_') {
+ buf.append((char)c);
+ c = reader.read();
+ }
+
+ return c;
}
int skipSpaces(CommentSkipper reader, int c) throws IOException {
- while (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
- if (c == '\n' || c == '\r')
- output.write(c);
+ while (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
+ if (c == '\n' || c == '\r')
+ output.write(c);
- c = reader.read();
- }
+ c = reader.read();
+ }
- return c;
+ return c;
}
/**
* import <i>class name</i> by <i>assistant</i> (<i>args1</i>, <i>args2</i>, ...);
* </pre></ul>
*
- * @param classname class name
- * @param assistantname assistant
- * @param argv args1, args2, ...
+ * @param classname class name
+ * @param assistantname assistant
+ * @param argv args1, args2, ...
*/
private void runAssistant(String importname, String assistantname,
- Vector argv)
- throws IOException, CannotCompileException
+ Vector argv)
+ throws IOException, CannotCompileException
{
- Class assistant;
- Assistant a;
- int s = argv.size();
- String[] args = new String[s];
- for (int i = 0; i < s; ++i)
- args[i] = (String)argv.elementAt(i);
-
- try {
- assistant = Class.forName(assistantname);
- }
- catch (ClassNotFoundException e) {
- throw new CannotCompileException("Cannot find " + assistantname);
- }
-
- try {
- a = (Assistant)assistant.newInstance();
- }
- catch (Exception e) {
- throw new CannotCompileException(e);
- }
-
- CtClass[] imports = a.assist(classPool, importname, args);
- s = imports.length;
- if (s < 1)
- output.write(" java.lang.Object;");
- else {
- output.write(' ');
- output.write(imports[0].getName());
- output.write(';');
- for (int i = 1; i < s; ++i) {
- output.write(" import ");
- output.write(imports[1].getName());
- output.write(';');
- }
- }
+ Class assistant;
+ Assistant a;
+ int s = argv.size();
+ String[] args = new String[s];
+ for (int i = 0; i < s; ++i)
+ args[i] = (String)argv.elementAt(i);
+
+ try {
+ assistant = Class.forName(assistantname);
+ }
+ catch (ClassNotFoundException e) {
+ throw new CannotCompileException("Cannot find " + assistantname);
+ }
+
+ try {
+ a = (Assistant)assistant.newInstance();
+ }
+ catch (Exception e) {
+ throw new CannotCompileException(e);
+ }
+
+ CtClass[] imports = a.assist(classPool, importname, args);
+ s = imports.length;
+ if (s < 1)
+ output.write(" java.lang.Object;");
+ else {
+ output.write(' ');
+ output.write(imports[0].getName());
+ output.write(';');
+ for (int i = 1; i < s; ++i) {
+ output.write(" import ");
+ output.write(imports[1].getName());
+ output.write(';');
+ }
+ }
}
private String getOutputFilename(String input) {
- int i = input.lastIndexOf('.');
- if (i < 0)
- i = input.length();
+ int i = input.lastIndexOf('.');
+ if (i < 0)
+ i = input.length();
- return input.substring(0, i) + ".java";
+ return input.substring(0, i) + ".java";
}
public static void main(String[] args) {
- if (args.length > 0)
- try {
- Compiler c = new Compiler(args[0]);
- c.process();
- }
- catch (IOException e) {
- System.err.println(e);
- }
- catch (CannotCompileException e) {
- System.err.println(e);
- }
- else {
- System.err.println("Javassist version " + CtClass.version);
- System.err.println("No source file is specified.");
- }
+ if (args.length > 0)
+ try {
+ Compiler c = new Compiler(args[0]);
+ c.process();
+ }
+ catch (IOException e) {
+ System.err.println(e);
+ }
+ catch (CannotCompileException e) {
+ System.err.println(e);
+ }
+ else {
+ System.err.println("Javassist version " + CtClass.version);
+ System.err.println("No source file is specified.");
+ }
}
}
private BufferedWriter output;
public CommentSkipper(BufferedReader reader, BufferedWriter writer) {
- input = reader;
- output = writer;
+ input = reader;
+ output = writer;
}
public int read() throws IOException {
- int c;
- while ((c = input.read()) != -1)
- if (c != '/')
- return c;
- else {
- c = input.read();
- if (c == '/')
- skipCxxComments();
- else if (c == '*')
- skipCComments();
- else
- output.write('/');
- }
-
- return c;
+ int c;
+ while ((c = input.read()) != -1)
+ if (c != '/')
+ return c;
+ else {
+ c = input.read();
+ if (c == '/')
+ skipCxxComments();
+ else if (c == '*')
+ skipCComments();
+ else
+ output.write('/');
+ }
+
+ return c;
}
private void skipCxxComments() throws IOException {
- int c;
- output.write("//");
- while ((c = input.read()) != -1) {
- output.write(c);
- if (c == '\n' || c == '\r')
- break;
- }
+ int c;
+ output.write("//");
+ while ((c = input.read()) != -1) {
+ output.write(c);
+ if (c == '\n' || c == '\r')
+ break;
+ }
}
private void skipCComments() throws IOException {
- int c;
- boolean star = false;
- output.write("/*");
- while ((c = input.read()) != -1) {
- output.write(c);
- if (c == '*')
- star = true;
- else if(star && c == '/')
- break;
- else
- star = false;
- }
+ int c;
+ boolean star = false;
+ output.write("/*");
+ while ((c = input.read()) != -1) {
+ output.write(c);
+ if (c == '*')
+ star = true;
+ else if(star && c == '/')
+ break;
+ else
+ star = false;
+ }
}
}
--- /dev/null
+<html>
+<body>
+A sample preprocessor.
+
+<p>The preprocessor for running Javassist at compile time.
+The produced class files are saved on a local disk.
+
+<p>This package is provided as a sample implementation of the
+preprocessor using Javassist. All the programs in this package
+uses only the regular Javassist API; they never call any hidden
+methods.
+
+</body>
+</html>
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
/**
*/
public class CannotCreateException extends Exception {
public CannotCreateException(String s) {
- super(s);
+ super(s);
}
public CannotCreateException(Exception e) {
- super("by " + e.toString());
+ super("by " + e.toString());
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
import java.lang.reflect.InvocationTargetException;
* Constructs a CannotInvokeException with an error message.
*/
public CannotInvokeException(String reason) {
- super(reason);
+ super(reason);
}
/**
* Constructs a CannotInvokeException with an InvocationTargetException.
*/
public CannotInvokeException(InvocationTargetException e) {
- super("by " + e.getTargetException().toString());
- err = e.getTargetException();
+ super("by " + e.getTargetException().toString());
+ err = e.getTargetException();
}
/**
* Constructs a CannotInvokeException with an IllegalAccessException.
*/
public CannotInvokeException(IllegalAccessException e) {
- super("by " + e.toString());
- err = e;
+ super("by " + e.toString());
+ err = e;
}
/**
* Constructs a CannotInvokeException with an ClassNotFoundException.
*/
public CannotInvokeException(ClassNotFoundException e) {
- super("by " + e.toString());
- err = e;
+ super("by " + e.toString());
+ err = e;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
import java.lang.reflect.*;
/**
* Constructs a <code>ClassMetaobject</code>.
*
- * @param params <code>params[0]</code> is the name of the class
- * of the reflective objects.
+ * @param params <code>params[0]</code> is the name of the class
+ * of the reflective objects.
*/
public ClassMetaobject(String[] params)
{
- try {
- javaClass = getClassObject(params[0]);
- }
- catch (ClassNotFoundException e) {
- javaClass = null;
- }
+ try {
+ javaClass = getClassObject(params[0]);
+ }
+ catch (ClassNotFoundException e) {
+ javaClass = null;
+ }
- constructors = javaClass.getConstructors();
- methods = null;
+ constructors = javaClass.getConstructors();
+ methods = null;
}
private void writeObject(ObjectOutputStream out) throws IOException {
- out.writeUTF(javaClass.getName());
+ out.writeUTF(javaClass.getName());
}
private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
+ throws IOException, ClassNotFoundException
{
- javaClass = getClassObject(in.readUTF());
- constructors = javaClass.getConstructors();
- methods = null;
+ javaClass = getClassObject(in.readUTF());
+ constructors = javaClass.getConstructors();
+ methods = null;
}
private Class getClassObject(String name) throws ClassNotFoundException {
- if (useContextClassLoader)
- return Thread.currentThread().getContextClassLoader()
- .loadClass(name);
- else
- return Class.forName(name);
+ if (useContextClassLoader)
+ return Thread.currentThread().getContextClassLoader()
+ .loadClass(name);
+ else
+ return Class.forName(name);
}
/**
* Obtains the <code>java.lang.Class</code> representing this class.
*/
public final Class getJavaClass() {
- return javaClass;
+ return javaClass;
}
/**
* Obtains the name of this class.
*/
public final String getName() {
- return javaClass.getName();
+ return javaClass.getName();
}
/**
* Returns true if <code>obj</code> is an instance of this class.
*/
public final boolean isInstance(Object obj) {
- return javaClass.isInstance(obj);
+ return javaClass.isInstance(obj);
}
/**
* Creates a new instance of the class.
*
- * @param args the arguments passed to the constructor.
+ * @param args the arguments passed to the constructor.
*/
public final Object newInstance(Object[] args)
- throws CannotCreateException
+ throws CannotCreateException
{
- int n = constructors.length;
- for (int i = 0; i < n; ++i) {
- try {
- return constructors[i].newInstance(args);
- }
- catch (IllegalArgumentException e) {
- // try again
- }
- catch (InstantiationException e) {
- throw new CannotCreateException(e);
- }
- catch (IllegalAccessException e) {
- throw new CannotCreateException(e);
- }
- catch (InvocationTargetException e) {
- throw new CannotCreateException(e);
- }
- }
+ int n = constructors.length;
+ for (int i = 0; i < n; ++i) {
+ try {
+ return constructors[i].newInstance(args);
+ }
+ catch (IllegalArgumentException e) {
+ // try again
+ }
+ catch (InstantiationException e) {
+ throw new CannotCreateException(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new CannotCreateException(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new CannotCreateException(e);
+ }
+ }
- throw new CannotCreateException("no constructor matches");
+ throw new CannotCreateException("no constructor matches");
}
/**
* <p>Every subclass of this class should redefine this method.
*/
public Object trapFieldRead(String name) {
- Class jc = getJavaClass();
- try {
- return jc.getField(name).get(null);
- }
- catch (NoSuchFieldException e) {
- throw new RuntimeException(e.toString());
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e.toString());
- }
+ Class jc = getJavaClass();
+ try {
+ return jc.getField(name).get(null);
+ }
+ catch (NoSuchFieldException e) {
+ throw new RuntimeException(e.toString());
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e.toString());
+ }
}
/**
* <p>Every subclass of this class should redefine this method.
*/
public void trapFieldWrite(String name, Object value) {
- Class jc = getJavaClass();
- try {
- jc.getField(name).set(null, value);
- }
- catch (NoSuchFieldException e) {
- throw new RuntimeException(e.toString());
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e.toString());
- }
+ Class jc = getJavaClass();
+ try {
+ jc.getField(name).set(null, value);
+ }
+ catch (NoSuchFieldException e) {
+ throw new RuntimeException(e.toString());
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e.toString());
+ }
}
/**
* Invokes a method whose name begins with
* <code>methodPrefix "_m_"</code> and the identifier.
*
- * @exception CannotInvokeException if the invocation fails.
+ * @exception CannotInvokeException if the invocation fails.
*/
static public Object invoke(Object target, int identifier, Object[] args)
- throws Throwable
+ throws Throwable
{
- Method[] allmethods = target.getClass().getMethods();
- int n = allmethods.length;
- String head = methodPrefix + identifier;
- for (int i = 0; i < n; ++i)
- if (allmethods[i].getName().startsWith(head)) {
- try {
- return allmethods[i].invoke(target, args);
- } catch (java.lang.reflect.InvocationTargetException e) {
- throw e.getTargetException();
- } catch (java.lang.IllegalAccessException e) {
- throw new CannotInvokeException(e);
- }
- }
+ Method[] allmethods = target.getClass().getMethods();
+ int n = allmethods.length;
+ String head = methodPrefix + identifier;
+ for (int i = 0; i < n; ++i)
+ if (allmethods[i].getName().startsWith(head)) {
+ try {
+ return allmethods[i].invoke(target, args);
+ } catch (java.lang.reflect.InvocationTargetException e) {
+ throw e.getTargetException();
+ } catch (java.lang.IllegalAccessException e) {
+ throw new CannotInvokeException(e);
+ }
+ }
- throw new CannotInvokeException("cannot find a method");
+ throw new CannotInvokeException("cannot find a method");
}
/**
* <p>Every subclass of this class should redefine this method.
*/
public Object trapMethodcall(int identifier, Object[] args)
- throws Throwable
+ throws Throwable
{
- try {
- Method[] m = getReflectiveMethods();
- return m[identifier].invoke(null, args);
- }
- catch (java.lang.reflect.InvocationTargetException e) {
- throw e.getTargetException();
- }
+ try {
+ Method[] m = getReflectiveMethods();
+ return m[identifier].invoke(null, args);
+ }
+ catch (java.lang.reflect.InvocationTargetException e) {
+ throw e.getTargetException();
+ }
catch (java.lang.IllegalAccessException e) {
- throw new CannotInvokeException(e);
- }
+ throw new CannotInvokeException(e);
+ }
}
/**
* object. This method is for the internal use only.
*/
public final Method[] getReflectiveMethods() {
- if (methods != null)
- return methods;
+ if (methods != null)
+ return methods;
- Class baseclass = getJavaClass();
- Method[] allmethods = baseclass.getMethods();
- int n = allmethods.length;
- methods = new Method[n];
- for (int i = 0; i < n; ++i) {
- Method m = allmethods[i];
- if (m.getDeclaringClass() == baseclass) {
- String mname = m.getName();
- if (mname.startsWith(methodPrefix)) {
- int k = 0;
- for (int j = methodPrefixLen;; ++j) {
- char c = mname.charAt(j);
- if ('0' <= c && c <= '9')
- k = k * 10 + c - '0';
- else
- break;
- }
+ Class baseclass = getJavaClass();
+ Method[] allmethods = baseclass.getMethods();
+ int n = allmethods.length;
+ methods = new Method[n];
+ for (int i = 0; i < n; ++i) {
+ Method m = allmethods[i];
+ if (m.getDeclaringClass() == baseclass) {
+ String mname = m.getName();
+ if (mname.startsWith(methodPrefix)) {
+ int k = 0;
+ for (int j = methodPrefixLen;; ++j) {
+ char c = mname.charAt(j);
+ if ('0' <= c && c <= '9')
+ k = k * 10 + c - '0';
+ else
+ break;
+ }
- methods[k] = m;
- }
- }
- }
+ methods[k] = m;
+ }
+ }
+ }
- return methods;
+ return methods;
}
/**
* by <code>identifier</code>.
*/
public final String getMethodName(int identifier) {
- String mname = getReflectiveMethods()[identifier].getName();
- int j = ClassMetaobject.methodPrefixLen;
- for (;;) {
- char c = mname.charAt(j++);
- if (c < '0' || '9' < c)
- break;
- }
+ String mname = getReflectiveMethods()[identifier].getName();
+ int j = ClassMetaobject.methodPrefixLen;
+ for (;;) {
+ char c = mname.charAt(j++);
+ if (c < '0' || '9' < c)
+ break;
+ }
- return mname.substring(j);
+ return mname.substring(j);
}
/**
* by <code>identifier</code>.
*/
public final Class[] getParameterTypes(int identifier) {
- return getReflectiveMethods()[identifier].getParameterTypes();
+ return getReflectiveMethods()[identifier].getParameterTypes();
}
/**
* return type of the method specified by <code>identifier</code>.
*/
public final Class getReturnType(int identifier) {
- return getReflectiveMethods()[identifier].getReturnType();
+ return getReflectiveMethods()[identifier].getReturnType();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
import javassist.CtClass;
public class Compiler {
public static void main(String[] args) throws Exception {
- if (args.length == 0) {
- help(System.err);
- return;
- }
+ if (args.length == 0) {
+ help(System.err);
+ return;
+ }
- CompiledClass[] entries = new CompiledClass[args.length];
- int n = parse(args, entries);
+ CompiledClass[] entries = new CompiledClass[args.length];
+ int n = parse(args, entries);
- if (n < 1) {
- System.err.println("bad parameter.");
- return;
- }
+ if (n < 1) {
+ System.err.println("bad parameter.");
+ return;
+ }
- processClasses(entries, n);
+ processClasses(entries, n);
}
private static void processClasses(CompiledClass[] entries, int n)
- throws Exception
+ throws Exception
{
- Reflection implementor = new Reflection();
- ClassPool pool = ClassPool.getDefault(implementor);
-
- for (int i = 0; i < n; ++i) {
- CtClass c = pool.get(entries[i].classname);
- if (entries[i].metaobject != null
- || entries[i].classobject != null) {
- String metaobj, classobj;
-
- if (entries[i].metaobject == null)
- metaobj = "javassist.reflect.Metaobject";
- else
- metaobj = entries[i].metaobject;
-
- if (entries[i].classobject == null)
- classobj = "javassist.reflect.ClassMetaobject";
- else
- classobj = entries[i].classobject;
-
- if (!implementor.makeReflective(c, pool.get(metaobj),
- pool.get(classobj)))
- System.err.println("Warning: " + c.getName()
- + " is reflective. It was not changed.");
-
- System.err.println(c.getName() + ": " + metaobj + ", "
- + classobj);
- }
- else
- System.err.println(c.getName() + ": not reflective");
- }
-
- for (int i = 0; i < n; ++i)
- pool.writeFile(entries[i].classname);
+ Reflection implementor = new Reflection();
+ ClassPool pool = ClassPool.getDefault(implementor);
+
+ for (int i = 0; i < n; ++i) {
+ CtClass c = pool.get(entries[i].classname);
+ if (entries[i].metaobject != null
+ || entries[i].classobject != null) {
+ String metaobj, classobj;
+
+ if (entries[i].metaobject == null)
+ metaobj = "javassist.reflect.Metaobject";
+ else
+ metaobj = entries[i].metaobject;
+
+ if (entries[i].classobject == null)
+ classobj = "javassist.reflect.ClassMetaobject";
+ else
+ classobj = entries[i].classobject;
+
+ if (!implementor.makeReflective(c, pool.get(metaobj),
+ pool.get(classobj)))
+ System.err.println("Warning: " + c.getName()
+ + " is reflective. It was not changed.");
+
+ System.err.println(c.getName() + ": " + metaobj + ", "
+ + classobj);
+ }
+ else
+ System.err.println(c.getName() + ": not reflective");
+ }
+
+ for (int i = 0; i < n; ++i)
+ pool.writeFile(entries[i].classname);
}
private static int parse(String[] args, CompiledClass[] result) {
- int n = -1;
- for (int i = 0; i < args.length; ++i) {
- String a = args[i];
- if (a.equals("-m"))
- if (n < 0 || i + 1 > args.length)
- return -1;
- else
- result[n].metaobject = args[++i];
- else if (a.equals("-c"))
- if (n < 0 || i + 1 > args.length)
- return -1;
- else
- result[n].classobject = args[++i];
- else if (a.charAt(0) == '-')
- return -1;
- else {
- CompiledClass cc = new CompiledClass();
- cc.classname = a;
- cc.metaobject = null;
- cc.classobject = null;
- result[++n] = cc;
- }
- }
-
- return n + 1;
+ int n = -1;
+ for (int i = 0; i < args.length; ++i) {
+ String a = args[i];
+ if (a.equals("-m"))
+ if (n < 0 || i + 1 > args.length)
+ return -1;
+ else
+ result[n].metaobject = args[++i];
+ else if (a.equals("-c"))
+ if (n < 0 || i + 1 > args.length)
+ return -1;
+ else
+ result[n].classobject = args[++i];
+ else if (a.charAt(0) == '-')
+ return -1;
+ else {
+ CompiledClass cc = new CompiledClass();
+ cc.classname = a;
+ cc.metaobject = null;
+ cc.classobject = null;
+ result[++n] = cc;
+ }
+ }
+
+ return n + 1;
}
private static void help(PrintStream out) {
- out.println("Usage: java javassist.reflect.Compiler");
- out.println(" (<class> [-m <metaobject>] [-c <class metaobject>])+");
+ out.println("Usage: java javassist.reflect.Compiler");
+ out.println(" (<class> [-m <metaobject>] [-c <class metaobject>])+");
}
}
/*
- * This file is part of the Javassist toolkit.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
import javassist.CannotCompileException;
* Loads a class with an instance of <code>Loader</code>
* and calls <code>main()</code> in that class.
*
- * @param args[0] class name to be loaded.
- * @param args[1-n] parameters passed to <code>main()</code>.
+ * @param args[0] class name to be loaded.
+ * @param args[1-n] parameters passed to <code>main()</code>.
*/
public static void main(String[] args) throws Throwable {
- Loader cl = new Loader();
- cl.run(args);
+ Loader cl = new Loader();
+ cl.run(args);
}
/**
* Constructs a new class loader.
*/
public Loader() {
- super();
- delegateLoadingOf("javassist.reflect.Loader");
+ super();
+ delegateLoadingOf("javassist.reflect.Loader");
- reflection = new Reflection();
- setClassPool(ClassPool.getDefault(reflection));
+ reflection = new Reflection();
+ setClassPool(ClassPool.getDefault(reflection));
}
/**
* If the super class is also made reflective, it must be done
* before the sub class.
*
- * @param clazz the reflective class.
- * @param metaobject the class of metaobjects.
- * It must be a subclass of
- * <code>Metaobject</code>.
- * @param metaclass the class of the class metaobject.
- * It must be a subclass of
- * <code>ClassMetaobject</code>.
- * @return <code>false</code> if the class is already reflective.
+ * @param clazz the reflective class.
+ * @param metaobject the class of metaobjects.
+ * It must be a subclass of
+ * <code>Metaobject</code>.
+ * @param metaclass the class of the class metaobject.
+ * It must be a subclass of
+ * <code>ClassMetaobject</code>.
+ * @return <code>false</code> if the class is already reflective.
*
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
*/
public boolean makeReflective(String clazz,
- String metaobject, String metaclass)
- throws CannotCompileException, NotFoundException
+ String metaobject, String metaclass)
+ throws CannotCompileException, NotFoundException
{
- return reflection.makeReflective(clazz, metaobject, metaclass);
+ return reflection.makeReflective(clazz, metaobject, metaclass);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
/**
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
import java.lang.reflect.Method;
* constructed before the constructor is called on the base-level
* object.
*
- * @param self the object that this metaobject is associated with.
- * @param args the parameters passed to the constructor of
- * <code>self</code>.
+ * @param self the object that this metaobject is associated with.
+ * @param args the parameters passed to the constructor of
+ * <code>self</code>.
*/
public Metaobject(Object self, Object[] args) {
- baseobject = (Metalevel)self;
- classmetaobject = baseobject._getClass();
- methods = classmetaobject.getReflectiveMethods();
+ baseobject = (Metalevel)self;
+ classmetaobject = baseobject._getClass();
+ methods = classmetaobject.getReflectiveMethods();
}
/**
* for initialization.
*/
protected Metaobject() {
- baseobject = null;
- classmetaobject = null;
- methods = null;
+ baseobject = null;
+ classmetaobject = null;
+ methods = null;
}
private void writeObject(ObjectOutputStream out) throws IOException {
- out.writeObject(baseobject);
+ out.writeObject(baseobject);
}
private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
+ throws IOException, ClassNotFoundException
{
- baseobject = (Metalevel)in.readObject();
- classmetaobject = baseobject._getClass();
- methods = classmetaobject.getReflectiveMethods();
+ baseobject = (Metalevel)in.readObject();
+ classmetaobject = baseobject._getClass();
+ methods = classmetaobject.getReflectiveMethods();
}
/**
* @see javassist.reflect.ClassMetaobject
*/
public final ClassMetaobject getClassMetaobject() {
- return classmetaobject;
+ return classmetaobject;
}
/**
* Obtains the object controlled by this metaobject.
*/
public final Object getObject() {
- return baseobject;
+ return baseobject;
}
/**
* Changes the object controlled by this metaobject.
*
- * @param self the object
+ * @param self the object
*/
public final void setObject(Object self) {
- baseobject = (Metalevel)self;
- classmetaobject = baseobject._getClass();
- methods = classmetaobject.getReflectiveMethods();
+ baseobject = (Metalevel)self;
+ classmetaobject = baseobject._getClass();
+ methods = classmetaobject.getReflectiveMethods();
- // call _setMetaobject() after the metaobject is settled.
- baseobject._setMetaobject(this);
+ // call _setMetaobject() after the metaobject is settled.
+ baseobject._setMetaobject(this);
}
/**
*/
public final String getMethodName(int identifier) {
String mname = methods[identifier].getName();
- int j = ClassMetaobject.methodPrefixLen;
- for (;;) {
- char c = mname.charAt(j++);
- if (c < '0' || '9' < c)
- break;
- }
-
- return mname.substring(j);
+ int j = ClassMetaobject.methodPrefixLen;
+ for (;;) {
+ char c = mname.charAt(j++);
+ if (c < '0' || '9' < c)
+ break;
+ }
+
+ return mname.substring(j);
}
/**
* by <code>identifier</code>.
*/
public final Class[] getParameterTypes(int identifier) {
- return methods[identifier].getParameterTypes();
+ return methods[identifier].getParameterTypes();
}
/**
* return type of the method specified by <code>identifier</code>.
*/
public final Class getReturnType(int identifier) {
- return methods[identifier].getReturnType();
+ return methods[identifier].getReturnType();
}
/**
* <p>Every subclass of this class should redefine this method.
*/
public Object trapFieldRead(String name) {
- Class jc = getClassMetaobject().getJavaClass();
- try {
- return jc.getField(name).get(getObject());
- }
- catch (NoSuchFieldException e) {
- throw new RuntimeException(e.toString());
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e.toString());
- }
+ Class jc = getClassMetaobject().getJavaClass();
+ try {
+ return jc.getField(name).get(getObject());
+ }
+ catch (NoSuchFieldException e) {
+ throw new RuntimeException(e.toString());
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e.toString());
+ }
}
/**
* <p>Every subclass of this class should redefine this method.
*/
public void trapFieldWrite(String name, Object value) {
- Class jc = getClassMetaobject().getJavaClass();
- try {
- jc.getField(name).set(getObject(), value);
- }
- catch (NoSuchFieldException e) {
- throw new RuntimeException(e.toString());
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e.toString());
- }
+ Class jc = getClassMetaobject().getJavaClass();
+ try {
+ jc.getField(name).set(getObject(), value);
+ }
+ catch (NoSuchFieldException e) {
+ throw new RuntimeException(e.toString());
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e.toString());
+ }
}
/**
* constructor of the super class finishes.
*/
public Object trapMethodcall(int identifier, Object[] args)
- throws Throwable
+ throws Throwable
{
- try {
- return methods[identifier].invoke(getObject(), args);
- }
- catch (java.lang.reflect.InvocationTargetException e) {
- throw e.getTargetException();
- }
+ try {
+ return methods[identifier].invoke(getObject(), args);
+ }
+ catch (java.lang.reflect.InvocationTargetException e) {
+ throw e.getTargetException();
+ }
catch (java.lang.IllegalAccessException e) {
- throw new CannotInvokeException(e);
- }
+ throw new CannotInvokeException(e);
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
import javassist.*;
protected CodeConverter converter;
private boolean isExcluded(String name) {
- return name.startsWith(ClassMetaobject.methodPrefix)
- || name.equals(classobjectAccessor)
- || name.equals(metaobjectSetter)
- || name.equals(metaobjectGetter)
- || name.startsWith(readPrefix)
- || name.startsWith(writePrefix);
+ return name.startsWith(ClassMetaobject.methodPrefix)
+ || name.equals(classobjectAccessor)
+ || name.equals(metaobjectSetter)
+ || name.equals(metaobjectGetter)
+ || name.startsWith(readPrefix)
+ || name.startsWith(writePrefix);
}
/**
* Constructs a new <code>Reflection</code> object.
*/
public Reflection() {
- classPool = null;
- converter = new CodeConverter();
+ classPool = null;
+ converter = new CodeConverter();
}
/**
* Initializes.
*/
public void start(ClassPool pool) throws NotFoundException {
- classPool = pool;
- final String msg
- = "javassist.reflect.Sample is not found or broken.";
- try {
- CtClass c = classPool.get("javassist.reflect.Sample");
- trapMethod = c.getDeclaredMethod("trap");
- trapStaticMethod = c.getDeclaredMethod("trapStatic");
- trapRead = c.getDeclaredMethod("trapRead");
- trapWrite = c.getDeclaredMethod("trapWrite");
- readParam
- = new CtClass[] { classPool.get("java.lang.Object") };
- }
- catch (NotFoundException e) {
- throw new RuntimeException(msg);
- }
+ classPool = pool;
+ final String msg
+ = "javassist.reflect.Sample is not found or broken.";
+ try {
+ CtClass c = classPool.get("javassist.reflect.Sample");
+ trapMethod = c.getDeclaredMethod("trap");
+ trapStaticMethod = c.getDeclaredMethod("trapStatic");
+ trapRead = c.getDeclaredMethod("trapRead");
+ trapWrite = c.getDeclaredMethod("trapWrite");
+ readParam
+ = new CtClass[] { classPool.get("java.lang.Object") };
+ }
+ catch (NotFoundException e) {
+ throw new RuntimeException(msg);
+ }
}
/**
* in reflective classes.
*/
public void onWrite(ClassPool pool, String classname)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- CtClass c = pool.get(classname);
- c.instrument(converter);
+ CtClass c = pool.get(classname);
+ c.instrument(converter);
}
/**
* If the super class is also made reflective, it must be done
* before the sub class.
*
- * @param classname the name of the reflective class
- * @param metaobject the class name of metaobjects.
- * @param metaclass the class name of the class metaobject.
- * @return <code>false</code> if the class is already reflective.
+ * @param classname the name of the reflective class
+ * @param metaobject the class name of metaobjects.
+ * @param metaclass the class name of the class metaobject.
+ * @return <code>false</code> if the class is already reflective.
*
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
*/
public boolean makeReflective(String classname,
- String metaobject, String metaclass)
- throws CannotCompileException, NotFoundException
+ String metaobject, String metaclass)
+ throws CannotCompileException, NotFoundException
{
- return makeReflective(classPool.get(classname),
- classPool.get(metaobject),
- classPool.get(metaclass));
+ return makeReflective(classPool.get(classname),
+ classPool.get(metaobject),
+ classPool.get(metaclass));
}
/**
* If the super class is also made reflective, it must be done
* before the sub class.
*
- * @param clazz the reflective class.
- * @param metaobject the class of metaobjects.
- * It must be a subclass of
- * <code>Metaobject</code>.
- * @param metaclass the class of the class metaobject.
- * It must be a subclass of
- * <code>ClassMetaobject</code>.
- * @return <code>false</code> if the class is already reflective.
+ * @param clazz the reflective class.
+ * @param metaobject the class of metaobjects.
+ * It must be a subclass of
+ * <code>Metaobject</code>.
+ * @param metaclass the class of the class metaobject.
+ * It must be a subclass of
+ * <code>ClassMetaobject</code>.
+ * @return <code>false</code> if the class is already reflective.
*
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
*/
public boolean makeReflective(Class clazz,
- Class metaobject, Class metaclass)
- throws CannotCompileException, NotFoundException
+ Class metaobject, Class metaclass)
+ throws CannotCompileException, NotFoundException
{
- return makeReflective(clazz.getName(), metaobject.getName(),
- metaclass.getName());
+ return makeReflective(clazz.getName(), metaobject.getName(),
+ metaclass.getName());
}
/**
* If the super class is also made reflective, it must be done
* before the sub class.
*
- * @param clazz the reflective class.
- * @param metaobject the class of metaobjects.
- * It must be a subclass of
- * <code>Metaobject</code>.
- * @param metaclass the class of the class metaobject.
- * It must be a subclass of
- * <code>ClassMetaobject</code>.
- * @return <code>false</code> if the class is already reflective.
+ * @param clazz the reflective class.
+ * @param metaobject the class of metaobjects.
+ * It must be a subclass of
+ * <code>Metaobject</code>.
+ * @param metaclass the class of the class metaobject.
+ * It must be a subclass of
+ * <code>ClassMetaobject</code>.
+ * @return <code>false</code> if the class is already reflective.
*
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
*/
public boolean makeReflective(CtClass clazz,
- CtClass metaobject, CtClass metaclass)
- throws CannotCompileException, NotFoundException
+ CtClass metaobject, CtClass metaclass)
+ throws CannotCompileException, NotFoundException
{
- registerReflectiveClass(clazz);
- return modifyClassfile(clazz, metaobject, metaclass);
+ registerReflectiveClass(clazz);
+ return modifyClassfile(clazz, metaobject, metaclass);
}
/**
* of this class are instrumented.
*/
private void registerReflectiveClass(CtClass clazz) {
- CtField[] fs = clazz.getDeclaredFields();
- for (int i = 0; i < fs.length; ++i) {
- CtField f = fs[i];
- int mod = f.getModifiers();
- if ((mod & Modifier.PUBLIC) != 0 && (mod & Modifier.FINAL) == 0) {
- String name = f.getName();
- converter.replaceFieldRead(f, clazz, readPrefix + name);
- converter.replaceFieldWrite(f, clazz, writePrefix + name);
- }
- }
+ CtField[] fs = clazz.getDeclaredFields();
+ for (int i = 0; i < fs.length; ++i) {
+ CtField f = fs[i];
+ int mod = f.getModifiers();
+ if ((mod & Modifier.PUBLIC) != 0 && (mod & Modifier.FINAL) == 0) {
+ String name = f.getName();
+ converter.replaceFieldRead(f, clazz, readPrefix + name);
+ converter.replaceFieldWrite(f, clazz, writePrefix + name);
+ }
+ }
}
private boolean modifyClassfile(CtClass clazz, CtClass metaobject,
- CtClass metaclass)
- throws CannotCompileException, NotFoundException
+ CtClass metaclass)
+ throws CannotCompileException, NotFoundException
{
- if (clazz.getAttribute("Reflective") != null)
- return false; // this is already reflective.
- else
- clazz.setAttribute("Reflective", new byte[0]);
-
- CtClass mlevel = classPool.get("javassist.reflect.Metalevel");
- boolean addMeta = !clazz.subtypeOf(mlevel);
- if (addMeta)
- clazz.addInterface(mlevel);
-
- processMethods(clazz, addMeta);
- processFields(clazz);
-
- CtField f;
- if (addMeta) {
- f = new CtField(classPool.get("javassist.reflect.Metaobject"),
- metaobjectField, clazz);
- f.setModifiers(Modifier.PROTECTED);
- clazz.addField(f, CtField.Initializer.byNewWithParams(metaobject));
-
- clazz.addMethod(CtNewMethod.getter(metaobjectGetter, f));
- clazz.addMethod(CtNewMethod.setter(metaobjectSetter, f));
- }
-
- f = new CtField(classPool.get("javassist.reflect.ClassMetaobject"),
- classobjectField, clazz);
- f.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
- clazz.addField(f, CtField.Initializer.byNew(metaclass,
- new String[] { clazz.getName() }));
-
- clazz.addMethod(CtNewMethod.getter(classobjectAccessor, f));
- return true;
+ if (clazz.getAttribute("Reflective") != null)
+ return false; // this is already reflective.
+ else
+ clazz.setAttribute("Reflective", new byte[0]);
+
+ CtClass mlevel = classPool.get("javassist.reflect.Metalevel");
+ boolean addMeta = !clazz.subtypeOf(mlevel);
+ if (addMeta)
+ clazz.addInterface(mlevel);
+
+ processMethods(clazz, addMeta);
+ processFields(clazz);
+
+ CtField f;
+ if (addMeta) {
+ f = new CtField(classPool.get("javassist.reflect.Metaobject"),
+ metaobjectField, clazz);
+ f.setModifiers(Modifier.PROTECTED);
+ clazz.addField(f, CtField.Initializer.byNewWithParams(metaobject));
+
+ clazz.addMethod(CtNewMethod.getter(metaobjectGetter, f));
+ clazz.addMethod(CtNewMethod.setter(metaobjectSetter, f));
+ }
+
+ f = new CtField(classPool.get("javassist.reflect.ClassMetaobject"),
+ classobjectField, clazz);
+ f.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
+ clazz.addField(f, CtField.Initializer.byNew(metaclass,
+ new String[] { clazz.getName() }));
+
+ clazz.addMethod(CtNewMethod.getter(classobjectAccessor, f));
+ return true;
}
private void processMethods(CtClass clazz, boolean dontSearch)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- CtMethod[] ms = clazz.getMethods();
- int identifier = 0;
- for (int i = 0; i < ms.length; ++i) {
- CtMethod m = ms[i];
- int mod = m.getModifiers();
- if (Modifier.isPublic(mod) && !Modifier.isAbstract(mod))
- processMethods0(mod, clazz, m, i, dontSearch);
- }
+ CtMethod[] ms = clazz.getMethods();
+ int identifier = 0;
+ for (int i = 0; i < ms.length; ++i) {
+ CtMethod m = ms[i];
+ int mod = m.getModifiers();
+ if (Modifier.isPublic(mod) && !Modifier.isAbstract(mod))
+ processMethods0(mod, clazz, m, i, dontSearch);
+ }
}
private void processMethods0(int mod, CtClass clazz,
- CtMethod m, int identifier, boolean dontSearch)
- throws CannotCompileException, NotFoundException
+ CtMethod m, int identifier, boolean dontSearch)
+ throws CannotCompileException, NotFoundException
{
- CtMethod body;
- String name = m.getName();
-
- if (isExcluded(name)) // internally-used method inherited
- return; // from a reflective class.
-
- CtMethod m2;
- if (m.getDeclaringClass() == clazz) {
- if (Modifier.isNative(mod))
- return;
-
- m2 = m;
- }
- else {
- if (Modifier.isFinal(mod))
- return;
-
- mod &= ~Modifier.NATIVE;
- m2 = CtNewMethod.delegator(findOriginal(m, dontSearch), clazz);
- m2.setModifiers(mod);
- clazz.addMethod(m2);
- }
-
- m2.setName(ClassMetaobject.methodPrefix + identifier
- + "_" + name);
-
- if (Modifier.isStatic(mod))
- body = trapStaticMethod;
- else
- body = trapMethod;
-
- CtMethod wmethod
- = CtNewMethod.wrapped(m.getReturnType(), name,
- m.getParameterTypes(), m.getExceptionTypes(),
- body, ConstParameter.integer(identifier),
- clazz);
- wmethod.setModifiers(mod);
- clazz.addMethod(wmethod);
+ CtMethod body;
+ String name = m.getName();
+
+ if (isExcluded(name)) // internally-used method inherited
+ return; // from a reflective class.
+
+ CtMethod m2;
+ if (m.getDeclaringClass() == clazz) {
+ if (Modifier.isNative(mod))
+ return;
+
+ m2 = m;
+ }
+ else {
+ if (Modifier.isFinal(mod))
+ return;
+
+ mod &= ~Modifier.NATIVE;
+ m2 = CtNewMethod.delegator(findOriginal(m, dontSearch), clazz);
+ m2.setModifiers(mod);
+ clazz.addMethod(m2);
+ }
+
+ m2.setName(ClassMetaobject.methodPrefix + identifier
+ + "_" + name);
+
+ if (Modifier.isStatic(mod))
+ body = trapStaticMethod;
+ else
+ body = trapMethod;
+
+ CtMethod wmethod
+ = CtNewMethod.wrapped(m.getReturnType(), name,
+ m.getParameterTypes(), m.getExceptionTypes(),
+ body, ConstParameter.integer(identifier),
+ clazz);
+ wmethod.setModifiers(mod);
+ clazz.addMethod(wmethod);
}
private CtMethod findOriginal(CtMethod m, boolean dontSearch)
- throws NotFoundException
+ throws NotFoundException
{
- if (dontSearch)
- return m;
-
- String name = m.getName();
- CtMethod[] ms = m.getDeclaringClass().getDeclaredMethods();
- for (int i = 0; i < ms.length; ++i) {
- String orgName = ms[i].getName();
- if (orgName.endsWith(name)
- && orgName.startsWith(ClassMetaobject.methodPrefix)
- && ms[i].getSignature().equals(m.getSignature()))
- return ms[i];
- }
-
- return m;
+ if (dontSearch)
+ return m;
+
+ String name = m.getName();
+ CtMethod[] ms = m.getDeclaringClass().getDeclaredMethods();
+ for (int i = 0; i < ms.length; ++i) {
+ String orgName = ms[i].getName();
+ if (orgName.endsWith(name)
+ && orgName.startsWith(ClassMetaobject.methodPrefix)
+ && ms[i].getSignature().equals(m.getSignature()))
+ return ms[i];
+ }
+
+ return m;
}
private void processFields(CtClass clazz)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- CtField[] fs = clazz.getDeclaredFields();
- for (int i = 0; i < fs.length; ++i) {
- CtField f = fs[i];
- int mod = f.getModifiers();
- if ((mod & Modifier.PUBLIC) != 0 && (mod & Modifier.FINAL) == 0) {
- mod |= Modifier.STATIC;
- String name = f.getName();
- CtClass ftype = f.getType();
- CtMethod wmethod
- = CtNewMethod.wrapped(ftype, readPrefix + name,
- readParam, null, trapRead,
- ConstParameter.string(name),
- clazz);
- wmethod.setModifiers(mod);
- clazz.addMethod(wmethod);
- CtClass[] writeParam = new CtClass[2];
- writeParam[0] = classPool.get("java.lang.Object");
- writeParam[1] = ftype;
- wmethod = CtNewMethod.wrapped(CtClass.voidType,
- writePrefix + name,
- writeParam, null, trapWrite,
- ConstParameter.string(name), clazz);
- wmethod.setModifiers(mod);
- clazz.addMethod(wmethod);
- }
- }
+ CtField[] fs = clazz.getDeclaredFields();
+ for (int i = 0; i < fs.length; ++i) {
+ CtField f = fs[i];
+ int mod = f.getModifiers();
+ if ((mod & Modifier.PUBLIC) != 0 && (mod & Modifier.FINAL) == 0) {
+ mod |= Modifier.STATIC;
+ String name = f.getName();
+ CtClass ftype = f.getType();
+ CtMethod wmethod
+ = CtNewMethod.wrapped(ftype, readPrefix + name,
+ readParam, null, trapRead,
+ ConstParameter.string(name),
+ clazz);
+ wmethod.setModifiers(mod);
+ clazz.addMethod(wmethod);
+ CtClass[] writeParam = new CtClass[2];
+ writeParam[0] = classPool.get("java.lang.Object");
+ writeParam[1] = ftype;
+ wmethod = CtNewMethod.wrapped(CtClass.voidType,
+ writePrefix + name,
+ writeParam, null, trapWrite,
+ ConstParameter.string(name), clazz);
+ wmethod.setModifiers(mod);
+ clazz.addMethod(wmethod);
+ }
+ }
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.reflect;
/**
private static ClassMetaobject _classobject;
public Object trap(Object[] args, int identifier) throws Throwable {
- Metaobject mobj;
- mobj = _metaobject;
- if (mobj == null)
- return ClassMetaobject.invoke(this, identifier, args);
- else
- return mobj.trapMethodcall(identifier, args);
+ Metaobject mobj;
+ mobj = _metaobject;
+ if (mobj == null)
+ return ClassMetaobject.invoke(this, identifier, args);
+ else
+ return mobj.trapMethodcall(identifier, args);
}
public static Object trapStatic(Object[] args, int identifier)
- throws Throwable
+ throws Throwable
{
- return _classobject.trapMethodcall(identifier, args);
+ return _classobject.trapMethodcall(identifier, args);
}
public static Object trapRead(Object[] args, String name) {
- if (args[0] == null)
- return _classobject.trapFieldRead(name);
- else
- return ((Metalevel)args[0])._getMetaobject().trapFieldRead(name);
+ if (args[0] == null)
+ return _classobject.trapFieldRead(name);
+ else
+ return ((Metalevel)args[0])._getMetaobject().trapFieldRead(name);
}
public static Object trapWrite(Object[] args, String name) {
- Metalevel base = (Metalevel)args[0];
- if (base == null)
- _classobject.trapFieldWrite(name, args[1]);
- else
- base._getMetaobject().trapFieldWrite(name, args[1]);
+ Metalevel base = (Metalevel)args[0];
+ if (base == null)
+ _classobject.trapFieldWrite(name, args[1]);
+ else
+ base._getMetaobject().trapFieldWrite(name, args[1]);
- return null;
+ return null;
}
}
--- /dev/null
+<html>
+<body>
+Runtime Reflection.
+
+<p>This package enables a metaobject to trap method calls and field
+accesses on a regular Java object. It provides a class
+<code>Reflection</code>, which is a main module for implementing
+runtime reflection.
+It also provides
+a class <code>Loader</code> and <code>Compiler</code>
+as utilities for dynamically or statically
+translating a regular class into a reflective class.
+
+<p>An instance of the reflective class is associated with
+a runtime metaobject and a runtime class metaobject, which control
+the behavior of that instance.
+The runtime
+metaobject is created for every (base-level) instance but the
+runtime class metaobject is created for every (base-level) class.
+<code>Metaobject</code> is the root class of the runtime
+metaobject and <code>ClassMetaobject</code> is the root class
+of the runtime class metaobject.
+
+<p>This package is provided as a sample implementation of the
+reflection mechanism with Javassist. All the programs in this package
+uses only the regular Javassist API; they never call any hidden
+methods.
+
+<p>The most significant class in this package is <code>Reflection</code>.
+See the description of this class first.
+
+</body>
+</html>
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
import java.io.*;
private Vector exportedObjects;
private static final byte[] okHeader
- = "HTTP/1.0 200 OK\r\n\r\n".getBytes();
+ = "HTTP/1.0 200 OK\r\n\r\n".getBytes();
/**
* Constructs a web server.
*
- * @param port port number
+ * @param port port number
*/
public AppletServer(String port)
- throws IOException, NotFoundException, CannotCompileException
+ throws IOException, NotFoundException, CannotCompileException
{
- this(Integer.parseInt(port));
+ this(Integer.parseInt(port));
}
/**
* Constructs a web server.
*
- * @param port port number
+ * @param port port number
*/
public AppletServer(int port)
- throws IOException, NotFoundException, CannotCompileException
+ throws IOException, NotFoundException, CannotCompileException
{
- this(ClassPool.getDefault(new StubGenerator()), port);
+ this(ClassPool.getDefault(new StubGenerator()), port);
}
/**
* Constructs a web server.
*
- * @param port port number
- * @param src the source of classs files.
+ * @param port port number
+ * @param src the source of classs files.
*/
public AppletServer(int port, ClassPool src)
- throws IOException, NotFoundException, CannotCompileException
+ throws IOException, NotFoundException, CannotCompileException
{
- this(new ClassPool(src, new StubGenerator()), port);
+ this(new ClassPool(src, new StubGenerator()), port);
}
private AppletServer(ClassPool loader, int port)
- throws IOException, NotFoundException, CannotCompileException
+ throws IOException, NotFoundException, CannotCompileException
{
- super(port);
- exportedNames = new Hashtable();
- exportedObjects = new Vector();
- stubGen = (StubGenerator)loader.getTranslator();
- setClassPool(loader);
+ super(port);
+ exportedNames = new Hashtable();
+ exportedObjects = new Vector();
+ stubGen = (StubGenerator)loader.getTranslator();
+ setClassPool(loader);
}
/**
* Begins the HTTP service.
*/
public void run() {
- super.run();
+ super.run();
}
/**
* to access the exported object. A remote applet can load
* the proxy class and call a method on the exported object.
*
- * @param name the name used for looking the object up.
- * @param object the exported object.
- * @return the object identifier
+ * @param name the name used for looking the object up.
+ * @param object the exported object.
+ * @return the object identifier
*
* @see javassist.rmi.ObjectImporter#lookupObject(String)
*/
public synchronized int exportObject(String name, Object obj)
- throws CannotCompileException
+ throws CannotCompileException
{
- Class clazz = obj.getClass();
- ExportedObject eo = new ExportedObject();
- eo.object = obj;
- eo.methods = clazz.getMethods();
- exportedObjects.addElement(eo);
- eo.identifier = exportedObjects.size() - 1;
- if (name != null)
- exportedNames.put(name, eo);
-
- try {
- stubGen.makeProxyClass(clazz);
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
-
- return eo.identifier;
+ Class clazz = obj.getClass();
+ ExportedObject eo = new ExportedObject();
+ eo.object = obj;
+ eo.methods = clazz.getMethods();
+ exportedObjects.addElement(eo);
+ eo.identifier = exportedObjects.size() - 1;
+ if (name != null)
+ exportedNames.put(name, eo);
+
+ try {
+ stubGen.makeProxyClass(clazz);
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+
+ return eo.identifier;
}
/**
* Processes a request from a web browser (an ObjectImporter).
*/
public void doReply(InputStream in, OutputStream out, String cmd)
- throws IOException, BadHttpRequest
+ throws IOException, BadHttpRequest
{
- if (cmd.startsWith("POST /rmi "))
- processRMI(in, out);
- else if (cmd.startsWith("POST /lookup "))
- lookupName(cmd, in, out);
- else
- super.doReply(in, out, cmd);
+ if (cmd.startsWith("POST /rmi "))
+ processRMI(in, out);
+ else if (cmd.startsWith("POST /lookup "))
+ lookupName(cmd, in, out);
+ else
+ super.doReply(in, out, cmd);
}
private void processRMI(InputStream ins, OutputStream outs)
- throws IOException
+ throws IOException
{
- ObjectInputStream in = new ObjectInputStream(ins);
-
- int objectId = in.readInt();
- int methodId = in.readInt();
- Exception err = null;
- Object rvalue = null;
- try {
- ExportedObject eo
- = (ExportedObject)exportedObjects.elementAt(objectId);
- Object[] args = readParameters(in);
- rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object,
- args));
- }
- catch(Exception e) {
- err = e;
- logging2(e.toString());
- }
-
- outs.write(okHeader);
- ObjectOutputStream out = new ObjectOutputStream(outs);
- if (err != null) {
- out.writeBoolean(false);
- out.writeUTF(err.toString());
- }
- else
- try {
- out.writeBoolean(true);
- out.writeObject(rvalue);
- }
- catch (NotSerializableException e) {
- logging2(e.toString());
- }
- catch (InvalidClassException e) {
- logging2(e.toString());
- }
-
- out.flush();
- out.close();
- in.close();
+ ObjectInputStream in = new ObjectInputStream(ins);
+
+ int objectId = in.readInt();
+ int methodId = in.readInt();
+ Exception err = null;
+ Object rvalue = null;
+ try {
+ ExportedObject eo
+ = (ExportedObject)exportedObjects.elementAt(objectId);
+ Object[] args = readParameters(in);
+ rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object,
+ args));
+ }
+ catch(Exception e) {
+ err = e;
+ logging2(e.toString());
+ }
+
+ outs.write(okHeader);
+ ObjectOutputStream out = new ObjectOutputStream(outs);
+ if (err != null) {
+ out.writeBoolean(false);
+ out.writeUTF(err.toString());
+ }
+ else
+ try {
+ out.writeBoolean(true);
+ out.writeObject(rvalue);
+ }
+ catch (NotSerializableException e) {
+ logging2(e.toString());
+ }
+ catch (InvalidClassException e) {
+ logging2(e.toString());
+ }
+
+ out.flush();
+ out.close();
+ in.close();
}
private Object[] readParameters(ObjectInputStream in)
- throws IOException, ClassNotFoundException
+ throws IOException, ClassNotFoundException
{
- int n = in.readInt();
- Object[] args = new Object[n];
- for (int i = 0; i < n; ++i) {
- Object a = in.readObject();
- if (a instanceof RemoteRef) {
- RemoteRef ref = (RemoteRef)a;
- ExportedObject eo
- = (ExportedObject)exportedObjects.elementAt(ref.oid);
- a = eo.object;
- }
-
- args[i] = a;
- }
-
- return args;
+ int n = in.readInt();
+ Object[] args = new Object[n];
+ for (int i = 0; i < n; ++i) {
+ Object a = in.readObject();
+ if (a instanceof RemoteRef) {
+ RemoteRef ref = (RemoteRef)a;
+ ExportedObject eo
+ = (ExportedObject)exportedObjects.elementAt(ref.oid);
+ a = eo.object;
+ }
+
+ args[i] = a;
+ }
+
+ return args;
}
private Object convertRvalue(Object rvalue)
- throws CannotCompileException
+ throws CannotCompileException
{
- if (rvalue == null)
- return null; // the return type is void.
-
- String classname = rvalue.getClass().getName();
- if (stubGen.isProxyClass(classname))
- return new RemoteRef(exportObject(null, rvalue), classname);
- else
- return rvalue;
+ if (rvalue == null)
+ return null; // the return type is void.
+
+ String classname = rvalue.getClass().getName();
+ if (stubGen.isProxyClass(classname))
+ return new RemoteRef(exportObject(null, rvalue), classname);
+ else
+ return rvalue;
}
private void lookupName(String cmd, InputStream ins, OutputStream outs)
- throws IOException
+ throws IOException
{
- ObjectInputStream in = new ObjectInputStream(ins);
- String name = DataInputStream.readUTF(in);
- ExportedObject found = (ExportedObject)exportedNames.get(name);
- outs.write(okHeader);
- ObjectOutputStream out = new ObjectOutputStream(outs);
- if (found == null) {
- logging2(name + "not found.");
- out.writeInt(-1); // error code
- out.writeUTF("error");
- }
- else {
- logging2(name);
- out.writeInt(found.identifier);
- out.writeUTF(found.object.getClass().getName());
- }
-
- out.flush();
- out.close();
- in.close();
+ ObjectInputStream in = new ObjectInputStream(ins);
+ String name = DataInputStream.readUTF(in);
+ ExportedObject found = (ExportedObject)exportedNames.get(name);
+ outs.write(okHeader);
+ ObjectOutputStream out = new ObjectOutputStream(outs);
+ if (found == null) {
+ logging2(name + "not found.");
+ out.writeInt(-1); // error code
+ out.writeUTF("error");
+ }
+ else {
+ logging2(name);
+ out.writeInt(found.identifier);
+ out.writeUTF(found.object.getClass().getName());
+ }
+
+ out.flush();
+ out.close();
+ in.close();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
import java.io.*;
* <p>Remote objects are imported from the web server that the given
* applet has been loaded from.
*
- * @param applet the applet loaded from the <code>Webserver</code>.
+ * @param applet the applet loaded from the <code>Webserver</code>.
*/
public ObjectImporter(Applet applet) {
- URL codebase = applet.getCodeBase();
- orgServername = servername = codebase.getHost();
- orgPort = port = codebase.getPort();
+ URL codebase = applet.getCodeBase();
+ orgServername = servername = codebase.getHost();
+ orgPort = port = codebase.getPort();
}
/**
* @see javassist.web.Viewer
*/
public ObjectImporter(String servername, int port) {
- this.orgServername = this.servername = servername;
- this.orgPort = this.port = port;
+ this.orgServername = this.servername = servername;
+ this.orgPort = this.port = port;
}
/**
* Finds the object exported by a server with the specified name.
* If the object is not found, this method returns null.
*
- * @param name the name of the exported object.
- * @return the proxy object or null.
+ * @param name the name of the exported object.
+ * @return the proxy object or null.
*/
public Object getObject(String name) {
- try {
- return lookupObject(name);
- }
- catch (ObjectNotFoundException e) {
- return null;
- }
+ try {
+ return lookupObject(name);
+ }
+ catch (ObjectNotFoundException e) {
+ return null;
+ }
}
/**
* importer connects a server through the http proxy server.
*/
public void setHttpProxy(String host, int port) {
- String proxyHeader = "POST http://" + orgServername + ":" + orgPort;
- String cmd = proxyHeader + "/lookup HTTP/1.0";
- lookupCommand = cmd.getBytes();
- cmd = proxyHeader + "/rmi HTTP/1.0";
- rmiCommand = cmd.getBytes();
- this.servername = host;
- this.port = port;
+ String proxyHeader = "POST http://" + orgServername + ":" + orgPort;
+ String cmd = proxyHeader + "/lookup HTTP/1.0";
+ lookupCommand = cmd.getBytes();
+ cmd = proxyHeader + "/rmi HTTP/1.0";
+ rmiCommand = cmd.getBytes();
+ this.servername = host;
+ this.port = port;
}
/**
* It sends a POST request to the server (via an http proxy server
* if needed).
*
- * @param name the name of the exported object.
- * @return the proxy object.
+ * @param name the name of the exported object.
+ * @return the proxy object.
*/
public Object lookupObject(String name) throws ObjectNotFoundException
{
- try {
- Socket sock = new Socket(servername, port);
- OutputStream out = sock.getOutputStream();
- out.write(lookupCommand);
- out.write(endofline);
- out.write(endofline);
+ try {
+ Socket sock = new Socket(servername, port);
+ OutputStream out = sock.getOutputStream();
+ out.write(lookupCommand);
+ out.write(endofline);
+ out.write(endofline);
- ObjectOutputStream dout = new ObjectOutputStream(out);
- dout.writeUTF(name);
- dout.flush();
+ ObjectOutputStream dout = new ObjectOutputStream(out);
+ dout.writeUTF(name);
+ dout.flush();
- InputStream in = new BufferedInputStream(sock.getInputStream());
- skipHeader(in);
- ObjectInputStream din = new ObjectInputStream(in);
- int n = din.readInt();
- String classname = din.readUTF();
- din.close();
- dout.close();
- sock.close();
+ InputStream in = new BufferedInputStream(sock.getInputStream());
+ skipHeader(in);
+ ObjectInputStream din = new ObjectInputStream(in);
+ int n = din.readInt();
+ String classname = din.readUTF();
+ din.close();
+ dout.close();
+ sock.close();
- if (n >= 0)
- return createProxy(n, classname);
- }
- catch (Exception e) {
- e.printStackTrace();
- throw new ObjectNotFoundException(name, e);
- }
+ if (n >= 0)
+ return createProxy(n, classname);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new ObjectNotFoundException(name, e);
+ }
- throw new ObjectNotFoundException(name);
+ throw new ObjectNotFoundException(name);
}
private static final Class[] proxyConstructorParamTypes
- = new Class[] { ObjectImporter.class, int.class };
+ = new Class[] { ObjectImporter.class, int.class };
private Object createProxy(int oid, String classname) throws Exception {
- Class c = Class.forName(classname);
- Constructor cons = c.getConstructor(proxyConstructorParamTypes);
- return cons.newInstance(new Object[] { this, new Integer(oid) });
+ Class c = Class.forName(classname);
+ Constructor cons = c.getConstructor(proxyConstructorParamTypes);
+ return cons.newInstance(new Object[] { this, new Integer(oid) });
}
/**
* <p>This method is called by only proxy objects.
*/
public Object call(int objectid, int methodid, Object[] args)
- throws RemoteException
+ throws RemoteException
{
- boolean result;
- Object rvalue;
- String errmsg;
+ boolean result;
+ Object rvalue;
+ String errmsg;
- try {
- /* This method establishes a raw tcp connection for sending
- * a POST message. Thus the object cannot communicate a
- * remote object beyond a fire wall. To avoid this problem,
- * the connection should be established with a mechanism
- * collaborating a proxy server. Unfortunately, java.lang.URL
- * does not seem to provide such a mechanism.
- *
- * You might think that using HttpURLConnection is a better
- * way than constructing a raw tcp connection. Unfortunately,
- * URL.openConnection() does not return an HttpURLConnection
- * object in Netscape's JVM. It returns a
- * netscape.net.URLConnection object.
- *
- * lookupObject() has the same problem.
- */
- Socket sock = new Socket(servername, port);
- OutputStream out = new BufferedOutputStream(
- sock.getOutputStream());
- out.write(rmiCommand);
- out.write(endofline);
- out.write(endofline);
+ try {
+ /* This method establishes a raw tcp connection for sending
+ * a POST message. Thus the object cannot communicate a
+ * remote object beyond a fire wall. To avoid this problem,
+ * the connection should be established with a mechanism
+ * collaborating a proxy server. Unfortunately, java.lang.URL
+ * does not seem to provide such a mechanism.
+ *
+ * You might think that using HttpURLConnection is a better
+ * way than constructing a raw tcp connection. Unfortunately,
+ * URL.openConnection() does not return an HttpURLConnection
+ * object in Netscape's JVM. It returns a
+ * netscape.net.URLConnection object.
+ *
+ * lookupObject() has the same problem.
+ */
+ Socket sock = new Socket(servername, port);
+ OutputStream out = new BufferedOutputStream(
+ sock.getOutputStream());
+ out.write(rmiCommand);
+ out.write(endofline);
+ out.write(endofline);
- ObjectOutputStream dout = new ObjectOutputStream(out);
- dout.writeInt(objectid);
- dout.writeInt(methodid);
- writeParameters(dout, args);
- dout.flush();
+ ObjectOutputStream dout = new ObjectOutputStream(out);
+ dout.writeInt(objectid);
+ dout.writeInt(methodid);
+ writeParameters(dout, args);
+ dout.flush();
- InputStream ins = new BufferedInputStream(sock.getInputStream());
- skipHeader(ins);
- ObjectInputStream din = new ObjectInputStream(ins);
- result = din.readBoolean();
- rvalue = null;
- errmsg = null;
- if (result)
- rvalue = din.readObject();
- else
- errmsg = din.readUTF();
+ InputStream ins = new BufferedInputStream(sock.getInputStream());
+ skipHeader(ins);
+ ObjectInputStream din = new ObjectInputStream(ins);
+ result = din.readBoolean();
+ rvalue = null;
+ errmsg = null;
+ if (result)
+ rvalue = din.readObject();
+ else
+ errmsg = din.readUTF();
- din.close();
- dout.close();
- sock.close();
+ din.close();
+ dout.close();
+ sock.close();
- if (rvalue instanceof RemoteRef) {
- RemoteRef ref = (RemoteRef)rvalue;
- rvalue = createProxy(ref.oid, ref.classname);
- }
- }
- catch (ClassNotFoundException e) {
- throw new RemoteException(e);
- }
- catch (IOException e) {
- throw new RemoteException(e);
- }
- catch (Exception e) {
- throw new RemoteException(e);
- }
+ if (rvalue instanceof RemoteRef) {
+ RemoteRef ref = (RemoteRef)rvalue;
+ rvalue = createProxy(ref.oid, ref.classname);
+ }
+ }
+ catch (ClassNotFoundException e) {
+ throw new RemoteException(e);
+ }
+ catch (IOException e) {
+ throw new RemoteException(e);
+ }
+ catch (Exception e) {
+ throw new RemoteException(e);
+ }
- if (result)
- return rvalue;
- else
- throw new RemoteException(errmsg);
+ if (result)
+ return rvalue;
+ else
+ throw new RemoteException(errmsg);
}
private void skipHeader(InputStream in) throws IOException {
- int len;
- do {
- int c;
- len = 0;
- while ((c = in.read()) >= 0 && c != 0x0d)
- ++len;
+ int len;
+ do {
+ int c;
+ len = 0;
+ while ((c = in.read()) >= 0 && c != 0x0d)
+ ++len;
- in.read(); /* skip 0x0a (LF) */
- } while (len > 0);
+ in.read(); /* skip 0x0a (LF) */
+ } while (len > 0);
}
private void writeParameters(ObjectOutputStream dout, Object[] params)
- throws IOException
+ throws IOException
{
- int n = params.length;
- dout.writeInt(n);
- for (int i = 0; i < n; ++i)
- if (params[i] instanceof Proxy) {
- Proxy p = (Proxy)params[i];
- dout.writeObject(new RemoteRef(p._getObjectId()));
- }
- else
- dout.writeObject(params[i]);
+ int n = params.length;
+ dout.writeInt(n);
+ for (int i = 0; i < n; ++i)
+ if (params[i] instanceof Proxy) {
+ Proxy p = (Proxy)params[i];
+ dout.writeObject(new RemoteRef(p._getObjectId()));
+ }
+ else
+ dout.writeObject(params[i]);
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
public class ObjectNotFoundException extends Exception {
public ObjectNotFoundException(String name) {
- super(name + " is not exported");
+ super(name + " is not exported");
}
public ObjectNotFoundException(String name, Exception e) {
- super(name + " because of " + e.toString());
+ super(name + " because of " + e.toString());
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
/**
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
/**
*/
public class RemoteException extends RuntimeException {
public RemoteException(String msg) {
- super(msg);
+ super(msg);
}
public RemoteException(Exception e) {
- super("by " + e.toString());
+ super("by " + e.toString());
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
/**
public String classname;
public RemoteRef(int i) {
- oid = i;
- classname = null;
+ oid = i;
+ classname = null;
}
public RemoteRef(int i, String name) {
- oid = i;
- classname = name;
+ oid = i;
+ classname = name;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
/**
private int objectId;
public Object forward(Object[] args, int identifier) {
- return importer.call(objectId, identifier, args);
+ return importer.call(objectId, identifier, args);
}
public static Object forwardStatic(Object[] args, int identifier)
- throws RemoteException
+ throws RemoteException
{
- throw new RemoteException("cannot call a static method.");
+ throw new RemoteException("cannot call a static method.");
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.rmi;
import java.io.*;
* Constructs a stub-code generator.
*/
public StubGenerator() {
- proxyClasses = new Hashtable();
+ proxyClasses = new Hashtable();
}
/**
* @see javassist.Translator#start(ClassPool)
*/
public void start(ClassPool pool) throws NotFoundException {
- classPool = pool;
- CtClass c = pool.get(sampleClass);
- forwardMethod = c.getDeclaredMethod("forward");
- forwardStaticMethod = c.getDeclaredMethod("forwardStatic");
-
- proxyConstructorParamTypes
- = pool.get(new String[] { "javassist.rmi.ObjectImporter",
- "int" });
- interfacesForProxy
- = pool.get(new String[] { "java.io.Serializable",
- "javassist.rmi.Proxy" });
- exceptionForProxy
- = new CtClass[] { pool.get("javassist.rmi.RemoteException") };
+ classPool = pool;
+ CtClass c = pool.get(sampleClass);
+ forwardMethod = c.getDeclaredMethod("forward");
+ forwardStaticMethod = c.getDeclaredMethod("forwardStatic");
+
+ proxyConstructorParamTypes
+ = pool.get(new String[] { "javassist.rmi.ObjectImporter",
+ "int" });
+ interfacesForProxy
+ = pool.get(new String[] { "java.io.Serializable",
+ "javassist.rmi.Proxy" });
+ exceptionForProxy
+ = new CtClass[] { pool.get("javassist.rmi.RemoteException") };
}
public void onWrite(ClassPool pool, String classname) {}
* Returns <code>true</code> if the specified class is a proxy class
* recorded by <code>makeProxyClass()</code>.
*
- * @param name a fully-qualified class name
+ * @param name a fully-qualified class name
*/
public boolean isProxyClass(String name) {
- return proxyClasses.get(name) != null;
+ return proxyClasses.get(name) != null;
}
/**
* Makes a proxy class. The produced class is substituted
* for the original class.
*
- * @param clazz the class referenced
- * through the proxy class.
- * @return <code>false</code> if the proxy class
- * has been already produced.
+ * @param clazz the class referenced
+ * through the proxy class.
+ * @return <code>false</code> if the proxy class
+ * has been already produced.
*/
public synchronized boolean makeProxyClass(Class clazz)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- String classname = clazz.getName();
- if (proxyClasses.get(classname) != null)
- return false;
- else {
- CtClass ctclazz = produceProxyClass(classPool.get(classname),
- clazz);
- proxyClasses.put(classname, ctclazz);
- modifySuperclass(ctclazz);
- return true;
- }
+ String classname = clazz.getName();
+ if (proxyClasses.get(classname) != null)
+ return false;
+ else {
+ CtClass ctclazz = produceProxyClass(classPool.get(classname),
+ clazz);
+ proxyClasses.put(classname, ctclazz);
+ modifySuperclass(ctclazz);
+ return true;
+ }
}
private CtClass produceProxyClass(CtClass orgclass, Class orgRtClass)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- int modify = orgclass.getModifiers();
- if (Modifier.isAbstract(modify) || Modifier.isNative(modify)
- || !Modifier.isPublic(modify))
- throw new CannotCompileException(orgclass.getName()
- + " must be public, non-native, and non-abstract.");
-
- CtClass proxy = classPool.makeClass(orgclass.getName(),
- orgclass.getSuperclass());
-
- proxy.setInterfaces(interfacesForProxy);
-
- CtField f
- = new CtField(classPool.get("javassist.rmi.ObjectImporter"),
- fieldImporter, proxy);
- f.setModifiers(Modifier.PRIVATE);
- proxy.addField(f, CtField.Initializer.byParameter(0));
-
- f = new CtField(CtClass.intType, fieldObjectId, proxy);
- f.setModifiers(Modifier.PRIVATE);
- proxy.addField(f, CtField.Initializer.byParameter(1));
-
- proxy.addMethod(CtNewMethod.getter(accessorObjectId, f));
-
- proxy.addConstructor(CtNewConstructor.defaultConstructor(proxy));
- CtConstructor cons
- = CtNewConstructor.skeleton(proxyConstructorParamTypes,
- null, proxy);
- proxy.addConstructor(cons);
-
- try {
- addMethods(proxy, orgRtClass.getMethods());
- return proxy;
- }
- catch (SecurityException e) {
- throw new CannotCompileException(e);
- }
+ int modify = orgclass.getModifiers();
+ if (Modifier.isAbstract(modify) || Modifier.isNative(modify)
+ || !Modifier.isPublic(modify))
+ throw new CannotCompileException(orgclass.getName()
+ + " must be public, non-native, and non-abstract.");
+
+ CtClass proxy = classPool.makeClass(orgclass.getName(),
+ orgclass.getSuperclass());
+
+ proxy.setInterfaces(interfacesForProxy);
+
+ CtField f
+ = new CtField(classPool.get("javassist.rmi.ObjectImporter"),
+ fieldImporter, proxy);
+ f.setModifiers(Modifier.PRIVATE);
+ proxy.addField(f, CtField.Initializer.byParameter(0));
+
+ f = new CtField(CtClass.intType, fieldObjectId, proxy);
+ f.setModifiers(Modifier.PRIVATE);
+ proxy.addField(f, CtField.Initializer.byParameter(1));
+
+ proxy.addMethod(CtNewMethod.getter(accessorObjectId, f));
+
+ proxy.addConstructor(CtNewConstructor.defaultConstructor(proxy));
+ CtConstructor cons
+ = CtNewConstructor.skeleton(proxyConstructorParamTypes,
+ null, proxy);
+ proxy.addConstructor(cons);
+
+ try {
+ addMethods(proxy, orgRtClass.getMethods());
+ return proxy;
+ }
+ catch (SecurityException e) {
+ throw new CannotCompileException(e);
+ }
}
private CtClass toCtClass(Class rtclass) throws NotFoundException {
- String name;
- if (!rtclass.isArray())
- name = rtclass.getName();
- else {
- StringBuffer sbuf = new StringBuffer();
- do {
- sbuf.append("[]");
- rtclass = rtclass.getComponentType();
- } while(rtclass.isArray());
- sbuf.insert(0, rtclass.getName());
- name = sbuf.toString();
- }
-
- return classPool.get(name);
+ String name;
+ if (!rtclass.isArray())
+ name = rtclass.getName();
+ else {
+ StringBuffer sbuf = new StringBuffer();
+ do {
+ sbuf.append("[]");
+ rtclass = rtclass.getComponentType();
+ } while(rtclass.isArray());
+ sbuf.insert(0, rtclass.getName());
+ name = sbuf.toString();
+ }
+
+ return classPool.get(name);
}
private CtClass[] toCtClass(Class[] rtclasses) throws NotFoundException {
- int n = rtclasses.length;
- CtClass[] ctclasses = new CtClass[n];
- for (int i = 0; i < n; ++i)
- ctclasses[i] = toCtClass(rtclasses[i]);
+ int n = rtclasses.length;
+ CtClass[] ctclasses = new CtClass[n];
+ for (int i = 0; i < n; ++i)
+ ctclasses[i] = toCtClass(rtclasses[i]);
- return ctclasses;
+ return ctclasses;
}
/* ms must not be an array of CtMethod. To invoke a method ms[i]
* on a server, a client must send i to the server.
*/
private void addMethods(CtClass proxy, Method[] ms)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- CtMethod wmethod;
- for (int i = 0; i < ms.length; ++i) {
- Method m = ms[i];
- int mod = m.getModifiers();
- if (m.getDeclaringClass() != Object.class
- && !Modifier.isFinal(mod))
- if (Modifier.isPublic(mod)) {
- CtMethod body;
- if (Modifier.isStatic(mod))
- body = forwardStaticMethod;
- else
- body = forwardMethod;
-
- wmethod
- = CtNewMethod.wrapped(toCtClass(m.getReturnType()),
- m.getName(),
- toCtClass(m.getParameterTypes()),
- exceptionForProxy,
- body,
- ConstParameter.integer(i),
- proxy);
- wmethod.setModifiers(mod);
- proxy.addMethod(wmethod);
- }
- else if (!Modifier.isProtected(mod)
- && !Modifier.isPrivate(mod))
- // if package method
- throw new CannotCompileException(
- "the methods must be public, protected, or private.");
- }
+ CtMethod wmethod;
+ for (int i = 0; i < ms.length; ++i) {
+ Method m = ms[i];
+ int mod = m.getModifiers();
+ if (m.getDeclaringClass() != Object.class
+ && !Modifier.isFinal(mod))
+ if (Modifier.isPublic(mod)) {
+ CtMethod body;
+ if (Modifier.isStatic(mod))
+ body = forwardStaticMethod;
+ else
+ body = forwardMethod;
+
+ wmethod
+ = CtNewMethod.wrapped(toCtClass(m.getReturnType()),
+ m.getName(),
+ toCtClass(m.getParameterTypes()),
+ exceptionForProxy,
+ body,
+ ConstParameter.integer(i),
+ proxy);
+ wmethod.setModifiers(mod);
+ proxy.addMethod(wmethod);
+ }
+ else if (!Modifier.isProtected(mod)
+ && !Modifier.isPrivate(mod))
+ // if package method
+ throw new CannotCompileException(
+ "the methods must be public, protected, or private.");
+ }
}
/**
* Adds a default constructor to the super classes.
*/
private void modifySuperclass(CtClass orgclass)
- throws CannotCompileException, NotFoundException
+ throws CannotCompileException, NotFoundException
{
- CtClass superclazz;
- for (;; orgclass = superclazz) {
- superclazz = orgclass.getSuperclass();
- if (superclazz == null)
- break;
-
- String name = superclazz.getName();
- try {
- superclazz.getDeclaredConstructor(null);
- break; // the constructor with no arguments is found.
- }
- catch (NotFoundException e) {
- }
-
- superclazz.addConstructor(
- CtNewConstructor.defaultConstructor(superclazz));
- }
+ CtClass superclazz;
+ for (;; orgclass = superclazz) {
+ superclazz = orgclass.getSuperclass();
+ if (superclazz == null)
+ break;
+
+ String name = superclazz.getName();
+ try {
+ superclazz.getDeclaredConstructor(null);
+ break; // the constructor with no arguments is found.
+ }
+ catch (NotFoundException e) {
+ }
+
+ superclazz.addConstructor(
+ CtNewConstructor.defaultConstructor(superclazz));
+ }
}
}
--- /dev/null
+<html>
+<body>
+Remote Method Invocation.
+
+<p>This package enables applets to access remote objects
+running on the web server with regular Java syntax.
+It is provided as a sample implementation with Javassist.
+All the programs in this package uses only the regular
+Javassist API; they never call any hidden methods.
+
+<p>The most significant class of this package is
+<code>ObjectImporter</code>.
+See the description of this class first.
+
+</body>
+</html>
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.runtime;
/**
*/
public class Cflow extends ThreadLocal {
private static class Depth {
- private int depth;
- Depth() { depth = 0; }
- int get() { return depth; }
- void inc() { ++depth; }
- void dec() { --depth; }
+ private int depth;
+ Depth() { depth = 0; }
+ int get() { return depth; }
+ void inc() { ++depth; }
+ void dec() { --depth; }
}
protected synchronized Object initialValue() {
- return new Depth();
+ return new Depth();
}
/**
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.runtime;
/**
public static boolean useContextClassLoader = false;
private static Class getClassObject(String name)
- throws ClassNotFoundException
+ throws ClassNotFoundException
{
- if (useContextClassLoader)
- return Thread.currentThread().getContextClassLoader()
- .loadClass(name);
- else
- return Class.forName(name);
+ if (useContextClassLoader)
+ return Thread.currentThread().getContextClassLoader()
+ .loadClass(name);
+ else
+ return Class.forName(name);
}
/**
* It is used for implementing <code>$class</code>.
*/
public static Class getClazz(String name) {
- try {
- return getClassObject(name);
- }
- catch (ClassNotFoundException e) {
- throw new RuntimeException("$class: internal error");
- }
+ try {
+ return getClassObject(name);
+ }
+ catch (ClassNotFoundException e) {
+ throw new RuntimeException("$class: internal error");
+ }
}
/**
* signature. It is used for implementing <code>$sig</code>.
*/
public static Class[] getParams(String desc) {
- if (desc.charAt(0) != '(')
- throw new RuntimeException("$sig: internal error");
+ if (desc.charAt(0) != '(')
+ throw new RuntimeException("$sig: internal error");
- return getType(desc, desc.length(), 1, 0);
+ return getType(desc, desc.length(), 1, 0);
}
/**
* It is used for implementing <code>$type</code>.
*/
public static Class getType(String desc) {
- Class[] result = getType(desc, desc.length(), 0, 0);
- if (result == null || result.length != 1)
- throw new RuntimeException("$type: internal error");
+ Class[] result = getType(desc, desc.length(), 0, 0);
+ if (result == null || result.length != 1)
+ throw new RuntimeException("$type: internal error");
- return result[0];
+ return result[0];
}
private static Class[] getType(String desc, int descLen,
- int start, int num) {
- Class clazz;
- if (start >= descLen)
- return new Class[num];
-
- char c = desc.charAt(start);
- switch (c) {
- case 'Z' :
- clazz = Boolean.TYPE;
- break;
- case 'C' :
- clazz = Character.TYPE;
- break;
- case 'B' :
- clazz = Byte.TYPE;
- break;
- case 'S' :
- clazz = Short.TYPE;
- break;
- case 'I' :
- clazz = Integer.TYPE;
- break;
- case 'J' :
- clazz = Long.TYPE;
- break;
- case 'F' :
- clazz = Float.TYPE;
- break;
- case 'D' :
- clazz = Double.TYPE;
- break;
- case 'V' :
- clazz = Void.TYPE;
- break;
- case 'L' :
- case '[' :
- return getClassType(desc, descLen, start, num);
- default :
- return new Class[num];
- }
-
- Class[] result = getType(desc, descLen, start + 1, num + 1);
- result[num] = clazz;
- return result;
+ int start, int num) {
+ Class clazz;
+ if (start >= descLen)
+ return new Class[num];
+
+ char c = desc.charAt(start);
+ switch (c) {
+ case 'Z' :
+ clazz = Boolean.TYPE;
+ break;
+ case 'C' :
+ clazz = Character.TYPE;
+ break;
+ case 'B' :
+ clazz = Byte.TYPE;
+ break;
+ case 'S' :
+ clazz = Short.TYPE;
+ break;
+ case 'I' :
+ clazz = Integer.TYPE;
+ break;
+ case 'J' :
+ clazz = Long.TYPE;
+ break;
+ case 'F' :
+ clazz = Float.TYPE;
+ break;
+ case 'D' :
+ clazz = Double.TYPE;
+ break;
+ case 'V' :
+ clazz = Void.TYPE;
+ break;
+ case 'L' :
+ case '[' :
+ return getClassType(desc, descLen, start, num);
+ default :
+ return new Class[num];
+ }
+
+ Class[] result = getType(desc, descLen, start + 1, num + 1);
+ result[num] = clazz;
+ return result;
}
private static Class[] getClassType(String desc, int descLen,
- int start, int num) {
- int end = start;
- while (desc.charAt(end) == '[')
- ++end;
-
- if (desc.charAt(end) == 'L') {
- end = desc.indexOf(';', end);
- if (end < 0)
- throw new IndexOutOfBoundsException("bad descriptor");
- }
-
- String cname;
- if (desc.charAt(start) == 'L')
- cname = desc.substring(start + 1, end);
- else
- cname = desc.substring(start, end + 1);
-
- Class[] result = getType(desc, descLen, end + 1, num + 1);
- try {
- result[num] = getClassObject(cname.replace('/', '.'));
- }
- catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
-
- return result;
+ int start, int num) {
+ int end = start;
+ while (desc.charAt(end) == '[')
+ ++end;
+
+ if (desc.charAt(end) == 'L') {
+ end = desc.indexOf(';', end);
+ if (end < 0)
+ throw new IndexOutOfBoundsException("bad descriptor");
+ }
+
+ String cname;
+ if (desc.charAt(start) == 'L')
+ cname = desc.substring(start + 1, end);
+ else
+ cname = desc.substring(start, end + 1);
+
+ Class[] result = getType(desc, descLen, end + 1, num + 1);
+ try {
+ result[num] = getClassObject(cname.replace('/', '.'));
+ }
+ catch (ClassNotFoundException e) {
+ // "new RuntimeException(e)" is not available in JDK 1.3.
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return result;
}
}
--- /dev/null
+<html>
+<body>
+Runtime support classes required by modified bytecode.
+
+<p>This package includes support classes that may be required by
+classes modified with Javassist. Note that most of the modified
+classes do not require these support classes. See the documentation
+of every support class to know which kind of modification needs
+a support class.
+
+</body>
+</html>
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.web;
/**
public BadHttpRequest(Exception _e) { e = _e; }
public String toString() {
- if (e == null)
- return super.toString();
- else
- return e.toString();
+ if (e == null)
+ return super.toString();
+ else
+ return e.toString();
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.web;
import java.io.*;
* Starts a program.
*/
public static void main(String[] args) throws Throwable {
- if (args.length >= 3) {
- Viewer cl = new Viewer(args[0], Integer.parseInt(args[1]));
- String[] args2 = new String[args.length - 3];
- System.arraycopy(args, 3, args2, 0, args.length - 3);
- cl.run(args[2], args2);
- }
- else
- System.err.println(
- "Usage: java javassist.web.Viewer <host> <port> class [args ...]");
+ if (args.length >= 3) {
+ Viewer cl = new Viewer(args[0], Integer.parseInt(args[1]));
+ String[] args2 = new String[args.length - 3];
+ System.arraycopy(args, 3, args2, 0, args.length - 3);
+ cl.run(args[2], args2);
+ }
+ else
+ System.err.println(
+ "Usage: java javassist.web.Viewer <host> <port> class [args ...]");
}
/**
* Constructs a viewer.
*
- * @param host server name
- * @param p port number
+ * @param host server name
+ * @param p port number
*/
public Viewer(String host, int p) {
- server = host;
- port = p;
+ server = host;
+ port = p;
}
/**
/**
* Invokes main() in the class specified by <code>classname</code>.
*
- * @param classname executed class
- * @param args the arguments passed to <code>main()</code>.
+ * @param classname executed class
+ * @param args the arguments passed to <code>main()</code>.
*/
public void run(String classname, String[] args)
- throws Throwable
+ throws Throwable
{
- Class c = loadClass(classname);
- try {
- c.getDeclaredMethod("main", new Class[] { String[].class })
- .invoke(null, new Object[] { args });
- }
- catch (java.lang.reflect.InvocationTargetException e) {
- throw e.getTargetException();
- }
+ Class c = loadClass(classname);
+ try {
+ c.getDeclaredMethod("main", new Class[] { String[].class })
+ .invoke(null, new Object[] { args });
+ }
+ catch (java.lang.reflect.InvocationTargetException e) {
+ throw e.getTargetException();
+ }
}
/**
* Requests the class loader to load a class.
*/
protected synchronized Class loadClass(String name, boolean resolve)
- throws ClassNotFoundException
+ throws ClassNotFoundException
{
- Class c = findLoadedClass(name);
- if (c == null)
- c = findClass(name);
+ Class c = findLoadedClass(name);
+ if (c == null)
+ c = findClass(name);
- if (c == null)
- throw new ClassNotFoundException(name);
+ if (c == null)
+ throw new ClassNotFoundException(name);
- if (resolve)
- resolveClass(c);
+ if (resolve)
+ resolveClass(c);
- return c;
+ return c;
}
/**
* <code>Viewer</code>.
*/
protected Class findClass(String name) throws ClassNotFoundException {
- Class c = null;
- if (name.startsWith("java.") || name.startsWith("javax.")
- || name.equals("javassist.web.Viewer"))
- c = findSystemClass(name);
-
- if (c == null)
- try {
- byte[] b = fetchClass(name);
- if (b != null)
- c = defineClass(name, b, 0, b.length);
- }
- catch (Exception e) {
- }
-
- return c;
+ Class c = null;
+ if (name.startsWith("java.") || name.startsWith("javax.")
+ || name.equals("javassist.web.Viewer"))
+ c = findSystemClass(name);
+
+ if (c == null)
+ try {
+ byte[] b = fetchClass(name);
+ if (b != null)
+ c = defineClass(name, b, 0, b.length);
+ }
+ catch (Exception e) {
+ }
+
+ return c;
}
/**
*/
protected byte[] fetchClass(String classname) throws Exception
{
- byte[] b;
- URL url = new URL("http", server, port,
- "/" + classname.replace('.', '/') + ".class");
- URLConnection con = url.openConnection();
- con.connect();
- int size = con.getContentLength();
- InputStream s = con.getInputStream();
- if (size <= 0)
- b = readStream(s);
- else {
- b = new byte[size];
- int len = 0;
- do {
- int n = s.read(b, len, size - len);
- if (n < 0) {
- s.close();
- throw new IOException("the stream was closed: "
- + classname);
- }
- len += n;
- } while (len < size);
- }
-
- s.close();
- return b;
+ byte[] b;
+ URL url = new URL("http", server, port,
+ "/" + classname.replace('.', '/') + ".class");
+ URLConnection con = url.openConnection();
+ con.connect();
+ int size = con.getContentLength();
+ InputStream s = con.getInputStream();
+ if (size <= 0)
+ b = readStream(s);
+ else {
+ b = new byte[size];
+ int len = 0;
+ do {
+ int n = s.read(b, len, size - len);
+ if (n < 0) {
+ s.close();
+ throw new IOException("the stream was closed: "
+ + classname);
+ }
+ len += n;
+ } while (len < size);
+ }
+
+ s.close();
+ return b;
}
private byte[] readStream(InputStream fin) throws IOException {
- byte[] buf = new byte[4096];
- int size = 0;
- int len = 0;
- do {
- size += len;
- if (buf.length - size <= 0) {
- byte[] newbuf = new byte[buf.length * 2];
- System.arraycopy(buf, 0, newbuf, 0, size);
- buf = newbuf;
- }
-
- len = fin.read(buf, size, buf.length - size);
- } while (len >= 0);
-
- byte[] result = new byte[size];
- System.arraycopy(buf, 0, result, 0, size);
- return result;
+ byte[] buf = new byte[4096];
+ int size = 0;
+ int len = 0;
+ do {
+ size += len;
+ if (buf.length - size <= 0) {
+ byte[] newbuf = new byte[buf.length * 2];
+ System.arraycopy(buf, 0, newbuf, 0, size);
+ buf = newbuf;
+ }
+
+ len = fin.read(buf, size, buf.length - size);
+ } while (len >= 0);
+
+ byte[] result = new byte[size];
+ System.arraycopy(buf, 0, result, 0, size);
+ return result;
}
}
/*
- * This file is part of the Javassist toolkit.
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Javassist.
- *
- * The Initial Developer of the Original Code is Shigeru Chiba. Portions
- * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
- * All Rights Reserved.
- *
- * Contributor(s):
- *
- * The development of this software is supported in part by the PRESTO
- * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*/
-
package javassist.web;
import java.net.*;
* The port number is specified by the first argument.
*/
public static void main(String[] args) throws IOException {
- if (args.length == 1) {
- Webserver web = new Webserver(args[0]);
- web.run();
- }
- else
- System.err.println(
- "Usage: java javassist.web.Webserver <port number>");
+ if (args.length == 1) {
+ Webserver web = new Webserver(args[0]);
+ web.run();
+ }
+ else
+ System.err.println(
+ "Usage: java javassist.web.Webserver <port number>");
}
/**
* Constructs a web server.
*
- * @param port port number
+ * @param port port number
*/
public Webserver(String port) throws IOException {
- this(Integer.parseInt(port));
+ this(Integer.parseInt(port));
}
/**
* Constructs a web server.
*
- * @param port port number
+ * @param port port number
*/
public Webserver(int port) throws IOException {
- socket = new ServerSocket(port);
- classPool = null;
+ socket = new ServerSocket(port);
+ classPool = null;
}
/**
* <code>ClassPool</code> object for obtaining a class file.
*/
public void setClassPool(ClassPool loader) {
- classPool = loader;
+ classPool = loader;
}
/**
* Closes the socket.
*/
public void end() throws IOException {
- socket.close();
+ socket.close();
}
/**
* Prints a log message.
*/
public void logging(String msg) {
- System.out.println(msg);
+ System.out.println(msg);
}
/**
* Prints a log message.
*/
public void logging(String msg1, String msg2) {
- System.out.print(msg1);
- System.out.print(" ");
- System.out.println(msg2);
+ System.out.print(msg1);
+ System.out.print(" ");
+ System.out.println(msg2);
}
/**
* Prints a log message.
*/
public void logging(String msg1, String msg2, String msg3) {
- System.out.print(msg1);
- System.out.print(" ");
- System.out.print(msg2);
- System.out.print(" ");
- System.out.println(msg3);
+ System.out.print(msg1);
+ System.out.print(" ");
+ System.out.print(msg2);
+ System.out.print(" ");
+ System.out.println(msg3);
}
/**
* Prints a log message with indentation.
*/
public void logging2(String msg) {
- System.out.print(" ");
- System.out.println(msg);
+ System.out.print(" ");
+ System.out.println(msg);
}
/**
* Begins the HTTP service.
*/
public void run() {
- System.err.println("ready to service...");
- for (;;)
- try {
- ServiceThread th = new ServiceThread(this, socket.accept());
- th.start();
- }
- catch (IOException e) {
- logging(e.toString());
- }
+ System.err.println("ready to service...");
+ for (;;)
+ try {
+ ServiceThread th = new ServiceThread(this, socket.accept());
+ th.start();
+ }
+ catch (IOException e) {
+ logging(e.toString());
+ }
}
final void process(Socket clnt) throws IOException {
- InputStream in = new BufferedInputStream(clnt.getInputStream());
- String cmd = readLine(in);
- logging(clnt.getInetAddress().getHostName(),
- new Date().toString(), cmd);
- while (skipLine(in) > 0){
- }
-
- OutputStream out = new BufferedOutputStream(clnt.getOutputStream());
- try {
- doReply(in, out, cmd);
- }
- catch (BadHttpRequest e) {
- replyError(out, e);
- }
-
- out.flush();
- in.close();
- out.close();
- clnt.close();
+ InputStream in = new BufferedInputStream(clnt.getInputStream());
+ String cmd = readLine(in);
+ logging(clnt.getInetAddress().getHostName(),
+ new Date().toString(), cmd);
+ while (skipLine(in) > 0){
+ }
+
+ OutputStream out = new BufferedOutputStream(clnt.getOutputStream());
+ try {
+ doReply(in, out, cmd);
+ }
+ catch (BadHttpRequest e) {
+ replyError(out, e);
+ }
+
+ out.flush();
+ in.close();
+ out.close();
+ clnt.close();
}
private String readLine(InputStream in) throws IOException {
- StringBuffer buf = new StringBuffer();
- int c;
- while ((c = in.read()) >= 0 && c != 0x0d)
- buf.append((char)c);
+ StringBuffer buf = new StringBuffer();
+ int c;
+ while ((c = in.read()) >= 0 && c != 0x0d)
+ buf.append((char)c);
- in.read(); /* skip 0x0a (LF) */
- return buf.toString();
+ in.read(); /* skip 0x0a (LF) */
+ return buf.toString();
}
private int skipLine(InputStream in) throws IOException {
- int c;
- int len = 0;
- while ((c = in.read()) >= 0 && c != 0x0d)
- ++len;
+ int c;
+ int len = 0;
+ while ((c = in.read()) >= 0 && c != 0x0d)
+ ++len;
- in.read(); /* skip 0x0a (LF) */
- return len;
+ in.read(); /* skip 0x0a (LF) */
+ return len;
}
/**
* Proceses a HTTP request from a client.
*
- * @param out the output stream to a client
- * @param cmd the command received from a client
+ * @param out the output stream to a client
+ * @param cmd the command received from a client
*/
public void doReply(InputStream in, OutputStream out, String cmd)
- throws IOException, BadHttpRequest
+ throws IOException, BadHttpRequest
{
- int len;
- int fileType;
- String filename, urlName;
-
- if (cmd.startsWith("GET /"))
- filename = urlName = cmd.substring(5, cmd.indexOf(' ', 5));
- else
- throw new BadHttpRequest();
-
- if (filename.endsWith(".class"))
- fileType = typeClass;
- else if (filename.endsWith(".html") || filename.endsWith(".htm"))
- fileType = typeHtml;
- else if (filename.endsWith(".gif"))
- fileType = typeGif;
- else if (filename.endsWith(".jpg"))
- fileType = typeJpeg;
- else
- fileType = typeText; // or textUnknown
-
- len = filename.length();
- if (fileType == typeClass
- && letUsersSendClassfile(out, filename, len))
- return;
-
- checkFilename(filename, len);
- if (htmlfileBase != null)
- filename = htmlfileBase + filename;
-
- if (File.separatorChar != '/')
- filename = filename.replace('/', File.separatorChar);
-
- File file = new File(filename);
- if (file.canRead()) {
- sendHeader(out, file.length(), fileType);
- FileInputStream fin = new FileInputStream(file);
- for (;;) {
- len = fin.read(filebuffer);
- if (len <= 0)
- break;
- else
- out.write(filebuffer, 0, len);
- }
-
- fin.close();
- return;
- }
-
- // If the file is not found under the html-file directory,
- // then Class.getResourceAsStream() is tried.
-
- if (fileType == typeClass) {
- InputStream fin
- = getClass().getResourceAsStream("/" + urlName);
- if (fin != null) {
- ByteArrayOutputStream barray = new ByteArrayOutputStream();
- for (;;) {
- len = fin.read(filebuffer);
- if (len <= 0)
- break;
- else
- barray.write(filebuffer, 0, len);
- }
-
- byte[] classfile = barray.toByteArray();
- sendHeader(out, classfile.length, typeClass);
- out.write(classfile);
- fin.close();
- return;
- }
- }
-
- throw new BadHttpRequest();
+ int len;
+ int fileType;
+ String filename, urlName;
+
+ if (cmd.startsWith("GET /"))
+ filename = urlName = cmd.substring(5, cmd.indexOf(' ', 5));
+ else
+ throw new BadHttpRequest();
+
+ if (filename.endsWith(".class"))
+ fileType = typeClass;
+ else if (filename.endsWith(".html") || filename.endsWith(".htm"))
+ fileType = typeHtml;
+ else if (filename.endsWith(".gif"))
+ fileType = typeGif;
+ else if (filename.endsWith(".jpg"))
+ fileType = typeJpeg;
+ else
+ fileType = typeText; // or textUnknown
+
+ len = filename.length();
+ if (fileType == typeClass
+ && letUsersSendClassfile(out, filename, len))
+ return;
+
+ checkFilename(filename, len);
+ if (htmlfileBase != null)
+ filename = htmlfileBase + filename;
+
+ if (File.separatorChar != '/')
+ filename = filename.replace('/', File.separatorChar);
+
+ File file = new File(filename);
+ if (file.canRead()) {
+ sendHeader(out, file.length(), fileType);
+ FileInputStream fin = new FileInputStream(file);
+ for (;;) {
+ len = fin.read(filebuffer);
+ if (len <= 0)
+ break;
+ else
+ out.write(filebuffer, 0, len);
+ }
+
+ fin.close();
+ return;
+ }
+
+ // If the file is not found under the html-file directory,
+ // then Class.getResourceAsStream() is tried.
+
+ if (fileType == typeClass) {
+ InputStream fin
+ = getClass().getResourceAsStream("/" + urlName);
+ if (fin != null) {
+ ByteArrayOutputStream barray = new ByteArrayOutputStream();
+ for (;;) {
+ len = fin.read(filebuffer);
+ if (len <= 0)
+ break;
+ else
+ barray.write(filebuffer, 0, len);
+ }
+
+ byte[] classfile = barray.toByteArray();
+ sendHeader(out, classfile.length, typeClass);
+ out.write(classfile);
+ fin.close();
+ return;
+ }
+ }
+
+ throw new BadHttpRequest();
}
private void checkFilename(String filename, int len)
- throws BadHttpRequest
+ throws BadHttpRequest
{
- for (int i = 0; i < len; ++i) {
- char c = filename.charAt(i);
- if (!Character.isJavaIdentifierPart(c) && c != '.' && c != '/')
- throw new BadHttpRequest();
- }
-
- if (filename.indexOf("..") >= 0)
- throw new BadHttpRequest();
+ for (int i = 0; i < len; ++i) {
+ char c = filename.charAt(i);
+ if (!Character.isJavaIdentifierPart(c) && c != '.' && c != '/')
+ throw new BadHttpRequest();
+ }
+
+ if (filename.indexOf("..") >= 0)
+ throw new BadHttpRequest();
}
private boolean letUsersSendClassfile(OutputStream out,
- String filename, int length)
- throws IOException, BadHttpRequest
+ String filename, int length)
+ throws IOException, BadHttpRequest
{
- if (classPool == null)
- return false;
-
- byte[] classfile;
- String classname
- = filename.substring(0, length - 6).replace('/', '.');
- try {
- classfile = classPool.write(classname);
- if (debugDir != null)
- classPool.writeFile(classname, debugDir);
- }
- catch (Exception e) {
- throw new BadHttpRequest(e);
- }
-
- sendHeader(out, classfile.length, typeClass);
- out.write(classfile);
- return true;
+ if (classPool == null)
+ return false;
+
+ byte[] classfile;
+ String classname
+ = filename.substring(0, length - 6).replace('/', '.');
+ try {
+ classfile = classPool.write(classname);
+ if (debugDir != null)
+ classPool.writeFile(classname, debugDir);
+ }
+ catch (Exception e) {
+ throw new BadHttpRequest(e);
+ }
+
+ sendHeader(out, classfile.length, typeClass);
+ out.write(classfile);
+ return true;
}
private void sendHeader(OutputStream out, long dataLength, int filetype)
- throws IOException
+ throws IOException
{
- out.write("HTTP/1.0 200 OK".getBytes());
- out.write(endofline);
- out.write("Content-Length: ".getBytes());
- out.write(Long.toString(dataLength).getBytes());
- out.write(endofline);
- if (filetype == typeClass)
- out.write("Content-Type: application/octet-stream".getBytes());
- else if (filetype == typeHtml)
- out.write("Content-Type: text/html".getBytes());
- else if (filetype == typeGif)
- out.write("Content-Type: image/gif".getBytes());
- else if (filetype == typeJpeg)
- out.write("Content-Type: image/jpg".getBytes());
- else if (filetype == typeText)
- out.write("Content-Type: text/plain".getBytes());
-
- out.write(endofline);
- out.write(endofline);
+ out.write("HTTP/1.0 200 OK".getBytes());
+ out.write(endofline);
+ out.write("Content-Length: ".getBytes());
+ out.write(Long.toString(dataLength).getBytes());
+ out.write(endofline);
+ if (filetype == typeClass)
+ out.write("Content-Type: application/octet-stream".getBytes());
+ else if (filetype == typeHtml)
+ out.write("Content-Type: text/html".getBytes());
+ else if (filetype == typeGif)
+ out.write("Content-Type: image/gif".getBytes());
+ else if (filetype == typeJpeg)
+ out.write("Content-Type: image/jpg".getBytes());
+ else if (filetype == typeText)
+ out.write("Content-Type: text/plain".getBytes());
+
+ out.write(endofline);
+ out.write(endofline);
}
private void replyError(OutputStream out, BadHttpRequest e)
- throws IOException
+ throws IOException
{
- logging2("bad request: " + e.toString());
- out.write("HTTP/1.0 400 Bad Request".getBytes());
- out.write(endofline);
- out.write(endofline);
- out.write("<H1>Bad Request</H1>".getBytes());
+ logging2("bad request: " + e.toString());
+ out.write("HTTP/1.0 400 Bad Request".getBytes());
+ out.write(endofline);
+ out.write(endofline);
+ out.write("<H1>Bad Request</H1>".getBytes());
}
}
Socket sock;
public ServiceThread(Webserver w, Socket s) {
- web = w;
- sock = s;
+ web = w;
+ sock = s;
}
public void run() {
- try {
- web.process(sock);
- }
- catch (IOException e) {
- }
+ try {
+ web.process(sock);
+ }
+ catch (IOException e) {
+ }
}
}
--- /dev/null
+<html>
+<body>
+Web server.
+
+<p>This package provides a simple web server for other packages.
+</body>
+</html>
-h1,h2,h3 {\r
- color:#663300;\r
- padding:4px 6px 6px 10px;\r
- border-width:1px 0px 1px 0px;\r
- border-color:#F5DEB3;\r
- border-style:solid;\r
-}\r
-\r
-h3 {\r
- padding-left: 30px;\r
-}\r
-\r
-h4 {\r
- color:#663300;\r
-}\r
-\r
-em {\r
- color:#cc0000;\r
-}\r
+h1,h2,h3 {
+ color:#663300;
+ padding:4px 6px 6px 10px;
+ border-width:1px 0px 1px 0px;
+ border-color:#F5DEB3;
+ border-style:solid;
+}
+
+h3 {
+ padding-left: 30px;
+}
+
+h4 {
+ color:#663300;
+}
+
+em {
+ color:#cc0000;
+}
-<html>\r
-<head>\r
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
- <title>Javassist Tutorial</title>\r
- <link rel="stylesheet" type="text/css" href="brown.css">\r
-</head>\r
-<body>\r
-\r
-<b>\r
-<font size="+3">\r
-Getting Started with Javassist\r
-</font>\r
-\r
-<p><font size="+2">\r
-Shigeru Chiba\r
-</font>\r
-</b>\r
-\r
-<p><div align="right"><a href="tutorial2.html">Next page</a></div>\r
-\r
-<ul>1. <a href="#read">Reading bytecode</a>\r
-<br>2. <a href="#def">Defining a new class</a>\r
-<br>3. <a href="#mod">Modifying a class at load time</a>\r
-<br>4. <a href="#load">Class loader</a>\r
-<br>5. <a href="tutorial2.html#intro">Introspection and customization</a>\r
-</ul>\r
-\r
-<p><br>\r
-\r
-<a name="read">\r
-<h2>1. Reading bytecode</h2>\r
-\r
-<p>Javassist is a class library for dealing with Java bytecode.\r
-Java bytecode is stored in a binary file called a class file.\r
-Each class file contains one Java class or interface.\r
-\r
-<p>The class <code>Javassist.CtClass</code> is an abstract representation\r
-of a class file. A <code>CtClass</code> object is a handle for dealing\r
-with a class file. The following program is a very simple example:\r
-\r
-<ul><pre>\r
-ClassPool pool = ClassPool.getDefault();\r
-CtClass cc = pool.get("test.Rectangle");\r
-cc.setSuperclass(pool.get("test.Point"));\r
-pool.writeFile("test.Rectangle"); // or simply, cc.writeFile()\r
-</pre></ul>\r
-\r
-<p>This program first obtains a <code>ClassPool</code> object,\r
-which controls bytecode modification with Javassist.\r
-The <code>ClassPool</code> object is a container of <code>CtClass</code>\r
-object representing a class file.\r
-It reads a class file on demand for constructing a <code>CtClass</code>\r
-object and contains the constructed object until it is written out\r
-to a file or an output stream.\r
-\r
-<p>To modify the definition of a class, the users must first obtain a\r
-reference to the <code>CtClass</code> object representing that class.\r
-<code>ClassPool.get()</code> is used for this purpose.\r
-In the case of the program above, the <code>CtClass</code> object\r
-representing a class <code>test.Rectangle</code> is obtained from\r
-the <code>ClassPool</code> object\r
-and it is assigned\r
-to a variable <code>cc</code>. Then it is modified so that\r
-the superclass of <code>test.Rectangle</code> is changed into\r
-a class <code>test.Point</code>.\r
-This change is reflected on the original class file when\r
-<code>ClassPool.writeFile()</code> is finally called.\r
-\r
-<p>Note that <code>writeFile()</code> is a method declared in not\r
-<code>CtClass</code> but <code>ClassPool</code>.\r
-If this method is called, the <code>ClassPool</code>\r
-finds a <code>CtClass</code> object specified with a class name\r
-among the objects that the <code>ClassPool</code> contains.\r
-Then it translates that <code>CtClass</code> object into a class file\r
-and writes it on a local disk.\r
-\r
-<p>There is also <code>writeFile()</code> defined in <code>CtClass</code>.\r
-Thus, the last line in the program above can be rewritten into:\r
-\r
-<ul><pre>cc.writeFile();</pre></ul>\r
-\r
-<p>This method is a convenient method for invoking <code>writeFile()</code>\r
-in <code>ClassPool</code> with the name of the class represented by\r
-<code>cc</code>.\r
-\r
-<p>Javassist also provides a method for directly obtaining the\r
-modified bytecode. To do this, call <code>write()</code>:\r
-\r
-<ul><pre>\r
-byte[] b = pool.write("test.Rectangle");\r
-</pre></ul>\r
-\r
-<p>The contents of the class file for <code>test.Rectangle</code> are\r
-assigned to a variable <code>b</code> in the form of byte array.\r
-<code>writeFile()</code> also internally calls <code>write()</code>\r
-to obtain the byte array written in a class file.\r
-\r
-<p>The default <code>ClassPool</code> returned\r
-by a static method <code>ClassPool.getDefault()</code>\r
-searches the same path as the underlying JVM.\r
-The users can expand this class search path if needed.\r
-For example, the following code adds a directory\r
-<code>/usr/local/javalib</code>\r
-to the search path:\r
-\r
-<ul><pre>\r
-ClassPool pool = ClassPool.getDefault();\r
-pool.insertClassPath("/usr/local/javalib");\r
-</pre></ul>\r
-\r
-<p>The search path that the users can add is not only a directory but also\r
-a URL:\r
-\r
-<ul><pre>\r
-ClassPool pool = ClassPool.getDefault();\r
-ClassPath cp = new URLClassPath("www.foo.com", 80, "/java/", "com.foo.");\r
-pool.insertClassPath(cp);\r
-</pre></ul>\r
-\r
-<p>This program adds "http://www.foo.com:80/java/" to the class search\r
-path. This URL is used only for searching classes belonging to a\r
-package <code>com.foo</code>.\r
-\r
-<p>You can directly give a byte array to a <code>ClassPool</code> object\r
-and construct a <code>CtClass</code> object from that array. To do this,\r
-use <code>ByteArrayClassPath</code>. For example,\r
-\r
-<ul><pre>\r
-ClassPool cp = ClassPool.getDefault();\r
-byte[] b = <em>a byte array</em>;\r
-String name = <em>class name</em>;\r
-cp.insertClassPath(new ByteArrayClassPath(name, b));\r
-CtClass cc = cp.get(name);\r
-</pre></ul>\r
-\r
-<p>The obtained <code>CtClass</code> object represents\r
-a class defined by the class file specified by <code>b</code>.\r
-\r
-\r
-<p>Since <code>ClassPath</code> is an interface, the users can define\r
-a new class implementing this interface and they can add an instance\r
-of that class so that a class file is obtained from a non-standard resource.\r
-\r
-<p><br>\r
-\r
-<a name="def">\r
-<h2>2. Defining a new class</h2>\r
-\r
-<p>To define a new class from scratch, <code>makeClass()</code>\r
-must be called on a <code>ClassPool</code>.\r
-\r
-<ul><pre>\r
-ClassPool pool = ClassPool.getDefault();\r
-CtClass cc = pool.makeClass("Point");\r
-</pre></ul>\r
-\r
-<p>This program defines a class <code>Point</code>\r
-including no members.\r
-\r
-<p>A new class can be also defined as a copy of an existing class.\r
-The program below does that:\r
-\r
-<ul><pre>\r
-ClassPool pool = ClassPool.getDefault();\r
-CtClass cc = pool.makeClass("Point");\r
-cc.setName("Pair");\r
-</pre></ul>\r
-\r
-<p>This program first obtains the <code>CtClass</code> object\r
-for class <code>Point</code>. Then it gives a new name <code>Pair</code>\r
-to that <code>CtClass</code> object.\r
-If <code>get("Point")</code> is called on the <code>ClassPool</code>\r
-object, then a class file <code>Point.class</code> is read again and\r
-a new <code>CtClass</code> object for class <code>Point</code> is constructed\r
-again.\r
-\r
-<ul><pre>\r
-ClassPool pool = ClassPool.getDefault();\r
-CtClass cc = pool.makeClass("Point");\r
-CtClass cc1 = pool.get("Point"); // cc1 is identical to cc.\r
-cc.setName("Pair");\r
-CtClass cc2 = pool.get("Pair"); // cc2 is identical to cc.\r
-CtClass cc3 = pool.get("Point"); // cc3 is not identical to cc.\r
-</pre></ul>\r
-\r
-<p><br>\r
-\r
-<a name="mod">\r
-<h2>3. Modifying a class at load time</h2>\r
-\r
-<p>If what classes are modified is known in advance,\r
-the easiest way for modifying the classes is as follows:\r
-\r
-<ul><li>1. Get a <code>CtClass</code> object by calling\r
- <code>ClassPool.get()</code>,\r
- <li>2. Modify it, and\r
- <li>3. Call <code>ClassPool.write()</code> or <code>writeFile()</code>.\r
-</ul>\r
-\r
-<p>If whether a class is modified or not is determined at load time,\r
-the users can write an event listener so that it is notified\r
-when a class is loaded into the JVM.\r
-A class loader (<code>java.lang.ClassLoader</code>) working with\r
-Javassist must call <code>ClassPool.write()</code> for obtaining\r
-a class file. The users can write an event listener so that it is\r
-notified when the class loader calls <code>ClassPool.write()</code>.\r
-The event-listener class must implement the following interface:\r
-\r
-<ul><pre>public interface Translator {\r
- public void start(ClassPool pool)\r
- throws NotFoundException, CannotCompileException;\r
- public void onWrite(ClassPool pool, String classname)\r
- throws NotFoundException, CannotCompileException;\r
-}</pre></ul>\r
-\r
-<p>The method <code>start()</code> is called when this event listener\r
-is registered to a <code>ClassPool</code> object.\r
-The method <code>onWrite()</code> is called when <code>write()</code>\r
-(or similar methods) is called on the <code>ClassPool</code> object.\r
-The second parameter of <code>onWrite()</code> is the name of the class\r
-to be written out.\r
-\r
-<p>Note that <code>start()</code> or <code>onWrite()</code> do not have\r
-to call <code>write()</code> or <code>writeFile()</code>. For example,\r
-\r
-<ul><pre>public class MyAnotherTranslator implements Translator {\r
- public void start(ClassPool pool)\r
- throws NotFoundException, CannotCompileException {}\r
- public void onWrite(ClassPool pool, String classname)\r
- throws NotFoundException, CannotCompileException\r
- {\r
- CtClass cc = pool.get(classname);\r
- cc.setModifiers(Modifier.PUBLIC);\r
- }\r
-}</pre></ul>\r
-\r
-<p>All the classes written out by <code>write()</code> are made public\r
-just before their definitions are translated into an byte array.\r
-\r
-<p><center><img src="overview.gif" alt="overview"></center>\r
-\r
-<p>The two methods <code>start()</code> and <code>onWrite()</code>\r
-can modify not only a <code>CtClass</code> object specified by\r
-the given <code>classname</code> but also\r
-<em>any</em> <code>CtClass</code> objects contained\r
-in the given <code>ClassPool</code>. \r
-They can call <code>ClassPool.get()</code> for obtaining any\r
-<code>CtClass</code> object.\r
-If a modified <code>CtClass</code> object is not written out immediately,\r
-the modification is recorded until that object is written out.\r
-\r
-<p><center><img src="sequence.gif" alt="sequence diagram"></center>\r
-\r
-<p>To register an event listener to a <code>ClassPool</code>,\r
-it must be passed to a constructor of <code>ClassPool</code>. \r
-Only a single event listener can be registered.\r
-If more than one event listeners are needed, multiple\r
-<code>ClassPool</code>s should be connected to be a single\r
-stream. For example,\r
-\r
-<ul><pre>Translator t1 = new MyTranslator();\r
-ClassPool c1 = new ClassPool(t1);\r
-Translator t2 = new MyAnotherTranslator();\r
-ClassPool c2 = new ClassPool(c1, t2);</pre></ul>\r
-\r
-<p>This program connects two <code>ClassPool</code>s.\r
-If a class loader calls <code>write()</code> on <code>c2</code>,\r
-the specified class file is first modified by <code>t1</code> and\r
-then by <code>t2</code>. <code>write()</code> returns the resulting\r
-class file.\r
-\r
-First, <code>onWrite()</code> on <code>t1</code> is called since\r
-<code>c2</code> obtains a class file by calling <code>write()</code>\r
-on <code>c1</code>. Then <code>onWrite()</code> on <code>t2</code>\r
-is called. If <code>onWrite()</code> called on <code>t2</code>\r
-obtains a <code>CtClass</code> object from <code>c2</code>, that\r
-<code>CtClass</code> object represents the class file that\r
-<code>t1</code> has modified.\r
-\r
-<p><center><img src="two.gif" alt="two translators"></center>\r
-\r
-<p><br>\r
-\r
-<a name="load">\r
-<h2>4. Class loader</h2>\r
-\r
-<p>Javassist can be used with a class loader so that bytecode can be\r
-modified at load time. The users of Javassist can define their own\r
-version of class loader but they can also use a class loader provided\r
-by Javassist.\r
-\r
-<p><br>\r
-\r
-<h3>4.1 Using <code>javassist.Loader</code></h3>\r
-\r
-<p>Javassist provides a class loader\r
-<code>javassist.Loader</code>. This class loader uses a\r
-<code>javassist.ClassPool</code> object for reading a class file.\r
-\r
-<p>For example, <code>javassist.Loader</code> can be used for loading\r
-a particular class modified with Javassist.\r
-\r
-<ul><pre>\r
-import javassist.*;\r
-import test.Rectangle;\r
-\r
-public class Main {\r
- public static void main(String[] args) throws Throwable {\r
- ClassPool pool = ClassPool.getDefault();\r
- Loader cl = new Loader(pool);\r
-\r
- CtClass ct = pool.get("test.Rectangle");\r
- ct.setSuperclass(pool.get("test.Point"));\r
-\r
- Class c = cl.loadClass("test.Rectangle");\r
- Object rect = c.newInstance();\r
- :\r
- }\r
-}\r
-</pre></ul>\r
-\r
-<p>This program modifies a class <code>test.Rectangle</code>. The\r
-superclass of <code>test.Rectangle</code> is set to a\r
-<code>test.Point</code> class. Then this program loads the modified\r
-class into the JVM, and creates a new instance of the\r
-<code>test.Rectangle</code> class.\r
-\r
-<p>The users can use a <code>javassist.Translator</code> object\r
-for modifying class files.\r
-Suppose that an instance of a class <code>MyTranslator</code>,\r
-which implements\r
-<code>javassist.Translator</code>, performs modification of class files.\r
-To run an application class <code>MyApp</code> with the\r
-<code>MyTranslator</code> object, write a main class:\r
-\r
-<ul><pre>\r
-import javassist.*;\r
-\r
-public class Main2 {\r
- public static void main(String[] args) throws Throwable {\r
- Translator t = new MyTranslator();\r
- ClassPool pool = ClassPool.getDefault(t);\r
- Loader cl = new Loader(pool);\r
- cl.run("MyApp", args);\r
- }\r
-}\r
-</pre></ul>\r
-\r
-<p>To run this program, do:\r
-\r
-<ul><pre>\r
-% java Main <i>arg1</i> <i>arg2</i>...\r
-</pre></ul>\r
-\r
-<p>The class <code>MyApp</code> and the other application classes\r
-are translated by <code>MyTranslator</code>.\r
-\r
-<p>Note that <em>application</em> classes like <code>MyApp</code> cannot\r
-access the <em>loader</em> classes such as <code>Main</code>,\r
-<code>MyTranslator</code> and <code>ClassPool</code> because they\r
-are loaded by different loaders. The application classes are loaded\r
-by <code>javassist.Loader</code> whereas the loader classes such as\r
-<code>Main</code> are by the default Java class loader.\r
-\r
-<p>In Java, for security reasons, a single class file may be loaded\r
-into the JVM by two distinct class loaders so that two different\r
-classes would be created. For example,\r
-\r
-<ul><pre>class Point {\r
- int x, y;\r
-}\r
-\r
-class Box {\r
- Point base;\r
- Point getBase() { return base; }\r
-}\r
-\r
-class Window {\r
- Point size;\r
- Point getSize() { return size; }\r
-}</pre></ul>\r
-\r
-<p>Suppose that a class <code>Box</code> is loaded by a class loader\r
-<code>L1</code> while a class <code>Window</code> is loaded by a class\r
-loader <code>L2</code>. Then, the obejcts returned by\r
-<code>getBase()</code> and <code>getSize()</code> are not instances of\r
-the same class <code>Point</code>.\r
-<code>getBase()</code> returns an instance of the class <code>Point</code>\r
-loaded by <code>L1</code> whereas <code>getSize()</code> returns an\r
-instance of <code>Point</code> loaded by <code>L2</code>. The two versions\r
-of the class <code>Point</code> are distinct. They belong to different\r
-name spaces. For more details, see the following paper:\r
-\r
-<ul>Sheng Liang and Gilad Bracha,\r
-"Dynamic Class Loading in the Java Virtual Machine",\r
-<br><i>ACM OOPSLA'98</i>, pp.36-44, 1998.</ul>\r
-\r
-<p>To avoid this problem, the two class loaders <code>L1</code> and\r
-<code>L2</code> must delegate the loading operation of the class\r
-<code>Point</code> to another class loader, <code>L3</code>, which is\r
-a parent class loader of <code>L1</code> and <code>L2</code>.\r
-<code>delegateLoadingOf()</code> in <code>javassist.Loader</code>\r
-is a method for specifying what classes should be loaded by the\r
-parent loader.\r
-\r
-<p>If <code>L1</code> is the parent class loader of <code>L2</code>,\r
-that is, if <code>L1</code> loads the class of <code>L2</code>,\r
-then <code>L2</code> can delegate the loading operation of\r
-<code>Point</code> to <code>L1</code> for avoiding the problem above.\r
-However, this technique does not work in the case below:\r
-\r
-<ul><pre>class Point { // loaded by L1\r
- Window win;\r
- int x, y;\r
-}\r
-\r
-class Box { // loaded by L1\r
- Point base;\r
- Point getBase() { return base; }\r
-}\r
-\r
-class Window { // loaded by L2\r
- Point size;\r
- Point getSize() { size.win = this; return size; }\r
-}</pre></ul>\r
-\r
-<p>Since all the classes included in a class definition loaded by\r
-a class loader <code>L1</code> are also loaded by <code>L1</code>,\r
-the class of the field <code>win</code> in <code>Point</code> is\r
-now the class <code>Window</code> loaded by <code>L1</code>.\r
-Thus <code>size.win = this</code> in <code>getSize()</code> raises\r
-a runtime exception because of type mismatch; the type of\r
-<code>size.win</code> is the class <code>Point</code> loaded by\r
-<code>L1</code> whereas the type of <code>this</code> is the class\r
-<code>Point</code> loaded by <code>L2</code>.\r
-\r
-<p><br>\r
-\r
-<h3>4.2 Writing a class loader</h3>\r
-\r
-<p>A simple class loader using Javassist is as follows:\r
-\r
-<ul><pre>import javassist.*;\r
-\r
-public class SimpleLoader extends ClassLoader {\r
- /* Call MyApp.main().\r
- */\r
- public static void main(String[] args) throws Throwable {\r
- SimpleLoader s = new SimpleLoader();\r
- Class c = s.loadClass("MyApp");\r
- c.getDeclaredMethod("main", new Class[] { String[].class })\r
- .invoke(null, new Object[] { args });\r
- }\r
-\r
- private ClassPool pool;\r
-\r
- public SimpleLoader() throws NotFoundException {\r
- pool = ClassPool.getDefault();\r
- pool.insertClassPath("./class"); // <em>MyApp.class must be there.</em>\r
- }\r
-\r
- /* Finds a specified class.\r
- * The bytecode for that class can be modified.\r
- */\r
- protected Class findClass(String name) throws ClassNotFoundException {\r
- try {\r
- CtClass cc = pool.get(name);\r
- // <em>modify the CtClass object here</em>\r
- byte[] b = pool.write(name);\r
- return defineClass(name, b, 0, b.length);\r
- } catch (NotFoundException e) {\r
- throw new ClassNotFoundException();\r
- } catch (IOException e) {\r
- throw new ClassNotFoundException();\r
- } catch (CannotCompileException e) {\r
- throw new ClassNotFoundException();\r
- }\r
- }\r
-}</pre></ul>\r
-\r
-<p>The class <code>MyApp</code> is an application program.\r
-To execute this program, first put the class file under the\r
-<code>./class</code> directory, which must <em>not</em> be included\r
-in the class search path. The directory name is specified by\r
-<code>insertClassPath()</code> in the constructor.\r
-You can choose a different name instead of <code>./class</code> if you want.\r
-Then do as follows:\r
-\r
-<ul><code>% java SimpleLoader</code></ul>\r
-\r
-<p>The class loader loads the class <code>MyApp</code>\r
-(<code>./class/MyApp.class</code>) and calls\r
-<code>MyApp.main()</code> with the command line parameters.\r
-Note that <code>MyApp.class</code> must not be under the directory\r
-that the system class loader searches. Otherwise, the system class\r
-loader, which is the parent loader of <code>SimpleLoader</code>,\r
-loads the class <code>MyApp</code>.\r
-\r
-<p>This is the simplest way of using Javassist. However, if you write\r
-a more complex class loader, you may need detailed knowledge of\r
-Java's class loading mechanism. For example, the program above puts the\r
-<code>MyApp</code> class in a name space separated from the name space\r
-that the class <code>SimpleLoader</code> belongs to because the two\r
-classes are loaded by different class loaders.\r
-Hence, the\r
-<code>MyApp</code> class cannot directly access the class\r
-<code>SimpleLoader</code>.\r
-\r
-<p><br>\r
-\r
-<h3>4.3 Modifying a system class</h3>\r
-\r
-<p>The system classes like <code>java.lang.String</code> cannot be\r
-loaded by a class loader other than the system class loader.\r
-Therefore, <code>SimpleLoader</code> or <code>javassist.Loader</code>\r
-shown above cannot modify the system classes at loading time.\r
-\r
-<p>If your application needs to do that, the system classes must be\r
-<em>statically</em> modified. For example, the following program\r
-adds a new field <code>hiddenValue</code> to <code>java.lang.String</code>:\r
-\r
-<ul><pre>ClassPool pool = ClassPool.getDefault();\r
-CtClass cc = pool.get("java.lang.String");\r
-cc.addField(new CtField(CtClass.intType, "hiddenValue", cc));\r
-pool.writeFile("java.lang.String", ".");</pre></ul>\r
-\r
-<p>This program produces a file <code>"./java/lang/String.class"</code>.\r
-\r
-<p>To run your program <code>MyApp</code>\r
-with this modified <code>String</code> class, do as follows:\r
-\r
-<ul><pre>\r
-% java -Xbootclasspath/p:. MyApp <i>arg1</i> <i>arg2</i>...\r
-</pre></ul>\r
-\r
-<p>Suppose that the definition of <code>MyApp</code> is as follows:\r
-\r
-<ul><pre>public class MyApp {\r
- public static void main(String[] args) throws Exception {\r
- System.out.println(String.class.getField("hiddenValue").getName());\r
- }\r
-}</pre></ul>\r
-\r
-<p>If the modified <code>String</code> class is correctly loaded,\r
-<code>MyApp</code> prints <code>hiddenValue</code>.\r
-\r
-<p><i>Note: Applications that use this technique for the purpose of\r
-overriding a system class in <code>rt.jar</code> should not be\r
-deployed as doing so would contravene the Java 2 Runtime Environment\r
-binary code license.</i>\r
-\r
-<p><br>\r
-\r
-<a href="tutorial2.html">Next page</a>\r
-\r
-<hr>\r
-Java(TM) is a trademark of Sun Microsystems, Inc.<br>\r
-Copyright (C) 2000-2002 by Shigeru Chiba, All rights reserved.\r
-</body>\r
-</html>\r
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Javassist Tutorial</title>
+ <link rel="stylesheet" type="text/css" href="brown.css">
+</head>
+<body>
+
+<b>
+<font size="+3">
+Getting Started with Javassist
+</font>
+
+<p><font size="+2">
+Shigeru Chiba
+</font>
+</b>
+
+<p><div align="right"><a href="tutorial2.html">Next page</a></div>
+
+<ul>1. <a href="#read">Reading bytecode</a>
+<br>2. <a href="#def">Defining a new class</a>
+<br>3. <a href="#mod">Modifying a class at load time</a>
+<br>4. <a href="#load">Class loader</a>
+<br>5. <a href="tutorial2.html#intro">Introspection and customization</a>
+</ul>
+
+<p><br>
+
+<a name="read">
+<h2>1. Reading bytecode</h2>
+
+<p>Javassist is a class library for dealing with Java bytecode.
+Java bytecode is stored in a binary file called a class file.
+Each class file contains one Java class or interface.
+
+<p>The class <code>Javassist.CtClass</code> is an abstract representation
+of a class file. A <code>CtClass</code> object is a handle for dealing
+with a class file. The following program is a very simple example:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("test.Rectangle");
+cc.setSuperclass(pool.get("test.Point"));
+pool.writeFile("test.Rectangle"); // or simply, cc.writeFile()
+</pre></ul>
+
+<p>This program first obtains a <code>ClassPool</code> object,
+which controls bytecode modification with Javassist.
+The <code>ClassPool</code> object is a container of <code>CtClass</code>
+object representing a class file.
+It reads a class file on demand for constructing a <code>CtClass</code>
+object and contains the constructed object until it is written out
+to a file or an output stream.
+
+<p>The <code>ClassPool</code> object is used to maintain one-to-one
+mapping between classes and <code>CtClass</code> objects. Javassist
+never allows two distinct <code>CtClass</code> objects to represent
+the same class. This is a crucial feature to consistent program
+transformaiton.
+
+<p>To modify the definition of a class, the users must first obtain a
+reference to the <code>CtClass</code> object representing that class.
+<code>ClassPool.get()</code> is used for this purpose.
+In the case of the program above, the <code>CtClass</code> object
+representing a class <code>test.Rectangle</code> is obtained from
+the <code>ClassPool</code> object
+and it is assigned
+to a variable <code>cc</code>. Then it is modified so that
+the superclass of <code>test.Rectangle</code> is changed into
+a class <code>test.Point</code>.
+This change is reflected on the original class file when
+<code>ClassPool.writeFile()</code> is finally called.
+
+<p>Note that <code>writeFile()</code> is a method declared in not
+<code>CtClass</code> but <code>ClassPool</code>.
+If this method is called, the <code>ClassPool</code>
+finds a <code>CtClass</code> object specified with a class name
+among the objects that the <code>ClassPool</code> contains.
+Then it translates that <code>CtClass</code> object into a class file
+and writes it on a local disk.
+
+<p>There is also <code>writeFile()</code> defined in <code>CtClass</code>.
+Thus, the last line in the program above can be rewritten into:
+
+<ul><pre>cc.writeFile();</pre></ul>
+
+<p>This method is a convenient method for invoking <code>writeFile()</code>
+in <code>ClassPool</code> with the name of the class represented by
+<code>cc</code>.
+
+<p>Javassist also provides a method for directly obtaining the
+modified bytecode. To do this, call <code>write()</code>:
+
+<ul><pre>
+byte[] b = pool.write("test.Rectangle");
+</pre></ul>
+
+<p>The contents of the class file for <code>test.Rectangle</code> are
+assigned to a variable <code>b</code> in the form of byte array.
+<code>writeFile()</code> also internally calls <code>write()</code>
+to obtain the byte array written in a class file.
+
+<p>The default <code>ClassPool</code> returned
+by a static method <code>ClassPool.getDefault()</code>
+searches the same path as the underlying JVM.
+The users can expand this class search path if needed.
+For example, the following code adds a directory
+<code>/usr/local/javalib</code>
+to the search path:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+pool.insertClassPath("/usr/local/javalib");
+</pre></ul>
+
+<p>The search path that the users can add is not only a directory but also
+a URL:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+ClassPath cp = new URLClassPath("www.foo.com", 80, "/java/", "com.foo.");
+pool.insertClassPath(cp);
+</pre></ul>
+
+<p>This program adds "http://www.foo.com:80/java/" to the class search
+path. This URL is used only for searching classes belonging to a
+package <code>com.foo</code>.
+
+<p>You can directly give a byte array to a <code>ClassPool</code> object
+and construct a <code>CtClass</code> object from that array. To do this,
+use <code>ByteArrayClassPath</code>. For example,
+
+<ul><pre>
+ClassPool cp = ClassPool.getDefault();
+byte[] b = <em>a byte array</em>;
+String name = <em>class name</em>;
+cp.insertClassPath(new ByteArrayClassPath(name, b));
+CtClass cc = cp.get(name);
+</pre></ul>
+
+<p>The obtained <code>CtClass</code> object represents
+a class defined by the class file specified by <code>b</code>.
+
+<p>Since <code>ClassPath</code> is an interface, the users can define
+a new class implementing this interface and they can add an instance
+of that class so that a class file is obtained from a non-standard resource.
+
+<p>If you want to directly construct a <code>CtClass</code> object
+from a class file but you do not know the fully-qualified name
+of the class, then
+you can use <code>makeClass()</code> in <code>CtClass</code>:
+
+<ul><pre>
+ClassPool cp = ClassPool.getDefault();
+InputStream ins = <em>an input stream for reading a class file</em>;
+CtClass cc = cp.makeClass(ins);
+</pre></ul>
+
+<p><code>makeClass()</code> returns the <code>CtClass</code> object
+constructed from the given input stream. You can use
+<code>makeClass()</code> for eagerly feeding class files to
+the <code>ClassPool</code> object. This might improve performance
+if the search path includes a large jar file. Since
+the <code>ClassPool</code> object reads a class file on demand,
+it might repeatedly search the whole jar file for every class file.
+<code>makeClass()</code> can be used for optimizing this search.
+The <code>CtClass</code> constructed by <code>makeClass()</code>
+is kept in the <code>ClassPool</code> object and the class file is never
+read again.
+
+<p><br>
+
+<a name="def">
+<h2>2. Defining a new class</h2>
+
+<p>To define a new class from scratch, <code>makeClass()</code>
+must be called on a <code>ClassPool</code>.
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+</pre></ul>
+
+<p>This program defines a class <code>Point</code>
+including no members.
+
+<p>A new class can be also defined as a copy of an existing class.
+The program below does that:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+cc.setName("Pair");
+</pre></ul>
+
+<p>This program first obtains the <code>CtClass</code> object
+for class <code>Point</code>. Then it gives a new name <code>Pair</code>
+to that <code>CtClass</code> object.
+If <code>get("Point")</code> is called on the <code>ClassPool</code>
+object, then a class file <code>Point.class</code> is read again and
+a new <code>CtClass</code> object for class <code>Point</code> is constructed
+again.
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+CtClass cc1 = pool.get("Point"); // cc1 is identical to cc.
+cc.setName("Pair");
+CtClass cc2 = pool.get("Pair"); // cc2 is identical to cc.
+CtClass cc3 = pool.get("Point"); // cc3 is not identical to cc.
+</pre></ul>
+
+<p><br>
+
+<a name="mod">
+<h2>3. Modifying a class at load time</h2>
+
+<p>If what classes are modified is known in advance,
+the easiest way for modifying the classes is as follows:
+
+<ul><li>1. Get a <code>CtClass</code> object by calling
+ <code>ClassPool.get()</code>,
+ <li>2. Modify it, and
+ <li>3. Call <code>ClassPool.write()</code> or <code>writeFile()</code>.
+</ul>
+
+<p>If whether a class is modified or not is determined at load time,
+the users can write an event listener so that it is notified
+when a class is loaded into the JVM.
+A class loader (<code>java.lang.ClassLoader</code>) working with
+Javassist must call <code>ClassPool.write()</code> for obtaining
+a class file. The users can write an event listener so that it is
+notified when the class loader calls <code>ClassPool.write()</code>.
+The event-listener class must implement the following interface:
+
+<ul><pre>public interface Translator {
+ public void start(ClassPool pool)
+ throws NotFoundException, CannotCompileException;
+ public void onWrite(ClassPool pool, String classname)
+ throws NotFoundException, CannotCompileException;
+}</pre></ul>
+
+<p>The method <code>start()</code> is called when this event listener
+is registered to a <code>ClassPool</code> object.
+The method <code>onWrite()</code> is called when <code>write()</code>
+(or similar methods) is called on the <code>ClassPool</code> object.
+The second parameter of <code>onWrite()</code> is the name of the class
+to be written out.
+
+<p>Note that <code>start()</code> or <code>onWrite()</code> do not have
+to call <code>write()</code> or <code>writeFile()</code>. For example,
+
+<ul><pre>public class MyAnotherTranslator implements Translator {
+ public void start(ClassPool pool)
+ throws NotFoundException, CannotCompileException {}
+ public void onWrite(ClassPool pool, String classname)
+ throws NotFoundException, CannotCompileException
+ {
+ CtClass cc = pool.get(classname);
+ cc.setModifiers(Modifier.PUBLIC);
+ }
+}</pre></ul>
+
+<p>All the classes written out by <code>write()</code> are made public
+just before their definitions are translated into an byte array.
+
+<p><center><img src="overview.gif" alt="overview"></center>
+
+<p>The two methods <code>start()</code> and <code>onWrite()</code>
+can modify not only a <code>CtClass</code> object specified by
+the given <code>classname</code> but also
+<em>any</em> <code>CtClass</code> objects contained
+in the given <code>ClassPool</code>.
+They can call <code>ClassPool.get()</code> for obtaining any
+<code>CtClass</code> object.
+If a modified <code>CtClass</code> object is not written out immediately,
+the modification is recorded until that object is written out.
+
+<p><center><img src="sequence.gif" alt="sequence diagram"></center>
+
+<p>To register an event listener to a <code>ClassPool</code>,
+it must be passed to a constructor of <code>ClassPool</code>.
+Only a single event listener can be registered.
+If more than one event listeners are needed, multiple
+<code>ClassPool</code>s should be connected to be a single
+stream. For example,
+
+<ul><pre>Translator t1 = new MyTranslator();
+ClassPool c1 = new ClassPool(t1);
+Translator t2 = new MyAnotherTranslator();
+ClassPool c2 = new ClassPool(c1, t2);</pre></ul>
+
+<p>This program connects two <code>ClassPool</code>s.
+If a class loader calls <code>write()</code> on <code>c2</code>,
+the specified class file is first modified by <code>t1</code> and
+then by <code>t2</code>. <code>write()</code> returns the resulting
+class file.
+
+First, <code>onWrite()</code> on <code>t1</code> is called since
+<code>c2</code> obtains a class file by calling <code>write()</code>
+on <code>c1</code>. Then <code>onWrite()</code> on <code>t2</code>
+is called. If <code>onWrite()</code> called on <code>t2</code>
+obtains a <code>CtClass</code> object from <code>c2</code>, that
+<code>CtClass</code> object represents the class file that
+<code>t1</code> has modified.
+
+<p><center><img src="two.gif" alt="two translators"></center>
+
+<p><br>
+
+<a name="load">
+<h2>4. Class loader</h2>
+
+<p>Javassist can be used with a class loader so that bytecode can be
+modified at load time. The users of Javassist can define their own
+version of class loader but they can also use a class loader provided
+by Javassist.
+
+<p><br>
+
+<h3>4.1 Using <code>javassist.Loader</code></h3>
+
+<p>Javassist provides a class loader
+<code>javassist.Loader</code>. This class loader uses a
+<code>javassist.ClassPool</code> object for reading a class file.
+
+<p>For example, <code>javassist.Loader</code> can be used for loading
+a particular class modified with Javassist.
+
+<ul><pre>
+import javassist.*;
+import test.Rectangle;
+
+public class Main {
+ public static void main(String[] args) throws Throwable {
+ ClassPool pool = ClassPool.getDefault();
+ Loader cl = new Loader(pool);
+
+ CtClass ct = pool.get("test.Rectangle");
+ ct.setSuperclass(pool.get("test.Point"));
+
+ Class c = cl.loadClass("test.Rectangle");
+ Object rect = c.newInstance();
+ :
+ }
+}
+</pre></ul>
+
+<p>This program modifies a class <code>test.Rectangle</code>. The
+superclass of <code>test.Rectangle</code> is set to a
+<code>test.Point</code> class. Then this program loads the modified
+class into the JVM, and creates a new instance of the
+<code>test.Rectangle</code> class.
+
+<p>The users can use a <code>javassist.Translator</code> object
+for modifying class files.
+Suppose that an instance of a class <code>MyTranslator</code>,
+which implements
+<code>javassist.Translator</code>, performs modification of class files.
+To run an application class <code>MyApp</code> with the
+<code>MyTranslator</code> object, write a main class:
+
+<ul><pre>
+import javassist.*;
+
+public class Main2 {
+ public static void main(String[] args) throws Throwable {
+ Translator t = new MyTranslator();
+ ClassPool pool = ClassPool.getDefault(t);
+ Loader cl = new Loader(pool);
+ cl.run("MyApp", args);
+ }
+}
+</pre></ul>
+
+<p>To run this program, do:
+
+<ul><pre>
+% java Main <i>arg1</i> <i>arg2</i>...
+</pre></ul>
+
+<p>The class <code>MyApp</code> and the other application classes
+are translated by <code>MyTranslator</code>.
+
+<p>Note that <em>application</em> classes like <code>MyApp</code> cannot
+access the <em>loader</em> classes such as <code>Main</code>,
+<code>MyTranslator</code> and <code>ClassPool</code> because they
+are loaded by different loaders. The application classes are loaded
+by <code>javassist.Loader</code> whereas the loader classes such as
+<code>Main</code> are by the default Java class loader.
+
+<p>In Java, for security reasons, a single class file may be loaded
+into the JVM by two distinct class loaders so that two different
+classes would be created. For example,
+
+<ul><pre>class Point {
+ int x, y;
+}
+
+class Box {
+ Point base;
+ Point getBase() { return base; }
+}
+
+class Window {
+ Point size;
+ Point getSize() { return size; }
+}</pre></ul>
+
+<p>Suppose that a class <code>Box</code> is loaded by a class loader
+<code>L1</code> while a class <code>Window</code> is loaded by a class
+loader <code>L2</code>. Then, the obejcts returned by
+<code>getBase()</code> and <code>getSize()</code> are not instances of
+the same class <code>Point</code>.
+<code>getBase()</code> returns an instance of the class <code>Point</code>
+loaded by <code>L1</code> whereas <code>getSize()</code> returns an
+instance of <code>Point</code> loaded by <code>L2</code>. The two versions
+of the class <code>Point</code> are distinct. They belong to different
+name spaces. For more details, see the following paper:
+
+<ul>Sheng Liang and Gilad Bracha,
+"Dynamic Class Loading in the Java Virtual Machine",
+<br><i>ACM OOPSLA'98</i>, pp.36-44, 1998.</ul>
+
+<p>To avoid this problem, the two class loaders <code>L1</code> and
+<code>L2</code> must delegate the loading operation of the class
+<code>Point</code> to another class loader, <code>L3</code>, which is
+a parent class loader of <code>L1</code> and <code>L2</code>.
+<code>delegateLoadingOf()</code> in <code>javassist.Loader</code>
+is a method for specifying what classes should be loaded by the
+parent loader.
+
+<p>If <code>L1</code> is the parent class loader of <code>L2</code>,
+that is, if <code>L1</code> loads the class of <code>L2</code>,
+then <code>L2</code> can delegate the loading operation of
+<code>Point</code> to <code>L1</code> for avoiding the problem above.
+However, this technique does not work in the case below:
+
+<ul><pre>class Point { // loaded by L1
+ Window win;
+ int x, y;
+}
+
+class Box { // loaded by L1
+ Point base;
+ Point getBase() { return base; }
+}
+
+class Window { // loaded by L2
+ Point size;
+ Point getSize() { size.win = this; return size; }
+}</pre></ul>
+
+<p>Since all the classes included in a class definition loaded by
+a class loader <code>L1</code> are also loaded by <code>L1</code>,
+the class of the field <code>win</code> in <code>Point</code> is
+now the class <code>Window</code> loaded by <code>L1</code>.
+Thus <code>size.win = this</code> in <code>getSize()</code> raises
+a runtime exception because of type mismatch; the type of
+<code>size.win</code> is the class <code>Point</code> loaded by
+<code>L1</code> whereas the type of <code>this</code> is the class
+<code>Point</code> loaded by <code>L2</code>.
+
+<p><br>
+
+<h3>4.2 Writing a class loader</h3>
+
+<p>A simple class loader using Javassist is as follows:
+
+<ul><pre>import javassist.*;
+
+public class SimpleLoader extends ClassLoader {
+ /* Call MyApp.main().
+ */
+ public static void main(String[] args) throws Throwable {
+ SimpleLoader s = new SimpleLoader();
+ Class c = s.loadClass("MyApp");
+ c.getDeclaredMethod("main", new Class[] { String[].class })
+ .invoke(null, new Object[] { args });
+ }
+
+ private ClassPool pool;
+
+ public SimpleLoader() throws NotFoundException {
+ pool = ClassPool.getDefault();
+ pool.insertClassPath("./class"); // <em>MyApp.class must be there.</em>
+ }
+
+ /* Finds a specified class.
+ * The bytecode for that class can be modified.
+ */
+ protected Class findClass(String name) throws ClassNotFoundException {
+ try {
+ CtClass cc = pool.get(name);
+ // <em>modify the CtClass object here</em>
+ byte[] b = pool.write(name);
+ return defineClass(name, b, 0, b.length);
+ } catch (NotFoundException e) {
+ throw new ClassNotFoundException();
+ } catch (IOException e) {
+ throw new ClassNotFoundException();
+ } catch (CannotCompileException e) {
+ throw new ClassNotFoundException();
+ }
+ }
+}</pre></ul>
+
+<p>The class <code>MyApp</code> is an application program.
+To execute this program, first put the class file under the
+<code>./class</code> directory, which must <em>not</em> be included
+in the class search path. The directory name is specified by
+<code>insertClassPath()</code> in the constructor.
+You can choose a different name instead of <code>./class</code> if you want.
+Then do as follows:
+
+<ul><code>% java SimpleLoader</code></ul>
+
+<p>The class loader loads the class <code>MyApp</code>
+(<code>./class/MyApp.class</code>) and calls
+<code>MyApp.main()</code> with the command line parameters.
+Note that <code>MyApp.class</code> must not be under the directory
+that the system class loader searches. Otherwise, the system class
+loader, which is the parent loader of <code>SimpleLoader</code>,
+loads the class <code>MyApp</code>.
+
+<p>This is the simplest way of using Javassist. However, if you write
+a more complex class loader, you may need detailed knowledge of
+Java's class loading mechanism. For example, the program above puts the
+<code>MyApp</code> class in a name space separated from the name space
+that the class <code>SimpleLoader</code> belongs to because the two
+classes are loaded by different class loaders.
+Hence, the
+<code>MyApp</code> class cannot directly access the class
+<code>SimpleLoader</code>.
+
+<p><br>
+
+<h3>4.3 Modifying a system class</h3>
+
+<p>The system classes like <code>java.lang.String</code> cannot be
+loaded by a class loader other than the system class loader.
+Therefore, <code>SimpleLoader</code> or <code>javassist.Loader</code>
+shown above cannot modify the system classes at loading time.
+
+<p>If your application needs to do that, the system classes must be
+<em>statically</em> modified. For example, the following program
+adds a new field <code>hiddenValue</code> to <code>java.lang.String</code>:
+
+<ul><pre>ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("java.lang.String");
+cc.addField(new CtField(CtClass.intType, "hiddenValue", cc));
+pool.writeFile("java.lang.String", ".");</pre></ul>
+
+<p>This program produces a file <code>"./java/lang/String.class"</code>.
+
+<p>To run your program <code>MyApp</code>
+with this modified <code>String</code> class, do as follows:
+
+<ul><pre>
+% java -Xbootclasspath/p:. MyApp <i>arg1</i> <i>arg2</i>...
+</pre></ul>
+
+<p>Suppose that the definition of <code>MyApp</code> is as follows:
+
+<ul><pre>public class MyApp {
+ public static void main(String[] args) throws Exception {
+ System.out.println(String.class.getField("hiddenValue").getName());
+ }
+}</pre></ul>
+
+<p>If the modified <code>String</code> class is correctly loaded,
+<code>MyApp</code> prints <code>hiddenValue</code>.
+
+<p><i>Note: Applications that use this technique for the purpose of
+overriding a system class in <code>rt.jar</code> should not be
+deployed as doing so would contravene the Java 2 Runtime Environment
+binary code license.</i>
+
+<p><br>
+
+<a href="tutorial2.html">Next page</a>
+
+<hr>
+Java(TM) is a trademark of Sun Microsystems, Inc.<br>
+Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved.
+</body>
+</html>
-<html>\r
-<head>\r
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r
- <title>Javassist Tutorial</title>\r
- <link rel="stylesheet" type="text/css" href="brown.css">\r
-</head>\r
-\r
-<body>\r
-\r
-<div align="right">Getting Started with Javassist</div>\r
-\r
-<div align="left"><a href="tutorial.html">Previous page</a></div>\r
-\r
-<a name="intro">\r
-<h2>5. Introspection and customization</h2>\r
-\r
-<p><code>CtClass</code> provides methods for introspection. The\r
-introspective ability of Javassist is compatible with that of\r
-the Java reflection API. <code>CtClass</code> provides\r
-<code>getName()</code>, <code>getSuperclass()</code>,\r
-<code>getMethods()</code>, and so on.\r
-<code>CtClass</code> also provides methods for modifying a class\r
-definition. It allows to add a new field, constructor, and method.\r
-Instrumenting a method body is also possible.\r
-\r
-<p><hr width="40%">\r
-\r
-<ul>\r
-Javassist does not allow to remove a method or field, but it allows\r
-to change the name. So if a method is not necessary any more, it should be\r
-renamed and changed to be a private method by calling\r
-<code>setName()</code>\r
-and <code>setModifiers()</code> declared in <code>CtMethod</code>.\r
-\r
-<p>Javassist does not allow to add an extra parameter to an existing\r
-method, either. Instead of doing that, a new method receiving the\r
-extra parameter as well as the other parameters should be added to the\r
-same class. For example, if you want to add an extra <code>int</code>\r
-parameter <code>newZ</code> to a method:\r
-\r
-<ul><pre>void move(int newX, int newY) { x = newX; y = newY; }</pre></ul>\r
-\r
-<p>in a <code>Point</code> class, then you should add the following\r
-method to the <code>Point</code> class:\r
-\r
-<ul><pre>void move(int newX, int newY, int newZ) {\r
- // do what you want with newZ.\r
- move(newX, newY);\r
-}</pre></ul>\r
-\r
-</ul>\r
-\r
-<p><hr width="40%">\r
-\r
-<p>Javassist also provides low-level API for directly editing a raw\r
-class file. For example, <code>getClassFile()</code> in\r
-<code>CtClass</code> returns a <code>ClassFile</code> object\r
-representing a raw class file. <code>getMethodInfo()</code> in\r
-<code>CtMethod</code> returns a <code>MethodInfo</code> object\r
-representing a <code>method_info</code> structure included in a class\r
-file. The low-level API uses the vocabulary from the Java Virtual\r
-machine specification. The users must have the knowledge about class\r
-files and bytecode. For more details, the users should see the\r
-<code>javassist.bytecode</code> package.\r
-\r
-<p><br>\r
-\r
-<h3>5.1 Inserting source text at the beginning/end of a method body</h3>\r
-\r
-<p><code>CtMethod</code> and <code>CtConstructor</code> provide\r
-methods <code>insertBefore()</code>, <code>insertAfter()</code>, and\r
-<code>addCatch()</code>. They are used for inserting a code fragment\r
-into the body of an existing method. The users can specify those code\r
-fragments with <em>source text</em> written in Java.\r
-Javassist includes a simple Java compiler for processing source\r
-text. It receives source text\r
-written in Java and compiles it into Java bytecode, which will be inserted\r
-into a method body.\r
-\r
-<p>The methods <code>insertBefore()</code>, <code>insertAfter()</code>, and\r
-<code>addCatch()</code> receives a <code>String</code> object representing\r
-a statement or a block. A statement is a single control structure like\r
-<code>if</code> and <code>while</code> or an expression ending with\r
-a semi colon (<code>;</code>). A block is a set of\r
-statements surrounded with braces <code>{}</code>.\r
-Hence each of the following lines is an example of valid statement or block:\r
-\r
-<ul><pre>System.out.println("Hello");\r
-{ System.out.println("Hello"); }\r
-if (i < 0) { i = -i; }\r
-</pre></ul>\r
-\r
-<p>The statement and the block can refer to fields and methods.\r
-However, they <em>cannot refer to local variables</em> declared in the\r
-method that they are inserted into.\r
-They can refer to the parameters\r
-to the method although they must use different names\r
-<code>$0</code>, <code>$1</code>, <code>$2</code>, ... described\r
-below. Declaring a local variable in the block is allowed.\r
-\r
-<!--\r
-<p><center><table border=8 cellspacing=0 bordercolor="#cfcfcf">\r
-<tr><td bgcolor="#cfcfcf">\r
-<b>Tip:</b>\r
-<br>    Local variables are not accessible.  \r
-</td></tr>\r
-</table></center>\r
--->\r
-\r
-<p>The <code>String</code> object passed to the methods\r
-<code>insertBefore()</code>, <code>insertAfter()</code>, and\r
-<code>addCatch()</code> are compiled by\r
-the compiler included in Javassist.\r
-Since the compiler supports language extensions,\r
-several identifiers starting with <code>$</code>\r
-have special meaning:\r
-\r
-<ul><table border=0>\r
-<tr>\r
-<td><code>$0</code>, <code>$1</code>, <code>$2</code>, ...    </td>\r
-<td>Actual parameters</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$args</code></td>\r
-<td>An array of parameters.\r
-The type of <code>$args</code> is <code>Object[]</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$$</code></td>\r
-<td rowspan=2>All actual parameters.<br>\r
-For example, <code>m($$)</code> is equivalent to\r
-<code>m($1,$2,</code>...<code>)</code></td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr>\r
-<td><code>$cflow(</code>...<code>)</code></td>\r
-<td><code>cflow</code> variable</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$r</code></td>\r
-<td>The result type. It is used in a cast expression.</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$w</code></td>\r
-<td>The wrapper type. It is used in a cast expression.</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$_</code></td>\r
-<td>The resulting value</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$sig</code></td>\r
-<td>An array of <code>java.lang.Class</code> objects representing\r
-the formal parameter types.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$type</code></td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the formal result type.</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$class</code></td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the class currently edited.</td>\r
-</tr>\r
-\r
-</table>\r
-</ul>\r
-\r
-<h4>$0, $1, $2, ...</h4>\r
-\r
-<p>The parameters passed to the methods <code>insertBefore()</code>,\r
-<code>insertAfter()</code>, and <code>addCatch()</code>\r
-are accessible with\r
-<code>$0</code>, <code>$1</code>, <code>$2</code>, ... instead of\r
-the original parameter names.\r
-<code>$1</code> represents the\r
-first parameter, <code>$2</code> represents the second parameter, and\r
-so on. The types of those variables are identical to the parameter\r
-types.\r
-<code>$0</code> is\r
-equivalent to <code>this</code>. If the method is static,\r
-<code>$0</code> is not available.\r
-\r
-<p>These variables are used as following. Suppose that a class\r
-<code>Point</code>:\r
-\r
-<pre><ul>class Point {\r
- int x, y;\r
- void move(int dx, int dy) { x += dx; y += dy; }\r
-}\r
-</ul></pre>\r
-\r
-<p>To print the values of <code>dx</code> and <code>dy</code>\r
-whenever the method <code>move()</code> is called, execute this\r
-program:\r
-\r
-<ul><pre>ClassPool pool = ClassPool.getDefault();\r
-CtClass cc = pool.get("Point");\r
-CtMethod m = cc.getDeclaredMethod("move");\r
-m.insertBefore("{ System.out.println($1); System.out.println($2); }");\r
-cc.writeFile();\r
-</pre></ul>\r
-\r
-<p>Note that the source text passed to <code>insertBefore()</code> is\r
-surrounded with braces <code>{}</code>.\r
-<code>insertBefore()</code> accepts only a single statement or a block\r
-surrounded with braces.\r
-\r
-<p>The definition of the class <code>Point</code> after the\r
-modification is like this:\r
-\r
-<pre><ul>class Point {\r
- int x, y;\r
- void move(int dx, int dy) {\r
- { System.out.println(dx); System.out.println(dy); }\r
- x += dx; y += dy;\r
- }\r
-}\r
-</ul></pre>\r
-\r
-<p><code>$1</code> and <code>$2</code> are replaced with\r
-<code>dx</code> and <code>dy</code>, respectively.\r
-\r
-<p><code>$1</code>, <code>$2</code>, <code>$3</code> ... are\r
-updatable. If a new value is assigend to one of those variables,\r
-then the value of the parameter represented by that variable is\r
-also updated.\r
-\r
-\r
-<h4>$args</h4>\r
-\r
-<p>The variable <code>$args</code> represents an array of all the\r
-parameters. The type of that variable is an array of class\r
-<code>Object</code>. If a parameter type is a primitive type such as\r
-<code>int</code>, then the parameter value is converted into a wrapper\r
-object such as <code>java.lang.Integer</code> to store in\r
-<code>$args</code>. Thus, <code>$args[0]</code> is equivalent to\r
-<code>$1</code> unless the type of the first parameter is a primitive\r
-type. Note that <code>$args[0]</code> is not equivalent to\r
-<code>$0</code>; <code>$0</code> represents <code>this</code>.\r
-\r
-<p>If an array of <code>Object</code> is assigned to\r
-<code>$args</code>, then each element of that array is\r
-assigned to each parameter. If a parameter type is a primitive\r
-type, the type of the corresponding element must be a wrapper type.\r
-The value is converted from the wrapper type to the primitive type\r
-before it is assigned to the parameter.\r
-\r
-<h4>$$</h4>\r
-\r
-<p>The variable <code>$$</code> is abbreviation of a list of\r
-all the parameters separated by commas.\r
-For example, if the number of the parameters\r
-to method <code>move()</code> is three, then\r
-\r
-<ul><pre>move($$)</pre></ul>\r
-\r
-<p>is equivalent to this:\r
-\r
-<ul><pre>move($1, $2, $3)</pre></ul>\r
-\r
-<p>If <code>move()</code> does not take any parameters,\r
-then <code>move($$)</code> is\r
-equivalent to <code>move()</code>.\r
-\r
-<p><code>$$</code> can be used with another method.\r
-If you write an expression:\r
-\r
-<ul><pre>exMove($$, context)</pre></ul>\r
-\r
-<p>then this expression is equivalent to:\r
-\r
-<ul><pre>exMove($1, $2, $3, context)</pre></ul>\r
-\r
-<p>Note that <code>$$</code> enables generic notation of method call\r
-with respect to the number of parameters.\r
-It is typically used with <code>$proceed</code> shown later.\r
-\r
-<h4>$cflow</h4>\r
-\r
-<p><code>$cflow</code> means "control flow".\r
-This read-only variable returns the depth of the recursive calls\r
-to a specific method.\r
-\r
-<p>Suppose that the method shown below is represented by a\r
-<code>CtMethod</code> object <code>cm</code>:\r
-\r
-<ul><pre>int fact(int n) {\r
- if (n <= 1)\r
- return n;\r
- else\r
- return n * fact(n - 1);\r
-}</pre></ul>\r
-\r
-<p>To use <code>$cflow</code>, first declare that <code>$cflow</code>\r
-is used for monitoring calls to the method <code>fact()</code>:\r
-\r
-<ul><pre>CtMethod cm = ...;\r
-cm.useCflow("fact");</pre></ul>\r
-\r
-<p>The parameter to <code>useCflow()</code> is the identifier of the\r
-declared <code>$cflow</code> variable. Any valid Java name can be\r
-used as the identifier. Since the identifier can also include\r
-<code>.</code> (dot), for example, <code>"my.Test.fact"</code>\r
-is a valid identifier.\r
-\r
-<p>Then, <code>$cflow(fact)</code> represents the depth of the\r
-recursive calls to the method specified by <code>cm</code>. The value\r
-of <code>$cflow(fact)</code> is 0 (zero) when the method is\r
-first called whereas it is 1 when the method is recursively called\r
-within the method. For example,\r
-\r
-<ul><pre>\r
-cm.insertBefore("if ($cflow(fact) == 0)"\r
- + " System.out.println(\"fact \" + $1);");\r
-</pre></ul>\r
-\r
-<p>translates the method <code>fact()</code> so that it shows the\r
-parameter. Since the value of <code>$cflow(fact)</code> is checked,\r
-the method <code>fact()</code> does not show the parameter if it is\r
-recursively called within <code>fact()</code>.\r
-\r
-<p>The value of <code>$cflow</code> is the number of stack frames\r
-associated with the specified method <code>cm</code>\r
-under the current topmost\r
-stack frame for the current thread. <code>$cflow</code> is also\r
-accessible within a method different from the specified method\r
-<code>cm</code>.\r
-\r
-<h4>$r</h4>\r
-\r
-<p><code>$r</code> represents the result type (return type) of the method.\r
-It must be used as the cast type in a cast expression.\r
-For example, this is a typical use:\r
-\r
-<ul><pre>Object result = ... ;\r
-$_ = ($r)result;</pre></ul>\r
-\r
-<p>If the result type is a primitive type, then <code>($r)</code>\r
-converts from the wrapper type to the primitive type.\r
-For example, if the result type is <code>int</code>, then\r
-<code>($r)</code> converts from <code>java.lang.Integer</code> to\r
-<code>int</code>.\r
-\r
-<p>If the result type is <code>void</code>, then\r
-<code>($r)</code> does not convert a type; it does nothing.\r
-Moreover, the soruce text can include a <code>return</code>\r
-statement with a resulting value:\r
-\r
-<ul><pre>return ($r)result;</pre></ul>\r
-\r
-<p>Here, <code>result</code> is some local variable.\r
-Since <code>($r)</code> is specified, the resulting value is\r
-discarded.\r
-This <code>return</code> statement is regarded as the equivalent\r
-of the <code>return</code> statement without a resulting value:\r
-\r
-<ul><pre>return;</pre></ul>\r
-\r
-<h4>$w</h4>\r
-\r
-<p><code>$w</code> represents a wrapper type.\r
-It must be used as the cast type in a cast expression.\r
-<code>($w)</code> converts from a primitive type to the corresponding\r
-wrapper type.\r
-\r
-The following code is an example:\r
-\r
-<ul><pre>Integer i = ($w)5;</pre></ul>\r
-\r
-<p>The selected wrapper type depends on the type of the expression\r
-following <code>($w)</code>. If the type of the expression is\r
-<code>double</code>, then the wrapper type is <code>java.lang.Double</code>.\r
-\r
-<p>If the type of the expression following <code>($w)</code> is not\r
-a primitive type, then <code>($w)</code> does nothing.\r
-\r
-<h4>$_</h4>\r
-\r
-<p><code>insertAfter()</code> in <code>CtMethod</code> and\r
-<code>CtConstructor</code> inserts the\r
-compiled code at the end of the method. In the statement given to\r
-<code>insertAfter()</code>, not only the variables shown above such as\r
-<code>$0</code>, <code>$1</code>, ... but also <code>$_</code> is\r
-available.\r
-\r
-<p>The variable <code>$_</code> represents the resulting value of the\r
-method. The type of that variable is the type of the result type (the\r
-return type) of the method. If the result type is <code>void</code>,\r
-then the type of <code>$_</code> is <code>Object</code> and the value\r
-of <code>$_</code> is <code>null</code>.\r
-\r
-<p>Although the compiled code inserted by <code>insertAfter()</code>\r
-is executed just before the control normally returns from the method,\r
-it can be also executed when an exception is thrown from the method.\r
-To execute it when an exception is thrown, the second parameter\r
-<code>asFinally</code> to <code>insertAfter()</code> must be\r
-<code>true</code>.\r
-\r
-<p>If an exception is thrown, the compiled code inserted by\r
-<code>insertAfter()</code> is executed as a <code>finally</code>\r
-clause. The value of <code>$_</code> is <code>0</code> or\r
-<code>null</code> in the compiled code. After the execution of the\r
-compiled code terminates, the exception originally thrown is re-thrown\r
-to the caller. Note that the value of <code>$_</code> is never thrown\r
-to the caller; it is rather discarded.\r
-\r
-<h4>$sig</h4>\r
-\r
-<p>The value of <code>$sig</code> is an array of\r
-<code>java.lang.Class</code> objects that represent the formal\r
-parameter types in declaration order.\r
-\r
-<h4>$type</h4>\r
-\r
-<p>The value of <code>$type</code> is an <code>java.lang.Class</code>\r
-object representing the formal type of the result value. This\r
-variable is available only in <code>insertAfter()</code> in\r
-<code>CtMethod</code> and <code>CtConstructor</code>.\r
-\r
-<h4>$class</h4>\r
-\r
-<p>The value of <code>$class</code> is an <code>java.lang.Class</code>\r
-object representing the class in which the edited method is declared.\r
-\r
-<h4>addCatch()</h4>\r
-\r
-<p><code>addCatch()</code> inserts a code fragment into a method body\r
-so that the code fragment is executed when the method body throws\r
-an exception and the control returns to the caller. In the source\r
-text representing the inserted code fragment, the exception value\r
-is referred to with the name specified by the third parameter to\r
-<code>addCatch()</code>.\r
-\r
-<p>For example, this program:\r
-\r
-<ul><pre>\r
-CtMethod m = ...;\r
-CtClass etype = ClassPool.getDefault().get("java.io.IOException");\r
-m.addCatch("{ System.out.println(e); throw e; }", etype, "e");\r
-</pre></ul>\r
-\r
-<p>translates the method body represented by <code>m</code> into\r
-something like this:\r
-\r
-<ul><pre>\r
-try {\r
- <font face="serif"><em>the original method body</em></font>\r
-}\r
-catch (java.io.IOException e) {\r
- System.out.println(e);\r
- throw e;\r
-}\r
-</pre></ul>\r
-\r
-<p>Note that the inserted code fragment must end with a\r
-<code>throw</code> or <code>return</code> statement.\r
-\r
-<p><br>\r
-\r
-<h3>5.2 Modifying a method body</h3>\r
-\r
-<p><code>javassist.expr.ExprEditor</code> is a class\r
-for replacing an expression in a method body.\r
-The users can define a subclass of <code>ExprEditor</code>\r
-to specify how an expression is modified.\r
-\r
-<p>To run an <code>ExprEditor</code> object, the users must\r
-call <code>instrument()</code> in <code>CtMethod</code> or\r
-<code>CtClass</code>.\r
-\r
-For example,\r
-\r
-<ul><pre>\r
-CtMethod cm = ... ;\r
-cm.instrument(\r
- new ExprEditor() {\r
- public void edit(MethodCall m)\r
- throws CannotCompileException\r
- {\r
- if (m.getClassName().equals("Point")\r
- && m.getMethodName().equals("move"))\r
- m.replace("{ $1 = 0; $_ = $proceed($$); }");\r
- }\r
- });\r
-</pre></ul>\r
-\r
-<p>searches the method body represented by <code>cm</code> and\r
-replaces all calls to <code>move()</code> in class <code>Point</code>\r
-with a block:\r
-\r
-<ul><pre>{ $1 = 0; $_ = $proceed($$); }\r
-</pre></ul>\r
-\r
-<p>so that the first parameter to <code>move()</code> is always 0.\r
-Note that the substituted code is not an expression but\r
-a statement or a block.\r
-\r
-<p>The method <code>instrument()</code> searches a method body.\r
-If it finds an expression such as a method call, field access, and object\r
-creation, then it calls <code>edit()</code> on the given\r
-<code>ExprEditor</code> object. The parameter to <code>edit()</code>\r
-is an object representing the found expression. The <code>edit()</code>\r
-method can inspect and replace the expression through that object.\r
-\r
-<p>Calling <code>replace()</code> on the parameter to <code>edit()</code>\r
-substitutes the given statement or block for the expression. If the given\r
-block is an empty block, that is, if <code>replace("{}")</code>\r
-is executed, then the expression is removed from the method body.\r
-\r
-If you want to insert a statement (or a block) before/after the\r
-expression, a block like the following should be passed to\r
-<code>replace()</code>:\r
-\r
-<ul><pre>\r
-{ <em>before-statements;</em>\r
- $_ = $proceed($$);\r
- <em>after-statements;</em> }\r
-</pre></ul>\r
-\r
-<p>whichever the expression is either a method call, field access,\r
-object creation, or others. The second statement could be:\r
-\r
-<ul><pre>$_ = $proceed();</pre></ul>\r
-\r
-<p>if the expression is read access, or\r
-\r
-<ul><pre>$proceed($$);</pre></ul>\r
-\r
-<p>if the expression is write access.\r
-\r
-<h4>javassist.expr.MethodCall</h4>\r
-\r
-<p>A <code>MethodCall</code> object represents a method call.\r
-The method <code>replace()</code> in\r
-<code>MethodCall</code> substitutes a statement or\r
-a block for the method call.\r
-It receives source text representing the substitued statement or\r
-block, in which the identifiers starting with <code>$</code>\r
-have special meaning as in the source text passed to\r
-<code>insertBefore()</code>.\r
-\r
-<ul><table border=0>\r
-<tr>\r
-<td><code>$0</code></td>\r
-<td rowspan=3>\r
-The target object of the method call.<br>\r
-This is not equivalent to <code>this</code>, which represents\r
-the caller-side <code>this</code> object.<br>\r
-<code>$0</code> is <code>null</code> if the method is static.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr>\r
-<td><code>$1</code>, <code>$2</code>, ...    </td>\r
-<td>\r
-The parameters of the method call.\r
-</td>\r
-</tr>\r
-\r
-<tr><td>\r
-<code>$_</code></td>\r
-<td>The resulting value of the method call.</td>\r
-</tr>\r
-\r
-<tr><td><code>$r</code></td>\r
-<td>The result type of the method call.</td>\r
-</tr>\r
-\r
-<tr><td><code>$class</code>    </td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the class declaring the method.\r
-</td>\r
-</tr>\r
-\r
-<tr><td><code>$sig</code>    </td>\r
-<td>An array of <code>java.lang.Class</code> objects representing\r
-the formal parameter types.</td>\r
-</tr>\r
-\r
-<tr><td><code>$type</code>    </td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the formal result type.</td>\r
-</tr>\r
-\r
-<tr><td><code>$proceed</code>    </td>\r
-<td>The name of the method originally called\r
-in the expression.</td>\r
-</tr>\r
-\r
-</table>\r
-</ul>\r
-\r
-<p>Here the method call means the one represented by the\r
-<code>MethodCall</code> object.\r
-\r
-<p>The other identifiers such as <code>$w</code>,\r
-<code>$args</code> and <code>$$</code>\r
-are also available.\r
-\r
-<p>Unless the result type of the method call is <code>void</code>,\r
-a value must be assigned to\r
-<code>$_</code> in the source text and the type of <code>$_</code>\r
-is the result type.\r
-If the result type is <code>void</code>, the type of <code>$_</code>\r
-is <code>Object</code> and the value assigned to <code>$_</code>\r
-is ignored.\r
-\r
-<p><code>$proceed</code> is not a <code>String</code> value but special\r
-syntax. It must be followed by an argument list surrounded by parentheses\r
-<code>( )</code>.\r
-\r
-<h4>javassist.expr.FieldAccess</h4>\r
-\r
-<p>A <code>FieldAccess</code> object represents field access.\r
-The method <code>edit()</code> in <code>ExprEditor</code>\r
-receive this object if field access is found.\r
-The method <code>replace()</code> in\r
-<code>FieldAccess</code> receives\r
-source text representing the substitued statement or\r
-block for the field access.\r
-\r
-In the source text, the identifiers starting with <code>$</code>\r
-have also special meaning:\r
-\r
-<ul><table border=0>\r
-<tr>\r
-<td><code>$0</code></td>\r
-<td rowspan=3>\r
-The object containing the field accessed by the expression.\r
-This is not equivalent to <code>this</code>.<br>\r
-<code>this</code> represents the object that the method including the\r
-expression is invoked on.<br>\r
-<code>$0</code> is <code>null</code> if the field is static.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr>\r
-<td><code>$1</code></td>\r
-<td rowspan=2>\r
-The value that would be stored in the field\r
-if the expression is write access.\r
-<br>Otherwise, <code>$1</code> is not available.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr>\r
-<td><code>$_</code></td>\r
-<td rowspan=2>\r
-The resulting value of the field access\r
-if the expression is read access.\r
-<br>Otherwise, the value stored in <code>$_</code> is discarded.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-<tr>\r
-<td><code>$r</code></td>\r
-<td rowspan=2>\r
-The type of the field if the expression is read access.\r
-<br>Otherwise, <code>$r</code> is <code>void</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr><td><code>$class</code>    </td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the class declaring the field.\r
-</td></tr>\r
-\r
-<tr><td><code>$type</code></td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the field type.</td>\r
-</tr>\r
-\r
-<tr><td><code>$proceed</code>    </td>\r
-<td>The name of a virtual method executing the original\r
-field access.\r
-.</td>\r
-</tr>\r
-\r
-</table>\r
-</ul>\r
-\r
-<p>The other identifiers such as <code>$w</code>,\r
-<code>$args</code> and <code>$$</code>\r
-are also available.\r
-\r
-<p>If the expression is read access, a value must be assigned to\r
-<code>$_</code> in the source text. The type of <code>$_</code>\r
-is the type of the field.\r
-\r
-<h4>javassist.expr.NewExpr</h4>\r
-\r
-<p>A <code>NewExpr</code> object represents object creation\r
-with the <code>new</code> operator.\r
-The method <code>edit()</code> in <code>ExprEditor</code>\r
-receive this object if object creation is found.\r
-The method <code>replace()</code> in\r
-<code>NewExpr</code> receives\r
-source text representing the substitued statement or\r
-block for the object creation.\r
-\r
-In the source text, the identifiers starting with <code>$</code>\r
-have also special meaning:\r
-\r
-<ul><table border=0>\r
-\r
-<tr>\r
-<td><code>$0</code></td>\r
-<td>\r
-<code>null</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$1</code>, <code>$2</code>, ...    </td>\r
-<td>\r
-The parameters to the constructor.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$_</code></td>\r
-<td rowspan=2>\r
-The resulting value of the object creation.\r
-<br>A newly created object must be stored in this variable.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr>\r
-<td><code>$r</code></td>\r
-<td>\r
-The type of the created object.\r
-</td>\r
-</tr>\r
-\r
-<tr><td><code>$class</code>    </td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the class of the created object.\r
-</td></tr>\r
-\r
-<tr><td><code>$sig</code>    </td>\r
-<td>An array of <code>java.lang.Class</code> objects representing\r
-the formal parameter types.</td>\r
-</tr>\r
-\r
-<tr><td><code>$proceed</code>    </td>\r
-<td>The name of a virtual method executing the original\r
-object creation.\r
-.</td>\r
-</tr>\r
-\r
-</table>\r
-</ul>\r
-\r
-<p>The other identifiers such as <code>$w</code>,\r
-<code>$args</code> and <code>$$</code>\r
-are also available.\r
-\r
-<h4>javassist.expr.Instanceof</h4>\r
-\r
-<p>A <code>Instanceof</code> object represents an <code>instanceof</code>\r
-expression.\r
-The method <code>edit()</code> in <code>ExprEditor</code>\r
-receive this object if an instanceof expression is found.\r
-The method <code>replace()</code> in\r
-<code>Instanceof</code> receives\r
-source text representing the substitued statement or\r
-block for the expression.\r
-\r
-In the source text, the identifiers starting with <code>$</code>\r
-have also special meaning:\r
-\r
-<ul><table border=0>\r
-\r
-<tr>\r
-<td><code>$0</code></td>\r
-<td>\r
-<code>null</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$1</code></td>\r
-<td>\r
-The value on the left hand side of the original\r
-<code>instanceof</code> operator.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$_</code></td>\r
-<td>\r
-The resulting value of the expression.\r
-The type of <code>$_</code> is <code>boolean</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$r</code></td>\r
-<td>\r
-The type on the right hand side of the <code>instanceof</code> operator.\r
-</td>\r
-</tr>\r
-\r
-<tr><td><code>$type</code></td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the type on the right hand side of the <code>instanceof</code> operator.\r
-</td>\r
-</tr>\r
-\r
-<tr><td><code>$proceed</code>    </td>\r
-<td rowspan=4>The name of a virtual method executing the original\r
-<code>instanceof</code> expression.\r
-<br>It takes one parameter (the type is <code>java.lang.Object</code>)\r
-and returns true\r
-<br>if the parameter value is an instance of the type on the right\r
-hand side of\r
-<br>the original <code>instanceof</code> operator.\r
-Otherwise, it returns false.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-<tr><td> </td></tr>\r
-<tr><td> </td></tr>\r
-\r
-</table>\r
-</ul>\r
-\r
-<p>The other identifiers such as <code>$w</code>,\r
-<code>$args</code> and <code>$$</code>\r
-are also available.\r
-\r
-<h4>javassist.expr.Cast</h4>\r
-\r
-<p>A <code>Cast</code> object represents an expression for\r
-explicit type casting.\r
-The method <code>edit()</code> in <code>ExprEditor</code>\r
-receive this object if explicit type casting is found.\r
-The method <code>replace()</code> in\r
-<code>Cast</code> receives\r
-source text representing the substitued statement or\r
-block for the expression.\r
-\r
-In the source text, the identifiers starting with <code>$</code>\r
-have also special meaning:\r
-\r
-<ul><table border=0>\r
-\r
-<tr>\r
-<td><code>$0</code></td>\r
-<td>\r
-<code>null</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$1</code></td>\r
-<td>\r
-The value the type of which is explicitly cast.\r
-</td>\r
-</tr>\r
-\r
-<tr>\r
-<td><code>$_</code></td>\r
-<td rowspan=2>\r
-The resulting value of the expression.\r
-The type of <code>$_</code> is the same as the type\r
-<br>after the explicit casting, that is, the type surrounded\r
-by <code>( )</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr>\r
-<td><code>$r</code></td>\r
-<td>the type after the explicit casting, or the type surrounded\r
-by <code>( )</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr><td><code>$type</code></td>\r
-<td>A <code>java.lang.Class</code> object representing\r
-the same type as <code>$r</code>.\r
-</td>\r
-</tr>\r
-\r
-<tr><td><code>$proceed</code>    </td>\r
-<td rowspan=3>The name of a virtual method executing the original\r
-type casting.\r
-<br>It takes one parameter of the type <code>java.lang.Object</code>\r
-and returns it after\r
-<br>the explicit type casting specified by the original expression.\r
-\r
-</td>\r
-</tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-<tr><td> </td></tr>\r
-\r
-</table>\r
-</ul>\r
-\r
-<p>The other identifiers such as <code>$w</code>,\r
-<code>$args</code> and <code>$$</code>\r
-are also available.\r
-\r
-<p><br>\r
-\r
-<h3>5.3 Adding a new method or field</h3>\r
-\r
-<p>Javassist allows the users to create a new method and constructor\r
-from scratch. <code>CtNewMethod</code>\r
-and <code>CtNewConstructor</code> provide several factory methods,\r
-which are static methods for creating <code>CtMethod</code> or\r
-<code>CtConstructor</code> objects.\r
-Especially, <code>make()</code> creates \r
-a <code>CtMethod</code> or <code>CtConstructor</code> object\r
-from the given source text.\r
-\r
-<p>For example, this program:\r
-\r
-<ul><pre>\r
-CtClass point = ClassPool.getDefault().get("Point");\r
-CtMethod m = CtNewMethod.make(\r
- "public int xmove(int dx) { x += dx; }",\r
- point);\r
-point.addMethod(m);\r
-</pre></ul>\r
-\r
-<p>adds a public method <code>xmove()</code> to class <code>Point</code>.\r
-In this example, <code>x</code> is a <code>int</code> field in\r
-the class <code>Point</code>.\r
-\r
-<p>The source text passed to <code>make()</code> can refer to\r
-<code>$proceed</code> if the target object and the target method name\r
-are also given to <code>make()</code>. For example,\r
-\r
-<ul><pre>\r
-CtClass point = ClassPool.getDefault().get("Point");\r
-CtMethod m = CtNewMethod.make(\r
- "public int ymove(int dy) { $proceed(0, dy); }",\r
- point, "this", "move");\r
-</pre></ul>\r
-\r
-<p>this program creates a method <code>ymove()</code> defined below:\r
-\r
-<ul><pre>\r
-public int ymove(int dy) { this.move(0, dy); }\r
-</pre></ul>\r
-\r
-<p>Note that <code>$proceed</code> has been replaced with\r
-<code>this.move</code>.\r
-\r
-<p>Javassist also allows the users to create a new field.\r
-\r
-<ul><pre>\r
-CtClass point = ClassPool.getDefault().get("Point");\r
-CtField f = new CtField(CtClass.intType, "z", point);\r
-point.addField(f);\r
-</pre></ul>\r
-\r
-<p>This program adds a field named <code>z</code> to class\r
-<code>Point</code>.\r
-\r
-<p>If the initial value of the added field must be specified,\r
-the program shown above must be modified into:\r
-\r
-<ul><pre>\r
-CtClass point = ClassPool.getDefault().get("Point");\r
-CtField f = new CtField(CtClass.intType, "z", point);\r
-point.addField(f, "0"); <em>// initial value is 0.</em>\r
-</pre></ul>\r
-\r
-<p>Now, the method <code>addField()</code> receives the second parameter,\r
-which is the source text representing an expression computing the initial\r
-value. This source text can be any Java expression if the result type\r
-of the expression matches the type of the field. Note that an expression\r
-does not end with a semi colon (<code>;</code>).\r
-\r
-<p><br>\r
-\r
-<h3>5.4 Limitations</h3>\r
-\r
-<p>In the current implementation, the Java compiler included in Javassist\r
-has several limitations with respect to the language that the compiler can\r
-accept. Those limitations are:\r
-\r
-<p><li>The <code>.class</code> notation is not supported. Use the\r
-method <code>Class.forName()</code>.\r
-In regular\r
-Java, an expression <code>Point.class</code> means a <code>Class</code>\r
-object representing the <code>Point</code> class. This notation is\r
-not available.\r
-\r
-<p><li>Array initializers, a comma-separated list of expressions\r
-enclosed by braces <code>{</code> and <code>}</code>, are not\r
-supported.\r
-\r
-<p><li>Inner classes or anonymous classes are not supported.\r
-\r
-<p><li><code>switch</code> statements are not supported yet.\r
-\r
-<p><li>Labeled <code>continue</code> and <code>break</code> statements\r
-are not supported.\r
-\r
-<p><li>The <code>finally</code> clause following\r
-<code>try</code> and <code>catch</code> clauses is not supported.\r
-\r
-<p><li>The compiler does not correctly implement the Java method dispatch\r
-algorithm. The compiler may confuse if methods defined in a class\r
-have the same name but take different parameter lists.\r
-\r
-<p><li>The users are recommended to use <code>#</code> as the separator\r
-between a class name and a static method or field name.\r
-For example, in regular Java,\r
-\r
-<ul><pre>javassist.CtClass.intType.getName()</pre></ul>\r
-\r
-<p>calls a method <code>getName()</code> on\r
-the object indicated by the static field <code>intType</code>\r
-in <code>javassist.CtClass</code>. In Javassist, the users can\r
-write the expression shown above but they are recommended to\r
-write:\r
-\r
-<ul><pre>javassist.CtClass#intType.getName()</pre></ul>\r
-\r
-<p>so that the compiler can quickly parse the expression.\r
-</ul>\r
-\r
-<p><br>\r
-\r
-<a href="tutorial.html">Previous page</a>\r
-\r
-<hr>\r
-Java(TM) is a trademark of Sun Microsystems, Inc.<br>\r
-Copyright (C) 2000-2002 by Shigeru Chiba, All rights reserved.\r
-</body>\r
-</html>\r
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Javassist Tutorial</title>
+ <link rel="stylesheet" type="text/css" href="brown.css">
+</head>
+
+<body>
+
+<div align="right">Getting Started with Javassist</div>
+
+<div align="left"><a href="tutorial.html">Previous page</a></div>
+
+<a name="intro">
+<h2>5. Introspection and customization</h2>
+
+<p><code>CtClass</code> provides methods for introspection. The
+introspective ability of Javassist is compatible with that of
+the Java reflection API. <code>CtClass</code> provides
+<code>getName()</code>, <code>getSuperclass()</code>,
+<code>getMethods()</code>, and so on.
+<code>CtClass</code> also provides methods for modifying a class
+definition. It allows to add a new field, constructor, and method.
+Instrumenting a method body is also possible.
+
+<p><hr width="40%">
+
+<ul>
+Javassist does not allow to remove a method or field, but it allows
+to change the name. So if a method is not necessary any more, it should be
+renamed and changed to be a private method by calling
+<code>setName()</code>
+and <code>setModifiers()</code> declared in <code>CtMethod</code>.
+
+<p>Javassist does not allow to add an extra parameter to an existing
+method, either. Instead of doing that, a new method receiving the
+extra parameter as well as the other parameters should be added to the
+same class. For example, if you want to add an extra <code>int</code>
+parameter <code>newZ</code> to a method:
+
+<ul><pre>void move(int newX, int newY) { x = newX; y = newY; }</pre></ul>
+
+<p>in a <code>Point</code> class, then you should add the following
+method to the <code>Point</code> class:
+
+<ul><pre>void move(int newX, int newY, int newZ) {
+ // do what you want with newZ.
+ move(newX, newY);
+}</pre></ul>
+
+</ul>
+
+<p><hr width="40%">
+
+<p>Javassist also provides low-level API for directly editing a raw
+class file. For example, <code>getClassFile()</code> in
+<code>CtClass</code> returns a <code>ClassFile</code> object
+representing a raw class file. <code>getMethodInfo()</code> in
+<code>CtMethod</code> returns a <code>MethodInfo</code> object
+representing a <code>method_info</code> structure included in a class
+file. The low-level API uses the vocabulary from the Java Virtual
+machine specification. The users must have the knowledge about class
+files and bytecode. For more details, the users should see the
+<code>javassist.bytecode</code> package.
+
+<p><br>
+
+<h3>5.1 Inserting source text at the beginning/end of a method body</h3>
+
+<p><code>CtMethod</code> and <code>CtConstructor</code> provide
+methods <code>insertBefore()</code>, <code>insertAfter()</code>, and
+<code>addCatch()</code>. They are used for inserting a code fragment
+into the body of an existing method. The users can specify those code
+fragments with <em>source text</em> written in Java.
+Javassist includes a simple Java compiler for processing source
+text. It receives source text
+written in Java and compiles it into Java bytecode, which will be inserted
+into a method body.
+
+<p>The methods <code>insertBefore()</code>, <code>insertAfter()</code>, and
+<code>addCatch()</code> receives a <code>String</code> object representing
+a statement or a block. A statement is a single control structure like
+<code>if</code> and <code>while</code> or an expression ending with
+a semi colon (<code>;</code>). A block is a set of
+statements surrounded with braces <code>{}</code>.
+Hence each of the following lines is an example of valid statement or block:
+
+<ul><pre>System.out.println("Hello");
+{ System.out.println("Hello"); }
+if (i < 0) { i = -i; }
+</pre></ul>
+
+<p>The statement and the block can refer to fields and methods.
+However, they <em>cannot refer to local variables</em> declared in the
+method that they are inserted into.
+They can refer to the parameters
+to the method although they must use different names
+<code>$0</code>, <code>$1</code>, <code>$2</code>, ... described
+below. Declaring a local variable in the block is allowed.
+
+<!--
+<p><center><table border=8 cellspacing=0 bordercolor="#cfcfcf">
+<tr><td bgcolor="#cfcfcf">
+<b>Tip:</b>
+<br>    Local variables are not accessible.  
+</td></tr>
+</table></center>
+-->
+
+<p>The <code>String</code> object passed to the methods
+<code>insertBefore()</code>, <code>insertAfter()</code>, and
+<code>addCatch()</code> are compiled by
+the compiler included in Javassist.
+Since the compiler supports language extensions,
+several identifiers starting with <code>$</code>
+have special meaning:
+
+<ul><table border=0>
+<tr>
+<td><code>$0</code>, <code>$1</code>, <code>$2</code>, ...    </td>
+<td>Actual parameters</td>
+</tr>
+
+<tr>
+<td><code>$args</code></td>
+<td>An array of parameters.
+The type of <code>$args</code> is <code>Object[]</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$$</code></td>
+<td rowspan=2>All actual parameters.<br>
+For example, <code>m($$)</code> is equivalent to
+<code>m($1,$2,</code>...<code>)</code></td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$cflow(</code>...<code>)</code></td>
+<td><code>cflow</code> variable</td>
+</tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>The result type. It is used in a cast expression.</td>
+</tr>
+
+<tr>
+<td><code>$w</code></td>
+<td>The wrapper type. It is used in a cast expression.</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td>The resulting value</td>
+</tr>
+
+<tr>
+<td><code>$sig</code></td>
+<td>An array of <code>java.lang.Class</code> objects representing
+the formal parameter types.
+</td>
+</tr>
+
+<tr>
+<td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the formal result type.</td>
+</tr>
+
+<tr>
+<td><code>$class</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the class currently edited.</td>
+</tr>
+
+</table>
+</ul>
+
+<h4>$0, $1, $2, ...</h4>
+
+<p>The parameters passed to the methods <code>insertBefore()</code>,
+<code>insertAfter()</code>, and <code>addCatch()</code>
+are accessible with
+<code>$0</code>, <code>$1</code>, <code>$2</code>, ... instead of
+the original parameter names.
+<code>$1</code> represents the
+first parameter, <code>$2</code> represents the second parameter, and
+so on. The types of those variables are identical to the parameter
+types.
+<code>$0</code> is
+equivalent to <code>this</code>. If the method is static,
+<code>$0</code> is not available.
+
+<p>These variables are used as following. Suppose that a class
+<code>Point</code>:
+
+<pre><ul>class Point {
+ int x, y;
+ void move(int dx, int dy) { x += dx; y += dy; }
+}
+</ul></pre>
+
+<p>To print the values of <code>dx</code> and <code>dy</code>
+whenever the method <code>move()</code> is called, execute this
+program:
+
+<ul><pre>ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("Point");
+CtMethod m = cc.getDeclaredMethod("move");
+m.insertBefore("{ System.out.println($1); System.out.println($2); }");
+cc.writeFile();
+</pre></ul>
+
+<p>Note that the source text passed to <code>insertBefore()</code> is
+surrounded with braces <code>{}</code>.
+<code>insertBefore()</code> accepts only a single statement or a block
+surrounded with braces.
+
+<p>The definition of the class <code>Point</code> after the
+modification is like this:
+
+<pre><ul>class Point {
+ int x, y;
+ void move(int dx, int dy) {
+ { System.out.println(dx); System.out.println(dy); }
+ x += dx; y += dy;
+ }
+}
+</ul></pre>
+
+<p><code>$1</code> and <code>$2</code> are replaced with
+<code>dx</code> and <code>dy</code>, respectively.
+
+<p><code>$1</code>, <code>$2</code>, <code>$3</code> ... are
+updatable. If a new value is assigend to one of those variables,
+then the value of the parameter represented by that variable is
+also updated.
+
+
+<h4>$args</h4>
+
+<p>The variable <code>$args</code> represents an array of all the
+parameters. The type of that variable is an array of class
+<code>Object</code>. If a parameter type is a primitive type such as
+<code>int</code>, then the parameter value is converted into a wrapper
+object such as <code>java.lang.Integer</code> to store in
+<code>$args</code>. Thus, <code>$args[0]</code> is equivalent to
+<code>$1</code> unless the type of the first parameter is a primitive
+type. Note that <code>$args[0]</code> is not equivalent to
+<code>$0</code>; <code>$0</code> represents <code>this</code>.
+
+<p>If an array of <code>Object</code> is assigned to
+<code>$args</code>, then each element of that array is
+assigned to each parameter. If a parameter type is a primitive
+type, the type of the corresponding element must be a wrapper type.
+The value is converted from the wrapper type to the primitive type
+before it is assigned to the parameter.
+
+<h4>$$</h4>
+
+<p>The variable <code>$$</code> is abbreviation of a list of
+all the parameters separated by commas.
+For example, if the number of the parameters
+to method <code>move()</code> is three, then
+
+<ul><pre>move($$)</pre></ul>
+
+<p>is equivalent to this:
+
+<ul><pre>move($1, $2, $3)</pre></ul>
+
+<p>If <code>move()</code> does not take any parameters,
+then <code>move($$)</code> is
+equivalent to <code>move()</code>.
+
+<p><code>$$</code> can be used with another method.
+If you write an expression:
+
+<ul><pre>exMove($$, context)</pre></ul>
+
+<p>then this expression is equivalent to:
+
+<ul><pre>exMove($1, $2, $3, context)</pre></ul>
+
+<p>Note that <code>$$</code> enables generic notation of method call
+with respect to the number of parameters.
+It is typically used with <code>$proceed</code> shown later.
+
+<h4>$cflow</h4>
+
+<p><code>$cflow</code> means "control flow".
+This read-only variable returns the depth of the recursive calls
+to a specific method.
+
+<p>Suppose that the method shown below is represented by a
+<code>CtMethod</code> object <code>cm</code>:
+
+<ul><pre>int fact(int n) {
+ if (n <= 1)
+ return n;
+ else
+ return n * fact(n - 1);
+}</pre></ul>
+
+<p>To use <code>$cflow</code>, first declare that <code>$cflow</code>
+is used for monitoring calls to the method <code>fact()</code>:
+
+<ul><pre>CtMethod cm = ...;
+cm.useCflow("fact");</pre></ul>
+
+<p>The parameter to <code>useCflow()</code> is the identifier of the
+declared <code>$cflow</code> variable. Any valid Java name can be
+used as the identifier. Since the identifier can also include
+<code>.</code> (dot), for example, <code>"my.Test.fact"</code>
+is a valid identifier.
+
+<p>Then, <code>$cflow(fact)</code> represents the depth of the
+recursive calls to the method specified by <code>cm</code>. The value
+of <code>$cflow(fact)</code> is 0 (zero) when the method is
+first called whereas it is 1 when the method is recursively called
+within the method. For example,
+
+<ul><pre>
+cm.insertBefore("if ($cflow(fact) == 0)"
+ + " System.out.println(\"fact \" + $1);");
+</pre></ul>
+
+<p>translates the method <code>fact()</code> so that it shows the
+parameter. Since the value of <code>$cflow(fact)</code> is checked,
+the method <code>fact()</code> does not show the parameter if it is
+recursively called within <code>fact()</code>.
+
+<p>The value of <code>$cflow</code> is the number of stack frames
+associated with the specified method <code>cm</code>
+under the current topmost
+stack frame for the current thread. <code>$cflow</code> is also
+accessible within a method different from the specified method
+<code>cm</code>.
+
+<h4>$r</h4>
+
+<p><code>$r</code> represents the result type (return type) of the method.
+It must be used as the cast type in a cast expression.
+For example, this is a typical use:
+
+<ul><pre>Object result = ... ;
+$_ = ($r)result;</pre></ul>
+
+<p>If the result type is a primitive type, then <code>($r)</code>
+converts from the wrapper type to the primitive type.
+For example, if the result type is <code>int</code>, then
+<code>($r)</code> converts from <code>java.lang.Integer</code> to
+<code>int</code>.
+
+<p>If the result type is <code>void</code>, then
+<code>($r)</code> does not convert a type; it does nothing.
+Moreover, the soruce text can include a <code>return</code>
+statement with a resulting value:
+
+<ul><pre>return ($r)result;</pre></ul>
+
+<p>Here, <code>result</code> is some local variable.
+Since <code>($r)</code> is specified, the resulting value is
+discarded.
+This <code>return</code> statement is regarded as the equivalent
+of the <code>return</code> statement without a resulting value:
+
+<ul><pre>return;</pre></ul>
+
+<h4>$w</h4>
+
+<p><code>$w</code> represents a wrapper type.
+It must be used as the cast type in a cast expression.
+<code>($w)</code> converts from a primitive type to the corresponding
+wrapper type.
+
+The following code is an example:
+
+<ul><pre>Integer i = ($w)5;</pre></ul>
+
+<p>The selected wrapper type depends on the type of the expression
+following <code>($w)</code>. If the type of the expression is
+<code>double</code>, then the wrapper type is <code>java.lang.Double</code>.
+
+<p>If the type of the expression following <code>($w)</code> is not
+a primitive type, then <code>($w)</code> does nothing.
+
+<h4>$_</h4>
+
+<p><code>insertAfter()</code> in <code>CtMethod</code> and
+<code>CtConstructor</code> inserts the
+compiled code at the end of the method. In the statement given to
+<code>insertAfter()</code>, not only the variables shown above such as
+<code>$0</code>, <code>$1</code>, ... but also <code>$_</code> is
+available.
+
+<p>The variable <code>$_</code> represents the resulting value of the
+method. The type of that variable is the type of the result type (the
+return type) of the method. If the result type is <code>void</code>,
+then the type of <code>$_</code> is <code>Object</code> and the value
+of <code>$_</code> is <code>null</code>.
+
+<p>Although the compiled code inserted by <code>insertAfter()</code>
+is executed just before the control normally returns from the method,
+it can be also executed when an exception is thrown from the method.
+To execute it when an exception is thrown, the second parameter
+<code>asFinally</code> to <code>insertAfter()</code> must be
+<code>true</code>.
+
+<p>If an exception is thrown, the compiled code inserted by
+<code>insertAfter()</code> is executed as a <code>finally</code>
+clause. The value of <code>$_</code> is <code>0</code> or
+<code>null</code> in the compiled code. After the execution of the
+compiled code terminates, the exception originally thrown is re-thrown
+to the caller. Note that the value of <code>$_</code> is never thrown
+to the caller; it is rather discarded.
+
+<h4>$sig</h4>
+
+<p>The value of <code>$sig</code> is an array of
+<code>java.lang.Class</code> objects that represent the formal
+parameter types in declaration order.
+
+<h4>$type</h4>
+
+<p>The value of <code>$type</code> is an <code>java.lang.Class</code>
+object representing the formal type of the result value. This
+variable is available only in <code>insertAfter()</code> in
+<code>CtMethod</code> and <code>CtConstructor</code>.
+
+<h4>$class</h4>
+
+<p>The value of <code>$class</code> is an <code>java.lang.Class</code>
+object representing the class in which the edited method is declared.
+
+<h4>addCatch()</h4>
+
+<p><code>addCatch()</code> inserts a code fragment into a method body
+so that the code fragment is executed when the method body throws
+an exception and the control returns to the caller. In the source
+text representing the inserted code fragment, the exception value
+is referred to with the special variable <code>$e</code>.
+
+<p>For example, this program:
+
+<ul><pre>
+CtMethod m = ...;
+CtClass etype = ClassPool.getDefault().get("java.io.IOException");
+m.addCatch("{ System.out.println($e); throw $e; }", etype);
+</pre></ul>
+
+<p>translates the method body represented by <code>m</code> into
+something like this:
+
+<ul><pre>
+try {
+ <font face="serif"><em>the original method body</em></font>
+}
+catch (java.io.IOException e) {
+ System.out.println(e);
+ throw e;
+}
+</pre></ul>
+
+<p>Note that the inserted code fragment must end with a
+<code>throw</code> or <code>return</code> statement.
+
+<p><br>
+
+<h3>5.2 Modifying a method body</h3>
+
+<p><code>javassist.expr.ExprEditor</code> is a class
+for replacing an expression in a method body.
+The users can define a subclass of <code>ExprEditor</code>
+to specify how an expression is modified.
+
+<p>To run an <code>ExprEditor</code> object, the users must
+call <code>instrument()</code> in <code>CtMethod</code> or
+<code>CtClass</code>.
+
+For example,
+
+<ul><pre>
+CtMethod cm = ... ;
+cm.instrument(
+ new ExprEditor() {
+ public void edit(MethodCall m)
+ throws CannotCompileException
+ {
+ if (m.getClassName().equals("Point")
+ && m.getMethodName().equals("move"))
+ m.replace("{ $1 = 0; $_ = $proceed($$); }");
+ }
+ });
+</pre></ul>
+
+<p>searches the method body represented by <code>cm</code> and
+replaces all calls to <code>move()</code> in class <code>Point</code>
+with a block:
+
+<ul><pre>{ $1 = 0; $_ = $proceed($$); }
+</pre></ul>
+
+<p>so that the first parameter to <code>move()</code> is always 0.
+Note that the substituted code is not an expression but
+a statement or a block.
+
+<p>The method <code>instrument()</code> searches a method body.
+If it finds an expression such as a method call, field access, and object
+creation, then it calls <code>edit()</code> on the given
+<code>ExprEditor</code> object. The parameter to <code>edit()</code>
+is an object representing the found expression. The <code>edit()</code>
+method can inspect and replace the expression through that object.
+
+<p>Calling <code>replace()</code> on the parameter to <code>edit()</code>
+substitutes the given statement or block for the expression. If the given
+block is an empty block, that is, if <code>replace("{}")</code>
+is executed, then the expression is removed from the method body.
+
+If you want to insert a statement (or a block) before/after the
+expression, a block like the following should be passed to
+<code>replace()</code>:
+
+<ul><pre>
+{ <em>before-statements;</em>
+ $_ = $proceed($$);
+ <em>after-statements;</em> }
+</pre></ul>
+
+<p>whichever the expression is either a method call, field access,
+object creation, or others. The second statement could be:
+
+<ul><pre>$_ = $proceed();</pre></ul>
+
+<p>if the expression is read access, or
+
+<ul><pre>$proceed($$);</pre></ul>
+
+<p>if the expression is write access.
+
+<h4>javassist.expr.MethodCall</h4>
+
+<p>A <code>MethodCall</code> object represents a method call.
+The method <code>replace()</code> in
+<code>MethodCall</code> substitutes a statement or
+a block for the method call.
+It receives source text representing the substitued statement or
+block, in which the identifiers starting with <code>$</code>
+have special meaning as in the source text passed to
+<code>insertBefore()</code>.
+
+<ul><table border=0>
+<tr>
+<td><code>$0</code></td>
+<td rowspan=3>
+The target object of the method call.<br>
+This is not equivalent to <code>this</code>, which represents
+the caller-side <code>this</code> object.<br>
+<code>$0</code> is <code>null</code> if the method is static.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$1</code>, <code>$2</code>, ...    </td>
+<td>
+The parameters of the method call.
+</td>
+</tr>
+
+<tr><td>
+<code>$_</code></td>
+<td>The resulting value of the method call.</td>
+</tr>
+
+<tr><td><code>$r</code></td>
+<td>The result type of the method call.</td>
+</tr>
+
+<tr><td><code>$class</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the class declaring the method.
+</td>
+</tr>
+
+<tr><td><code>$sig</code>    </td>
+<td>An array of <code>java.lang.Class</code> objects representing
+the formal parameter types.</td>
+</tr>
+
+<tr><td><code>$type</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the formal result type.</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td>The name of the method originally called
+in the expression.</td>
+</tr>
+
+</table>
+</ul>
+
+<p>Here the method call means the one represented by the
+<code>MethodCall</code> object.
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<p>Unless the result type of the method call is <code>void</code>,
+a value must be assigned to
+<code>$_</code> in the source text and the type of <code>$_</code>
+is the result type.
+If the result type is <code>void</code>, the type of <code>$_</code>
+is <code>Object</code> and the value assigned to <code>$_</code>
+is ignored.
+
+<p><code>$proceed</code> is not a <code>String</code> value but special
+syntax. It must be followed by an argument list surrounded by parentheses
+<code>( )</code>.
+
+<h4>javassist.expr.FieldAccess</h4>
+
+<p>A <code>FieldAccess</code> object represents field access.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receives this object if field access is found.
+The method <code>replace()</code> in
+<code>FieldAccess</code> receives
+source text representing the substitued statement or
+block for the field access.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+<tr>
+<td><code>$0</code></td>
+<td rowspan=3>
+The object containing the field accessed by the expression.
+This is not equivalent to <code>this</code>.<br>
+<code>this</code> represents the object that the method including the
+expression is invoked on.<br>
+<code>$0</code> is <code>null</code> if the field is static.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$1</code></td>
+<td rowspan=2>
+The value that would be stored in the field
+if the expression is write access.
+<br>Otherwise, <code>$1</code> is not available.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$_</code></td>
+<td rowspan=2>
+The resulting value of the field access
+if the expression is read access.
+<br>Otherwise, the value stored in <code>$_</code> is discarded.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+<tr>
+<td><code>$r</code></td>
+<td rowspan=2>
+The type of the field if the expression is read access.
+<br>Otherwise, <code>$r</code> is <code>void</code>.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td><code>$class</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the class declaring the field.
+</td></tr>
+
+<tr><td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the field type.</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td>The name of a virtual method executing the original
+field access.
+.</td>
+</tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<p>If the expression is read access, a value must be assigned to
+<code>$_</code> in the source text. The type of <code>$_</code>
+is the type of the field.
+
+<h4>javassist.expr.NewExpr</h4>
+
+<p>A <code>NewExpr</code> object represents object creation
+with the <code>new</code> operator.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receives this object if object creation is found.
+The method <code>replace()</code> in
+<code>NewExpr</code> receives
+source text representing the substitued statement or
+block for the object creation.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$0</code></td>
+<td>
+<code>null</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$1</code>, <code>$2</code>, ...    </td>
+<td>
+The parameters to the constructor.
+</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td rowspan=2>
+The resulting value of the object creation.
+<br>A newly created object must be stored in this variable.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>
+The type of the created object.
+</td>
+</tr>
+
+<tr><td><code>$class</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the class of the created object.
+</td></tr>
+
+<tr><td><code>$sig</code>    </td>
+<td>An array of <code>java.lang.Class</code> objects representing
+the formal parameter types.</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td>The name of a virtual method executing the original
+object creation.
+.</td>
+</tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<h4>javassist.expr.Instanceof</h4>
+
+<p>A <code>Instanceof</code> object represents an <code>instanceof</code>
+expression.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receives this object if an instanceof expression is found.
+The method <code>replace()</code> in
+<code>Instanceof</code> receives
+source text representing the substitued statement or
+block for the expression.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$0</code></td>
+<td>
+<code>null</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$1</code></td>
+<td>
+The value on the left hand side of the original
+<code>instanceof</code> operator.
+</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td>
+The resulting value of the expression.
+The type of <code>$_</code> is <code>boolean</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>
+The type on the right hand side of the <code>instanceof</code> operator.
+</td>
+</tr>
+
+<tr><td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the type on the right hand side of the <code>instanceof</code> operator.
+</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td rowspan=4>The name of a virtual method executing the original
+<code>instanceof</code> expression.
+<br>It takes one parameter (the type is <code>java.lang.Object</code>)
+and returns true
+<br>if the parameter value is an instance of the type on the right
+hand side of
+<br>the original <code>instanceof</code> operator.
+Otherwise, it returns false.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+<tr><td> </td></tr>
+<tr><td> </td></tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<h4>javassist.expr.Cast</h4>
+
+<p>A <code>Cast</code> object represents an expression for
+explicit type casting.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receives this object if explicit type casting is found.
+The method <code>replace()</code> in
+<code>Cast</code> receives
+source text representing the substitued statement or
+block for the expression.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$0</code></td>
+<td>
+<code>null</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$1</code></td>
+<td>
+The value the type of which is explicitly cast.
+</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td rowspan=2>
+The resulting value of the expression.
+The type of <code>$_</code> is the same as the type
+<br>after the explicit casting, that is, the type surrounded
+by <code>( )</code>.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>the type after the explicit casting, or the type surrounded
+by <code>( )</code>.
+</td>
+</tr>
+
+<tr><td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the same type as <code>$r</code>.
+</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td rowspan=3>The name of a virtual method executing the original
+type casting.
+<br>It takes one parameter of the type <code>java.lang.Object</code>
+and returns it after
+<br>the explicit type casting specified by the original expression.
+
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td> </td></tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<h4>javassist.expr.Handler</h4>
+
+<p>A <code>Handler</code> object represents a <code>catch</code>
+clause of <code>try-catch</code> statement.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receives this object if a <code>catch</code> is found.
+The method <code>insertBefore()</code> in
+<code>Handler</code> compiles the received
+source text and inserts it at the beginning of the <code>catch</code> clause.
+
+In the source text, the identifiers starting with <code>$</code>
+have special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$1</code></td>
+<td>
+The exception object caught by the <code>catch</code> clause.
+</td>
+</tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>the type of the exception caught by the <code>catch</code> clause.
+It is used in a cast expression.
+</td>
+</tr>
+
+<tr>
+<td><code>$w</code></td>
+<td>The wrapper type. It is used in a cast expression.
+</td>
+</tr>
+
+<tr><td><code>$type</code>    </td>
+<td rowspan=2>
+A <code>java.lang.Class</code> object representing
+<br>the type of the exception caught by the <code>catch</code> clause.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+</table>
+</ul>
+
+<p>If a new exception object is assigned to <code>$1</code>,
+it is passed to the original <code>catch</code> clause as the caught
+exception.
+
+<p><br>
+
+<h3>5.3 Adding a new method or field</h3>
+
+<p>Javassist allows the users to create a new method and constructor
+from scratch. <code>CtNewMethod</code>
+and <code>CtNewConstructor</code> provide several factory methods,
+which are static methods for creating <code>CtMethod</code> or
+<code>CtConstructor</code> objects.
+Especially, <code>make()</code> creates
+a <code>CtMethod</code> or <code>CtConstructor</code> object
+from the given source text.
+
+<p>For example, this program:
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtMethod m = CtNewMethod.make(
+ "public int xmove(int dx) { x += dx; }",
+ point);
+point.addMethod(m);
+</pre></ul>
+
+<p>adds a public method <code>xmove()</code> to class <code>Point</code>.
+In this example, <code>x</code> is a <code>int</code> field in
+the class <code>Point</code>.
+
+<p>The source text passed to <code>make()</code> can refer to
+<code>$proceed</code> if the target object and the target method name
+are also given to <code>make()</code>. For example,
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtMethod m = CtNewMethod.make(
+ "public int ymove(int dy) { $proceed(0, dy); }",
+ point, "this", "move");
+</pre></ul>
+
+<p>this program creates a method <code>ymove()</code> defined below:
+
+<ul><pre>
+public int ymove(int dy) { this.move(0, dy); }
+</pre></ul>
+
+<p>Note that <code>$proceed</code> has been replaced with
+<code>this.move</code>.
+
+<p>Javassist also allows the users to create a new field.
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtField f = new CtField(CtClass.intType, "z", point);
+point.addField(f);
+</pre></ul>
+
+<p>This program adds a field named <code>z</code> to class
+<code>Point</code>.
+
+<p>If the initial value of the added field must be specified,
+the program shown above must be modified into:
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtField f = new CtField(CtClass.intType, "z", point);
+point.addField(f, "0"); <em>// initial value is 0.</em>
+</pre></ul>
+
+<p>Now, the method <code>addField()</code> receives the second parameter,
+which is the source text representing an expression computing the initial
+value. This source text can be any Java expression if the result type
+of the expression matches the type of the field. Note that an expression
+does not end with a semi colon (<code>;</code>).
+
+<p><br>
+
+<h3>5.4 Limitations</h3>
+
+<p>In the current implementation, the Java compiler included in Javassist
+has several limitations with respect to the language that the compiler can
+accept. Those limitations are:
+
+<p><li>The <code>.class</code> notation is not supported. Use the
+method <code>Class.forName()</code>.
+In regular
+Java, an expression <code>Point.class</code> means a <code>Class</code>
+object representing the <code>Point</code> class. This notation is
+not available.
+
+<p><li>Array initializers, a comma-separated list of expressions
+enclosed by braces <code>{</code> and <code>}</code>, are not
+supported.
+
+<p><li>Inner classes or anonymous classes are not supported.
+
+<p><li><code>switch</code> statements are not supported yet.
+
+<p><li>Labeled <code>continue</code> and <code>break</code> statements
+are not supported.
+
+<p><li>The <code>finally</code> clause following
+<code>try</code> and <code>catch</code> clauses is not supported.
+
+<p><li>The compiler does not correctly implement the Java method dispatch
+algorithm. The compiler may confuse if methods defined in a class
+have the same name but take different parameter lists.
+
+<p><li>The users are recommended to use <code>#</code> as the separator
+between a class name and a static method or field name.
+For example, in regular Java,
+
+<ul><pre>javassist.CtClass.intType.getName()</pre></ul>
+
+<p>calls a method <code>getName()</code> on
+the object indicated by the static field <code>intType</code>
+in <code>javassist.CtClass</code>. In Javassist, the users can
+write the expression shown above but they are recommended to
+write:
+
+<ul><pre>javassist.CtClass#intType.getName()</pre></ul>
+
+<p>so that the compiler can quickly parse the expression.
+</ul>
+
+<p><br>
+
+<a href="tutorial.html">Previous page</a>
+
+<hr>
+Java(TM) is a trademark of Sun Microsystems, Inc.<br>
+Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved.
+</body>
+</html>