From: chiba Date: Wed, 23 Apr 2003 17:08:37 +0000 (+0000) Subject: Changed the copyright notices and removed tab characters. X-Git-Tag: rel_3_17_1_ga~595 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cdeddfd6fc34a06734f9fa525cf5c7437a6c8fb6;p=javassist.git Changed the copyright notices and removed tab characters. git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@9 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- diff --git a/License.html b/License.html index dda30cc9..e6476247 100644 --- a/License.html +++ b/License.html @@ -1,18 +1,589 @@ - - -Javassist License - - - -

-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. -

- - + + + +GNU Lesser General Public License - GNU Project - Free Software Foundation (FSF) + + +

GNU Lesser General Public License

+ +

+This GNU Lesser General Public License counts as the successor +of the GNU Library General Public License. +

+ +

Table of Contents

+ + +

+ +


+ +

+ + + +

GNU LESSER GENERAL PUBLIC LICENSE

+

+Version 2.1, February 1999 + +

+

+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.]
+
+ + +

Preamble

+ +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ 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. +

+ +

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+ + +

+0. +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". +

+ 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. +

+ 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".) +

+ "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. +

+ 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. +

+1. +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. +

+ 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. +

+2. +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: +

+

+

+3. +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. +

+ 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. +

+ This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. +

+4. +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. +

+ 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. +

+5. +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. +

+ 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. +

+ 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. +

+ 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.) +

+ 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. +

+6. +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. +

+ 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: +

+

+

+ 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. +

+ 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. +

+7. 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: +

+

+

+8. 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. +

+9. +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. +

+10. +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. +

+11. +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. +

+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. +

+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. +

+This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. +

+12. +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. +

+13. +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. +

+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. +

+14. +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. +

+NO WARRANTY +

+15. +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. +

+16. +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. +

+

END OF TERMS AND CONDITIONS

+ +

How to Apply These Terms to Your New Libraries

+

+ 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). +

+ 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. +

+ +

+one line to give the library's name and an idea of what it does.
+Copyright (C) year  name of author
+
+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
+
+ +

+Also add information on how to contact you by electronic and paper mail. + +

+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: + +

+

+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+ +

+That's all there is to it! + +


+ +Copyright notice above.
+Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111, USA +

+Updated: + +$Date: 2003-04-23 17:07:51 $ $Author: chiba $ + +


+ + diff --git a/Readme.html b/Readme.html index 7b154ce1..77a01657 100644 --- a/Readme.html +++ b/Readme.html @@ -7,7 +7,7 @@

Javassist version 2

-

in February, 2003. +

in April, 2003.
Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved.


@@ -15,13 +15,14 @@

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.


@@ -45,8 +46,8 @@ the users to directly edit a class file. -

  • ./javassist-src.zip -The source archive +
  • ./src/main +The source files @@ -233,6 +234,17 @@ see javassist.Dump.

    Changes

    +

    - version 2.5 in April, 2003. +
    From this version, Javassist is part of the JBoss project. +

    +

    - version 2.4 in February, 2003.

    * - * @param origMethod the method originally invoked. - * @param beforeMethod the method invoked before - * origMethod. + * @param origMethod the method originally invoked. + * @param beforeMethod the method invoked before + * origMethod. */ 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); + } } /** @@ -317,60 +306,60 @@ public class CodeConverter { * Point p2 = p.move(tmp1, tmp2); * Verbose.print(p, tmp1, tmp2); * - * @param origMethod the method originally invoked. - * @param afterMethod the method invoked after - * origMethod. + * @param origMethod the method originally invoked. + * @param afterMethod the method invoked after + * origMethod. */ 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); } } diff --git a/src/main/javassist/CtArray.java b/src/main/javassist/CtArray.java index 904f15c9..bfd63919 100644 --- a/src/main/javassist/CtArray.java +++ b/src/main/javassist/CtArray.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -33,61 +22,61 @@ final class CtArray extends CtClass { // 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(); + } } } diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java index 220612b7..af4c80eb 100644 --- a/src/main/javassist/CtBehavior.java +++ b/src/main/javassist/CtBehavior.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -38,8 +27,8 @@ public abstract class CtBehavior extends CtMember { protected MethodInfo methodInfo; protected CtBehavior(CtClass clazz, MethodInfo minfo) { - super(clazz); - methodInfo = minfo; + super(clazz); + methodInfo = minfo; } /** @@ -47,8 +36,8 @@ public abstract class CtBehavior extends CtMember { * class file. */ public MethodInfo getMethodInfo() { - declaringClass.checkModify(); - return methodInfo; + declaringClass.checkModify(); + return methodInfo; } /** @@ -59,12 +48,12 @@ public abstract class CtBehavior extends CtMember { /** * Obtains the modifiers of the member. * - * @return modifiers encoded with - * javassist.Modifier. + * @return modifiers encoded with + * javassist.Modifier. * @see Modifier */ public int getModifiers() { - return AccessFlag.toModifier(methodInfo.getAccessFlags()); + return AccessFlag.toModifier(methodInfo.getAccessFlags()); } /** @@ -73,8 +62,8 @@ public abstract class CtBehavior extends CtMember { * @see Modifier */ public void setModifiers(int mod) { - declaringClass.checkModify(); - methodInfo.setAccessFlags(AccessFlag.of(mod)); + declaringClass.checkModify(); + methodInfo.setAccessFlags(AccessFlag.of(mod)); } /** @@ -88,16 +77,16 @@ public abstract class CtBehavior extends CtMember { * 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()); } /** @@ -107,93 +96,98 @@ public abstract class CtBehavior extends CtMember { * 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); } /** @@ -201,26 +195,26 @@ public abstract class CtBehavior extends CtMember { * 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)); } /** @@ -234,110 +228,113 @@ public abstract class CtBehavior extends CtMember { * For example, if the given name is "Point.paint", * then the variable is indicated by $cflow(Point.paint). * - * @param name $cflow name. It can include - * alphabets, numbers, _, - * $, and . (dot). + * @param name $cflow name. It can include + * alphabets, numbers, _, + * $, and . (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); + } } /** @@ -345,186 +342,189 @@ public abstract class CtBehavior extends CtMember { * 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); + } } */ @@ -532,51 +532,67 @@ public abstract class CtBehavior extends CtMember { * 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, + * $e. */ 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); + } } } diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index 1d70b8bf..ee523dce 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -1,28 +1,17 @@ /* - * 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; @@ -45,7 +34,7 @@ public abstract class CtClass { /** * 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"; @@ -106,55 +95,55 @@ public abstract class CtClass { 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; } /** @@ -169,8 +158,8 @@ public abstract class CtClass { * is true. */ public ClassFile getClassFile() { - checkModify(); - return getClassFile2(); + checkModify(); + return getClassFile2(); } /** @@ -189,11 +178,13 @@ public abstract class CtClass { */ 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. } /** @@ -205,7 +196,7 @@ public abstract class CtClass { * 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()); } /** @@ -219,7 +210,7 @@ public abstract class CtClass { * Returns true if this object represents an array type. */ public boolean isArray() { - return false; + return false; } /** @@ -227,7 +218,7 @@ public abstract class CtClass { * type of the array. Otherwise, it returns null. */ public CtClass getComponentType() throws NotFoundException { - return null; + return null; } /** @@ -236,7 +227,7 @@ public abstract class CtClass { * this class is the same as clazz. */ public boolean subtypeOf(CtClass clazz) throws NotFoundException { - return this == clazz || getName().equals(clazz.getName()); + return this == clazz || getName().equals(clazz.getName()); } /** @@ -248,46 +239,46 @@ public abstract class CtClass { * 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 null. */ 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 newName for all occurrences of a class * name oldName 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(); } /** @@ -304,11 +295,11 @@ public abstract class CtClass { * 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(); } /** @@ -319,26 +310,26 @@ public abstract class CtClass { *

    This method may return null. */ 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; } /** @@ -346,7 +337,7 @@ public abstract class CtClass { * It returns true if this object represents an interface. */ public boolean isInterface() { - return false; + return false; } /** @@ -356,18 +347,18 @@ public abstract class CtClass { * @see Modifier */ public int getModifiers() { - return 0; + return 0; } /** * Sets the modifiers. * - * @param mod modifiers encoded by - * javassist.Modifier + * @param mod modifiers encoded by + * javassist.Modifier * @see Modifier */ public void setModifiers(int mod) { - checkModify(); + checkModify(); } /** @@ -379,7 +370,7 @@ public abstract class CtClass { * the class represented by this object. */ public boolean subclassOf(CtClass superclass) { - return false; + return false; } /** @@ -388,14 +379,14 @@ public abstract class CtClass { * It returns null if the class is java.lang.Object. */ public CtClass getSuperclass() throws NotFoundException { - return null; + return null; } /** * Changes a super class. */ public void setSuperclass(CtClass clazz) throws CannotCompileException { - checkModify(); + checkModify(); } /** @@ -403,28 +394,28 @@ public abstract class CtClass { * class. */ public CtClass[] getInterfaces() throws NotFoundException { - return new CtClass[0]; + return new CtClass[0]; } /** * Sets interfaces. * - * @param list a list of the CtClass objects - * representing interfaces, or - * null if the class implements - * no interfaces. + * @param list a list of the CtClass objects + * representing interfaces, or + * null 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(); } /** @@ -440,7 +431,7 @@ public abstract class CtClass { * 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); } /** @@ -458,14 +449,14 @@ public abstract class CtClass { *

    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]; } /** @@ -473,7 +464,7 @@ public abstract class CtClass { * representing all the public constructors of the class. */ public CtConstructor[] getConstructors() { - return new CtConstructor[0]; + return new CtConstructor[0]; } /** @@ -483,14 +474,14 @@ public abstract class CtClass { * For details of the method descriptor, see the JVM specification * or javassist.bytecode.Descriptor. * - * @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"); } /** @@ -499,19 +490,19 @@ public abstract class CtClass { * @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); } /** @@ -523,7 +514,7 @@ public abstract class CtClass { * @see javassist.CtConstructor */ public CtConstructor getClassInitializer() { - return null; + return null; } /** @@ -533,7 +524,7 @@ public abstract class CtClass { * superclasses. */ public CtMethod[] getMethods() { - return new CtMethod[0]; + return new CtMethod[0]; } /** @@ -543,14 +534,14 @@ public abstract class CtClass { * 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); } /** @@ -560,7 +551,7 @@ public abstract class CtClass { * @see javassist.CtMethod */ public CtMethod[] getDeclaredMethods() { - return new CtMethod[0]; + return new CtMethod[0]; } /** @@ -569,14 +560,14 @@ public abstract class CtClass { * *

    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); } /** @@ -589,23 +580,23 @@ public abstract class CtClass { * @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(); } /** @@ -618,7 +609,7 @@ public abstract class CtClass { * @see javassist.CtField#CtField(CtField,CtClass) */ public void addField(CtField f) throws CannotCompileException { - addField(f, (CtField.Initializer)null); + addField(f, (CtField.Initializer)null); } /** @@ -641,15 +632,15 @@ public abstract class CtClass { *

    Here, the type of variable cc is CtClass. * The type of f is CtField. * - * @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(); } /** @@ -670,14 +661,14 @@ public abstract class CtClass { *

    This code adds an int 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(); } /** @@ -685,10 +676,10 @@ public abstract class CtClass { * 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; } /** @@ -700,11 +691,11 @@ public abstract class CtClass { * 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(); } /** @@ -713,12 +704,12 @@ public abstract class CtClass { * on every CtMethod and CtConstructor 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(); } /** @@ -727,12 +718,12 @@ public abstract class CtClass { * on every CtMethod and CtConstructor 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(); } /** @@ -750,9 +741,9 @@ public abstract class CtClass { * @see javassist.ClassPool#forName(String) */ public Class toClass() - throws NotFoundException, IOException, CannotCompileException + throws NotFoundException, IOException, CannotCompileException { - return getClassPool2().writeAsClass(getName()); + return getClassPool2().writeAsClass(getName()); } /** @@ -766,9 +757,9 @@ public abstract class CtClass { * @see javassist.ClassPool#write(String) */ public byte[] toBytecode() - throws NotFoundException, IOException, CannotCompileException + throws NotFoundException, IOException, CannotCompileException { - return getClassPool2().write(getName()); + return getClassPool2().write(getName()); } /** @@ -783,18 +774,18 @@ public abstract class CtClass { * @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; } /** @@ -809,11 +800,11 @@ public abstract class CtClass { * *

    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"); } } diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index e08ed7bd..f51642e3 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -31,6 +20,7 @@ import javassist.compiler.CompileError; 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; @@ -54,46 +44,52 @@ class CtClassType extends CtClass { 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; } @@ -102,758 +98,764 @@ class CtClassType extends CtClass { 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(), - "", "()V"); - m.setAccessFlags(AccessFlag.STATIC); - m.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(m); - } - else { - CodeAttribute codeAttr = m.getCodeAttribute(); - if (codeAttr == null) - throw new CannotCompileException("empty "); - - 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(), + "", "()V"); + m.setAccessFlags(AccessFlag.STATIC); + m.setCodeAttribute(code.toCodeAttribute()); + cf.addMethod(m); + } + else { + CodeAttribute codeAttr = m.getCodeAttribute(); + if (codeAttr == null) + throw new CannotCompileException("empty "); + + 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++; } @@ -865,8 +867,8 @@ class FieldInitLink { CtField.Initializer init; FieldInitLink(CtField f, CtField.Initializer i) { - next = null; - field = f; - init = i; + next = null; + field = f; + init = i; } } diff --git a/src/main/javassist/CtConstructor.java b/src/main/javassist/CtConstructor.java index 52024e77..2d4bd418 100644 --- a/src/main/javassist/CtConstructor.java +++ b/src/main/javassist/CtConstructor.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -49,8 +38,8 @@ public final class CtConstructor extends CtBehavior { protected CtConstructor next; protected CtConstructor(MethodInfo minfo, CtClass declaring) { - super(declaring, minfo); - next = null; + super(declaring, minfo); + next = null; } /** @@ -61,19 +50,19 @@ public final class CtConstructor extends CtBehavior { *

    The created constructor does not include a constructor body, * must be specified with setBody(). * - * @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, "", desc); - setModifiers(Modifier.PUBLIC); + this((MethodInfo)null, declaring); + ConstPool cp = declaring.getClassFile2().getConstPool(); + String desc = Descriptor.ofConstructor(parameters); + methodInfo = new MethodInfo(cp, "", desc); + setModifiers(Modifier.PUBLIC); } /** @@ -100,73 +89,73 @@ public final class CtConstructor extends CtBehavior { * copying it. Otherwise, use Class.forName() 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 null. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. * * @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; } /** @@ -174,32 +163,32 @@ public final class CtConstructor extends CtBehavior { * 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 - * javassist.Modifier. + * @return modifiers encoded with + * javassist.Modifier. * @see Modifier */ public int getModifiers() { - return super.getModifiers(); + return super.getModifiers(); } /** @@ -208,7 +197,7 @@ public final class CtConstructor extends CtBehavior { * @see Modifier */ public void setModifiers(int mod) { - super.setModifiers(mod); + super.setModifiers(mod); } /** @@ -218,24 +207,24 @@ public final class CtConstructor extends CtBehavior { * then this method returns "<clinit>". */ 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(); } /** @@ -244,33 +233,58 @@ public final class CtConstructor extends CtBehavior { * getSignature() 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); } /** @@ -280,16 +294,16 @@ public final class CtConstructor extends CtBehavior { * are replaced with the names specified by * map if map is not null. * - * @param src the method that the body is copied from. - * @param map the hashtable associating original class names - * with substituted names. - * It can be null. + * @param src the method that the body is copied from. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. */ 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); } /** @@ -297,20 +311,20 @@ public final class CtConstructor extends CtBehavior { * 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); } /** @@ -324,36 +338,36 @@ public final class CtConstructor extends CtBehavior { * For example, if the given name is "Point.paint", * then the variable is indicated by $cflow(Point.paint). * - * @param name $cflow name. It can include - * alphabets, numbers, _, - * $, and . (dot). + * @param name $cflow name. It can include + * alphabets, numbers, _, + * $, and . (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); } /** @@ -365,46 +379,46 @@ public final class CtConstructor extends CtBehavior { * 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); + } } /** @@ -412,29 +426,29 @@ public final class CtConstructor extends CtBehavior { * 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); } /** @@ -442,17 +456,14 @@ public final class CtConstructor extends CtBehavior { * 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); } } diff --git a/src/main/javassist/CtField.java b/src/main/javassist/CtField.java index 6bb45e9c..8812e554 100644 --- a/src/main/javassist/CtField.java +++ b/src/main/javassist/CtField.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -50,9 +39,9 @@ public class CtField extends CtMember { * call CtNewMethod.getter() and * CtNewMethod.setter(). * - * @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) @@ -60,9 +49,9 @@ public class CtField extends CtMember { * @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); } /** @@ -76,36 +65,36 @@ public class CtField extends CtMember { * call CtNewMethod.getter() and * CtNewMethod.setter(). * - * @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. @@ -115,11 +104,11 @@ public class CtField extends CtMember { /* 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); } /** @@ -133,55 +122,55 @@ public class CtField extends CtMember { *

    Note that the source code ends with ';' * (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; } /** @@ -193,22 +182,22 @@ public class CtField extends CtMember { * 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); } /** @@ -217,7 +206,7 @@ public class CtField extends CtMember { * @see Modifier */ public int getModifiers() { - return AccessFlag.toModifier(fieldInfo.getAccessFlags()); + return AccessFlag.toModifier(fieldInfo.getAccessFlags()); } /** @@ -226,23 +215,23 @@ public class CtField extends CtMember { * @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)); } /** @@ -250,26 +239,26 @@ public class CtField extends CtMember { * 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 @@ -288,408 +277,408 @@ public class CtField extends CtMember { * @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 java.lang.String type. - */ - public static Initializer constant(String s) { - return new StringInitializer(s); - } - - /** - * Makes an initializer using a constructor parameter. - * - *

    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. - * - *

    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: - * - *

      Object obj - the object including the field.
      - *
    - * - *

    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. - * - *

    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: - * - *

      Object obj - the object including the field.
      - * String[] strs - the character strings specified - * by stringParams
      - *
    - * - *

    If the initialized field is static, then the constructor - * receives only strs. - * - * @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. - * - *

    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: - * - *

      Object obj - the object including the field.
      - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
    - * - *

    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. - * - *

    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: - * - *

      Object obj - the object including the field.
      - * String[] strs - the character strings specified - * by stringParams
      - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
    - * - *

    If the initialized field is static, then the constructor receives - * only strs. - * - * @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. - * - *

    This initializer calls a static method and uses the returned - * value as the initial value of the field. - * The called method receives the parameters: - * - *

      Object obj - the object including the field.
      - *
    - * - *

    If the initialized field is static, then the method does - * not receive any parameters. - * - *

    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. - * - *

    This initializer calls a static method and uses the returned - * value as the initial value of the field. The called method - * receives the parameters: - * - *

      Object obj - the object including the field.
      - * String[] strs - the character strings specified - * by stringParams
      - *
    - * - *

    If the initialized field is static, then the method - * receive only strs. - * - *

    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. - * - *

    This initializer calls a static method and uses the returned - * value as the initial value of the field. The called method - * receives the parameters: - * - *

      Object obj - the object including the field.
      - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
    - * - *

    If the initialized field is static, then the method does - * not receive any parameters. - * - *

    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. - * - *

    This initializer calls a static method and uses the returned - * value as the initial value of the field. The called method - * receives the parameters: - * - *

      Object obj - the object including the field.
      - * String[] strs - the character strings specified - * by stringParams
      - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
    - * - *

    If the initialized field is static, then the method - * receive only strs. - * - *

    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 int 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 java.lang.String type. + */ + public static Initializer constant(String s) { + return new StringInitializer(s); + } + + /** + * Makes an initializer using a constructor parameter. + * + *

    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. + * + *

    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: + * + *

      Object obj - the object including the field.
      + *
    + * + *

    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. + * + *

    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: + * + *

      Object obj - the object including the field.
      + * String[] strs - the character strings specified + * by stringParams
      + *
    + * + *

    If the initialized field is static, then the constructor + * receives only strs. + * + * @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. + * + *

    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: + * + *

      Object obj - the object including the field.
      + * Object[] args - the parameters passed to the + * constructor of the object including the + * filed. + *
    + * + *

    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. + * + *

    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: + * + *

      Object obj - the object including the field.
      + * String[] strs - the character strings specified + * by stringParams
      + * Object[] args - the parameters passed to the + * constructor of the object including the + * filed. + *
    + * + *

    If the initialized field is static, then the constructor receives + * only strs. + * + * @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. + * + *

    This initializer calls a static method and uses the returned + * value as the initial value of the field. + * The called method receives the parameters: + * + *

      Object obj - the object including the field.
      + *
    + * + *

    If the initialized field is static, then the method does + * not receive any parameters. + * + *

    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. + * + *

    This initializer calls a static method and uses the returned + * value as the initial value of the field. The called method + * receives the parameters: + * + *

      Object obj - the object including the field.
      + * String[] strs - the character strings specified + * by stringParams
      + *
    + * + *

    If the initialized field is static, then the method + * receive only strs. + * + *

    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. + * + *

    This initializer calls a static method and uses the returned + * value as the initial value of the field. The called method + * receives the parameters: + * + *

      Object obj - the object including the field.
      + * Object[] args - the parameters passed to the + * constructor of the object including the + * filed. + *
    + * + *

    If the initialized field is static, then the method does + * not receive any parameters. + * + *

    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. + * + *

    This initializer calls a static method and uses the returned + * value as the initial value of the field. The called method + * receives the parameters: + * + *

      Object obj - the object including the field.
      + * String[] strs - the character strings specified + * by stringParams
      + * Object[] args - the parameters passed to the + * constructor of the object including the + * filed. + *
    + * + *

    If the initialized field is static, then the method + * receive only strs. + * + *

    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 int 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); + } } /** @@ -697,155 +686,155 @@ public class CtField extends CtMember { * 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, "", 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, "", 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_ - 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, "", 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, "", 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_ + code.addLdc(stringParams[j]); // ldc ... + code.add(Bytecode.AASTORE); // aastore + } + + return 4; + } } @@ -853,255 +842,255 @@ public class CtField extends CtMember { * 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 + } } } diff --git a/src/main/javassist/CtMember.java b/src/main/javassist/CtMember.java index 8621a18b..a2c18b04 100644 --- a/src/main/javassist/CtMember.java +++ b/src/main/javassist/CtMember.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -42,8 +31,8 @@ public abstract class CtMember { /** * Obtains the modifiers of the member. * - * @return modifiers encoded with - * javassist.Modifier. + * @return modifiers encoded with + * javassist.Modifier. * @see Modifier */ public abstract int getModifiers(); @@ -65,15 +54,15 @@ public abstract class CtMember { * 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); } diff --git a/src/main/javassist/CtMethod.java b/src/main/javassist/CtMethod.java index dbe1931c..c5955a47 100644 --- a/src/main/javassist/CtMethod.java +++ b/src/main/javassist/CtMethod.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -44,29 +33,29 @@ public final class CtMethod extends CtBehavior { 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 CtClass.addMethod(). * - * @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); } /** @@ -107,67 +96,67 @@ public final class CtMethod extends CtBehavior { * copying it. Otherwise, use Class.forName() 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 null. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. * * @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; } /** @@ -176,17 +165,17 @@ public final class CtMethod extends CtBehavior { * 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; } /** @@ -194,26 +183,26 @@ public final class CtMethod extends CtBehavior { * 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 - * javassist.Modifier. + * @return modifiers encoded with + * javassist.Modifier. * @see Modifier */ public int getModifiers() { - return super.getModifiers(); + return super.getModifiers(); } /** @@ -222,43 +211,43 @@ public final class CtMethod extends CtBehavior { * @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(); } /** @@ -268,33 +257,51 @@ public final class CtMethod extends CtBehavior { * 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, {}. + * 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); } /** @@ -306,54 +313,54 @@ public final class CtMethod extends CtBehavior { * are replaced with the names specified by * map if map is not null. * - * @param src the method that the body is copied from. - * @param map the hashtable associating original class names - * with substituted names. - * It can be null. + * @param src the method that the body is copied from. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. */ 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 null). + * @param mbody the wrapped method + * @param constParam the constant parameter given to + * the wrapped method + * (maybe null). * * @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); } /** @@ -361,20 +368,20 @@ public final class CtMethod extends CtBehavior { * 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); } /** @@ -388,46 +395,46 @@ public final class CtMethod extends CtBehavior { * For example, if the given name is "Point.paint", * then the variable is indicated by $cflow(Point.paint). * - * @param name $cflow name. It can include - * alphabets, numbers, _, - * $, and . (dot). + * @param name $cflow name. It can include + * alphabets, numbers, _, + * $, and . (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); } /** @@ -435,29 +442,29 @@ public final class CtMethod extends CtBehavior { * 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); } /** @@ -465,18 +472,15 @@ public final class CtMethod extends CtBehavior { * 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 @@ -491,89 +495,130 @@ public final class CtMethod extends CtBehavior { * @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 String 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 String 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"; + } } } diff --git a/src/main/javassist/CtNewClass.java b/src/main/javassist/CtNewClass.java index 09bf345d..d54eed65 100644 --- a/src/main/javassist/CtNewClass.java +++ b/src/main/javassist/CtNewClass.java @@ -1,28 +1,17 @@ /* - * 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; @@ -35,41 +24,41 @@ class CtNewClass extends CtClassType { 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); } /** @@ -80,29 +69,29 @@ class CtNewClass extends CtClassType { * 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()); } } diff --git a/src/main/javassist/CtNewConstructor.java b/src/main/javassist/CtNewConstructor.java index 13bae8a6..a29d4873 100644 --- a/src/main/javassist/CtNewConstructor.java +++ b/src/main/javassist/CtNewConstructor.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -41,14 +30,14 @@ public class CtNewConstructor { * 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 * Object 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 as is @@ -62,66 +51,66 @@ public class CtNewConstructor { * 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 {}. + * @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 {}. * @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 null. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. * * @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); } /** @@ -131,25 +120,25 @@ public class CtNewConstructor { * super(). */ 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(), - "", "()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(), + "", "()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; } /** @@ -164,18 +153,18 @@ public class CtNewConstructor { * 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); } /** @@ -184,17 +173,17 @@ public class CtNewConstructor { * specified by parameters 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); } /** @@ -287,27 +276,27 @@ public class CtNewConstructor { * } * } * - * @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 (PASS_NONE, - * PASS_ARRAY, - * or PASS_PARAMS) - * @param body appended body (may be null). - * It must be not a constructor but a method. - * @param cparam constant parameter (may be null.) - * @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 (PASS_NONE, + * PASS_ARRAY, + * or PASS_PARAMS) + * @param body appended body (may be null). + * It must be not a constructor but a method. + * @param cparam constant parameter (may be null.) + * @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); } } diff --git a/src/main/javassist/CtNewMethod.java b/src/main/javassist/CtNewMethod.java index 05532902..8e7d65ef 100644 --- a/src/main/javassist/CtNewMethod.java +++ b/src/main/javassist/CtNewMethod.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -45,13 +34,13 @@ public class CtNewMethod { * *

      "public Object id(Object obj) { return obj; }"
    * - * @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); } /** @@ -64,76 +53,76 @@ public class CtNewMethod { *

    If the source code includes $proceed(), 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 $proceed(). - * @param delegateMethod the name of the method - * that is called by $proceed(). + * @param delegateObj the source text specifying the object + * that is called on by $proceed(). + * @param delegateMethod the name of the method + * that is called by $proceed(). */ 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 {}. + * @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 {}. * @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 null. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. * * @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); } /** @@ -141,43 +130,43 @@ public class CtNewMethod { * 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 null. + * @param map the hashtable associating original class names + * with substituted names. + * It can be null. * * @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; } /** @@ -186,37 +175,37 @@ public class CtNewMethod { * 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()); } /** @@ -226,40 +215,40 @@ public class CtNewMethod { * 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()); } /** @@ -279,56 +268,56 @@ public class CtNewMethod { *

    The name of the created method can be changed by * setName(). * - * @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); } /** @@ -415,25 +404,25 @@ public class CtNewMethod { * StringVector class, which is a vector containing * only String 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 null). - * @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 null). + * @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); } } diff --git a/src/main/javassist/CtNewWrappedConstructor.java b/src/main/javassist/CtNewWrappedConstructor.java index fa4786e9..e575a845 100644 --- a/src/main/javassist/CtNewWrappedConstructor.java +++ b/src/main/javassist/CtNewWrappedConstructor.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -34,78 +23,78 @@ class CtNewWrappedConstructor extends CtNewWrappedMethod { 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, "", "()V"); - } - else if (howToCallSuper == PASS_PARAMS) { - stacksize = code.addLoadParameters(parameters) + 1; - code.addInvokespecial(superclazz, "", - 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, "", "()V"); + } + else if (howToCallSuper == PASS_PARAMS) { + stacksize = code.addLoadParameters(parameters) + 1; + code.addInvokespecial(superclazz, "", + 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, "", desc); - } + code.addInvokespecial(superclazz, "", 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; } } diff --git a/src/main/javassist/CtNewWrappedMethod.java b/src/main/javassist/CtNewWrappedMethod.java index 718e3c4f..ce135235 100644 --- a/src/main/javassist/CtNewWrappedMethod.java +++ b/src/main/javassist/CtNewWrappedMethod.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -35,165 +24,165 @@ class CtNewWrappedMethod { 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); + } } } diff --git a/src/main/javassist/CtPrimitiveType.java b/src/main/javassist/CtPrimitiveType.java index 8e73ca8e..015d3527 100644 --- a/src/main/javassist/CtPrimitiveType.java +++ b/src/main/javassist/CtPrimitiveType.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -39,16 +28,16 @@ public final class CtPrimitiveType extends CtClass { 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; } /** diff --git a/src/main/javassist/Dump.java b/src/main/javassist/Dump.java index afc91066..3d9f7494 100644 --- a/src/main/javassist/Dump.java +++ b/src/main/javassist/Dump.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -46,22 +35,22 @@ public class Dump { /** * 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 "); - return; - } + if (args.length != 1) { + System.err.println("Usage: java Dump "); + 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); } } diff --git a/src/main/javassist/Loader.java b/src/main/javassist/Loader.java index 948d3de9..06b30d25 100644 --- a/src/main/javassist/Loader.java +++ b/src/main/javassist/Loader.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -137,8 +126,8 @@ import java.util.Vector; * @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; /** @@ -158,19 +147,35 @@ public class Loader extends ClassLoader { * 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"); } /** @@ -182,17 +187,17 @@ public class Loader extends ClassLoader { * 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 ClassPool. */ public void setClassPool(ClassPool cp) { - source = cp; + source = cp; } /** @@ -201,70 +206,70 @@ public class Loader extends ClassLoader { * *

    This method calls run(). * - * @param args[0] class name to be loaded. - * @param args[1-n] parameters passed to main(). + * @param args[0] class name to be loaded. + * @param args[1-n] parameters passed to main(). * * @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 main() in that class. * - * @param args[0] the name of the loaded class. - * @param args[1-n] parameters passed to main(). + * @param args[0] the name of the loaded class. + * @param args[1-n] parameters passed to main(). */ 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 main() in that class. * - * @param classname the loaded class. - * @param args parameters passed to main(). + * @param classname the loaded class. + * @param args parameters passed to main(). */ 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; } /** @@ -275,66 +280,66 @@ public class Loader extends ClassLoader { * Loader. */ 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); } } diff --git a/src/main/javassist/Modifier.java b/src/main/javassist/Modifier.java index e6c7d2c5..0bd58086 100644 --- a/src/main/javassist/Modifier.java +++ b/src/main/javassist/Modifier.java @@ -1,28 +1,17 @@ /* - * 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; @@ -56,7 +45,7 @@ public class Modifier { * modifier. */ public static boolean isPublic(int mod) { - return (mod & PUBLIC) != 0; + return (mod & PUBLIC) != 0; } /** @@ -64,7 +53,7 @@ public class Modifier { * modifier. */ public static boolean isPrivate(int mod) { - return (mod & PRIVATE) != 0; + return (mod & PRIVATE) != 0; } /** @@ -72,7 +61,7 @@ public class Modifier { * modifier. */ public static boolean isProtected(int mod) { - return (mod & PROTECTED) != 0; + return (mod & PROTECTED) != 0; } /** @@ -80,7 +69,7 @@ public class Modifier { * modifier. */ public static boolean isStatic(int mod) { - return (mod & STATIC) != 0; + return (mod & STATIC) != 0; } /** @@ -88,7 +77,7 @@ public class Modifier { * modifier. */ public static boolean isFinal(int mod) { - return (mod & FINAL) != 0; + return (mod & FINAL) != 0; } /** @@ -96,7 +85,7 @@ public class Modifier { * modifier. */ public static boolean isSynchronized(int mod) { - return (mod & SYNCHRONIZED) != 0; + return (mod & SYNCHRONIZED) != 0; } /** @@ -104,7 +93,7 @@ public class Modifier { * modifier. */ public static boolean isVolatile(int mod) { - return (mod & VOLATILE) != 0; + return (mod & VOLATILE) != 0; } /** @@ -112,7 +101,7 @@ public class Modifier { * modifier. */ public static boolean isTransient(int mod) { - return (mod & TRANSIENT) != 0; + return (mod & TRANSIENT) != 0; } /** @@ -120,7 +109,7 @@ public class Modifier { * modifier. */ public static boolean isNative(int mod) { - return (mod & NATIVE) != 0; + return (mod & NATIVE) != 0; } /** @@ -128,7 +117,7 @@ public class Modifier { * modifier. */ public static boolean isInterface(int mod) { - return (mod & INTERFACE) != 0; + return (mod & INTERFACE) != 0; } /** @@ -136,7 +125,7 @@ public class Modifier { * modifier. */ public static boolean isAbstract(int mod) { - return (mod & ABSTRACT) != 0; + return (mod & ABSTRACT) != 0; } /** @@ -144,7 +133,7 @@ public class Modifier { * modifier. */ public static boolean isStrict(int mod) { - return (mod & STRICT) != 0; + return (mod & STRICT) != 0; } /** @@ -152,7 +141,7 @@ public class Modifier { * cleared. */ public static int setPublic(int mod) { - return (mod & ~(PRIVATE | PROTECTED)) | PUBLIC; + return (mod & ~(PRIVATE | PROTECTED)) | PUBLIC; } /** @@ -160,7 +149,7 @@ public class Modifier { * cleared. */ public static int setProtected(int mod) { - return (mod & ~(PRIVATE | PUBLIC)) | PROTECTED; + return (mod & ~(PRIVATE | PUBLIC)) | PROTECTED; } /** @@ -168,24 +157,24 @@ public class Modifier { * 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 mod. */ 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); } } diff --git a/src/main/javassist/NotFoundException.java b/src/main/javassist/NotFoundException.java index 30b4b882..ca2062e4 100644 --- a/src/main/javassist/NotFoundException.java +++ b/src/main/javassist/NotFoundException.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -30,10 +19,10 @@ 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()); } } diff --git a/src/main/javassist/SerialVersionUID.java b/src/main/javassist/SerialVersionUID.java index a16009ca..26fd3cf3 100644 --- a/src/main/javassist/SerialVersionUID.java +++ b/src/main/javassist/SerialVersionUID.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -43,35 +32,35 @@ public class SerialVersionUID { * 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")); } /** @@ -79,9 +68,9 @@ public class SerialVersionUID { * 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(); @@ -135,12 +124,12 @@ public class SerialVersionUID { 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]; @@ -149,7 +138,7 @@ public class SerialVersionUID { out.writeUTF(""); out.writeInt(mods); out.writeUTF(constructor.getMethodInfo2() - .getDescriptor().replace('/', '.')); + .getDescriptor().replace('/', '.')); } } @@ -157,15 +146,15 @@ public class SerialVersionUID { 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++) { @@ -175,7 +164,7 @@ public class SerialVersionUID { out.writeUTF(method.getName()); out.writeInt(mods); out.writeUTF(method.getMethodInfo2() - .getDescriptor().replace('/', '.')); + .getDescriptor().replace('/', '.')); } } @@ -188,13 +177,13 @@ public class SerialVersionUID { 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) { diff --git a/src/main/javassist/Translator.java b/src/main/javassist/Translator.java index 42599c9d..65718f61 100644 --- a/src/main/javassist/Translator.java +++ b/src/main/javassist/Translator.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -40,14 +29,14 @@ public interface Translator { * Is invoked by a ClassPool for initialization * when the object is attached to a ClassPool object. * - * @param pool the ClassPool that this translator - * is attached to. + * @param pool the ClassPool 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 ClassPool for notifying that @@ -56,9 +45,9 @@ public interface Translator { *

    If CtClass.frozen() is true, that is, if the class has been * already modified and written, then onWrite() is not invoked. * - * @param pool the ClassPool that this translator - * is attached to. - * @param classname a fully-qualified class name + * @param pool the ClassPool that this translator + * is attached to. + * @param classname a fully-qualified class name * * @see ClassPool#writeFile(String) * @see ClassPool#writeFile(String, String) @@ -66,5 +55,5 @@ public interface Translator { * @see ClassPool#write(String,DataOutputStream) */ void onWrite(ClassPool pool, String classname) - throws NotFoundException, CannotCompileException; + throws NotFoundException, CannotCompileException; } diff --git a/src/main/javassist/URLClassPath.java b/src/main/javassist/URLClassPath.java index c359c778..2bf05bd8 100644 --- a/src/main/javassist/URLClassPath.java +++ b/src/main/javassist/URLClassPath.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -41,7 +30,7 @@ public class URLClassPath implements ClassPath { protected String directory; protected String packageName; - /* + /** * Creates a search path specified with URL (http). * *

    This search path is used only if a requested @@ -51,93 +40,98 @@ public class URLClassPath implements ClassPath { * If packageName is null, 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; } } diff --git a/src/main/javassist/bytecode/AccessFlag.java b/src/main/javassist/bytecode/AccessFlag.java index c964ca7c..289445a2 100644 --- a/src/main/javassist/bytecode/AccessFlag.java +++ b/src/main/javassist/bytecode/AccessFlag.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -52,7 +41,7 @@ public class AccessFlag { * cleared. */ public static int setPublic(int accflags) { - return (accflags & ~(PRIVATE | PROTECTED)) | PUBLIC; + return (accflags & ~(PRIVATE | PROTECTED)) | PUBLIC; } /** @@ -60,7 +49,7 @@ public class AccessFlag { * cleared. */ public static int setProtected(int accflags) { - return (accflags & ~(PRIVATE | PUBLIC)) | PROTECTED; + return (accflags & ~(PRIVATE | PUBLIC)) | PROTECTED; } /** @@ -68,40 +57,40 @@ public class AccessFlag { * 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 accflags. */ 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; } } diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java index 29d7904b..ea7f0d40 100644 --- a/src/main/javassist/bytecode/AttributeInfo.java +++ b/src/main/javassist/bytecode/AttributeInfo.java @@ -1,28 +1,17 @@ /* - * 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; @@ -33,7 +22,7 @@ import java.util.LinkedList; import java.util.ListIterator; // Note: if you define a new subclass of AttributeInfo, then -// update AttributeInfo.read(). +// update AttributeInfo.read(). /** * attribute_info structure. @@ -44,66 +33,66 @@ public class AttributeInfo { 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 attribute_info structure. * - * @param cp constant pool table - * @param attrname attribute name - * @param attrinfo info field - * of attribute_info structure. + * @param cp constant pool table + * @param attrname attribute name + * @param attrinfo info field + * of attribute_info 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); } /** @@ -117,7 +106,7 @@ public class AttributeInfo { * The returned value is attribute_length + 6. */ public int length() { - return info.length + 6; + return info.length + 6; } /** @@ -142,99 +131,99 @@ public class AttributeInfo { * Makes a copy. Class names are replaced according to the * given Map 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); + } } } diff --git a/src/main/javassist/bytecode/BadBytecode.java b/src/main/javassist/bytecode/BadBytecode.java index 51d287d7..88cf6e95 100644 --- a/src/main/javassist/bytecode/BadBytecode.java +++ b/src/main/javassist/bytecode/BadBytecode.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -30,10 +19,10 @@ 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); } } diff --git a/src/main/javassist/bytecode/ByteArray.java b/src/main/javassist/bytecode/ByteArray.java index e10231e8..5d1c7500 100644 --- a/src/main/javassist/bytecode/ByteArray.java +++ b/src/main/javassist/bytecode/ByteArray.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -33,54 +22,54 @@ public class ByteArray { * 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]; } } diff --git a/src/main/javassist/bytecode/Bytecode.java b/src/main/javassist/bytecode/Bytecode.java index f903e4be..2a72547b 100644 --- a/src/main/javassist/bytecode/Bytecode.java +++ b/src/main/javassist/bytecode/Bytecode.java @@ -1,28 +1,17 @@ /* - * 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; @@ -78,25 +67,25 @@ public class Bytecode implements Opcode { * of max_stack and max_locals. * They can be changed later. * - * @param cp constant pool table. - * @param stacksize max_stack. - * @param localvars max_locals. + * @param cp constant pool table. + * @param stacksize max_stack. + * @param localvars max_locals. */ 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; } /** @@ -113,40 +102,40 @@ public class Bytecode implements Opcode { * Converts to a CodeAttribute. */ 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; } /** @@ -169,7 +158,7 @@ public class Bytecode implements Opcode { * @see #addOpcode(int) */ public void setMaxStack(int size) { - maxStack = size; + maxStack = size; } /** @@ -181,7 +170,7 @@ public class Bytecode implements Opcode { * Sets max_locals. */ public void setMaxLocals(int size) { - maxLocals = size; + maxLocals = size; } /** @@ -191,55 +180,55 @@ public class Bytecode implements Opcode { * used to pass method parameters and sets max_locals * to that number plus locals. * - * @param isStatic true if params 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 params 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 max_locals. */ public void incMaxLocals(int diff) { - maxLocals += diff; + maxLocals += diff; } /** * Adds a new entry of exception_table. */ 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 exception_table. */ 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); } /** @@ -247,34 +236,34 @@ public class Bytecode implements Opcode { * 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); + } } /** @@ -282,27 +271,27 @@ public class Bytecode implements Opcode { * 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); + } } /** @@ -310,22 +299,22 @@ public class Bytecode implements Opcode { * 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); + } } /** @@ -340,8 +329,8 @@ public class Bytecode implements Opcode { * growStack() must be explicitly called. */ public void addOpcode(int code) { - add(code); - growStack(STACK_GROW[code]); + add(code); + growStack(STACK_GROW[code]); } /** @@ -349,10 +338,10 @@ public class Bytecode implements Opcode { * It also updates max_stack 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); } /** @@ -365,12 +354,12 @@ public class Bytecode implements Opcode { * It also updates max_stack 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; } /** @@ -378,321 +367,321 @@ public class Bytecode implements Opcode { * 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_ - else if (n < 0x100) { - addOpcode(ALOAD); // aload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ALOAD); - addIndex(n); - } + if (n < 4) + addOpcode(42 + n); // aload_ + 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_ - else if (n < 0x100) { - addOpcode(ASTORE); // astore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ASTORE); - addIndex(n); - } + if (n < 4) + addOpcode(75 + n); // astore_ + 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_ -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_ -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_ - else if (n < 0x100) { - addOpcode(ILOAD); // iload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ILOAD); - addIndex(n); - } + if (n < 4) + addOpcode(26 + n); // iload_ + 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_ - else if (n < 0x100) { - addOpcode(ISTORE); // istore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ISTORE); - addIndex(n); - } + if (n < 4) + addOpcode(59 + n); // istore_ + 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_ - else - addLdc2w(n); + if (n == 0 || n == 1) + addOpcode(9 + (int)n); // lconst_ + 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_ - else if (n < 0x100) { - addOpcode(LLOAD); // lload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(LLOAD); - addIndex(n); - } + if (n < 4) + addOpcode(30 + n); // lload_ + 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_ - else if (n < 0x100) { - addOpcode(LSTORE); // lstore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(LSTORE); - addIndex(n); - } + if (n < 4) + addOpcode(63 + n); // lstore_ + 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_ - else - addLdc2w(d); + if (d == 0.0 || d == 1.0) + addOpcode(14 + (int)d); // dconst_ + 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_ - else if (n < 0x100) { - addOpcode(DLOAD); // dload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(DLOAD); - addIndex(n); - } + if (n < 4) + addOpcode(38 + n); // dload_ + 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_ - else if (n < 0x100) { - addOpcode(DSTORE); // dstore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(DSTORE); - addIndex(n); - } + if (n < 4) + addOpcode(71 + n); // dstore_ + 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_ - else - addLdc(constPool.addFloatInfo(f)); + if (f == 0.0f || f == 1.0f || f == 2.0f) + addOpcode(11 + (int)f); // fconst_ + 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_ - else if (n < 0x100) { - addOpcode(FLOAD); // fload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(FLOAD); - addIndex(n); - } + if (n < 4) + addOpcode(34 + n); // fload_ + 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_ - else if (n < 0x100) { - addOpcode(FSTORE); // fstore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(FSTORE); - addIndex(n); - } + if (n < 4) + addOpcode(67 + n); // fstore_ + 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 n. * - * @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 n. * - * @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; } /** @@ -700,207 +689,207 @@ public class Bytecode implements Opcode { * 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 CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. + * @param clazz the index of CONSTANT_Class_info + * 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 CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. + * @param clazz the index of CONSTANT_Class_info + * 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)); } /** @@ -910,15 +899,15 @@ public class Bytecode implements Opcode { * It must be directly declared in the class specified * in clazz. * - * @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); } /** @@ -928,14 +917,14 @@ public class Bytecode implements Opcode { * It must be directly declared in the class specified * in clazz. * - * @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); } /** @@ -945,14 +934,14 @@ public class Bytecode implements Opcode { * It must be directly declared in the class specified * in classname. * - * @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); } /** @@ -962,301 +951,301 @@ public class Bytecode implements Opcode { * It must be directly declared in the class specified * by clazz. * - * @param clazz the index of CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. + * @param clazz the index of CONSTANT_Class_info + * 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 CONSTANT_Class_info - * 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 CONSTANT_Class_info + * 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 String * 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 T_BOOLEAN, T_CHAR, ... + * @param atype T_BOOLEAN, T_CHAR, ... * @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 dimensions. + * @param clazz the array type. + * @param dimensions the sizes of all dimensions. + * @return the length of dimensions. */ 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 dim. + * @param clazz the array type. + * @param dim the number of the dimensions. + * @return the value of dim. */ 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 dim. + * @param desc the type descriptor of the created array. + * @param dim dimensions. + * @return the value of dim. */ 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 * java.lang.System.println(message). * - * @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"); } } diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java index 063caa59..38e50087 100644 --- a/src/main/javassist/bytecode/ClassFile.java +++ b/src/main/javassist/bytecode/ClassFile.java @@ -1,28 +1,17 @@ /* - * 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; @@ -49,85 +38,85 @@ public final class ClassFile { 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; } /** @@ -136,7 +125,7 @@ public final class ClassFile { * @see javassist.bytecode.AccessFlag */ public int getAccessFlags() { - return accessFlags; + return accessFlags; } /** @@ -145,14 +134,14 @@ public final class ClassFile { * @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; } /** @@ -160,14 +149,14 @@ public final class ClassFile { * 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); } /** @@ -175,7 +164,7 @@ public final class ClassFile { * the super class. */ public int getSuperclassId() { - return superClass; + return superClass; } /** @@ -188,24 +177,24 @@ public final class ClassFile { * 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 @@ -216,12 +205,12 @@ public final class ClassFile { * 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); + } } /** @@ -233,104 +222,104 @@ public final class ClassFile { * 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 - * java/lang/Object. + * @param classnames specifies which class name is replaced + * with which new name. Class names must + * be described with the JVM-internal + * representation like + * java/lang/Object. * * @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]); + } } /** @@ -338,18 +327,18 @@ public final class ClassFile { * 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; + } } /** @@ -364,7 +353,7 @@ public final class ClassFile { * Appends a field to the class. */ public void addField(FieldInfo finfo) { - fields.add(finfo); + fields.add(finfo); } /** @@ -379,18 +368,18 @@ public final class ClassFile { * 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; } /** @@ -398,14 +387,14 @@ public final class ClassFile { * 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); } /** @@ -419,18 +408,18 @@ public final class ClassFile { /** * 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; } /** @@ -438,63 +427,63 @@ public final class ClassFile { * 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); } /** @@ -502,42 +491,42 @@ public final class ClassFile { * 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); } } diff --git a/src/main/javassist/bytecode/ClassFileWriter.java b/src/main/javassist/bytecode/ClassFileWriter.java index 5b83a5aa..c7ddacbf 100644 --- a/src/main/javassist/bytecode/ClassFileWriter.java +++ b/src/main/javassist/bytecode/ClassFileWriter.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,78 +28,78 @@ public class ClassFileWriter { * 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(""); - printAttributes(ca.getAttributes(), out); - out.println(""); - } - 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(""); + printAttributes(ca.getAttributes(), out); + out.println(""); + } + else + out.println("attribute: " + ai.getName() + + " (" + ai.get().length + " byte): " + + ai.getClass().getName()); + } } } diff --git a/src/main/javassist/bytecode/CodeAttribute.java b/src/main/javassist/bytecode/CodeAttribute.java index 6f45c03e..84511f58 100644 --- a/src/main/javassist/bytecode/CodeAttribute.java +++ b/src/main/javassist/bytecode/CodeAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -58,100 +47,100 @@ public class CodeAttribute extends AttributeInfo implements Opcode { /** * Constructs a Code_attribute. * - * @param cp constant pool table - * @param stack max_stack - * @param locals max_locals - * @param code code[] - * @param etable exception_table[] + * @param cp constant pool table + * @param stack max_stack + * @param locals max_locals + * @param code code[] + * @param etable exception_table[] */ 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_attribute. * 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 Map 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 BadBytecode - * exception is thrown, it is - * converted into - * RuntimeCopyException. + * @param newCp the constant pool table used by the new copy. + * @param classnames pairs of replaced and substituted + * class names. + * @exception RuntimeCopyException if a BadBytecode + * exception is thrown, it is + * converted into + * RuntimeCopyException. * * @return CodeAttribute 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?"); + } } /** @@ -159,12 +148,12 @@ public class CodeAttribute extends AttributeInfo implements Opcode { * in CodeAttribute. */ public static class RuntimeCopyException extends RuntimeException { - /** - * Constructs an exception. - */ - public RuntimeCopyException(String s) { - super(s); - } + /** + * Constructs an exception. + */ + public RuntimeCopyException(String s) { + super(s); + } } /** @@ -173,38 +162,38 @@ public class CodeAttribute extends AttributeInfo implements Opcode { * The returned value is attribute_length + 6. */ 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()"); } /** @@ -212,50 +201,50 @@ public class CodeAttribute extends AttributeInfo implements Opcode { * this code attribute. */ public String getDeclaringClass() { - ConstPool cp = getConstPool(); - return cp.getClassName(); + ConstPool cp = getConstPool(); + return cp.getClassName(); } /** * Returns max_stack. */ public int getMaxStack() { - return maxStack; + return maxStack; } /** * Sets max_stack. */ public void setMaxStack(int value) { - maxStack = value; + maxStack = value; } /** * Returns max_locals. */ public int getMaxLocals() { - return maxLocals; + return maxLocals; } /** * Sets max_locals. */ public void setMaxLocals(int value) { - maxLocals = value; + maxLocals = value; } /** * Returns code_length. */ public int getCodeLength() { - return info.length; + return info.length; } /** * Returns code[]. */ public byte[] getCode() { - return info; + return info; } /** @@ -267,7 +256,7 @@ public class CodeAttribute extends AttributeInfo implements Opcode { * Makes a new iterator for reading this code attribute. */ public CodeIterator iterator() { - return new CodeIterator(this); + return new CodeIterator(this); } /** @@ -287,99 +276,99 @@ public class CodeAttribute extends AttributeInfo implements Opcode { * Returns the attribute with the specified name. * If it is not found, this method returns null. * - * @param name attribute name - * @return an AttributeInfo object or null. + * @param name attribute name + * @return an AttributeInfo 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; } } @@ -389,16 +378,16 @@ final class LdcEntry { 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; } } diff --git a/src/main/javassist/bytecode/CodeIterator.java b/src/main/javassist/bytecode/CodeIterator.java index 09735e27..f2923488 100644 --- a/src/main/javassist/bytecode/CodeIterator.java +++ b/src/main/javassist/bytecode/CodeIterator.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -41,17 +30,17 @@ public class CodeIterator implements Opcode { 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(); } /** @@ -67,21 +56,21 @@ public class CodeIterator implements Opcode { * @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_length of Code_attribute. */ public int getCodeLength() { - return bytecode.length; + return bytecode.length; } /** @@ -93,51 +82,51 @@ public class CodeIterator implements Opcode { * 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]; } /** @@ -156,9 +145,9 @@ public class CodeIterator implements Opcode { * @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; } /** @@ -176,11 +165,11 @@ public class CodeIterator implements Opcode { * *

    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); } /** @@ -198,12 +187,12 @@ public class CodeIterator implements Opcode { * *

    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 this() is found. + * @return the index of the INVOKESPECIAL instruction, or -1 + * if a super constructor invocation is not found + * but this() is found. */ public int skipSuperConstructor() throws BadBytecode { - return skipSuperConstructor0(0); + return skipSuperConstructor0(0); } /** @@ -221,44 +210,44 @@ public class CodeIterator implements Opcode { * *

    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 super() is found. + * @return the index of the INVOKESPECIAL instruction, or -1 + * if a explicit constructor invocation is not found + * but super() 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; } /** @@ -275,16 +264,16 @@ public class CodeIterator implements Opcode { * bytecode sequence for adjusting alignment if the code attribute * includes LOOKUPSWITCH or TABLESWITCH. * - * @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; } /** @@ -300,11 +289,11 @@ public class CodeIterator implements Opcode { * bytecode sequence for adjusting alignment if the code attribute * includes LOOKUPSWITCH or TABLESWITCH. * - * @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); } /** @@ -321,16 +310,16 @@ public class CodeIterator implements Opcode { * bytecode sequence for adjusting alignment if the code attribute * includes LOOKUPSWITCH or TABLESWITCH. * - * @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; } /** @@ -346,23 +335,23 @@ public class CodeIterator implements Opcode { * bytecode sequence for adjusting alignment if the code attribute * includes LOOKUPSWITCH or TABLESWITCH. * - * @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]; } /** @@ -377,13 +366,13 @@ public class CodeIterator implements Opcode { *

    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; } /** @@ -397,11 +386,13 @@ public class CodeIterator implements Opcode { * 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 length. */ - 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); } /** @@ -416,13 +407,13 @@ public class CodeIterator implements Opcode { *

    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; } /** @@ -436,28 +427,35 @@ public class CodeIterator implements Opcode { * 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 length. */ - 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; } /** @@ -465,53 +463,53 @@ public class CodeIterator implements Opcode { * 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(); } /** @@ -519,28 +517,28 @@ public class CodeIterator implements Opcode { * 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 @@ -548,45 +546,45 @@ public class CodeIterator implements Opcode { * 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(). @@ -598,143 +596,143 @@ public class CodeIterator implements Opcode { * 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, if_icmp, if_acmp, 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, if_icmp, if_acmp, 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; } } diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java index 5d079e3a..2a0f4c81 100644 --- a/src/main/javassist/bytecode/ConstPool.java +++ b/src/main/javassist/bytecode/ConstPool.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,10 +28,10 @@ import javassist.CtClass; */ public final class ConstPool { LongVector items; - int numOfItems; + int numOfItems; Hashtable classes; Hashtable strings; - int thisClassInfo; + int thisClassInfo; private static final int SIZE = 128; /** @@ -64,7 +53,7 @@ public final class ConstPool { * CONSTANT_InterfaceMethodref */ public static final int CONST_InterfaceMethodref - = InterfaceMethodrefInfo.tag; + = InterfaceMethodrefInfo.tag; /** * CONSTANT_String @@ -109,38 +98,38 @@ public final class ConstPool { /** * 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); } /** @@ -148,15 +137,15 @@ public final class ConstPool { * 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); } /** @@ -164,22 +153,22 @@ public final class ConstPool { * entry at the given index. */ public int getTag(int index) { - return getItem(index).getTag(); + return getItem(index).getTag(); } /** * Reads CONSTANT_Class_info structure * at the given index. * - * @return a fully-qualified class or interface name specified - * by name_index. + * @return a fully-qualified class or interface name specified + * by name_index. */ 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)); } /** @@ -188,8 +177,8 @@ public final class ConstPool { * 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; } /** @@ -198,8 +187,8 @@ public final class ConstPool { * 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; } /** @@ -208,8 +197,8 @@ public final class ConstPool { * 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; } /** @@ -220,11 +209,11 @@ public final class ConstPool { * @return the name of the class at that class_index. */ 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); } /** @@ -233,8 +222,8 @@ public final class ConstPool { * 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; } /** @@ -242,20 +231,20 @@ public final class ConstPool { * CONSTANT_NameAndType_info structure * indirectly specified by the given index. * - * @param index an index to a CONSTANT_Fieldref_info. - * @return the name of the field. + * @param index an index to a CONSTANT_Fieldref_info. + * @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); + } } /** @@ -263,20 +252,20 @@ public final class ConstPool { * CONSTANT_NameAndType_info structure * indirectly specified by the given index. * - * @param index an index to a CONSTANT_Fieldref_info. - * @return the type descriptor of the field. + * @param index an index to a CONSTANT_Fieldref_info. + * @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); + } } /** @@ -285,8 +274,8 @@ public final class ConstPool { * 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; } /** @@ -297,11 +286,11 @@ public final class ConstPool { * @return the name of the class at that class_index. */ 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); } /** @@ -310,8 +299,8 @@ public final class ConstPool { * 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; } /** @@ -319,21 +308,21 @@ public final class ConstPool { * CONSTANT_NameAndType_info structure * indirectly specified by the given index. * - * @param index an index to a CONSTANT_Methodref_info. - * @return the name of the method. + * @param index an index to a CONSTANT_Methodref_info. + * @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); + } } /** @@ -341,21 +330,21 @@ public final class ConstPool { * CONSTANT_NameAndType_info structure * indirectly specified by the given index. * - * @param index an index to a CONSTANT_Methodref_info. - * @return the descriptor of the method. + * @param index an index to a CONSTANT_Methodref_info. + * @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); + } } /** @@ -364,9 +353,9 @@ public final class ConstPool { * 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; } /** @@ -377,9 +366,9 @@ public final class ConstPool { * @return the name of the class at that class_index. */ public String getInterfaceMethodrefClassName(int index) { - InterfaceMethodrefInfo minfo - = (InterfaceMethodrefInfo)getItem(index); - return getClassInfo(minfo.classIndex); + InterfaceMethodrefInfo minfo + = (InterfaceMethodrefInfo)getItem(index); + return getClassInfo(minfo.classIndex); } /** @@ -388,9 +377,9 @@ public final class ConstPool { * 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; } /** @@ -398,23 +387,23 @@ public final class ConstPool { * CONSTANT_NameAndType_info structure * indirectly specified by the given index. * - * @param index an index to - * a CONSTANT_InterfaceMethodref_info. - * @return the name of the method. + * @param index an index to + * a CONSTANT_InterfaceMethodref_info. + * @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); + } } /** @@ -422,23 +411,23 @@ public final class ConstPool { * CONSTANT_NameAndType_info structure * indirectly specified by the given index. * - * @param index an index to - * a CONSTANT_InterfaceMethodref_info. - * @return the descriptor of the method. + * @param index an index to + * a CONSTANT_InterfaceMethodref_info. + * @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 CONSTANT_Integer_info, _Float_info, @@ -450,22 +439,22 @@ public final class ConstPool { * 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; } /** @@ -475,8 +464,8 @@ public final class ConstPool { * @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; } /** @@ -486,8 +475,8 @@ public final class ConstPool { * @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; } /** @@ -497,8 +486,8 @@ public final class ConstPool { * @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; } /** @@ -508,8 +497,8 @@ public final class ConstPool { * @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; } /** @@ -519,8 +508,8 @@ public final class ConstPool { * @return the string specified by string_index. */ public String getStringInfo(int index) { - StringInfo si = (StringInfo)getItem(index); - return getUtf8Info(si.string); + StringInfo si = (StringInfo)getItem(index); + return getUtf8Info(si.string); } /** @@ -530,8 +519,8 @@ public final class ConstPool { * @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; } /** @@ -539,13 +528,13 @@ public final class ConstPool { * structure at the given index represents the constructor * of the given class. * - * @return the descriptor_index specifying - * the type descriptor of the that constructor. - * If it is not that constructor, - * isConstructor() returns 0. + * @return the descriptor_index specifying + * the type descriptor of the that constructor. + * If it is not that constructor, + * isConstructor() returns 0. */ public int isConstructor(String classname, int index) { - return isMember(classname, MethodInfo.nameInit, index); + return isMember(classname, MethodInfo.nameInit, index); } /** @@ -555,30 +544,30 @@ public final class ConstPool { * 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 descriptor_index specifying - * the type descriptor of that member. - * If it is not that member, - * isMember() returns 0. + * @return the descriptor_index specifying + * the type descriptor of that member. + * If it is not that member, + * isMember() 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++; } /** @@ -587,20 +576,20 @@ public final class ConstPool { * The class names that the item refers to are renamed according * to the given map. * - * @param n the n-th item - * @param dest destination constant pool table - * @param classnames the map or null. + * @param n the n-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()); } /** @@ -609,21 +598,21 @@ public final class ConstPool { *

    This also adds a CONSTANT_Utf8_info 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;" instead of "". - // - // 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;" instead of "". + // + // note: toJvmName(toJvmName(c)) is equal to toJvmName(c). - return addClassInfo(Descriptor.toJvmName(c)); - } + return addClassInfo(Descriptor.toJvmName(c)); + } } /** @@ -632,20 +621,20 @@ public final class ConstPool { *

    This also adds a CONSTANT_Utf8_info 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); + } } /** @@ -653,23 +642,23 @@ public final class ConstPool { * *

    This also adds CONSTANT_Utf8_info structures. * - * @param name name_index - * @param type descriptor_index - * @return the index of the added entry. + * @param name name_index + * @param type descriptor_index + * @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 CONSTANT_NameAndType_info structure. * - * @param name name_index - * @param type descriptor_index - * @return the index of the added entry. + * @param name name_index + * @param type descriptor_index + * @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)); } /** @@ -678,27 +667,27 @@ public final class ConstPool { *

    This also adds a new CONSTANT_NameAndType_info * structure. * - * @param classInfo class_index - * @param name name_index - * of CONSTANT_NameAndType_info. - * @param type descriptor_index - * of CONSTANT_NameAndType_info. - * @return the index of the added entry. + * @param classInfo class_index + * @param name name_index + * of CONSTANT_NameAndType_info. + * @param type descriptor_index + * of CONSTANT_NameAndType_info. + * @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 CONSTANT_Fieldref_info structure. * - * @param classInfo class_index - * @param nameandtypeinfo name_and_type_index. - * @return the index of the added entry. + * @param classInfo class_index + * @param nameandtypeinfo name_and_type_index. + * @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)); } /** @@ -707,27 +696,27 @@ public final class ConstPool { *

    This also adds a new CONSTANT_NameAndType_info * structure. * - * @param classInfo class_index - * @param name name_index - * of CONSTANT_NameAndType_info. - * @param type descriptor_index - * of CONSTANT_NameAndType_info. - * @return the index of the added entry. + * @param classInfo class_index + * @param name name_index + * of CONSTANT_NameAndType_info. + * @param type descriptor_index + * of CONSTANT_NameAndType_info. + * @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 CONSTANT_Methodref_info structure. * - * @param classInfo class_index - * @param nameandtypeinfo name_and_type_index. - * @return the index of the added entry. + * @param classInfo class_index + * @param nameandtypeinfo name_and_type_index. + * @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)); } /** @@ -737,31 +726,31 @@ public final class ConstPool { *

    This also adds a new CONSTANT_NameAndType_info * structure. * - * @param classInfo class_index - * @param name name_index - * of CONSTANT_NameAndType_info. - * @param type descriptor_index - * of CONSTANT_NameAndType_info. - * @return the index of the added entry. + * @param classInfo class_index + * @param name name_index + * of CONSTANT_NameAndType_info. + * @param type descriptor_index + * of CONSTANT_NameAndType_info. + * @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 CONSTANT_InterfaceMethodref_info * structure. * - * @param classInfo class_index - * @param nameandtypeinfo name_and_type_index. - * @return the index of the added entry. + * @param classInfo class_index + * @param nameandtypeinfo name_and_type_index. + * @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)); } /** @@ -771,54 +760,54 @@ public final class ConstPool { *

    This also adds a new CONSTANT_Utf8_info * 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 CONSTANT_Integer_info * 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 CONSTANT_Float_info * 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 CONSTANT_Long_info * 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 CONSTANT_Double_info * 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; } /** @@ -830,131 +819,131 @@ public final class ConstPool { * 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(, 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(, 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); + } } } @@ -964,16 +953,16 @@ abstract class ConstInfo { 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(); } } @@ -983,13 +972,13 @@ class ConstInfoPadding extends ConstInfo { 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"); } } @@ -999,48 +988,48 @@ class ClassInfo extends ConstInfo { 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); } } @@ -1050,50 +1039,50 @@ class NameAndTypeInfo extends ConstInfo { 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); } } @@ -1102,34 +1091,34 @@ abstract class MemberrefInfo extends ConstInfo { 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(); @@ -1139,11 +1128,11 @@ class FieldrefInfo extends MemberrefInfo { 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; } @@ -1151,7 +1140,7 @@ class FieldrefInfo extends MemberrefInfo { public String getTagName() { return "Field"; } protected int copy2(ConstPool dest, int cindex, int ntindex) { - return dest.addFieldrefInfo(cindex, ntindex); + return dest.addFieldrefInfo(cindex, ntindex); } } @@ -1159,11 +1148,11 @@ class MethodrefInfo extends MemberrefInfo { 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; } @@ -1171,7 +1160,7 @@ class MethodrefInfo extends MemberrefInfo { public String getTagName() { return "Method"; } protected int copy2(ConstPool dest, int cindex, int ntindex) { - return dest.addMethodrefInfo(cindex, ntindex); + return dest.addMethodrefInfo(cindex, ntindex); } } @@ -1179,11 +1168,11 @@ class InterfaceMethodrefInfo extends MemberrefInfo { 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; } @@ -1191,7 +1180,7 @@ class InterfaceMethodrefInfo extends MemberrefInfo { public String getTagName() { return "Interface"; } protected int copy2(ConstPool dest, int cindex, int ntindex) { - return dest.addInterfaceMethodrefInfo(cindex, ntindex); + return dest.addInterfaceMethodrefInfo(cindex, ntindex); } } @@ -1200,27 +1189,27 @@ class StringInfo extends ConstInfo { 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); } } @@ -1229,27 +1218,27 @@ class IntegerInfo extends ConstInfo { 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); } } @@ -1258,27 +1247,27 @@ class FloatInfo extends ConstInfo { 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); } } @@ -1287,27 +1276,27 @@ class LongInfo extends ConstInfo { 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); } } @@ -1316,27 +1305,27 @@ class DoubleInfo extends ConstInfo { 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); } } @@ -1346,29 +1335,29 @@ class Utf8Info extends ConstInfo { 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("\""); } } diff --git a/src/main/javassist/bytecode/ConstantAttribute.java b/src/main/javassist/bytecode/ConstantAttribute.java index 4d913e15..3658b92f 100644 --- a/src/main/javassist/bytecode/ConstantAttribute.java +++ b/src/main/javassist/bytecode/ConstantAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,44 +28,44 @@ public class ConstantAttribute extends AttributeInfo { 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 constantvalue_index - * of ConstantValue_attribute. + * @param cp a constant pool table. + * @param index constantvalue_index + * of ConstantValue_attribute. */ 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 constantvalue_index. */ public int getConstantValue() { - return ByteArray.readU16bit(get(), 0); + return ByteArray.readU16bit(get(), 0); } /** * Makes a copy. Class names are replaced according to the * given Map 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); } } diff --git a/src/main/javassist/bytecode/Descriptor.java b/src/main/javassist/bytecode/Descriptor.java index 065fbccf..badec6b4 100644 --- a/src/main/javassist/bytecode/Descriptor.java +++ b/src/main/javassist/bytecode/Descriptor.java @@ -1,28 +1,17 @@ /* - * 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; @@ -45,7 +34,7 @@ public class Descriptor { * to toJvmName(s). */ public static String toJvmName(String classname) { - return classname.replace('.', '/'); + return classname.replace('.', '/'); } /** @@ -53,7 +42,7 @@ public class Descriptor { * the JVM to the normal one used in Java. */ public static String toJavaName(String classname) { - return classname.replace('/', '.'); + return classname.replace('/', '.'); } /** @@ -61,172 +50,172 @@ public class Descriptor { * 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 map. * - * @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(); } /** @@ -234,10 +223,10 @@ public class Descriptor { * For example, if the given parameter types are two int, * then this method returns "(II)". * - * @param paramTypes parameter types + * @param paramTypes parameter types */ public static String ofParameters(CtClass[] paramTypes) { - return ofMethod(null, paramTypes); + return ofMethod(null, paramTypes); } /** @@ -246,23 +235,23 @@ public class Descriptor { * *

    classname 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(); + } } /** @@ -272,16 +261,16 @@ public class Descriptor { * *

    classname 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); } /** @@ -289,98 +278,98 @@ public class Descriptor { * *

    classname 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 CtClass objects representing the parameter * types specified by the given descriptor. * - * @param desc descriptor - * @param cp the class pool used for obtaining - * a CtClass object. + * @param desc descriptor + * @param cp the class pool used for obtaining + * a CtClass 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 CtClass object representing the return * type specified by the given descriptor. * - * @param desc descriptor - * @param cp the class pool used for obtaining - * a CtClass object. + * @param desc descriptor + * @param cp the class pool used for obtaining + * a CtClass 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; } /** @@ -392,101 +381,101 @@ public class Descriptor { * it accepts Ljava.lang.Object; * as well as Ljava/lang/Object;. * - * @param desc descriptor - * @param cp the class pool used for obtaining - * a CtClass object. + * @param desc descriptor + * @param cp the class pool used for obtaining + * a CtClass 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; } /** @@ -498,46 +487,46 @@ public class Descriptor { * 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; } } diff --git a/src/main/javassist/bytecode/ExceptionTable.java b/src/main/javassist/bytecode/ExceptionTable.java index 71baa3b5..ce9765d6 100644 --- a/src/main/javassist/bytecode/ExceptionTable.java +++ b/src/main/javassist/bytecode/ExceptionTable.java @@ -1,28 +1,17 @@ /* - * 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; @@ -38,10 +27,10 @@ class ExceptionTableEntry { 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; } } @@ -55,26 +44,26 @@ public class ExceptionTable { /** * Constructs an exception_table[]. * - * @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; } /** @@ -82,143 +71,143 @@ public class ExceptionTable { * of entries in the exception_table[]. */ public int size() { - return entries.size(); + return entries.size(); } /** * Returns startPc of the n-th entry. * - * @param nth the n-th (>= 0). + * @param nth the n-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 startPc of the n-th entry. * - * @param nth the n-th (>= 0). - * @param value new value. + * @param nth the n-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 endPc of the n-th entry. * - * @param nth the n-th (>= 0). + * @param nth the n-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 endPc of the n-th entry. * - * @param nth the n-th (>= 0). - * @param value new value. + * @param nth the n-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 handlerPc of the n-th entry. * - * @param nth the n-th (>= 0). + * @param nth the n-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 handlerPc of the n-th entry. * - * @param nth the n-th (>= 0). - * @param value new value. + * @param nth the n-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 catchType of the n-th entry. * - * @param nth the n-th (>= 0). + * @param nth the n-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 catchType of the n-th entry. * - * @param nth the n-th (>= 0). - * @param value new value. + * @param nth the n-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 startPc - * @param end endPc - * @param handler handlerPc - * @param type catchType + * @param index index (>= 0) at which the entry is to be inserted. + * @param start startPc + * @param end endPc + * @param handler handlerPc + * @param type catchType */ 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 startPc - * @param end endPc - * @param handler handlerPc - * @param type catchType + * @param start startPc + * @param end endPc + * @param handler handlerPc + * @param type catchType */ 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); } /** @@ -226,50 +215,50 @@ public class ExceptionTable { * Class names are replaced according to the * given Map 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); + } } } diff --git a/src/main/javassist/bytecode/ExceptionsAttribute.java b/src/main/javassist/bytecode/ExceptionsAttribute.java index db304e71..cde680f6 100644 --- a/src/main/javassist/bytecode/ExceptionsAttribute.java +++ b/src/main/javassist/bytecode/ExceptionsAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,133 +28,133 @@ public class ExceptionsAttribute extends AttributeInfo { 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 Map 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 exception_index_table[]. */ 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 exception_index_table[]. */ 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; } /** @@ -177,7 +166,7 @@ public class ExceptionsAttribute extends AttributeInfo { * Returns the value of exception_index_table[nth]. */ 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); } } diff --git a/src/main/javassist/bytecode/FieldInfo.java b/src/main/javassist/bytecode/FieldInfo.java index d5e3591c..89f2cb2c 100644 --- a/src/main/javassist/bytecode/FieldInfo.java +++ b/src/main/javassist/bytecode/FieldInfo.java @@ -1,28 +1,17 @@ /* - * 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; @@ -42,32 +31,32 @@ public final class FieldInfo { 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 field_info 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); } /** @@ -80,14 +69,14 @@ public final class FieldInfo { * 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); } /** @@ -96,7 +85,7 @@ public final class FieldInfo { * @see AccessFlag */ public int getAccessFlags() { - return accessFlags; + return accessFlags; } /** @@ -105,7 +94,7 @@ public final class FieldInfo { * @see AccessFlag */ public void setAccessFlags(int acc) { - accessFlags = acc; + accessFlags = acc; } /** @@ -114,7 +103,7 @@ public final class FieldInfo { * @see Descriptor */ public String getDescriptor() { - return constPool.getUtf8Info(descriptor); + return constPool.getUtf8Info(descriptor); } /** @@ -123,8 +112,8 @@ public final class FieldInfo { * @see Descriptor */ public void setDescriptor(String desc) { - if (!desc.equals(getDescriptor())) - descriptor = constPool.addUtf8Info(desc); + if (!desc.equals(getDescriptor())) + descriptor = constPool.addUtf8Info(desc); } /** @@ -134,19 +123,19 @@ public final class FieldInfo { * @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); } /** @@ -154,32 +143,32 @@ public final class FieldInfo { * 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); + } } } diff --git a/src/main/javassist/bytecode/InnerClassesAttribute.java b/src/main/javassist/bytecode/InnerClassesAttribute.java index 954a166b..86adf1a9 100644 --- a/src/main/javassist/bytecode/InnerClassesAttribute.java +++ b/src/main/javassist/bytecode/InnerClassesAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,13 +28,13 @@ public class InnerClassesAttribute extends AttributeInfo { 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); } /** @@ -57,70 +46,70 @@ public class InnerClassesAttribute extends AttributeInfo { * Returns classes[nth].inner_class_info_index. */ public int innerClass(int nth) { - return ByteArray.readU16bit(get(), nth * 8 + 2); + return ByteArray.readU16bit(get(), nth * 8 + 2); } /** * Returns classes[nth].outer_class_info_index. */ public int outerClass(int nth) { - return ByteArray.readU16bit(get(), nth * 8 + 4); + return ByteArray.readU16bit(get(), nth * 8 + 4); } /** * Returns classes[nth].inner_name_index. */ public int innerName(int nth) { - return ByteArray.readU16bit(get(), nth * 8 + 6); + return ByteArray.readU16bit(get(), nth * 8 + 6); } /** * Returns classes[nth].inner_class_access_flags. */ 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 Map 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; } } diff --git a/src/main/javassist/bytecode/LineNumberAttribute.java b/src/main/javassist/bytecode/LineNumberAttribute.java index 35f1a020..eb597f84 100644 --- a/src/main/javassist/bytecode/LineNumberAttribute.java +++ b/src/main/javassist/bytecode/LineNumberAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,13 +28,13 @@ public class LineNumberAttribute extends AttributeInfo { 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); } /** @@ -53,7 +42,7 @@ public class LineNumberAttribute extends AttributeInfo { * This represents the number of entries in the table. */ public int tableLength() { - return ByteArray.readU16bit(info, 0); + return ByteArray.readU16bit(info, 0); } /** @@ -61,10 +50,10 @@ public class LineNumberAttribute extends AttributeInfo { * 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); } /** @@ -72,60 +61,60 @@ public class LineNumberAttribute extends AttributeInfo { * 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; } } diff --git a/src/main/javassist/bytecode/LongVector.java b/src/main/javassist/bytecode/LongVector.java index 86ba7938..ff6a4613 100644 --- a/src/main/javassist/bytecode/LongVector.java +++ b/src/main/javassist/bytecode/LongVector.java @@ -1,28 +1,17 @@ /* - * 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 { @@ -31,60 +20,60 @@ 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(", "); + } } */ } diff --git a/src/main/javassist/bytecode/MethodInfo.java b/src/main/javassist/bytecode/MethodInfo.java index 567529a3..1773b9e9 100644 --- a/src/main/javassist/bytecode/MethodInfo.java +++ b/src/main/javassist/bytecode/MethodInfo.java @@ -1,28 +1,17 @@ /* - * 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; @@ -44,7 +33,7 @@ public final class MethodInfo { int accessFlags; int name; int descriptor; - LinkedList attribute; // may be null + LinkedList attribute; // may be null /** * The name of constructors: <init>. @@ -58,29 +47,29 @@ public final class MethodInfo { public static final String nameClinit = ""; private MethodInfo(ConstPool cp) { - constPool = cp; - attribute = null; + constPool = cp; + attribute = null; } /** * Constructs a method_info 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); } /** @@ -92,32 +81,32 @@ public final class MethodInfo { * 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 method_info - * @param classnameMap specifies pairs of replaced and substituted - * name. + * @param cp a constant pool table + * @param methodname a method name + * @param src a source method_info + * @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); } /** @@ -125,8 +114,8 @@ public final class MethodInfo { * (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); } /** @@ -143,7 +132,7 @@ public final class MethodInfo { * Returns true if this is a class initializer (static initializer). */ public boolean isStaticInitializer() { - return getName().equals(nameClinit); + return getName().equals(nameClinit); } /** @@ -152,7 +141,7 @@ public final class MethodInfo { * @see AccessFlag */ public int getAccessFlags() { - return accessFlags; + return accessFlags; } /** @@ -161,7 +150,7 @@ public final class MethodInfo { * @see AccessFlag */ public void setAccessFlags(int acc) { - accessFlags = acc; + accessFlags = acc; } /** @@ -170,7 +159,7 @@ public final class MethodInfo { * @see Descriptor */ public String getDescriptor() { - return constPool.getUtf8Info(descriptor); + return constPool.getUtf8Info(descriptor); } /** @@ -179,8 +168,8 @@ public final class MethodInfo { * @see Descriptor */ public void setDescriptor(String desc) { - if (!desc.equals(getDescriptor())) - descriptor = constPool.addUtf8Info(desc); + if (!desc.equals(getDescriptor())) + descriptor = constPool.addUtf8Info(desc); } /** @@ -190,21 +179,21 @@ public final class MethodInfo { * @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 AttributeInfo object or null. + * @param name attribute name + * @return an AttributeInfo object or null. */ public AttributeInfo getAttribute(String name) { - return AttributeInfo.lookup(attribute, name); + return AttributeInfo.lookup(attribute, name); } /** @@ -212,42 +201,42 @@ public final class MethodInfo { * 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); } /** @@ -257,18 +246,18 @@ public final class MethodInfo { * as this method_info 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); } /** @@ -278,32 +267,32 @@ public final class MethodInfo { * as this method_info 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); } /** @@ -322,68 +311,68 @@ public final class MethodInfo { *

    This method does not perform anything unless this * MethodInfo 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); + } } } diff --git a/src/main/javassist/bytecode/Mnemonic.java b/src/main/javassist/bytecode/Mnemonic.java index 5fa4fd5c..1819ad1f 100644 --- a/src/main/javassist/bytecode/Mnemonic.java +++ b/src/main/javassist/bytecode/Mnemonic.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -45,207 +34,207 @@ public interface Mnemonic { * 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*/ }; } diff --git a/src/main/javassist/bytecode/Opcode.java b/src/main/javassist/bytecode/Opcode.java index e0c21b3c..fd3a7f90 100644 --- a/src/main/javassist/bytecode/Opcode.java +++ b/src/main/javassist/bytecode/Opcode.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -251,207 +240,207 @@ public interface Opcode { /* 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 }; } diff --git a/src/main/javassist/bytecode/SourceFileAttribute.java b/src/main/javassist/bytecode/SourceFileAttribute.java index 22e6f6f9..a8c0d98d 100644 --- a/src/main/javassist/bytecode/SourceFileAttribute.java +++ b/src/main/javassist/bytecode/SourceFileAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,42 +28,42 @@ public class SourceFileAttribute extends AttributeInfo { 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 sourcefile_index. */ 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 Map 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()); } } diff --git a/src/main/javassist/bytecode/SyntheticAttribute.java b/src/main/javassist/bytecode/SyntheticAttribute.java index 63d559ce..2b2b6a66 100644 --- a/src/main/javassist/bytecode/SyntheticAttribute.java +++ b/src/main/javassist/bytecode/SyntheticAttribute.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,28 +28,28 @@ public class SyntheticAttribute extends AttributeInfo { 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); } } diff --git a/src/main/javassist/bytecode/package.html b/src/main/javassist/bytecode/package.html new file mode 100644 index 00000000..9da3888a --- /dev/null +++ b/src/main/javassist/bytecode/package.html @@ -0,0 +1,18 @@ + + +Bytecode-level API. + +

    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. + +

    The users of this package must know the specifications of +class file and Java bytecode. For more details, read this book: + +

      Tim Lindholm and Frank Yellin, +"The Java Virtual Machine Specification 2nd Ed.", +Addison-Wesley, 1999. +
    + + + diff --git a/src/main/javassist/compiler/CodeGen.java b/src/main/javassist/compiler/CodeGen.java index 9a5f6771..d061e320 100644 --- a/src/main/javassist/compiler/CodeGen.java +++ b/src/main/javassist/compiler/CodeGen.java @@ -1,28 +1,17 @@ /* - * 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; @@ -54,34 +43,34 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { /* 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); } /** @@ -89,23 +78,23 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { * 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; } /** @@ -124,76 +113,76 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { * 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(); } @@ -204,353 +193,353 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { 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 >>>=. @@ -558,187 +547,187 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { * 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. @@ -746,94 +735,94 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { * 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. @@ -843,80 +832,80 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { * 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. @@ -924,60 +913,60 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { * 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; @@ -987,244 +976,244 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { 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; @@ -1232,328 +1221,328 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { 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()); + } } } diff --git a/src/main/javassist/compiler/CompileError.java b/src/main/javassist/compiler/CompileError.java index 98b97ef5..43b3c4e6 100644 --- a/src/main/javassist/compiler/CompileError.java +++ b/src/main/javassist/compiler/CompileError.java @@ -1,28 +1,17 @@ /* - * 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 { @@ -30,20 +19,20 @@ 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; } } diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java index 8f15ca81..5546e176 100644 --- a/src/main/javassist/compiler/Javac.java +++ b/src/main/javassist/compiler/Javac.java @@ -1,28 +1,17 @@ /* - * 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; @@ -51,12 +40,12 @@ public class Javac { /** * 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); } /** @@ -64,13 +53,13 @@ public class Javac { * The produced bytecode is stored in the Bytecode object * specified by b. * - * @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; } /** @@ -86,128 +75,128 @@ public class Javac { *

    In a method or constructor body, $0, $1, ... and $_ * are not available. * - * @return a CtMethod, CtConstructor, - * or CtField object. + * @return a CtMethod, CtConstructor, + * or CtField 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()); + } } /** @@ -220,9 +209,9 @@ public class Javac { * isStatic 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); } /** @@ -235,19 +224,19 @@ public class Javac { * compileExpr(). The correct value of * isStatic 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); } /** @@ -258,15 +247,15 @@ public class Javac { *

    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); } /** @@ -274,19 +263,19 @@ public class Javac { * 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); } /** @@ -294,39 +283,39 @@ public class Javac { * 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); } /** @@ -340,12 +329,12 @@ public class Javac { * ($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); // } } @@ -359,9 +348,9 @@ public class Javac { * 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); } /** @@ -374,7 +363,7 @@ public class Javac { * have been invoked. */ public void compileExpr(ASTree e) throws CompileError { - if (e != null) - e.accept(gen); + if (e != null) + e.accept(gen); } } diff --git a/src/main/javassist/compiler/JvstCodeGen.java b/src/main/javassist/compiler/JvstCodeGen.java index 6a365e16..e895bdce 100644 --- a/src/main/javassist/compiler/JvstCodeGen.java +++ b/src/main/javassist/compiler/JvstCodeGen.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -35,157 +24,157 @@ public class JvstCodeGen extends MemberCodeGen { 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); } /** @@ -193,79 +182,79 @@ public class JvstCodeGen extends MemberCodeGen { * 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 - 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, "", - "(" + 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 + 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, "", + "(" + 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: @@ -274,122 +263,122 @@ public class JvstCodeGen extends MemberCodeGen { * : ('.' )* */ 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; + } } */ @@ -397,18 +386,18 @@ public class JvstCodeGen extends MemberCodeGen { * Makes it valid to write "return ;" 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); } /** @@ -418,30 +407,30 @@ public class JvstCodeGen extends MemberCodeGen { *

    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; } /** @@ -450,12 +439,12 @@ public class JvstCodeGen extends MemberCodeGen { * 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); } /** @@ -463,83 +452,83 @@ public class JvstCodeGen extends MemberCodeGen { * $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 @@ -547,105 +536,105 @@ public class JvstCodeGen extends MemberCodeGen { * * 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_ - code.addAnewarray(javaLangObject); // anewarray Object - for (int i = 0; i < n; ++i) { - code.addOpcode(Bytecode.DUP); // dup - code.addIconst(i); // iconst_ - if (params[i].isPrimitive()) { - CtPrimitiveType pt = (CtPrimitiveType)params[i]; - String wrapper = pt.getWrapperName(); - code.addNew(wrapper); // new - code.addOpcode(Bytecode.DUP); // dup - int s = code.addLoad(regno, pt); // ?load - regno += s; - args[0] = pt; - code.addInvokespecial(wrapper, "", - Descriptor.ofMethod(CtClass.voidType, args)); - // invokespecial - } - else { - code.addAload(regno); // aload - ++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_ + code.addAnewarray(javaLangObject); // anewarray Object + for (int i = 0; i < n; ++i) { + code.addOpcode(Bytecode.DUP); // dup + code.addIconst(i); // iconst_ + if (params[i].isPrimitive()) { + CtPrimitiveType pt = (CtPrimitiveType)params[i]; + String wrapper = pt.getWrapperName(); + code.addNew(wrapper); // new + code.addOpcode(Bytecode.DUP); // dup + int s = code.addLoad(regno, pt); // ?load + regno += s; + args[0] = pt; + code.addInvokespecial(wrapper, "", + Descriptor.ofMethod(CtClass.voidType, args)); + // invokespecial + } + else { + code.addAload(regno); // aload + ++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"); } } diff --git a/src/main/javassist/compiler/KeywordTable.java b/src/main/javassist/compiler/KeywordTable.java index 57145bf8..833c9447 100644 --- a/src/main/javassist/compiler/KeywordTable.java +++ b/src/main/javassist/compiler/KeywordTable.java @@ -1,42 +1,31 @@ /* - * 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)); } } diff --git a/src/main/javassist/compiler/Lex.java b/src/main/javassist/compiler/Lex.java index fb188de5..69175dee 100644 --- a/src/main/javassist/compiler/Lex.java +++ b/src/main/javassist/compiler/Lex.java @@ -1,28 +1,17 @@ /* - * 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 { @@ -47,501 +36,501 @@ public class Lex implements TokenId { * 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; + } } } diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index d457a836..c9f18b61 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -1,28 +1,17 @@ /* - * 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; @@ -40,17 +29,17 @@ public class MemberCodeGen extends CodeGen { 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; } @@ -59,449 +48,449 @@ public class MemberCodeGen extends CodeGen { * 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), "", "()V"); + bytecode.addAload(0); + bytecode.addInvokespecial(getSuperclass(thisClass), "", "()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; // - 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; // + 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; @@ -517,391 +506,391 @@ public class MemberCodeGen extends CodeGen { * 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. @@ -910,136 +899,136 @@ public class MemberCodeGen extends CodeGen { * 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('/', '.'); } } diff --git a/src/main/javassist/compiler/NoFieldException.java b/src/main/javassist/compiler/NoFieldException.java index a8102863..0f52311e 100644 --- a/src/main/javassist/compiler/NoFieldException.java +++ b/src/main/javassist/compiler/NoFieldException.java @@ -1,28 +1,17 @@ /* - * 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; @@ -34,9 +23,9 @@ public class NoFieldException extends CompileError { /* 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. diff --git a/src/main/javassist/compiler/Parser.java b/src/main/javassist/compiler/Parser.java index 3039e5d1..1bc50aad 100644 --- a/src/main/javassist/compiler/Parser.java +++ b/src/main/javassist/compiler/Parser.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -31,7 +20,7 @@ public final class Parser implements TokenId { private Lex lex; public Parser(Lex lex) { - this.lex = lex; + this.lex = lex; } public boolean hasMore() { return lex.lookAhead() >= 0; } @@ -40,40 +29,40 @@ public final class Parser implements TokenId { * : 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 @@ -82,22 +71,22 @@ public final class Parser implements TokenId { * [ "=" 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 @@ -111,60 +100,60 @@ public final class Parser implements TokenId { * 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 @@ -173,233 +162,233 @@ public final class Parser implements TokenId { * | 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 "}" @@ -407,732 +396,732 @@ public final class Parser implements TokenId { * 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; } } diff --git a/src/main/javassist/compiler/ProceedHandler.java b/src/main/javassist/compiler/ProceedHandler.java index a787223e..17759d76 100644 --- a/src/main/javassist/compiler/ProceedHandler.java +++ b/src/main/javassist/compiler/ProceedHandler.java @@ -1,28 +1,17 @@ /* - * 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; @@ -36,5 +25,5 @@ import javassist.compiler.ast.ASTList; */ public interface ProceedHandler { void doit(JvstCodeGen gen, Bytecode b, ASTList args) - throws CompileError; + throws CompileError; } diff --git a/src/main/javassist/compiler/SymbolTable.java b/src/main/javassist/compiler/SymbolTable.java index be318811..56134b49 100644 --- a/src/main/javassist/compiler/SymbolTable.java +++ b/src/main/javassist/compiler/SymbolTable.java @@ -1,28 +1,17 @@ /* - * 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; @@ -34,21 +23,21 @@ public final class SymbolTable extends 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); } } diff --git a/src/main/javassist/compiler/SyntaxError.java b/src/main/javassist/compiler/SyntaxError.java index f4c06d8f..cea7b962 100644 --- a/src/main/javassist/compiler/SyntaxError.java +++ b/src/main/javassist/compiler/SyntaxError.java @@ -1,32 +1,21 @@ /* - * 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); } } diff --git a/src/main/javassist/compiler/TokenId.java b/src/main/javassist/compiler/TokenId.java index 8b78bf00..b0cd7acf 100644 --- a/src/main/javassist/compiler/TokenId.java +++ b/src/main/javassist/compiler/TokenId.java @@ -1,28 +1,17 @@ /* - * 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 { @@ -34,7 +23,7 @@ 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; @@ -45,7 +34,7 @@ public interface TokenId { 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; @@ -75,39 +64,39 @@ public interface TokenId { 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; @@ -121,14 +110,14 @@ public interface TokenId { 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; } diff --git a/src/main/javassist/compiler/ast/ASTList.java b/src/main/javassist/compiler/ast/ASTList.java index 887a528a..9364a32d 100644 --- a/src/main/javassist/compiler/ast/ASTList.java +++ b/src/main/javassist/compiler/ast/ASTList.java @@ -1,28 +1,17 @@ /* - * 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; @@ -36,17 +25,17 @@ public class ASTList extends ASTree { 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; } @@ -56,7 +45,7 @@ public class ASTList extends ASTree { public void setLeft(ASTree _left) { left = _left; } public void setRight(ASTree _right) { - right = (ASTList)_right; + right = (ASTList)_right; } /** @@ -65,7 +54,7 @@ public class ASTList extends ASTree { public ASTree head() { return left; } public void setHead(ASTree _head) { - left = _head; + left = _head; } /** @@ -74,60 +63,60 @@ public class ASTList extends ASTree { 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 ? "" : 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 ? "" : 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; } /** @@ -135,35 +124,35 @@ public class ASTList extends ASTree { * 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; + } } } diff --git a/src/main/javassist/compiler/ast/ASTree.java b/src/main/javassist/compiler/ast/ASTree.java index 72825142..85ecaf47 100644 --- a/src/main/javassist/compiler/ast/ASTree.java +++ b/src/main/javassist/compiler/ast/ASTree.java @@ -1,28 +1,17 @@ /* - * 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; @@ -50,11 +39,11 @@ public abstract class ASTree implements 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(); } /** @@ -62,7 +51,7 @@ public abstract class ASTree implements Serializable { * toString(). */ protected String getTag() { - String name = getClass().getName(); - return name.substring(name.lastIndexOf('.') + 1); + String name = getClass().getName(); + return name.substring(name.lastIndexOf('.') + 1); } } diff --git a/src/main/javassist/compiler/ast/AssignExpr.java b/src/main/javassist/compiler/ast/AssignExpr.java index 0a062d46..ec3e59b7 100644 --- a/src/main/javassist/compiler/ast/AssignExpr.java +++ b/src/main/javassist/compiler/ast/AssignExpr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -36,15 +25,15 @@ public class AssignExpr extends Expr { */ 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); } } diff --git a/src/main/javassist/compiler/ast/BinExpr.java b/src/main/javassist/compiler/ast/BinExpr.java index a8fdeb62..57bac5ef 100644 --- a/src/main/javassist/compiler/ast/BinExpr.java +++ b/src/main/javassist/compiler/ast/BinExpr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -37,11 +26,11 @@ public class BinExpr extends Expr { */ 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); } diff --git a/src/main/javassist/compiler/ast/CastExpr.java b/src/main/javassist/compiler/ast/CastExpr.java index 7f8775cb..62fbc61c 100644 --- a/src/main/javassist/compiler/ast/CastExpr.java +++ b/src/main/javassist/compiler/ast/CastExpr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -36,15 +25,15 @@ public class CastExpr extends ASTList implements 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 ... diff --git a/src/main/javassist/compiler/ast/CondExpr.java b/src/main/javassist/compiler/ast/CondExpr.java index d4a8a108..4451edc6 100644 --- a/src/main/javassist/compiler/ast/CondExpr.java +++ b/src/main/javassist/compiler/ast/CondExpr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -32,7 +21,7 @@ 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(); } diff --git a/src/main/javassist/compiler/ast/Declarator.java b/src/main/javassist/compiler/ast/Declarator.java index edeb839d..7361b92e 100644 --- a/src/main/javassist/compiler/ast/Declarator.java +++ b/src/main/javassist/compiler/ast/Declarator.java @@ -1,28 +1,17 @@ /* - * 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; @@ -35,43 +24,43 @@ public class Declarator extends ASTList implements 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, @@ -92,11 +81,11 @@ public class Declarator extends ASTList implements TokenId { 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; } @@ -106,23 +95,23 @@ public class Declarator extends ASTList implements TokenId { 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(); } } diff --git a/src/main/javassist/compiler/ast/DoubleConst.java b/src/main/javassist/compiler/ast/DoubleConst.java index 459f030f..dcd91c58 100644 --- a/src/main/javassist/compiler/ast/DoubleConst.java +++ b/src/main/javassist/compiler/ast/DoubleConst.java @@ -1,28 +1,17 @@ /* - * 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; @@ -45,6 +34,6 @@ public class DoubleConst extends ASTree { public String toString() { return Double.toString(value); } public void accept(Visitor v) throws CompileError { - v.atDoubleConst(this); + v.atDoubleConst(this); } } diff --git a/src/main/javassist/compiler/ast/Expr.java b/src/main/javassist/compiler/ast/Expr.java index 1fecc9ce..0e345ef2 100644 --- a/src/main/javassist/compiler/ast/Expr.java +++ b/src/main/javassist/compiler/ast/Expr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -41,17 +30,17 @@ public class Expr extends ASTList implements 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; } @@ -63,18 +52,18 @@ public class Expr extends ASTList implements TokenId { 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(); } } diff --git a/src/main/javassist/compiler/ast/FieldDecl.java b/src/main/javassist/compiler/ast/FieldDecl.java index d57dd632..481552c0 100644 --- a/src/main/javassist/compiler/ast/FieldDecl.java +++ b/src/main/javassist/compiler/ast/FieldDecl.java @@ -1,35 +1,24 @@ /* - * 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(); } @@ -39,6 +28,6 @@ public class FieldDecl extends ASTList { public ASTree getInit() { return (ASTree)sublist(2).head(); } public void accept(Visitor v) throws CompileError { - v.atFieldDecl(this); + v.atFieldDecl(this); } } diff --git a/src/main/javassist/compiler/ast/InstanceOfExpr.java b/src/main/javassist/compiler/ast/InstanceOfExpr.java index 03d6bc1f..81195065 100644 --- a/src/main/javassist/compiler/ast/InstanceOfExpr.java +++ b/src/main/javassist/compiler/ast/InstanceOfExpr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -32,18 +21,18 @@ 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); } } diff --git a/src/main/javassist/compiler/ast/IntConst.java b/src/main/javassist/compiler/ast/IntConst.java index 63ce70cb..12952c56 100644 --- a/src/main/javassist/compiler/ast/IntConst.java +++ b/src/main/javassist/compiler/ast/IntConst.java @@ -1,28 +1,17 @@ /* - * 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; @@ -45,6 +34,6 @@ public class IntConst extends ASTree { public String toString() { return Long.toString(value); } public void accept(Visitor v) throws CompileError { - v.atIntConst(this); + v.atIntConst(this); } } diff --git a/src/main/javassist/compiler/ast/Keyword.java b/src/main/javassist/compiler/ast/Keyword.java index 9e1798ec..864a2ce4 100644 --- a/src/main/javassist/compiler/ast/Keyword.java +++ b/src/main/javassist/compiler/ast/Keyword.java @@ -1,28 +1,17 @@ /* - * 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; @@ -34,7 +23,7 @@ public class Keyword extends ASTree { protected int tokenId; public Keyword(int token) { - tokenId = token; + tokenId = token; } public int get() { return tokenId; } diff --git a/src/main/javassist/compiler/ast/Member.java b/src/main/javassist/compiler/ast/Member.java index a4825874..fd7e86b9 100644 --- a/src/main/javassist/compiler/ast/Member.java +++ b/src/main/javassist/compiler/ast/Member.java @@ -1,28 +1,17 @@ /* - * 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; @@ -32,7 +21,7 @@ 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); } diff --git a/src/main/javassist/compiler/ast/MethodDecl.java b/src/main/javassist/compiler/ast/MethodDecl.java index 3c529014..b2e601fe 100644 --- a/src/main/javassist/compiler/ast/MethodDecl.java +++ b/src/main/javassist/compiler/ast/MethodDecl.java @@ -1,28 +1,17 @@ /* - * 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; @@ -31,12 +20,12 @@ public class MethodDecl extends ASTList { public static final String initName = ""; 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(); } @@ -50,6 +39,6 @@ public class MethodDecl extends ASTList { public Stmnt getBody() { return (Stmnt)sublist(4).head(); } public void accept(Visitor v) throws CompileError { - v.atMethodDecl(this); + v.atMethodDecl(this); } } diff --git a/src/main/javassist/compiler/ast/NewExpr.java b/src/main/javassist/compiler/ast/NewExpr.java index 33c721ed..bcb360dc 100644 --- a/src/main/javassist/compiler/ast/NewExpr.java +++ b/src/main/javassist/compiler/ast/NewExpr.java @@ -1,28 +1,17 @@ /* - * 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; @@ -36,27 +25,27 @@ public class NewExpr extends ASTList implements 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; } @@ -72,16 +61,16 @@ public class NewExpr extends ASTList implements TokenId { 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"; } } diff --git a/src/main/javassist/compiler/ast/Pair.java b/src/main/javassist/compiler/ast/Pair.java index 520207a8..7e46fe8b 100644 --- a/src/main/javassist/compiler/ast/Pair.java +++ b/src/main/javassist/compiler/ast/Pair.java @@ -1,28 +1,17 @@ /* - * 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; @@ -35,20 +24,20 @@ public class Pair extends ASTree { 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("( "); - sbuf.append(left == null ? "" : left.toString()); - sbuf.append(" . "); - sbuf.append(right == null ? "" : right.toString()); - sbuf.append(')'); - return sbuf.toString(); + StringBuffer sbuf = new StringBuffer(); + sbuf.append("( "); + sbuf.append(left == null ? "" : left.toString()); + sbuf.append(" . "); + sbuf.append(right == null ? "" : right.toString()); + sbuf.append(')'); + return sbuf.toString(); } public ASTree getLeft() { return left; } diff --git a/src/main/javassist/compiler/ast/Stmnt.java b/src/main/javassist/compiler/ast/Stmnt.java index c6b9a97e..b237e659 100644 --- a/src/main/javassist/compiler/ast/Stmnt.java +++ b/src/main/javassist/compiler/ast/Stmnt.java @@ -1,28 +1,17 @@ /* - * 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; @@ -35,25 +24,25 @@ public class Stmnt extends ASTList implements 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); } @@ -61,9 +50,9 @@ public class Stmnt extends ASTList implements TokenId { 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; } } diff --git a/src/main/javassist/compiler/ast/StringL.java b/src/main/javassist/compiler/ast/StringL.java index 5f173f50..5e99e5f0 100644 --- a/src/main/javassist/compiler/ast/StringL.java +++ b/src/main/javassist/compiler/ast/StringL.java @@ -1,28 +1,17 @@ /* - * 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; @@ -34,7 +23,7 @@ public class StringL extends ASTree { protected String text; public StringL(String t) { - text = t; + text = t; } public String get() { return text; } diff --git a/src/main/javassist/compiler/ast/Symbol.java b/src/main/javassist/compiler/ast/Symbol.java index c8e753bf..0d48ab8f 100644 --- a/src/main/javassist/compiler/ast/Symbol.java +++ b/src/main/javassist/compiler/ast/Symbol.java @@ -1,28 +1,17 @@ /* - * 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; @@ -34,7 +23,7 @@ public class Symbol extends ASTree { protected String identifier; public Symbol(String sym) { - identifier = sym; + identifier = sym; } public String get() { return identifier; } diff --git a/src/main/javassist/compiler/ast/Variable.java b/src/main/javassist/compiler/ast/Variable.java index 16112a99..63f9bee6 100644 --- a/src/main/javassist/compiler/ast/Variable.java +++ b/src/main/javassist/compiler/ast/Variable.java @@ -1,28 +1,17 @@ /* - * 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; @@ -34,14 +23,14 @@ public class Variable extends Symbol { 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); } diff --git a/src/main/javassist/compiler/ast/Visitor.java b/src/main/javassist/compiler/ast/Visitor.java index 685713de..e7b4596c 100644 --- a/src/main/javassist/compiler/ast/Visitor.java +++ b/src/main/javassist/compiler/ast/Visitor.java @@ -1,28 +1,17 @@ /* - * 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; diff --git a/src/main/javassist/convert/TransformAfter.java b/src/main/javassist/convert/TransformAfter.java index e9704348..1097f8b1 100644 --- a/src/main/javassist/convert/TransformAfter.java +++ b/src/main/javassist/convert/TransformAfter.java @@ -1,28 +1,17 @@ /* - * 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; @@ -33,24 +22,24 @@ import javassist.CannotCompileException; 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(); } } diff --git a/src/main/javassist/convert/TransformBefore.java b/src/main/javassist/convert/TransformBefore.java index 79deb10f..e0d3fd76 100644 --- a/src/main/javassist/convert/TransformBefore.java +++ b/src/main/javassist/convert/TransformBefore.java @@ -1,28 +1,17 @@ /* - * 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; @@ -38,77 +27,77 @@ public class TransformBefore extends TransformCall { 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; } } diff --git a/src/main/javassist/convert/TransformCall.java b/src/main/javassist/convert/TransformCall.java index 985a8bbb..7b6ca57e 100644 --- a/src/main/javassist/convert/TransformCall.java +++ b/src/main/javassist/convert/TransformCall.java @@ -1,28 +1,17 @@ /* - * 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; @@ -39,20 +28,20 @@ public class TransformCall extends Transformer { 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; } /** @@ -60,37 +49,37 @@ public class TransformCall extends Transformer { * 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; } } diff --git a/src/main/javassist/convert/TransformFieldAccess.java b/src/main/javassist/convert/TransformFieldAccess.java index bce010da..d951a204 100644 --- a/src/main/javassist/convert/TransformFieldAccess.java +++ b/src/main/javassist/convert/TransformFieldAccess.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -42,20 +31,20 @@ final public class TransformFieldAccess extends Transformer { 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; } /** @@ -65,28 +54,28 @@ final public class TransformFieldAccess extends Transformer { * 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; } } diff --git a/src/main/javassist/convert/TransformNew.java b/src/main/javassist/convert/TransformNew.java index a69918d8..6d373370 100644 --- a/src/main/javassist/convert/TransformNew.java +++ b/src/main/javassist/convert/TransformNew.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -34,15 +23,15 @@ final public class TransformNew extends Transformer { 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; } /** @@ -58,45 +47,45 @@ final public class TransformNew extends Transformer { * 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)); } } diff --git a/src/main/javassist/convert/TransformReadField.java b/src/main/javassist/convert/TransformReadField.java index fda192c1..fda3ff2c 100644 --- a/src/main/javassist/convert/TransformReadField.java +++ b/src/main/javassist/convert/TransformReadField.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -40,55 +29,55 @@ public class TransformReadField extends Transformer { 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; } } diff --git a/src/main/javassist/convert/TransformWriteField.java b/src/main/javassist/convert/TransformWriteField.java index 8c37c7fd..5f2a395c 100644 --- a/src/main/javassist/convert/TransformWriteField.java +++ b/src/main/javassist/convert/TransformWriteField.java @@ -1,28 +1,17 @@ /* - * 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; @@ -32,51 +21,51 @@ import javassist.CannotCompileException; 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; } } diff --git a/src/main/javassist/convert/Transformer.java b/src/main/javassist/convert/Transformer.java index f1a4b566..b15c325c 100644 --- a/src/main/javassist/convert/Transformer.java +++ b/src/main/javassist/convert/Transformer.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -39,7 +28,7 @@ public abstract class Transformer implements Opcode { private Transformer next; public Transformer(Transformer t) { - next = t; + next = t; } public Transformer getNext() { return next; } @@ -49,7 +38,7 @@ public abstract class Transformer implements Opcode { 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; } } diff --git a/src/main/javassist/expr/Cast.java b/src/main/javassist/expr/Cast.java index 44648e78..3747abf7 100644 --- a/src/main/javassist/expr/Cast.java +++ b/src/main/javassist/expr/Cast.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -38,7 +27,7 @@ public class Cast extends Expr { * 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); } /** @@ -51,19 +40,19 @@ public class Cast extends Expr { * 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(); } /** @@ -71,11 +60,11 @@ public class Cast extends Expr { * 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()); } /** @@ -85,7 +74,7 @@ public class Cast extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /** @@ -94,69 +83,69 @@ public class Cast extends Expr { * *

    $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 { - 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"); + } } /* $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); + } } } diff --git a/src/main/javassist/expr/Expr.java b/src/main/javassist/expr/Expr.java index d88d7939..f0defd48 100644 --- a/src/main/javassist/expr/Expr.java +++ b/src/main/javassist/expr/Expr.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -46,14 +35,14 @@ abstract class Expr implements Opcode { 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; } @@ -66,20 +55,20 @@ abstract class Expr implements Opcode { * 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"); } /** @@ -89,86 +78,86 @@ abstract class Expr implements Opcode { * 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 @@ -178,46 +167,46 @@ abstract class Expr implements Opcode { * 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(); } } diff --git a/src/main/javassist/expr/ExprEditor.java b/src/main/javassist/expr/ExprEditor.java index c6814ef5..f9508818 100644 --- a/src/main/javassist/expr/ExprEditor.java +++ b/src/main/javassist/expr/ExprEditor.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -83,104 +72,117 @@ public class ExprEditor { 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 new expression (overridable). * The default implementation performs nothing. * - * @param e the new expression creating an object. + * @param e the new expression creating an object. */ public void edit(NewExpr e) throws CannotCompileException {} @@ -208,4 +210,10 @@ public class ExprEditor { * 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 {} } diff --git a/src/main/javassist/expr/FieldAccess.java b/src/main/javassist/expr/FieldAccess.java index a524b07d..75382830 100644 --- a/src/main/javassist/expr/FieldAccess.java +++ b/src/main/javassist/expr/FieldAccess.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -37,9 +26,9 @@ public class FieldAccess extends Expr { 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; } /** @@ -52,75 +41,75 @@ public class FieldAccess extends Expr { * 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()); } /** @@ -130,16 +119,16 @@ public class FieldAccess extends Expr { * 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()); } */ @@ -151,150 +140,150 @@ public class FieldAccess extends Expr { * 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"); + } } /* $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() - * 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(); + } } } diff --git a/src/main/javassist/expr/Instanceof.java b/src/main/javassist/expr/Instanceof.java index 5b980f8e..ce66d977 100644 --- a/src/main/javassist/expr/Instanceof.java +++ b/src/main/javassist/expr/Instanceof.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -38,7 +27,7 @@ public class Instanceof extends Expr { * 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); } /** @@ -51,20 +40,20 @@ public class Instanceof extends Expr { * 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(); } /** @@ -73,11 +62,11 @@ public class Instanceof extends Expr { * 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()); } /** @@ -87,7 +76,7 @@ public class Instanceof extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /** @@ -96,70 +85,70 @@ public class Instanceof extends Expr { * *

    $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 { - 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); + } } } diff --git a/src/main/javassist/expr/MethodCall.java b/src/main/javassist/expr/MethodCall.java index 747380b4..e0801659 100644 --- a/src/main/javassist/expr/MethodCall.java +++ b/src/main/javassist/expr/MethodCall.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -37,19 +26,19 @@ public class MethodCall extends Expr { * 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); } /** @@ -62,19 +51,19 @@ public class MethodCall extends Expr { * 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(); } /** @@ -82,7 +71,7 @@ public class MethodCall extends Expr { * which the method is called on. */ private CtClass getCtClass() throws NotFoundException { - return thisClass.getClassPool().get(getClassName()); + return thisClass.getClassPool().get(getClassName()); } /** @@ -90,41 +79,41 @@ public class MethodCall extends Expr { * 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)); } /** @@ -134,15 +123,15 @@ public class MethodCall extends Expr { * 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()); } */ @@ -150,8 +139,8 @@ public class MethodCall extends Expr { * 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()); } */ @@ -161,60 +150,60 @@ public class MethodCall extends Expr { * *

    $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"); + } } } diff --git a/src/main/javassist/expr/NewExpr.java b/src/main/javassist/expr/NewExpr.java index 73546238..b816867a 100644 --- a/src/main/javassist/expr/NewExpr.java +++ b/src/main/javassist/expr/NewExpr.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -42,23 +31,23 @@ public class NewExpr extends Expr { * 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); } /** @@ -71,43 +60,43 @@ public class NewExpr extends Expr { * Returns the line number of the source line containing the * new 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 new 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); } /** @@ -117,30 +106,30 @@ public class NewExpr extends Expr { * 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"); } /** @@ -149,76 +138,76 @@ public class NewExpr extends Expr { * *

    $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); + } } } diff --git a/src/main/javassist/expr/package.html b/src/main/javassist/expr/package.html new file mode 100644 index 00000000..12a2c637 --- /dev/null +++ b/src/main/javassist/expr/package.html @@ -0,0 +1,8 @@ + + + +

    This package contains the classes for modifying a method body. +See ExprEditor (expression editor) for more details. + + + diff --git a/src/main/javassist/package.html b/src/main/javassist/package.html new file mode 100644 index 00000000..1b6e4b94 --- /dev/null +++ b/src/main/javassist/package.html @@ -0,0 +1,14 @@ + + +The Javassist Core API. + +

    Javassist (Java programming assistant) 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. + +

    The most significant class of this package is CtClass. +See the description of this class first. + + + diff --git a/src/main/javassist/preproc/Assistant.java b/src/main/javassist/preproc/Assistant.java index 60d7c4c2..96b72ffa 100644 --- a/src/main/javassist/preproc/Assistant.java +++ b/src/main/javassist/preproc/Assistant.java @@ -1,28 +1,17 @@ /* - * 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; @@ -52,12 +41,12 @@ public interface Assistant { * } * * - * @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; } diff --git a/src/main/javassist/preproc/Compiler.java b/src/main/javassist/preproc/Compiler.java index 60e6a9d7..c5b76b6b 100644 --- a/src/main/javassist/preproc/Compiler.java +++ b/src/main/javassist/preproc/Compiler.java @@ -1,28 +1,17 @@ /* - * 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; @@ -67,166 +56,166 @@ public class Compiler { /** * Constructs a Compiler 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; } /** @@ -236,75 +225,75 @@ public class Compiler { * import class name by assistant (args1, args2, ...); * * - * @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."); + } } } @@ -313,50 +302,50 @@ class CommentSkipper { 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; + } } } diff --git a/src/main/javassist/preproc/package.html b/src/main/javassist/preproc/package.html new file mode 100644 index 00000000..dee15e02 --- /dev/null +++ b/src/main/javassist/preproc/package.html @@ -0,0 +1,14 @@ + + +A sample preprocessor. + +

    The preprocessor for running Javassist at compile time. +The produced class files are saved on a local disk. + +

    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. + + + diff --git a/src/main/javassist/reflect/CannotCreateException.java b/src/main/javassist/reflect/CannotCreateException.java index 168032fb..d8993b78 100644 --- a/src/main/javassist/reflect/CannotCreateException.java +++ b/src/main/javassist/reflect/CannotCreateException.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -30,10 +19,10 @@ 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()); } } diff --git a/src/main/javassist/reflect/CannotInvokeException.java b/src/main/javassist/reflect/CannotInvokeException.java index 455c3e4d..ec7fdc5b 100644 --- a/src/main/javassist/reflect/CannotInvokeException.java +++ b/src/main/javassist/reflect/CannotInvokeException.java @@ -1,28 +1,17 @@ /* - * 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; @@ -46,30 +35,30 @@ public class CannotInvokeException extends RuntimeException { * 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; } } diff --git a/src/main/javassist/reflect/ClassMetaobject.java b/src/main/javassist/reflect/ClassMetaobject.java index 6c0de555..2e232824 100644 --- a/src/main/javassist/reflect/ClassMetaobject.java +++ b/src/main/javassist/reflect/ClassMetaobject.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -67,91 +56,91 @@ public class ClassMetaobject implements Serializable { /** * Constructs a ClassMetaobject. * - * @param params params[0] is the name of the class - * of the reflective objects. + * @param params params[0] 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 java.lang.Class 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 obj 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"); } /** @@ -162,16 +151,16 @@ public class ClassMetaobject implements Serializable { *

    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()); + } } /** @@ -182,42 +171,42 @@ public class ClassMetaobject implements Serializable { *

    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 * methodPrefix "_m_" 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"); } /** @@ -229,18 +218,18 @@ public class ClassMetaobject implements Serializable { *

    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); + } } /** @@ -248,33 +237,33 @@ public class ClassMetaobject implements Serializable { * 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; } /** @@ -282,15 +271,15 @@ public class ClassMetaobject implements Serializable { * by identifier. */ 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); } /** @@ -299,7 +288,7 @@ public class ClassMetaobject implements Serializable { * by identifier. */ public final Class[] getParameterTypes(int identifier) { - return getReflectiveMethods()[identifier].getParameterTypes(); + return getReflectiveMethods()[identifier].getParameterTypes(); } /** @@ -307,6 +296,6 @@ public class ClassMetaobject implements Serializable { * return type of the method specified by identifier. */ public final Class getReturnType(int identifier) { - return getReflectiveMethods()[identifier].getReturnType(); + return getReflectiveMethods()[identifier].getReturnType(); } } diff --git a/src/main/javassist/reflect/Compiler.java b/src/main/javassist/reflect/Compiler.java index 6e0b854e..6a61d4df 100644 --- a/src/main/javassist/reflect/Compiler.java +++ b/src/main/javassist/reflect/Compiler.java @@ -1,28 +1,17 @@ /* - * 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; @@ -80,90 +69,90 @@ class CompiledClass { 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(" ( [-m ] [-c ])+"); + out.println("Usage: java javassist.reflect.Compiler"); + out.println(" ( [-m ] [-c ])+"); } } diff --git a/src/main/javassist/reflect/Loader.java b/src/main/javassist/reflect/Loader.java index 5287593d..303ffd24 100644 --- a/src/main/javassist/reflect/Loader.java +++ b/src/main/javassist/reflect/Loader.java @@ -1,28 +1,17 @@ /* - * 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; @@ -123,23 +112,23 @@ public class Loader extends javassist.Loader { * Loads a class with an instance of Loader * and calls main() in that class. * - * @param args[0] class name to be loaded. - * @param args[1-n] parameters passed to main(). + * @param args[0] class name to be loaded. + * @param args[1-n] parameters passed to main(). */ 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)); } /** @@ -147,22 +136,22 @@ public class Loader extends javassist.Loader { * 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 - * Metaobject. - * @param metaclass the class of the class metaobject. - * It must be a subclass of - * ClassMetaobject. - * @return false if the class is already reflective. + * @param clazz the reflective class. + * @param metaobject the class of metaobjects. + * It must be a subclass of + * Metaobject. + * @param metaclass the class of the class metaobject. + * It must be a subclass of + * ClassMetaobject. + * @return false 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); } } diff --git a/src/main/javassist/reflect/Metalevel.java b/src/main/javassist/reflect/Metalevel.java index 96e53d52..4a087159 100644 --- a/src/main/javassist/reflect/Metalevel.java +++ b/src/main/javassist/reflect/Metalevel.java @@ -1,28 +1,17 @@ /* - * 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; /** diff --git a/src/main/javassist/reflect/Metaobject.java b/src/main/javassist/reflect/Metaobject.java index 8f1d02bc..7b6276dd 100644 --- a/src/main/javassist/reflect/Metaobject.java +++ b/src/main/javassist/reflect/Metaobject.java @@ -1,28 +1,17 @@ /* - * 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; @@ -55,14 +44,14 @@ public class Metaobject implements Serializable { * 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 - * self. + * @param self the object that this metaobject is associated with. + * @param args the parameters passed to the constructor of + * self. */ public Metaobject(Object self, Object[] args) { - baseobject = (Metalevel)self; - classmetaobject = baseobject._getClass(); - methods = classmetaobject.getReflectiveMethods(); + baseobject = (Metalevel)self; + classmetaobject = baseobject._getClass(); + methods = classmetaobject.getReflectiveMethods(); } /** @@ -71,21 +60,21 @@ public class Metaobject implements Serializable { * 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(); } /** @@ -94,28 +83,28 @@ public class Metaobject implements Serializable { * @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); } /** @@ -124,14 +113,14 @@ public class Metaobject implements Serializable { */ 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); } /** @@ -140,7 +129,7 @@ public class Metaobject implements Serializable { * by identifier. */ public final Class[] getParameterTypes(int identifier) { - return methods[identifier].getParameterTypes(); + return methods[identifier].getParameterTypes(); } /** @@ -148,7 +137,7 @@ public class Metaobject implements Serializable { * return type of the method specified by identifier. */ public final Class getReturnType(int identifier) { - return methods[identifier].getReturnType(); + return methods[identifier].getReturnType(); } /** @@ -159,16 +148,16 @@ public class Metaobject implements Serializable { *

    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()); + } } /** @@ -179,16 +168,16 @@ public class Metaobject implements Serializable { *

    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()); + } } /** @@ -224,16 +213,16 @@ public class Metaobject implements Serializable { * 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); + } } } diff --git a/src/main/javassist/reflect/Reflection.java b/src/main/javassist/reflect/Reflection.java index f76b396e..1629a856 100644 --- a/src/main/javassist/reflect/Reflection.java +++ b/src/main/javassist/reflect/Reflection.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -90,41 +79,41 @@ public class Reflection implements Translator { 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 Reflection 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); + } } /** @@ -132,10 +121,10 @@ public class Reflection implements Translator { * 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); } /** @@ -143,21 +132,21 @@ public class Reflection implements Translator { * 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 false 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 false 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)); } /** @@ -165,24 +154,24 @@ public class Reflection implements Translator { * 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 - * Metaobject. - * @param metaclass the class of the class metaobject. - * It must be a subclass of - * ClassMetaobject. - * @return false if the class is already reflective. + * @param clazz the reflective class. + * @param metaobject the class of metaobjects. + * It must be a subclass of + * Metaobject. + * @param metaclass the class of the class metaobject. + * It must be a subclass of + * ClassMetaobject. + * @return false 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()); } /** @@ -191,24 +180,24 @@ public class Reflection implements Translator { * 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 - * Metaobject. - * @param metaclass the class of the class metaobject. - * It must be a subclass of - * ClassMetaobject. - * @return false if the class is already reflective. + * @param clazz the reflective class. + * @param metaobject the class of metaobjects. + * It must be a subclass of + * Metaobject. + * @param metaclass the class of the class metaobject. + * It must be a subclass of + * ClassMetaobject. + * @return false 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); } /** @@ -216,160 +205,160 @@ public class Reflection implements Translator { * 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); + } + } } } diff --git a/src/main/javassist/reflect/Sample.java b/src/main/javassist/reflect/Sample.java index 0b760de2..66922aa6 100644 --- a/src/main/javassist/reflect/Sample.java +++ b/src/main/javassist/reflect/Sample.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -33,34 +22,34 @@ public class Sample { 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; } } diff --git a/src/main/javassist/reflect/package.html b/src/main/javassist/reflect/package.html new file mode 100644 index 00000000..de344d0c --- /dev/null +++ b/src/main/javassist/reflect/package.html @@ -0,0 +1,33 @@ + + +Runtime Reflection. + +

    This package enables a metaobject to trap method calls and field +accesses on a regular Java object. It provides a class +Reflection, which is a main module for implementing +runtime reflection. +It also provides +a class Loader and Compiler +as utilities for dynamically or statically +translating a regular class into a reflective class. + +

    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. +Metaobject is the root class of the runtime +metaobject and ClassMetaobject is the root class +of the runtime class metaobject. + +

    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. + +

    The most significant class in this package is Reflection. +See the description of this class first. + + + diff --git a/src/main/javassist/rmi/AppletServer.java b/src/main/javassist/rmi/AppletServer.java index 2b8c30e5..8a745842 100644 --- a/src/main/javassist/rmi/AppletServer.java +++ b/src/main/javassist/rmi/AppletServer.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -49,57 +38,57 @@ public class AppletServer extends Webserver { 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(); } /** @@ -108,147 +97,147 @@ public class AppletServer extends Webserver { * 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(); } } diff --git a/src/main/javassist/rmi/ObjectImporter.java b/src/main/javassist/rmi/ObjectImporter.java index 19b6cb4e..56a30cde 100644 --- a/src/main/javassist/rmi/ObjectImporter.java +++ b/src/main/javassist/rmi/ObjectImporter.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -95,12 +84,12 @@ public class ObjectImporter implements java.io.Serializable { *

    Remote objects are imported from the web server that the given * applet has been loaded from. * - * @param applet the applet loaded from the Webserver. + * @param applet the applet loaded from the Webserver. */ 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(); } /** @@ -117,24 +106,24 @@ public class ObjectImporter implements java.io.Serializable { * @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; + } } /** @@ -142,13 +131,13 @@ public class ObjectImporter implements java.io.Serializable { * 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; } /** @@ -156,49 +145,49 @@ public class ObjectImporter implements java.io.Serializable { * 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) }); } /** @@ -209,100 +198,100 @@ public class ObjectImporter implements java.io.Serializable { *

    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]); } } diff --git a/src/main/javassist/rmi/ObjectNotFoundException.java b/src/main/javassist/rmi/ObjectNotFoundException.java index e31db370..10cde1fe 100644 --- a/src/main/javassist/rmi/ObjectNotFoundException.java +++ b/src/main/javassist/rmi/ObjectNotFoundException.java @@ -1,36 +1,25 @@ /* - * 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()); } } diff --git a/src/main/javassist/rmi/Proxy.java b/src/main/javassist/rmi/Proxy.java index f310d358..9e744981 100644 --- a/src/main/javassist/rmi/Proxy.java +++ b/src/main/javassist/rmi/Proxy.java @@ -1,28 +1,17 @@ /* - * 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; /** diff --git a/src/main/javassist/rmi/RemoteException.java b/src/main/javassist/rmi/RemoteException.java index 6b89c64b..ee63b131 100644 --- a/src/main/javassist/rmi/RemoteException.java +++ b/src/main/javassist/rmi/RemoteException.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -31,10 +20,10 @@ 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()); } } diff --git a/src/main/javassist/rmi/RemoteRef.java b/src/main/javassist/rmi/RemoteRef.java index 0017ecc1..5b357580 100644 --- a/src/main/javassist/rmi/RemoteRef.java +++ b/src/main/javassist/rmi/RemoteRef.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -34,12 +23,12 @@ public class RemoteRef implements java.io.Serializable { 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; } } diff --git a/src/main/javassist/rmi/Sample.java b/src/main/javassist/rmi/Sample.java index fee85d27..474236a2 100644 --- a/src/main/javassist/rmi/Sample.java +++ b/src/main/javassist/rmi/Sample.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -35,12 +24,12 @@ public class Sample { 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."); } } diff --git a/src/main/javassist/rmi/StubGenerator.java b/src/main/javassist/rmi/StubGenerator.java index 9e77c383..52f2d493 100644 --- a/src/main/javassist/rmi/StubGenerator.java +++ b/src/main/javassist/rmi/StubGenerator.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -69,7 +58,7 @@ public class StubGenerator implements Translator { * Constructs a stub-code generator. */ public StubGenerator() { - proxyClasses = new Hashtable(); + proxyClasses = new Hashtable(); } /** @@ -78,19 +67,19 @@ public class StubGenerator implements Translator { * @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) {} @@ -99,163 +88,163 @@ public class StubGenerator implements Translator { * Returns true if the specified class is a proxy class * recorded by makeProxyClass(). * - * @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 false if the proxy class - * has been already produced. + * @param clazz the class referenced + * through the proxy class. + * @return false 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)); + } } } diff --git a/src/main/javassist/rmi/package.html b/src/main/javassist/rmi/package.html new file mode 100644 index 00000000..9f613666 --- /dev/null +++ b/src/main/javassist/rmi/package.html @@ -0,0 +1,16 @@ + + +Remote Method Invocation. + +

    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. + +

    The most significant class of this package is +ObjectImporter. +See the description of this class first. + + + diff --git a/src/main/javassist/runtime/Cflow.java b/src/main/javassist/runtime/Cflow.java index 693da245..a9ee36de 100644 --- a/src/main/javassist/runtime/Cflow.java +++ b/src/main/javassist/runtime/Cflow.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -34,15 +23,15 @@ 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(); } /** diff --git a/src/main/javassist/runtime/Desc.java b/src/main/javassist/runtime/Desc.java index 0bf49bf2..588188a5 100644 --- a/src/main/javassist/runtime/Desc.java +++ b/src/main/javassist/runtime/Desc.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -44,13 +33,13 @@ public class Desc { 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); } /** @@ -58,12 +47,12 @@ public class Desc { * It is used for implementing $class. */ 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"); + } } /** @@ -71,10 +60,10 @@ public class Desc { * signature. It is used for implementing $sig. */ 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); } /** @@ -82,86 +71,87 @@ public class Desc { * It is used for implementing $type. */ 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; } } diff --git a/src/main/javassist/runtime/package.html b/src/main/javassist/runtime/package.html new file mode 100644 index 00000000..313648f6 --- /dev/null +++ b/src/main/javassist/runtime/package.html @@ -0,0 +1,12 @@ + + +Runtime support classes required by modified bytecode. + +

    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. + + + diff --git a/src/main/javassist/web/BadHttpRequest.java b/src/main/javassist/web/BadHttpRequest.java index aafebce0..d55e5a9a 100644 --- a/src/main/javassist/web/BadHttpRequest.java +++ b/src/main/javassist/web/BadHttpRequest.java @@ -1,28 +1,17 @@ /* - * 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; /** @@ -36,9 +25,9 @@ public class BadHttpRequest extends Exception { 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(); } } diff --git a/src/main/javassist/web/Viewer.java b/src/main/javassist/web/Viewer.java index ce57c016..f2ad74ec 100644 --- a/src/main/javassist/web/Viewer.java +++ b/src/main/javassist/web/Viewer.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -65,26 +54,26 @@ public class Viewer extends ClassLoader { * 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 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 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; } /** @@ -100,39 +89,39 @@ public class Viewer extends ClassLoader { /** * Invokes main() in the class specified by classname. * - * @param classname executed class - * @param args the arguments passed to main(). + * @param classname executed class + * @param args the arguments passed to main(). */ 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; } /** @@ -146,21 +135,21 @@ public class Viewer extends ClassLoader { * Viewer. */ 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; } /** @@ -169,50 +158,50 @@ public class Viewer extends ClassLoader { */ 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; } } diff --git a/src/main/javassist/web/Webserver.java b/src/main/javassist/web/Webserver.java index 95ad05a2..ffc975ca 100644 --- a/src/main/javassist/web/Webserver.java +++ b/src/main/javassist/web/Webserver.java @@ -1,28 +1,17 @@ /* - * 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.*; @@ -91,32 +80,32 @@ public class Webserver { * 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 "); + if (args.length == 1) { + Webserver web = new Webserver(args[0]); + web.run(); + } + else + System.err.println( + "Usage: java javassist.web.Webserver "); } /** * 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; } /** @@ -124,260 +113,260 @@ public class Webserver { * ClassPool 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("

    Bad Request

    ".getBytes()); + logging2("bad request: " + e.toString()); + out.write("HTTP/1.0 400 Bad Request".getBytes()); + out.write(endofline); + out.write(endofline); + out.write("

    Bad Request

    ".getBytes()); } } @@ -386,15 +375,15 @@ class ServiceThread extends Thread { 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) { + } } } diff --git a/src/main/javassist/web/package.html b/src/main/javassist/web/package.html new file mode 100644 index 00000000..2204efe9 --- /dev/null +++ b/src/main/javassist/web/package.html @@ -0,0 +1,7 @@ + + +Web server. + +

    This package provides a simple web server for other packages. + + diff --git a/tutorial/brown.css b/tutorial/brown.css index b88ddb46..7570549f 100644 --- a/tutorial/brown.css +++ b/tutorial/brown.css @@ -1,19 +1,19 @@ -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; -} +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; +} diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html index 3fac03ee..29fcaec4 100644 --- a/tutorial/tutorial.html +++ b/tutorial/tutorial.html @@ -1,560 +1,588 @@ - - - - Javassist Tutorial - - - - - - -Getting Started with Javassist - - -

    -Shigeru Chiba - - - -

    - - - -


    - - -

    1. Reading bytecode

    - -

    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. - -

    The class Javassist.CtClass is an abstract representation -of a class file. A CtClass object is a handle for dealing -with a class file. The following program is a very simple example: - -

      -ClassPool pool = ClassPool.getDefault();
      -CtClass cc = pool.get("test.Rectangle");
      -cc.setSuperclass(pool.get("test.Point"));
      -pool.writeFile("test.Rectangle");          // or simply, cc.writeFile()
      -
    - -

    This program first obtains a ClassPool object, -which controls bytecode modification with Javassist. -The ClassPool object is a container of CtClass -object representing a class file. -It reads a class file on demand for constructing a CtClass -object and contains the constructed object until it is written out -to a file or an output stream. - -

    To modify the definition of a class, the users must first obtain a -reference to the CtClass object representing that class. -ClassPool.get() is used for this purpose. -In the case of the program above, the CtClass object -representing a class test.Rectangle is obtained from -the ClassPool object -and it is assigned -to a variable cc. Then it is modified so that -the superclass of test.Rectangle is changed into -a class test.Point. -This change is reflected on the original class file when -ClassPool.writeFile() is finally called. - -

    Note that writeFile() is a method declared in not -CtClass but ClassPool. -If this method is called, the ClassPool -finds a CtClass object specified with a class name -among the objects that the ClassPool contains. -Then it translates that CtClass object into a class file -and writes it on a local disk. - -

    There is also writeFile() defined in CtClass. -Thus, the last line in the program above can be rewritten into: - -

      cc.writeFile();
    - -

    This method is a convenient method for invoking writeFile() -in ClassPool with the name of the class represented by -cc. - -

    Javassist also provides a method for directly obtaining the -modified bytecode. To do this, call write(): - -

      -byte[] b = pool.write("test.Rectangle");
      -
    - -

    The contents of the class file for test.Rectangle are -assigned to a variable b in the form of byte array. -writeFile() also internally calls write() -to obtain the byte array written in a class file. - -

    The default ClassPool returned -by a static method ClassPool.getDefault() -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 -/usr/local/javalib -to the search path: - -

      -ClassPool pool = ClassPool.getDefault();
      -pool.insertClassPath("/usr/local/javalib");
      -
    - -

    The search path that the users can add is not only a directory but also -a URL: - -

      -ClassPool pool = ClassPool.getDefault();
      -ClassPath cp = new URLClassPath("www.foo.com", 80, "/java/", "com.foo.");
      -pool.insertClassPath(cp);
      -
    - -

    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 com.foo. - -

    You can directly give a byte array to a ClassPool object -and construct a CtClass object from that array. To do this, -use ByteArrayClassPath. For example, - -

      -ClassPool cp = ClassPool.getDefault();
      -byte[] b = a byte array;
      -String name = class name;
      -cp.insertClassPath(new ByteArrayClassPath(name, b));
      -CtClass cc = cp.get(name);
      -
    - -

    The obtained CtClass object represents -a class defined by the class file specified by b. - - -

    Since ClassPath 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. - -


    - -
    -

    2. Defining a new class

    - -

    To define a new class from scratch, makeClass() -must be called on a ClassPool. - -

      -ClassPool pool = ClassPool.getDefault();
      -CtClass cc = pool.makeClass("Point");
      -
    - -

    This program defines a class Point -including no members. - -

    A new class can be also defined as a copy of an existing class. -The program below does that: - -

      -ClassPool pool = ClassPool.getDefault();
      -CtClass cc = pool.makeClass("Point");
      -cc.setName("Pair");
      -
    - -

    This program first obtains the CtClass object -for class Point. Then it gives a new name Pair -to that CtClass object. -If get("Point") is called on the ClassPool -object, then a class file Point.class is read again and -a new CtClass object for class Point is constructed -again. - -

      -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.
      -
    - -


    - -
    -

    3. Modifying a class at load time

    - -

    If what classes are modified is known in advance, -the easiest way for modifying the classes is as follows: - -

    • 1. Get a CtClass object by calling - ClassPool.get(), -
    • 2. Modify it, and -
    • 3. Call ClassPool.write() or writeFile(). -
    - -

    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 (java.lang.ClassLoader) working with -Javassist must call ClassPool.write() for obtaining -a class file. The users can write an event listener so that it is -notified when the class loader calls ClassPool.write(). -The event-listener class must implement the following interface: - -

      public interface Translator {
      -    public void start(ClassPool pool)
      -        throws NotFoundException, CannotCompileException;
      -    public void onWrite(ClassPool pool, String classname)
      -        throws NotFoundException, CannotCompileException;
      -}
    - -

    The method start() is called when this event listener -is registered to a ClassPool object. -The method onWrite() is called when write() -(or similar methods) is called on the ClassPool object. -The second parameter of onWrite() is the name of the class -to be written out. - -

    Note that start() or onWrite() do not have -to call write() or writeFile(). For example, - -

      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);
      -    }
      -}
    - -

    All the classes written out by write() are made public -just before their definitions are translated into an byte array. - -

    overview
    - -

    The two methods start() and onWrite() -can modify not only a CtClass object specified by -the given classname but also -any CtClass objects contained -in the given ClassPool. -They can call ClassPool.get() for obtaining any -CtClass object. -If a modified CtClass object is not written out immediately, -the modification is recorded until that object is written out. - -

    sequence diagram
    - -

    To register an event listener to a ClassPool, -it must be passed to a constructor of ClassPool. -Only a single event listener can be registered. -If more than one event listeners are needed, multiple -ClassPools should be connected to be a single -stream. For example, - -

      Translator t1 = new MyTranslator();
      -ClassPool c1 = new ClassPool(t1);
      -Translator t2 = new MyAnotherTranslator();
      -ClassPool c2 = new ClassPool(c1, t2);
    - -

    This program connects two ClassPools. -If a class loader calls write() on c2, -the specified class file is first modified by t1 and -then by t2. write() returns the resulting -class file. - -First, onWrite() on t1 is called since -c2 obtains a class file by calling write() -on c1. Then onWrite() on t2 -is called. If onWrite() called on t2 -obtains a CtClass object from c2, that -CtClass object represents the class file that -t1 has modified. - -

    two translators
    - -


    - -
    -

    4. Class loader

    - -

    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. - -


    - -

    4.1 Using javassist.Loader

    - -

    Javassist provides a class loader -javassist.Loader. This class loader uses a -javassist.ClassPool object for reading a class file. - -

    For example, javassist.Loader can be used for loading -a particular class modified with Javassist. - -

      -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();
      -         :
      -  }
      -}
      -
    - -

    This program modifies a class test.Rectangle. The -superclass of test.Rectangle is set to a -test.Point class. Then this program loads the modified -class into the JVM, and creates a new instance of the -test.Rectangle class. - -

    The users can use a javassist.Translator object -for modifying class files. -Suppose that an instance of a class MyTranslator, -which implements -javassist.Translator, performs modification of class files. -To run an application class MyApp with the -MyTranslator object, write a main class: - -

      -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);
      -  }
      -}
      -
    - -

    To run this program, do: - -

      -% java Main arg1 arg2...
      -
    - -

    The class MyApp and the other application classes -are translated by MyTranslator. - -

    Note that application classes like MyApp cannot -access the loader classes such as Main, -MyTranslator and ClassPool because they -are loaded by different loaders. The application classes are loaded -by javassist.Loader whereas the loader classes such as -Main are by the default Java class loader. - -

    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, - -

      class Point {
      -    int x, y;
      -}
      -
      -class Box {
      -    Point base;
      -    Point getBase() { return base; }
      -}
      -
      -class Window {
      -    Point size;
      -    Point getSize() { return size; }
      -}
    - -

    Suppose that a class Box is loaded by a class loader -L1 while a class Window is loaded by a class -loader L2. Then, the obejcts returned by -getBase() and getSize() are not instances of -the same class Point. -getBase() returns an instance of the class Point -loaded by L1 whereas getSize() returns an -instance of Point loaded by L2. The two versions -of the class Point are distinct. They belong to different -name spaces. For more details, see the following paper: - -

      Sheng Liang and Gilad Bracha, -"Dynamic Class Loading in the Java Virtual Machine", -
      ACM OOPSLA'98, pp.36-44, 1998.
    - -

    To avoid this problem, the two class loaders L1 and -L2 must delegate the loading operation of the class -Point to another class loader, L3, which is -a parent class loader of L1 and L2. -delegateLoadingOf() in javassist.Loader -is a method for specifying what classes should be loaded by the -parent loader. - -

    If L1 is the parent class loader of L2, -that is, if L1 loads the class of L2, -then L2 can delegate the loading operation of -Point to L1 for avoiding the problem above. -However, this technique does not work in the case below: - -

      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; }
      -}
    - -

    Since all the classes included in a class definition loaded by -a class loader L1 are also loaded by L1, -the class of the field win in Point is -now the class Window loaded by L1. -Thus size.win = this in getSize() raises -a runtime exception because of type mismatch; the type of -size.win is the class Point loaded by -L1 whereas the type of this is the class -Point loaded by L2. - -


    - -

    4.2 Writing a class loader

    - -

    A simple class loader using Javassist is as follows: - -

      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"); // MyApp.class must be there.
      -    }
      -
      -    /* 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);
      -            // modify the CtClass object here
      -            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();
      -        }
      -    }
      -}
    - -

    The class MyApp is an application program. -To execute this program, first put the class file under the -./class directory, which must not be included -in the class search path. The directory name is specified by -insertClassPath() in the constructor. -You can choose a different name instead of ./class if you want. -Then do as follows: - -

      % java SimpleLoader
    - -

    The class loader loads the class MyApp -(./class/MyApp.class) and calls -MyApp.main() with the command line parameters. -Note that MyApp.class must not be under the directory -that the system class loader searches. Otherwise, the system class -loader, which is the parent loader of SimpleLoader, -loads the class MyApp. - -

    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 -MyApp class in a name space separated from the name space -that the class SimpleLoader belongs to because the two -classes are loaded by different class loaders. -Hence, the -MyApp class cannot directly access the class -SimpleLoader. - -


    - -

    4.3 Modifying a system class

    - -

    The system classes like java.lang.String cannot be -loaded by a class loader other than the system class loader. -Therefore, SimpleLoader or javassist.Loader -shown above cannot modify the system classes at loading time. - -

    If your application needs to do that, the system classes must be -statically modified. For example, the following program -adds a new field hiddenValue to java.lang.String: - -

      ClassPool pool = ClassPool.getDefault();
      -CtClass cc = pool.get("java.lang.String");
      -cc.addField(new CtField(CtClass.intType, "hiddenValue", cc));
      -pool.writeFile("java.lang.String", ".");
    - -

    This program produces a file "./java/lang/String.class". - -

    To run your program MyApp -with this modified String class, do as follows: - -

      -% java -Xbootclasspath/p:. MyApp arg1 arg2...
      -
    - -

    Suppose that the definition of MyApp is as follows: - -

      public class MyApp {
      -    public static void main(String[] args) throws Exception {
      -        System.out.println(String.class.getField("hiddenValue").getName());
      -    }
      -}
    - -

    If the modified String class is correctly loaded, -MyApp prints hiddenValue. - -

    Note: Applications that use this technique for the purpose of -overriding a system class in rt.jar should not be -deployed as doing so would contravene the Java 2 Runtime Environment -binary code license. - -


    - -
    Next page - -


    -Java(TM) is a trademark of Sun Microsystems, Inc.
    -Copyright (C) 2000-2002 by Shigeru Chiba, All rights reserved. - - + + + + Javassist Tutorial + + + + + + +Getting Started with Javassist + + +

    +Shigeru Chiba + + + +

    + + + +


    + + +

    1. Reading bytecode

    + +

    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. + +

    The class Javassist.CtClass is an abstract representation +of a class file. A CtClass object is a handle for dealing +with a class file. The following program is a very simple example: + +

      +ClassPool pool = ClassPool.getDefault();
      +CtClass cc = pool.get("test.Rectangle");
      +cc.setSuperclass(pool.get("test.Point"));
      +pool.writeFile("test.Rectangle");          // or simply, cc.writeFile()
      +
    + +

    This program first obtains a ClassPool object, +which controls bytecode modification with Javassist. +The ClassPool object is a container of CtClass +object representing a class file. +It reads a class file on demand for constructing a CtClass +object and contains the constructed object until it is written out +to a file or an output stream. + +

    The ClassPool object is used to maintain one-to-one +mapping between classes and CtClass objects. Javassist +never allows two distinct CtClass objects to represent +the same class. This is a crucial feature to consistent program +transformaiton. + +

    To modify the definition of a class, the users must first obtain a +reference to the CtClass object representing that class. +ClassPool.get() is used for this purpose. +In the case of the program above, the CtClass object +representing a class test.Rectangle is obtained from +the ClassPool object +and it is assigned +to a variable cc. Then it is modified so that +the superclass of test.Rectangle is changed into +a class test.Point. +This change is reflected on the original class file when +ClassPool.writeFile() is finally called. + +

    Note that writeFile() is a method declared in not +CtClass but ClassPool. +If this method is called, the ClassPool +finds a CtClass object specified with a class name +among the objects that the ClassPool contains. +Then it translates that CtClass object into a class file +and writes it on a local disk. + +

    There is also writeFile() defined in CtClass. +Thus, the last line in the program above can be rewritten into: + +

      cc.writeFile();
    + +

    This method is a convenient method for invoking writeFile() +in ClassPool with the name of the class represented by +cc. + +

    Javassist also provides a method for directly obtaining the +modified bytecode. To do this, call write(): + +

      +byte[] b = pool.write("test.Rectangle");
      +
    + +

    The contents of the class file for test.Rectangle are +assigned to a variable b in the form of byte array. +writeFile() also internally calls write() +to obtain the byte array written in a class file. + +

    The default ClassPool returned +by a static method ClassPool.getDefault() +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 +/usr/local/javalib +to the search path: + +

      +ClassPool pool = ClassPool.getDefault();
      +pool.insertClassPath("/usr/local/javalib");
      +
    + +

    The search path that the users can add is not only a directory but also +a URL: + +

      +ClassPool pool = ClassPool.getDefault();
      +ClassPath cp = new URLClassPath("www.foo.com", 80, "/java/", "com.foo.");
      +pool.insertClassPath(cp);
      +
    + +

    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 com.foo. + +

    You can directly give a byte array to a ClassPool object +and construct a CtClass object from that array. To do this, +use ByteArrayClassPath. For example, + +

      +ClassPool cp = ClassPool.getDefault();
      +byte[] b = a byte array;
      +String name = class name;
      +cp.insertClassPath(new ByteArrayClassPath(name, b));
      +CtClass cc = cp.get(name);
      +
    + +

    The obtained CtClass object represents +a class defined by the class file specified by b. + +

    Since ClassPath 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. + +

    If you want to directly construct a CtClass object +from a class file but you do not know the fully-qualified name +of the class, then +you can use makeClass() in CtClass: + +

      +ClassPool cp = ClassPool.getDefault();
      +InputStream ins = an input stream for reading a class file;
      +CtClass cc = cp.makeClass(ins);
      +
    + +

    makeClass() returns the CtClass object +constructed from the given input stream. You can use +makeClass() for eagerly feeding class files to +the ClassPool object. This might improve performance +if the search path includes a large jar file. Since +the ClassPool object reads a class file on demand, +it might repeatedly search the whole jar file for every class file. +makeClass() can be used for optimizing this search. +The CtClass constructed by makeClass() +is kept in the ClassPool object and the class file is never +read again. + +


    + +
    +

    2. Defining a new class

    + +

    To define a new class from scratch, makeClass() +must be called on a ClassPool. + +

      +ClassPool pool = ClassPool.getDefault();
      +CtClass cc = pool.makeClass("Point");
      +
    + +

    This program defines a class Point +including no members. + +

    A new class can be also defined as a copy of an existing class. +The program below does that: + +

      +ClassPool pool = ClassPool.getDefault();
      +CtClass cc = pool.makeClass("Point");
      +cc.setName("Pair");
      +
    + +

    This program first obtains the CtClass object +for class Point. Then it gives a new name Pair +to that CtClass object. +If get("Point") is called on the ClassPool +object, then a class file Point.class is read again and +a new CtClass object for class Point is constructed +again. + +

      +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.
      +
    + +


    + +
    +

    3. Modifying a class at load time

    + +

    If what classes are modified is known in advance, +the easiest way for modifying the classes is as follows: + +

    • 1. Get a CtClass object by calling + ClassPool.get(), +
    • 2. Modify it, and +
    • 3. Call ClassPool.write() or writeFile(). +
    + +

    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 (java.lang.ClassLoader) working with +Javassist must call ClassPool.write() for obtaining +a class file. The users can write an event listener so that it is +notified when the class loader calls ClassPool.write(). +The event-listener class must implement the following interface: + +

      public interface Translator {
      +    public void start(ClassPool pool)
      +        throws NotFoundException, CannotCompileException;
      +    public void onWrite(ClassPool pool, String classname)
      +        throws NotFoundException, CannotCompileException;
      +}
    + +

    The method start() is called when this event listener +is registered to a ClassPool object. +The method onWrite() is called when write() +(or similar methods) is called on the ClassPool object. +The second parameter of onWrite() is the name of the class +to be written out. + +

    Note that start() or onWrite() do not have +to call write() or writeFile(). For example, + +

      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);
      +    }
      +}
    + +

    All the classes written out by write() are made public +just before their definitions are translated into an byte array. + +

    overview
    + +

    The two methods start() and onWrite() +can modify not only a CtClass object specified by +the given classname but also +any CtClass objects contained +in the given ClassPool. +They can call ClassPool.get() for obtaining any +CtClass object. +If a modified CtClass object is not written out immediately, +the modification is recorded until that object is written out. + +

    sequence diagram
    + +

    To register an event listener to a ClassPool, +it must be passed to a constructor of ClassPool. +Only a single event listener can be registered. +If more than one event listeners are needed, multiple +ClassPools should be connected to be a single +stream. For example, + +

      Translator t1 = new MyTranslator();
      +ClassPool c1 = new ClassPool(t1);
      +Translator t2 = new MyAnotherTranslator();
      +ClassPool c2 = new ClassPool(c1, t2);
    + +

    This program connects two ClassPools. +If a class loader calls write() on c2, +the specified class file is first modified by t1 and +then by t2. write() returns the resulting +class file. + +First, onWrite() on t1 is called since +c2 obtains a class file by calling write() +on c1. Then onWrite() on t2 +is called. If onWrite() called on t2 +obtains a CtClass object from c2, that +CtClass object represents the class file that +t1 has modified. + +

    two translators
    + +


    + +
    +

    4. Class loader

    + +

    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. + +


    + +

    4.1 Using javassist.Loader

    + +

    Javassist provides a class loader +javassist.Loader. This class loader uses a +javassist.ClassPool object for reading a class file. + +

    For example, javassist.Loader can be used for loading +a particular class modified with Javassist. + +

      +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();
      +         :
      +  }
      +}
      +
    + +

    This program modifies a class test.Rectangle. The +superclass of test.Rectangle is set to a +test.Point class. Then this program loads the modified +class into the JVM, and creates a new instance of the +test.Rectangle class. + +

    The users can use a javassist.Translator object +for modifying class files. +Suppose that an instance of a class MyTranslator, +which implements +javassist.Translator, performs modification of class files. +To run an application class MyApp with the +MyTranslator object, write a main class: + +

      +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);
      +  }
      +}
      +
    + +

    To run this program, do: + +

      +% java Main arg1 arg2...
      +
    + +

    The class MyApp and the other application classes +are translated by MyTranslator. + +

    Note that application classes like MyApp cannot +access the loader classes such as Main, +MyTranslator and ClassPool because they +are loaded by different loaders. The application classes are loaded +by javassist.Loader whereas the loader classes such as +Main are by the default Java class loader. + +

    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, + +

      class Point {
      +    int x, y;
      +}
      +
      +class Box {
      +    Point base;
      +    Point getBase() { return base; }
      +}
      +
      +class Window {
      +    Point size;
      +    Point getSize() { return size; }
      +}
    + +

    Suppose that a class Box is loaded by a class loader +L1 while a class Window is loaded by a class +loader L2. Then, the obejcts returned by +getBase() and getSize() are not instances of +the same class Point. +getBase() returns an instance of the class Point +loaded by L1 whereas getSize() returns an +instance of Point loaded by L2. The two versions +of the class Point are distinct. They belong to different +name spaces. For more details, see the following paper: + +

      Sheng Liang and Gilad Bracha, +"Dynamic Class Loading in the Java Virtual Machine", +
      ACM OOPSLA'98, pp.36-44, 1998.
    + +

    To avoid this problem, the two class loaders L1 and +L2 must delegate the loading operation of the class +Point to another class loader, L3, which is +a parent class loader of L1 and L2. +delegateLoadingOf() in javassist.Loader +is a method for specifying what classes should be loaded by the +parent loader. + +

    If L1 is the parent class loader of L2, +that is, if L1 loads the class of L2, +then L2 can delegate the loading operation of +Point to L1 for avoiding the problem above. +However, this technique does not work in the case below: + +

      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; }
      +}
    + +

    Since all the classes included in a class definition loaded by +a class loader L1 are also loaded by L1, +the class of the field win in Point is +now the class Window loaded by L1. +Thus size.win = this in getSize() raises +a runtime exception because of type mismatch; the type of +size.win is the class Point loaded by +L1 whereas the type of this is the class +Point loaded by L2. + +


    + +

    4.2 Writing a class loader

    + +

    A simple class loader using Javassist is as follows: + +

      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"); // MyApp.class must be there.
      +    }
      +
      +    /* 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);
      +            // modify the CtClass object here
      +            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();
      +        }
      +    }
      +}
    + +

    The class MyApp is an application program. +To execute this program, first put the class file under the +./class directory, which must not be included +in the class search path. The directory name is specified by +insertClassPath() in the constructor. +You can choose a different name instead of ./class if you want. +Then do as follows: + +

      % java SimpleLoader
    + +

    The class loader loads the class MyApp +(./class/MyApp.class) and calls +MyApp.main() with the command line parameters. +Note that MyApp.class must not be under the directory +that the system class loader searches. Otherwise, the system class +loader, which is the parent loader of SimpleLoader, +loads the class MyApp. + +

    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 +MyApp class in a name space separated from the name space +that the class SimpleLoader belongs to because the two +classes are loaded by different class loaders. +Hence, the +MyApp class cannot directly access the class +SimpleLoader. + +


    + +

    4.3 Modifying a system class

    + +

    The system classes like java.lang.String cannot be +loaded by a class loader other than the system class loader. +Therefore, SimpleLoader or javassist.Loader +shown above cannot modify the system classes at loading time. + +

    If your application needs to do that, the system classes must be +statically modified. For example, the following program +adds a new field hiddenValue to java.lang.String: + +

      ClassPool pool = ClassPool.getDefault();
      +CtClass cc = pool.get("java.lang.String");
      +cc.addField(new CtField(CtClass.intType, "hiddenValue", cc));
      +pool.writeFile("java.lang.String", ".");
    + +

    This program produces a file "./java/lang/String.class". + +

    To run your program MyApp +with this modified String class, do as follows: + +

      +% java -Xbootclasspath/p:. MyApp arg1 arg2...
      +
    + +

    Suppose that the definition of MyApp is as follows: + +

      public class MyApp {
      +    public static void main(String[] args) throws Exception {
      +        System.out.println(String.class.getField("hiddenValue").getName());
      +    }
      +}
    + +

    If the modified String class is correctly loaded, +MyApp prints hiddenValue. + +

    Note: Applications that use this technique for the purpose of +overriding a system class in rt.jar should not be +deployed as doing so would contravene the Java 2 Runtime Environment +binary code license. + +


    + +
    Next page + +


    +Java(TM) is a trademark of Sun Microsystems, Inc.
    +Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved. + + diff --git a/tutorial/tutorial2.html b/tutorial/tutorial2.html index b76996ce..6287f1ee 100644 --- a/tutorial/tutorial2.html +++ b/tutorial/tutorial2.html @@ -1,1069 +1,1119 @@ - - - - Javassist Tutorial - - - - - -
    Getting Started with Javassist
    - - - - -

    5. Introspection and customization

    - -

    CtClass provides methods for introspection. The -introspective ability of Javassist is compatible with that of -the Java reflection API. CtClass provides -getName(), getSuperclass(), -getMethods(), and so on. -CtClass 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. - -


    - -
      -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 -setName() -and setModifiers() declared in CtMethod. - -

      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 int -parameter newZ to a method: - -

        void move(int newX, int newY) { x = newX; y = newY; }
      - -

      in a Point class, then you should add the following -method to the Point class: - -

        void move(int newX, int newY, int newZ) {
        -    // do what you want with newZ.
        -    move(newX, newY);
        -}
      - -
    - -


    - -

    Javassist also provides low-level API for directly editing a raw -class file. For example, getClassFile() in -CtClass returns a ClassFile object -representing a raw class file. getMethodInfo() in -CtMethod returns a MethodInfo object -representing a method_info 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 -javassist.bytecode package. - -


    - -

    5.1 Inserting source text at the beginning/end of a method body

    - -

    CtMethod and CtConstructor provide -methods insertBefore(), insertAfter(), and -addCatch(). They are used for inserting a code fragment -into the body of an existing method. The users can specify those code -fragments with source text 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. - -

    The methods insertBefore(), insertAfter(), and -addCatch() receives a String object representing -a statement or a block. A statement is a single control structure like -if and while or an expression ending with -a semi colon (;). A block is a set of -statements surrounded with braces {}. -Hence each of the following lines is an example of valid statement or block: - -

      System.out.println("Hello");
      -{ System.out.println("Hello"); }
      -if (i < 0) { i = -i; }
      -
    - -

    The statement and the block can refer to fields and methods. -However, they cannot refer to local variables declared in the -method that they are inserted into. -They can refer to the parameters -to the method although they must use different names -$0, $1, $2, ... described -below. Declaring a local variable in the block is allowed. - - - -

    The String object passed to the methods -insertBefore(), insertAfter(), and -addCatch() are compiled by -the compiler included in Javassist. -Since the compiler supports language extensions, -several identifiers starting with $ -have special meaning: - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $0, $1, $2, ...    Actual parameters
      $argsAn array of parameters. -The type of $args is Object[]. -
      $$All actual parameters.
      -For example, m($$) is equivalent to -m($1,$2,...)
       
      $cflow(...)cflow variable
      $rThe result type. It is used in a cast expression.
      $wThe wrapper type. It is used in a cast expression.
      $_The resulting value
      $sigAn array of java.lang.Class objects representing -the formal parameter types. -
      $typeA java.lang.Class object representing -the formal result type.
      $classA java.lang.Class object representing -the class currently edited.
      -
    - -

    $0, $1, $2, ...

    - -

    The parameters passed to the methods insertBefore(), -insertAfter(), and addCatch() -are accessible with -$0, $1, $2, ... instead of -the original parameter names. -$1 represents the -first parameter, $2 represents the second parameter, and -so on. The types of those variables are identical to the parameter -types. -$0 is -equivalent to this. If the method is static, -$0 is not available. - -

    These variables are used as following. Suppose that a class -Point: - -

      class Point { - int x, y; - void move(int dx, int dy) { x += dx; y += dy; } -} -
    - -

    To print the values of dx and dy -whenever the method move() is called, execute this -program: - -

      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();
      -
    - -

    Note that the source text passed to insertBefore() is -surrounded with braces {}. -insertBefore() accepts only a single statement or a block -surrounded with braces. - -

    The definition of the class Point after the -modification is like this: - -

      class Point { - int x, y; - void move(int dx, int dy) { - { System.out.println(dx); System.out.println(dy); } - x += dx; y += dy; - } -} -
    - -

    $1 and $2 are replaced with -dx and dy, respectively. - -

    $1, $2, $3 ... 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. - - -

    $args

    - -

    The variable $args represents an array of all the -parameters. The type of that variable is an array of class -Object. If a parameter type is a primitive type such as -int, then the parameter value is converted into a wrapper -object such as java.lang.Integer to store in -$args. Thus, $args[0] is equivalent to -$1 unless the type of the first parameter is a primitive -type. Note that $args[0] is not equivalent to -$0; $0 represents this. - -

    If an array of Object is assigned to -$args, 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. - -

    $$

    - -

    The variable $$ is abbreviation of a list of -all the parameters separated by commas. -For example, if the number of the parameters -to method move() is three, then - -

      move($$)
    - -

    is equivalent to this: - -

      move($1, $2, $3)
    - -

    If move() does not take any parameters, -then move($$) is -equivalent to move(). - -

    $$ can be used with another method. -If you write an expression: - -

      exMove($$, context)
    - -

    then this expression is equivalent to: - -

      exMove($1, $2, $3, context)
    - -

    Note that $$ enables generic notation of method call -with respect to the number of parameters. -It is typically used with $proceed shown later. - -

    $cflow

    - -

    $cflow means "control flow". -This read-only variable returns the depth of the recursive calls -to a specific method. - -

    Suppose that the method shown below is represented by a -CtMethod object cm: - -

      int fact(int n) {
      -    if (n <= 1)
      -        return n;
      -    else
      -        return n * fact(n - 1);
      -}
    - -

    To use $cflow, first declare that $cflow -is used for monitoring calls to the method fact(): - -

      CtMethod cm = ...;
      -cm.useCflow("fact");
    - -

    The parameter to useCflow() is the identifier of the -declared $cflow variable. Any valid Java name can be -used as the identifier. Since the identifier can also include -. (dot), for example, "my.Test.fact" -is a valid identifier. - -

    Then, $cflow(fact) represents the depth of the -recursive calls to the method specified by cm. The value -of $cflow(fact) is 0 (zero) when the method is -first called whereas it is 1 when the method is recursively called -within the method. For example, - -

      -cm.insertBefore("if ($cflow(fact) == 0)"
      -              + "    System.out.println(\"fact \" + $1);");
      -
    - -

    translates the method fact() so that it shows the -parameter. Since the value of $cflow(fact) is checked, -the method fact() does not show the parameter if it is -recursively called within fact(). - -

    The value of $cflow is the number of stack frames -associated with the specified method cm -under the current topmost -stack frame for the current thread. $cflow is also -accessible within a method different from the specified method -cm. - -

    $r

    - -

    $r 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: - -

      Object result = ... ;
      -$_ = ($r)result;
    - -

    If the result type is a primitive type, then ($r) -converts from the wrapper type to the primitive type. -For example, if the result type is int, then -($r) converts from java.lang.Integer to -int. - -

    If the result type is void, then -($r) does not convert a type; it does nothing. -Moreover, the soruce text can include a return -statement with a resulting value: - -

      return ($r)result;
    - -

    Here, result is some local variable. -Since ($r) is specified, the resulting value is -discarded. -This return statement is regarded as the equivalent -of the return statement without a resulting value: - -

      return;
    - -

    $w

    - -

    $w represents a wrapper type. -It must be used as the cast type in a cast expression. -($w) converts from a primitive type to the corresponding -wrapper type. - -The following code is an example: - -

      Integer i = ($w)5;
    - -

    The selected wrapper type depends on the type of the expression -following ($w). If the type of the expression is -double, then the wrapper type is java.lang.Double. - -

    If the type of the expression following ($w) is not -a primitive type, then ($w) does nothing. - -

    $_

    - -

    insertAfter() in CtMethod and -CtConstructor inserts the -compiled code at the end of the method. In the statement given to -insertAfter(), not only the variables shown above such as -$0, $1, ... but also $_ is -available. - -

    The variable $_ 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 void, -then the type of $_ is Object and the value -of $_ is null. - -

    Although the compiled code inserted by insertAfter() -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 -asFinally to insertAfter() must be -true. - -

    If an exception is thrown, the compiled code inserted by -insertAfter() is executed as a finally -clause. The value of $_ is 0 or -null 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 $_ is never thrown -to the caller; it is rather discarded. - -

    $sig

    - -

    The value of $sig is an array of -java.lang.Class objects that represent the formal -parameter types in declaration order. - -

    $type

    - -

    The value of $type is an java.lang.Class -object representing the formal type of the result value. This -variable is available only in insertAfter() in -CtMethod and CtConstructor. - -

    $class

    - -

    The value of $class is an java.lang.Class -object representing the class in which the edited method is declared. - -

    addCatch()

    - -

    addCatch() 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 name specified by the third parameter to -addCatch(). - -

    For example, this program: - -

      -CtMethod m = ...;
      -CtClass etype = ClassPool.getDefault().get("java.io.IOException");
      -m.addCatch("{ System.out.println(e); throw e; }", etype, "e");
      -
    - -

    translates the method body represented by m into -something like this: - -

      -try {
      -    the original method body
      -}
      -catch (java.io.IOException e) {
      -    System.out.println(e);
      -    throw e;
      -}
      -
    - -

    Note that the inserted code fragment must end with a -throw or return statement. - -


    - -

    5.2 Modifying a method body

    - -

    javassist.expr.ExprEditor is a class -for replacing an expression in a method body. -The users can define a subclass of ExprEditor -to specify how an expression is modified. - -

    To run an ExprEditor object, the users must -call instrument() in CtMethod or -CtClass. - -For example, - -

      -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($$); }");
      -        }
      -    });
      -
    - -

    searches the method body represented by cm and -replaces all calls to move() in class Point -with a block: - -

      { $1 = 0; $_ = $proceed($$); }
      -
    - -

    so that the first parameter to move() is always 0. -Note that the substituted code is not an expression but -a statement or a block. - -

    The method instrument() searches a method body. -If it finds an expression such as a method call, field access, and object -creation, then it calls edit() on the given -ExprEditor object. The parameter to edit() -is an object representing the found expression. The edit() -method can inspect and replace the expression through that object. - -

    Calling replace() on the parameter to edit() -substitutes the given statement or block for the expression. If the given -block is an empty block, that is, if replace("{}") -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 -replace(): - -

      -{ before-statements;
      -  $_ = $proceed($$);
      -  after-statements; }
      -
    - -

    whichever the expression is either a method call, field access, -object creation, or others. The second statement could be: - -

      $_ = $proceed();
    - -

    if the expression is read access, or - -

      $proceed($$);
    - -

    if the expression is write access. - -

    javassist.expr.MethodCall

    - -

    A MethodCall object represents a method call. -The method replace() in -MethodCall 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 $ -have special meaning as in the source text passed to -insertBefore(). - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $0 -The target object of the method call.
      -This is not equivalent to this, which represents -the caller-side this object.
      -$0 is null if the method is static. -
       
       
      $1, $2, ...     -The parameters of the method call. -
      -$_The resulting value of the method call.
      $rThe result type of the method call.
      $class    A java.lang.Class object representing -the class declaring the method. -
      $sig    An array of java.lang.Class objects representing -the formal parameter types.
      $type    A java.lang.Class object representing -the formal result type.
      $proceed    The name of the method originally called -in the expression.
      -
    - -

    Here the method call means the one represented by the -MethodCall object. - -

    The other identifiers such as $w, -$args and $$ -are also available. - -

    Unless the result type of the method call is void, -a value must be assigned to -$_ in the source text and the type of $_ -is the result type. -If the result type is void, the type of $_ -is Object and the value assigned to $_ -is ignored. - -

    $proceed is not a String value but special -syntax. It must be followed by an argument list surrounded by parentheses -( ). - -

    javassist.expr.FieldAccess

    - -

    A FieldAccess object represents field access. -The method edit() in ExprEditor -receive this object if field access is found. -The method replace() in -FieldAccess receives -source text representing the substitued statement or -block for the field access. - -In the source text, the identifiers starting with $ -have also special meaning: - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $0 -The object containing the field accessed by the expression. -This is not equivalent to this.
      -this represents the object that the method including the -expression is invoked on.
      -$0 is null if the field is static. -
       
       
      $1 -The value that would be stored in the field -if the expression is write access. -
      Otherwise, $1 is not available. -
       
      $_ -The resulting value of the field access -if the expression is read access. -
      Otherwise, the value stored in $_ is discarded. -
       
      $r -The type of the field if the expression is read access. -
      Otherwise, $r is void. -
       
      $class    A java.lang.Class object representing -the class declaring the field. -
      $typeA java.lang.Class object representing -the field type.
      $proceed    The name of a virtual method executing the original -field access. -.
      -
    - -

    The other identifiers such as $w, -$args and $$ -are also available. - -

    If the expression is read access, a value must be assigned to -$_ in the source text. The type of $_ -is the type of the field. - -

    javassist.expr.NewExpr

    - -

    A NewExpr object represents object creation -with the new operator. -The method edit() in ExprEditor -receive this object if object creation is found. -The method replace() in -NewExpr receives -source text representing the substitued statement or -block for the object creation. - -In the source text, the identifiers starting with $ -have also special meaning: - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $0 -null. -
      $1, $2, ...     -The parameters to the constructor. -
      $_ -The resulting value of the object creation. -
      A newly created object must be stored in this variable. -
       
      $r -The type of the created object. -
      $class    A java.lang.Class object representing -the class of the created object. -
      $sig    An array of java.lang.Class objects representing -the formal parameter types.
      $proceed    The name of a virtual method executing the original -object creation. -.
      -
    - -

    The other identifiers such as $w, -$args and $$ -are also available. - -

    javassist.expr.Instanceof

    - -

    A Instanceof object represents an instanceof -expression. -The method edit() in ExprEditor -receive this object if an instanceof expression is found. -The method replace() in -Instanceof receives -source text representing the substitued statement or -block for the expression. - -In the source text, the identifiers starting with $ -have also special meaning: - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $0 -null. -
      $1 -The value on the left hand side of the original -instanceof operator. -
      $_ -The resulting value of the expression. -The type of $_ is boolean. -
      $r -The type on the right hand side of the instanceof operator. -
      $typeA java.lang.Class object representing -the type on the right hand side of the instanceof operator. -
      $proceed    The name of a virtual method executing the original -instanceof expression. -
      It takes one parameter (the type is java.lang.Object) -and returns true -
      if the parameter value is an instance of the type on the right -hand side of -
      the original instanceof operator. -Otherwise, it returns false. -
       
       
       
      -
    - -

    The other identifiers such as $w, -$args and $$ -are also available. - -

    javassist.expr.Cast

    - -

    A Cast object represents an expression for -explicit type casting. -The method edit() in ExprEditor -receive this object if explicit type casting is found. -The method replace() in -Cast receives -source text representing the substitued statement or -block for the expression. - -In the source text, the identifiers starting with $ -have also special meaning: - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $0 -null. -
      $1 -The value the type of which is explicitly cast. -
      $_ -The resulting value of the expression. -The type of $_ is the same as the type -
      after the explicit casting, that is, the type surrounded -by ( ). -
       
      $rthe type after the explicit casting, or the type surrounded -by ( ). -
      $typeA java.lang.Class object representing -the same type as $r. -
      $proceed    The name of a virtual method executing the original -type casting. -
      It takes one parameter of the type java.lang.Object -and returns it after -
      the explicit type casting specified by the original expression. - -
       
       
      -
    - -

    The other identifiers such as $w, -$args and $$ -are also available. - -


    - -

    5.3 Adding a new method or field

    - -

    Javassist allows the users to create a new method and constructor -from scratch. CtNewMethod -and CtNewConstructor provide several factory methods, -which are static methods for creating CtMethod or -CtConstructor objects. -Especially, make() creates -a CtMethod or CtConstructor object -from the given source text. - -

    For example, this program: - -

      -CtClass point = ClassPool.getDefault().get("Point");
      -CtMethod m = CtNewMethod.make(
      -                 "public int xmove(int dx) { x += dx; }",
      -                 point);
      -point.addMethod(m);
      -
    - -

    adds a public method xmove() to class Point. -In this example, x is a int field in -the class Point. - -

    The source text passed to make() can refer to -$proceed if the target object and the target method name -are also given to make(). For example, - -

      -CtClass point = ClassPool.getDefault().get("Point");
      -CtMethod m = CtNewMethod.make(
      -                 "public int ymove(int dy) { $proceed(0, dy); }",
      -                 point, "this", "move");
      -
    - -

    this program creates a method ymove() defined below: - -

      -public int ymove(int dy) { this.move(0, dy); }
      -
    - -

    Note that $proceed has been replaced with -this.move. - -

    Javassist also allows the users to create a new field. - -

      -CtClass point = ClassPool.getDefault().get("Point");
      -CtField f = new CtField(CtClass.intType, "z", point);
      -point.addField(f);
      -
    - -

    This program adds a field named z to class -Point. - -

    If the initial value of the added field must be specified, -the program shown above must be modified into: - -

      -CtClass point = ClassPool.getDefault().get("Point");
      -CtField f = new CtField(CtClass.intType, "z", point);
      -point.addField(f, "0");    // initial value is 0.
      -
    - -

    Now, the method addField() 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 (;). - -


    - -

    5.4 Limitations

    - -

    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: - -

  • The .class notation is not supported. Use the -method Class.forName(). -In regular -Java, an expression Point.class means a Class -object representing the Point class. This notation is -not available. - -

  • Array initializers, a comma-separated list of expressions -enclosed by braces { and }, are not -supported. - -

  • Inner classes or anonymous classes are not supported. - -

  • switch statements are not supported yet. - -

  • Labeled continue and break statements -are not supported. - -

  • The finally clause following -try and catch clauses is not supported. - -

  • 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. - -

  • The users are recommended to use # as the separator -between a class name and a static method or field name. -For example, in regular Java, - -
      javassist.CtClass.intType.getName()
    - -

    calls a method getName() on -the object indicated by the static field intType -in javassist.CtClass. In Javassist, the users can -write the expression shown above but they are recommended to -write: - -

      javassist.CtClass#intType.getName()
    - -

    so that the compiler can quickly parse the expression. - - -


    - -
    Previous page - -


    -Java(TM) is a trademark of Sun Microsystems, Inc.
    -Copyright (C) 2000-2002 by Shigeru Chiba, All rights reserved. - - + + + + Javassist Tutorial + + + + + +
    Getting Started with Javassist
    + + + + +

    5. Introspection and customization

    + +

    CtClass provides methods for introspection. The +introspective ability of Javassist is compatible with that of +the Java reflection API. CtClass provides +getName(), getSuperclass(), +getMethods(), and so on. +CtClass 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. + +


    + +
      +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 +setName() +and setModifiers() declared in CtMethod. + +

      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 int +parameter newZ to a method: + +

        void move(int newX, int newY) { x = newX; y = newY; }
      + +

      in a Point class, then you should add the following +method to the Point class: + +

        void move(int newX, int newY, int newZ) {
        +    // do what you want with newZ.
        +    move(newX, newY);
        +}
      + +
    + +


    + +

    Javassist also provides low-level API for directly editing a raw +class file. For example, getClassFile() in +CtClass returns a ClassFile object +representing a raw class file. getMethodInfo() in +CtMethod returns a MethodInfo object +representing a method_info 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 +javassist.bytecode package. + +


    + +

    5.1 Inserting source text at the beginning/end of a method body

    + +

    CtMethod and CtConstructor provide +methods insertBefore(), insertAfter(), and +addCatch(). They are used for inserting a code fragment +into the body of an existing method. The users can specify those code +fragments with source text 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. + +

    The methods insertBefore(), insertAfter(), and +addCatch() receives a String object representing +a statement or a block. A statement is a single control structure like +if and while or an expression ending with +a semi colon (;). A block is a set of +statements surrounded with braces {}. +Hence each of the following lines is an example of valid statement or block: + +

      System.out.println("Hello");
      +{ System.out.println("Hello"); }
      +if (i < 0) { i = -i; }
      +
    + +

    The statement and the block can refer to fields and methods. +However, they cannot refer to local variables declared in the +method that they are inserted into. +They can refer to the parameters +to the method although they must use different names +$0, $1, $2, ... described +below. Declaring a local variable in the block is allowed. + + + +

    The String object passed to the methods +insertBefore(), insertAfter(), and +addCatch() are compiled by +the compiler included in Javassist. +Since the compiler supports language extensions, +several identifiers starting with $ +have special meaning: + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      $0, $1, $2, ...    Actual parameters
      $argsAn array of parameters. +The type of $args is Object[]. +
      $$All actual parameters.
      +For example, m($$) is equivalent to +m($1,$2,...)
       
      $cflow(...)cflow variable
      $rThe result type. It is used in a cast expression.
      $wThe wrapper type. It is used in a cast expression.
      $_The resulting value
      $sigAn array of java.lang.Class objects representing +the formal parameter types. +
      $typeA java.lang.Class object representing +the formal result type.
      $classA java.lang.Class object representing +the class currently edited.
      +
    + +

    $0, $1, $2, ...

    + +

    The parameters passed to the methods insertBefore(), +insertAfter(), and addCatch() +are accessible with +$0, $1, $2, ... instead of +the original parameter names. +$1 represents the +first parameter, $2 represents the second parameter, and +so on. The types of those variables are identical to the parameter +types. +$0 is +equivalent to this. If the method is static, +$0 is not available. + +

    These variables are used as following. Suppose that a class +Point: + +

      class Point { + int x, y; + void move(int dx, int dy) { x += dx; y += dy; } +} +
    + +

    To print the values of dx and dy +whenever the method move() is called, execute this +program: + +

      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();
      +
    + +

    Note that the source text passed to insertBefore() is +surrounded with braces {}. +insertBefore() accepts only a single statement or a block +surrounded with braces. + +

    The definition of the class Point after the +modification is like this: + +

      class Point { + int x, y; + void move(int dx, int dy) { + { System.out.println(dx); System.out.println(dy); } + x += dx; y += dy; + } +} +
    + +

    $1 and $2 are replaced with +dx and dy, respectively. + +

    $1, $2, $3 ... 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. + + +

    $args

    + +

    The variable $args represents an array of all the +parameters. The type of that variable is an array of class +Object. If a parameter type is a primitive type such as +int, then the parameter value is converted into a wrapper +object such as java.lang.Integer to store in +$args. Thus, $args[0] is equivalent to +$1 unless the type of the first parameter is a primitive +type. Note that $args[0] is not equivalent to +$0; $0 represents this. + +

    If an array of Object is assigned to +$args, 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. + +

    $$

    + +

    The variable $$ is abbreviation of a list of +all the parameters separated by commas. +For example, if the number of the parameters +to method move() is three, then + +

      move($$)
    + +

    is equivalent to this: + +

      move($1, $2, $3)
    + +

    If move() does not take any parameters, +then move($$) is +equivalent to move(). + +

    $$ can be used with another method. +If you write an expression: + +

      exMove($$, context)
    + +

    then this expression is equivalent to: + +

      exMove($1, $2, $3, context)
    + +

    Note that $$ enables generic notation of method call +with respect to the number of parameters. +It is typically used with $proceed shown later. + +

    $cflow

    + +

    $cflow means "control flow". +This read-only variable returns the depth of the recursive calls +to a specific method. + +

    Suppose that the method shown below is represented by a +CtMethod object cm: + +

      int fact(int n) {
      +    if (n <= 1)
      +        return n;
      +    else
      +        return n * fact(n - 1);
      +}
    + +

    To use $cflow, first declare that $cflow +is used for monitoring calls to the method fact(): + +

      CtMethod cm = ...;
      +cm.useCflow("fact");
    + +

    The parameter to useCflow() is the identifier of the +declared $cflow variable. Any valid Java name can be +used as the identifier. Since the identifier can also include +. (dot), for example, "my.Test.fact" +is a valid identifier. + +

    Then, $cflow(fact) represents the depth of the +recursive calls to the method specified by cm. The value +of $cflow(fact) is 0 (zero) when the method is +first called whereas it is 1 when the method is recursively called +within the method. For example, + +

      +cm.insertBefore("if ($cflow(fact) == 0)"
      +              + "    System.out.println(\"fact \" + $1);");
      +
    + +

    translates the method fact() so that it shows the +parameter. Since the value of $cflow(fact) is checked, +the method fact() does not show the parameter if it is +recursively called within fact(). + +

    The value of $cflow is the number of stack frames +associated with the specified method cm +under the current topmost +stack frame for the current thread. $cflow is also +accessible within a method different from the specified method +cm. + +

    $r

    + +

    $r 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: + +

      Object result = ... ;
      +$_ = ($r)result;
    + +

    If the result type is a primitive type, then ($r) +converts from the wrapper type to the primitive type. +For example, if the result type is int, then +($r) converts from java.lang.Integer to +int. + +

    If the result type is void, then +($r) does not convert a type; it does nothing. +Moreover, the soruce text can include a return +statement with a resulting value: + +

      return ($r)result;
    + +

    Here, result is some local variable. +Since ($r) is specified, the resulting value is +discarded. +This return statement is regarded as the equivalent +of the return statement without a resulting value: + +

      return;
    + +

    $w

    + +

    $w represents a wrapper type. +It must be used as the cast type in a cast expression. +($w) converts from a primitive type to the corresponding +wrapper type. + +The following code is an example: + +

      Integer i = ($w)5;
    + +

    The selected wrapper type depends on the type of the expression +following ($w). If the type of the expression is +double, then the wrapper type is java.lang.Double. + +

    If the type of the expression following ($w) is not +a primitive type, then ($w) does nothing. + +

    $_

    + +

    insertAfter() in CtMethod and +CtConstructor inserts the +compiled code at the end of the method. In the statement given to +insertAfter(), not only the variables shown above such as +$0, $1, ... but also $_ is +available. + +

    The variable $_ 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 void, +then the type of $_ is Object and the value +of $_ is null. + +

    Although the compiled code inserted by insertAfter() +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 +asFinally to insertAfter() must be +true. + +

    If an exception is thrown, the compiled code inserted by +insertAfter() is executed as a finally +clause. The value of $_ is 0 or +null 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 $_ is never thrown +to the caller; it is rather discarded. + +

    $sig

    + +

    The value of $sig is an array of +java.lang.Class objects that represent the formal +parameter types in declaration order. + +

    $type

    + +

    The value of $type is an java.lang.Class +object representing the formal type of the result value. This +variable is available only in insertAfter() in +CtMethod and CtConstructor. + +

    $class

    + +

    The value of $class is an java.lang.Class +object representing the class in which the edited method is declared. + +

    addCatch()

    + +

    addCatch() 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 $e. + +

    For example, this program: + +

      +CtMethod m = ...;
      +CtClass etype = ClassPool.getDefault().get("java.io.IOException");
      +m.addCatch("{ System.out.println($e); throw $e; }", etype);
      +
    + +

    translates the method body represented by m into +something like this: + +

      +try {
      +    the original method body
      +}
      +catch (java.io.IOException e) {
      +    System.out.println(e);
      +    throw e;
      +}
      +
    + +

    Note that the inserted code fragment must end with a +throw or return statement. + +


    + +

    5.2 Modifying a method body

    + +

    javassist.expr.ExprEditor is a class +for replacing an expression in a method body. +The users can define a subclass of ExprEditor +to specify how an expression is modified. + +

    To run an ExprEditor object, the users must +call instrument() in CtMethod or +CtClass. + +For example, + +

      +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($$); }");
      +        }
      +    });
      +
    + +

    searches the method body represented by cm and +replaces all calls to move() in class Point +with a block: + +

      { $1 = 0; $_ = $proceed($$); }
      +
    + +

    so that the first parameter to move() is always 0. +Note that the substituted code is not an expression but +a statement or a block. + +

    The method instrument() searches a method body. +If it finds an expression such as a method call, field access, and object +creation, then it calls edit() on the given +ExprEditor object. The parameter to edit() +is an object representing the found expression. The edit() +method can inspect and replace the expression through that object. + +

    Calling replace() on the parameter to edit() +substitutes the given statement or block for the expression. If the given +block is an empty block, that is, if replace("{}") +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 +replace(): + +

      +{ before-statements;
      +  $_ = $proceed($$);
      +  after-statements; }
      +
    + +

    whichever the expression is either a method call, field access, +object creation, or others. The second statement could be: + +

      $_ = $proceed();
    + +

    if the expression is read access, or + +

      $proceed($$);
    + +

    if the expression is write access. + +

    javassist.expr.MethodCall

    + +

    A MethodCall object represents a method call. +The method replace() in +MethodCall 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 $ +have special meaning as in the source text passed to +insertBefore(). + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      $0 +The target object of the method call.
      +This is not equivalent to this, which represents +the caller-side this object.
      +$0 is null if the method is static. +
       
       
      $1, $2, ...     +The parameters of the method call. +
      +$_The resulting value of the method call.
      $rThe result type of the method call.
      $class    A java.lang.Class object representing +the class declaring the method. +
      $sig    An array of java.lang.Class objects representing +the formal parameter types.
      $type    A java.lang.Class object representing +the formal result type.
      $proceed    The name of the method originally called +in the expression.
      +
    + +

    Here the method call means the one represented by the +MethodCall object. + +

    The other identifiers such as $w, +$args and $$ +are also available. + +

    Unless the result type of the method call is void, +a value must be assigned to +$_ in the source text and the type of $_ +is the result type. +If the result type is void, the type of $_ +is Object and the value assigned to $_ +is ignored. + +

    $proceed is not a String value but special +syntax. It must be followed by an argument list surrounded by parentheses +( ). + +

    javassist.expr.FieldAccess

    + +

    A FieldAccess object represents field access. +The method edit() in ExprEditor +receives this object if field access is found. +The method replace() in +FieldAccess receives +source text representing the substitued statement or +block for the field access. + +In the source text, the identifiers starting with $ +have also special meaning: + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      $0 +The object containing the field accessed by the expression. +This is not equivalent to this.
      +this represents the object that the method including the +expression is invoked on.
      +$0 is null if the field is static. +
       
       
      $1 +The value that would be stored in the field +if the expression is write access. +
      Otherwise, $1 is not available. +
       
      $_ +The resulting value of the field access +if the expression is read access. +
      Otherwise, the value stored in $_ is discarded. +
       
      $r +The type of the field if the expression is read access. +
      Otherwise, $r is void. +
       
      $class    A java.lang.Class object representing +the class declaring the field. +
      $typeA java.lang.Class object representing +the field type.
      $proceed    The name of a virtual method executing the original +field access. +.
      +
    + +

    The other identifiers such as $w, +$args and $$ +are also available. + +

    If the expression is read access, a value must be assigned to +$_ in the source text. The type of $_ +is the type of the field. + +

    javassist.expr.NewExpr

    + +

    A NewExpr object represents object creation +with the new operator. +The method edit() in ExprEditor +receives this object if object creation is found. +The method replace() in +NewExpr receives +source text representing the substitued statement or +block for the object creation. + +In the source text, the identifiers starting with $ +have also special meaning: + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      $0 +null. +
      $1, $2, ...     +The parameters to the constructor. +
      $_ +The resulting value of the object creation. +
      A newly created object must be stored in this variable. +
       
      $r +The type of the created object. +
      $class    A java.lang.Class object representing +the class of the created object. +
      $sig    An array of java.lang.Class objects representing +the formal parameter types.
      $proceed    The name of a virtual method executing the original +object creation. +.
      +
    + +

    The other identifiers such as $w, +$args and $$ +are also available. + +

    javassist.expr.Instanceof

    + +

    A Instanceof object represents an instanceof +expression. +The method edit() in ExprEditor +receives this object if an instanceof expression is found. +The method replace() in +Instanceof receives +source text representing the substitued statement or +block for the expression. + +In the source text, the identifiers starting with $ +have also special meaning: + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      $0 +null. +
      $1 +The value on the left hand side of the original +instanceof operator. +
      $_ +The resulting value of the expression. +The type of $_ is boolean. +
      $r +The type on the right hand side of the instanceof operator. +
      $typeA java.lang.Class object representing +the type on the right hand side of the instanceof operator. +
      $proceed    The name of a virtual method executing the original +instanceof expression. +
      It takes one parameter (the type is java.lang.Object) +and returns true +
      if the parameter value is an instance of the type on the right +hand side of +
      the original instanceof operator. +Otherwise, it returns false. +
       
       
       
      +
    + +

    The other identifiers such as $w, +$args and $$ +are also available. + +

    javassist.expr.Cast

    + +

    A Cast object represents an expression for +explicit type casting. +The method edit() in ExprEditor +receives this object if explicit type casting is found. +The method replace() in +Cast receives +source text representing the substitued statement or +block for the expression. + +In the source text, the identifiers starting with $ +have also special meaning: + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      $0 +null. +
      $1 +The value the type of which is explicitly cast. +
      $_ +The resulting value of the expression. +The type of $_ is the same as the type +
      after the explicit casting, that is, the type surrounded +by ( ). +
       
      $rthe type after the explicit casting, or the type surrounded +by ( ). +
      $typeA java.lang.Class object representing +the same type as $r. +
      $proceed    The name of a virtual method executing the original +type casting. +
      It takes one parameter of the type java.lang.Object +and returns it after +
      the explicit type casting specified by the original expression. + +
       
       
      +
    + +

    The other identifiers such as $w, +$args and $$ +are also available. + +

    javassist.expr.Handler

    + +

    A Handler object represents a catch +clause of try-catch statement. +The method edit() in ExprEditor +receives this object if a catch is found. +The method insertBefore() in +Handler compiles the received +source text and inserts it at the beginning of the catch clause. + +In the source text, the identifiers starting with $ +have special meaning: + +

      + + + + + + + + + + + + + + + + + + + + + + +
      $1 +The exception object caught by the catch clause. +
      $rthe type of the exception caught by the catch clause. +It is used in a cast expression. +
      $wThe wrapper type. It is used in a cast expression. +
      $type     +A java.lang.Class object representing +
      the type of the exception caught by the catch clause. +
       
      +
    + +

    If a new exception object is assigned to $1, +it is passed to the original catch clause as the caught +exception. + +


    + +

    5.3 Adding a new method or field

    + +

    Javassist allows the users to create a new method and constructor +from scratch. CtNewMethod +and CtNewConstructor provide several factory methods, +which are static methods for creating CtMethod or +CtConstructor objects. +Especially, make() creates +a CtMethod or CtConstructor object +from the given source text. + +

    For example, this program: + +

      +CtClass point = ClassPool.getDefault().get("Point");
      +CtMethod m = CtNewMethod.make(
      +                 "public int xmove(int dx) { x += dx; }",
      +                 point);
      +point.addMethod(m);
      +
    + +

    adds a public method xmove() to class Point. +In this example, x is a int field in +the class Point. + +

    The source text passed to make() can refer to +$proceed if the target object and the target method name +are also given to make(). For example, + +

      +CtClass point = ClassPool.getDefault().get("Point");
      +CtMethod m = CtNewMethod.make(
      +                 "public int ymove(int dy) { $proceed(0, dy); }",
      +                 point, "this", "move");
      +
    + +

    this program creates a method ymove() defined below: + +

      +public int ymove(int dy) { this.move(0, dy); }
      +
    + +

    Note that $proceed has been replaced with +this.move. + +

    Javassist also allows the users to create a new field. + +

      +CtClass point = ClassPool.getDefault().get("Point");
      +CtField f = new CtField(CtClass.intType, "z", point);
      +point.addField(f);
      +
    + +

    This program adds a field named z to class +Point. + +

    If the initial value of the added field must be specified, +the program shown above must be modified into: + +

      +CtClass point = ClassPool.getDefault().get("Point");
      +CtField f = new CtField(CtClass.intType, "z", point);
      +point.addField(f, "0");    // initial value is 0.
      +
    + +

    Now, the method addField() 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 (;). + +


    + +

    5.4 Limitations

    + +

    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: + +

  • The .class notation is not supported. Use the +method Class.forName(). +In regular +Java, an expression Point.class means a Class +object representing the Point class. This notation is +not available. + +

  • Array initializers, a comma-separated list of expressions +enclosed by braces { and }, are not +supported. + +

  • Inner classes or anonymous classes are not supported. + +

  • switch statements are not supported yet. + +

  • Labeled continue and break statements +are not supported. + +

  • The finally clause following +try and catch clauses is not supported. + +

  • 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. + +

  • The users are recommended to use # as the separator +between a class name and a static method or field name. +For example, in regular Java, + +
      javassist.CtClass.intType.getName()
    + +

    calls a method getName() on +the object indicated by the static field intType +in javassist.CtClass. In Javassist, the users can +write the expression shown above but they are recommended to +write: + +

      javassist.CtClass#intType.getName()
    + +

    so that the compiler can quickly parse the expression. + + +


    + +
    Previous page + +


    +Java(TM) is a trademark of Sun Microsystems, Inc.
    +Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved. + +